C++ 权限控制,权限的继承(下)

简介: C++ 权限控制,权限的继承

四.struct和class的区别

我们知道struct是C语言中定义结构体的关键字,calss是C++中创建类的关键字,那么他俩到底有什么区别呢?我们通过一个例子来观察:

#include <stdio.h>
struct Base{
  int a;
  int b;
  int c;
  int d;
}; 
void Test(){
  Base t;
  t.a = 1;
  t.b = 2;
  t.c = 3;
  t.d = 4;
}
int main(){
  Test();
  return 0;
}

我们先来通过struct关键字来定义,编译发现没有错误,那么我们再来通过class来创建一个类来观察一下:

#include <stdio.h>
class Base{
  int a;
  int b;
  int c;
  int d;
}; 
void Test(){
  Base t;
  t.a = 1;
  t.b = 2;
  t.c = 3;
  t.d = 4;
}
int main(){
  Test();
  return 0;
}

这时候我们编译,发现出现了问题:编译器报错:cannot access private member declared in class 'Base'并且报错四次,告诉我们不能访问Base中的成员a,b,c,d。而这样的报错,我们在前文中简介权限控制的时候就讲解过了。

那么我们就可以发现问题:我们用struct定义结构体的时候,它的成员权限默认为public,而我们calss创建类的时候,它的成员默认权限为private这就是struct和callss的区别。

五.private是否被继承

前文中我们提到:只有类中的成员才可以访问private变量或者函数,那么在继承的时候,private变量是否会继承呢?

我们首先通过观察类所占内存来分析是否继承:

#include <stdio.h>
class Base{
private:
  int a;
  int b;
public:
  int c;
  int d;
}; 
class Sub:public Base{
  int e;
  int f;
};
void Test(){
  Sub t;
  printf("%d",sizeof(Sub));
}
int main(){
  Test();
  return 0;
}

这里需要注意,我们继承的时候要在父类名前面加上public告诉编译器是共有类型,否则继承的父类变量全为private类型

我们在程序输出窗口可以看到输出了24,说明Base类中不管是public类型还是private类型,都被继承过来了。

但是需要注意一点,继承过来的private类型,在子类中,无法使用,Base类中的private类型,只有Base类中的成员才可以调用

我们通过实例来论证:

#include <stdio.h>
class Base{
private:
  int a;
  int b;
public:
  int c;
  int d;
}; 
class Sub:public Base{
public:
  int e;
  int f;
};
void Test(){
  Sub t;
  t.a = 1;
  t.b = 2;
  t.c = 3;
  t.d = 4;
  t.e = 5;
  t.f = 6;
}
int main(){
  Test();
  return 0;
}

我们编译时,编译器错误提示:

说明继承过来的Base类中的a和b,不能在子类中使用。

六.类的继承中的构造函数

我们再来观察一个有趣的过程:

#include <stdio.h>
class Base{
private:
  int a;
  int b;
public:
  int c;
  int d;
  Base(){
    printf("Base构造函数\n");
  }
}; 
class Sub:public Base{
public:
  int e;
  int f;
  Sub(int c,int d,int e,int f){
    printf("Sub构造函数\n");
    this->c = 1;
    this->d = 2;
    this->e = 3;
    this->f = 4;
  }
};
void Test(){
  Sub t(1,2,3,4);
}
int main(){
  Test();
  return 0;
}

我们来到反汇编查看:

push        4
push        3
push        2
push        1
lea         ecx,[ebp-18h]
call        @ILT+60(Sub::Sub) (00401041)

我们可以看到Sub的构造函数又调用了一个构造函数,我们跟进去看一下:

mov         dword ptr [ebp-4],ecx
mov         ecx,dword ptr [ebp-4]
call        @ILT+65(Base::Base) (00401046)

我们看到程序输出窗口输出:

那么我们可以分析:当调用子类的构造函数时,父类的构造函数也会被调用,我们在上一节也讲解了,如果我们没有在类中定义构造函数,编译器会自动为我们编译一个无参构造函数。

相关文章
|
3月前
|
存储 安全 Java
c++--继承
c++作为面向对象的语言三大特点其中之一就是继承,那么继承到底有何奥妙呢?继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用,继承就是类方法的复用。
88 0
|
6月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
345 6
|
8月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
134 16
|
8月前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
178 5
|
10月前
|
编译器 C++ 开发者
【C++】继承
C++中的继承是面向对象编程的核心特性之一,允许派生类继承基类的属性和方法,实现代码复用和类的层次结构。继承有三种类型:公有、私有和受保护继承,每种类型决定了派生类如何访问基类成员。此外,继承还涉及构造函数、析构函数、拷贝构造函数和赋值运算符的调用规则,以及解决多继承带来的二义性和数据冗余问题的虚拟继承。在设计类时,应谨慎选择继承和组合,以降低耦合度并提高代码的可维护性。
155 1
【C++】继承
|
11月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
130 1
|
11月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
122 1
|
11月前
|
安全 编译器 程序员
C++的忠实粉丝-继承的热情(1)
C++的忠实粉丝-继承的热情(1)
96 0
|
11月前
|
编译器 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
134 0
|
11月前
|
程序员 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
111 0