应该使用基类构造函数来初始化 确保基类的构造函数被调用是继承中非常重要的一部分,因为只有基类的构造函数知道如何正确初始化基类定义的成员。...派生类需要自己明确声明哪些函数或类是它的友元 如何解决编译错误: 要解决 Display 函数不能访问 Student 类的 _stuNum 成员的问题,可以在 Student 类中也声明 Display...静态成员变量在所有实例中共享,而静态成员函数可以在没有类实例的情况下直接通过类名调用。当静态成员被继承时,派生类共享同一个静态成员副本,因为静态成员是属于类的,不属于类的任何具体对象。...分析: Person::_count 是静态成员变量,并且初始化为 0。它统计 Person 及其派生类 Student 和 Graduate 的对象个数。...因此,第二次打印 _count 的结果是 0 静态成员的继承性质:静态成员在基类及其派生类之间是共享的,而不是每个派生类都有独立的静态成员副本。
拷贝构造函数与构造不同,必须在派生类的拷贝构造的初始化列表处显示调用基类的拷贝构造,完成基类成员的复制。在传参时有人可能会有疑问,调用基类的拷贝构造该如何将子类中基类成员提取出来呢?...类静态成员属于整个类,为所有对象共享,并不单属于某个特定对象,所以静态成员可以认为是属于基类和所有派生类,即属于整个继承体系。...但非静态成员并不符合上面所说的特性,非静态成员理应属于其所属类,所以基类对象中的成员和派生类对象中的基类成员互不干扰,即使两部分的成员在命名上完全相同,但是他们属于不同的类,不同的对象,互不干扰。...,同时也属于所有的派生类的所有对象,换句话可以说为静态成员属于基类和派生类 int main() { Person p; Student s; p....//非静态成员对于基类和派生类来说各有一份互不干扰,因为基类和派生类本身就是不同的类,下来的对象也是不同的,理应有各自的 //成员变量 Person* ptr = nullptr; //cout
(补充:静态非常量数据成员,其只能在类外定义和初始化,在类内仅是声明而已。)...static 类对象必须要在类外进行初始化,static 修饰的变量先于对象存在,所以 static 修饰的变量要在类外初始化; 由于 static 修饰的类成员属于类,不属于对象,因此 static...成员函数不能被 virtual 修饰,static 成员不属于任何对象或实例,所以加上 virtual 没有任何实际意义;静态成员函数没有 this 指针,虚函数的实现是为每一个对象分配一个 vptr...派生类中重写了这个虚函数,我们期望着根据对象的真实类型不同,而调用各自实现的虚函数,但实际上当我们创建一个派生类对象时,首先会创建派生类的基类部分,执行基类的构造函数,此时,派生类的自身部分还没有被初始化...,而虚函数意味着在运行期间进行类型确定,所以内联函数不能是虚函数; 静态函数,静态函数不属于对象属于类,静态成员函数没有this指针,因此静态函数设置为虚函数没有任何意义。
如图所示:派生类对象赋值给基类对象时是直接将派生类中属于基类那一部分切割给基类,引用和指针也是一样,基类的引用是派生类中属于基类那一部分成员的别名,基类的指针指向派生类中属于基类的那一部分。...派生类的默认成员函数 派生类的默认成员函数的规则如下: 1、派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。..._stuNum << endl; } ---- 六、继承与静态成员 1、继承与静态成员 在 类和对象下篇 中我们介绍了类的静态成员变量具有如下特性: 静态成员为所有类对象所共享,不属于某个具体的对象...在继承中,如果父类定义了 static 静态成员,则该静态成员也属于所有派生类及其对象;即整个继承体系里面只有一个这样的成员,并且无论派生出多少个子类,都只有一个 static 成员实例; class...; // 学号 }; 可以看到,父类和子类在操作时操作的都是同一个静态成员实例,因为父类和子类中静态成员是同一个地址;所以,静态成员属于所有父类及其对象,以及所有派生类及其对象,且只有一份。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。...继承的思想实现了 属于(IS-A) 关系。例如,哺乳动物 属于(IS-A) 动物,狗 属于(IS-A) 哺乳动物,因此狗 属于(IS-A) 动物。...C# 中创建派生类的语法如下: class { ... } class : { ... } 基类的初始化 派生类继承了基类的成员变量和成员方法。...您可以在成员初始化列表中进行父类的初始化。...当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。 虚方法是使用关键字 virtual 声明的。 虚方法可以在不同的继承类中有不同的实现。 对虚方法的调用是在运行时发生的。
静态构造函数在以下情况下使用:初始化静态成员:静态构造函数用于初始化类的静态成员。这些成员是类的所有实例共享的,只会在类加载时初始化一次。...静态成员和非静态成员的区别?静态变量、静态成员和非静态成员是面向对象编程中的概念,它们有不同的特性和使用方式。静态变量:静态变量是属于类而不是属于类的实例的变量。...这些成员属于类而不是类的实例,可以通过类名直接访问,而无需创建类的实例。静态成员在类加载时初始化,只会有一个副本,供所有实例和其他类访问。...() { // 执行静态方法的逻辑 }}非静态成员:非静态成员属于类的实例,每个实例都有自己的副本。...非静态变量属于类的实例,每个实例都有独立的副本,需要通过实例访问。静态成员包括静态字段、静态方法等,属于类而不是实例,可通过类名直接访问。
4.1 派生类的构造函数 4.2 派生类的拷贝构造函数 4.3 派生类的赋值运算符重载 4.4 派生类的析构函数 4.5 总结 五.继承与友元 六.继承与静态成员 6.1 静态成员 6.2 确定是否为解引用...(即便基类的成员函数会继承下来),那如何自己写出这几个默认成员函数呢?...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。 派生类对象析构清理先调用派生类析构再调基类的析构。...即以学生的身份他叫张三,以老师的身份它叫做张老师。 但指定作用域没有彻底解决这个问题,因为这样就是将二义性的东西彻底分开,即如上的地址不同,对象就不同。那如何彻底解决呢?...如何解决数据冗余和二义性的 继承和组合的区别?什么时候用继承?什么时候用组合? 答: 多继承中的一种特殊继承,即一个类可能被另一个类以不同的作用域继承多次。
隐藏(重定义)与重载 重载:在同一作用域; 隐藏:在不同的作用域,一个在父类,一个在子类。...五.派生类中的默认成员函数 1.构造函数 派生类必须先自动调用基类的默认构造(初始化基类的那一部分成员),如果基类没有默 认构造,就要在派生类的初始化列表阶段显式调用基类的构造函数,然后派生类调用自己...2.拷贝构造 派生类的拷贝构造必须先调用基类的拷贝构造完成基类的拷贝初始化。 3.赋值重载 派生类赋值重载必须先调用基类的赋值重载完成基类的复制。...友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员; 基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。...无论派生出多少个子 类,都只有一个static成员实例 ,静态成员不属于任何一个具体的实例对象,而是属于类本身,子类可以继承父类的静态成员,而不需要重新定义。
静态数据成员是属于类的,它只在类的范围内有效。因为不管产生了多少对象,类的静态数据成员都有着单一的存储空间,所以存储空间必须定义在一个单一的地方。...与静态数据成员不同,静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员。 而静态成员函数并不属于某一对象,它与任何对象都无关,因此静态成员函数没有 this 指针。...派生类的构造函数必须要以合适的初值作为参数,隐含调用基类和新增对象成员的构造函数,来初始化它们各自的数据成员,然后再加入新的语句对新增普通数据成员进行初始化。...(自左向右),而与在派生类构造函数的成员初始化列表中给出的顺序无关。...两个同名函数不在同一个类中,而是分别在:基类和派生类中,属于同名覆盖。若是重载函数,二者的参数个数和参数类型必须至少有一者不同,否则系统无法确定调用哪一个函数。
类静态成员变量:被类的所有对象共享,包括子对象。必须在类外初始化,不可以在构造函数内进行初始化。 类静态成员函数:所有对象共享该函数,不含this指针,不可使用类中非静态成员。...const和static不可同时修饰类成员函数,const修饰成员函数表示不能修改对象的状态,static修饰成员函数表示该函数属于类,不属于对象,二者相互矛盾。...4.如何理解多态 定义:同一操作作用于不同的对象,产生不同的执行结果。C++多态意味着当调用虚成员函数时,会根据调用类型对象的实际类型执行不同的操作。...Overload(重载):函数名相同,参数类型或顺序不同的函数构成重载。 Override(重写):派生类覆盖基类用virtual声明的成员函数。...Overwrite(隐藏):派生类的函数屏蔽了与其同名的基类函数。派生类的函数与基类函数同名,但是参数不同,隐藏基类函数。如果参数相同,但是基类没有virtual关键字,基类函数将被隐藏。
(派生类对应基类,子类对应父类,在使用时尽量对应使用) 之前我们了解的代码复用,比如模板类,模板函数等都属于函数复用,而继承属于类设计层次的复用。...继承后父类的成员(成员变量+成员函数)都变成子类的一部分,子类复用了父类的成员。 2.定义 1.格式 2.继承关系和访问限定符 继承方式和访问限定符所使用的关键字是一样的,但他们的功能不同。...fun函数并不构成重载,因为他们在不同的作用域,他们是隐藏关系 四、派生类的默认成员函数 1.构造函数 派生类构造函数必须调用基类的构造函数初始化基类那一部分成员,如果基类没有默认构造函数,派生类就必须在初始化列表处显示的调用基类构造函数...五、友元 友元关系不能继承,即基类的友元不能访问派生类的private和protected成员 六、静态成员 基类的静态成员,在整个继承体系中都只有一个这样的成员,即无论有多少个派生类,都只有一个static...(注意虚拟继承只能用在菱形继承中) 虚拟继承解决问题的原理: 简单来说是将D类中的A类成员放到所有成员的最下面,此时这一份A同时属于B和C。 那么B和C如何找到A呢?
一,构造函数 构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。...构造函数 构造函数是用来初始化对象的,虚函数依赖虚函数能产生地址,存储在虚函数表当中,对象必须存在/实例化(vfptr->vftable->虚函数地址),虚函数是在不同类型的对象产生不同的动作,...静态成员函数 静态成员函数对于每个类来说只有一份,所有的对象都共享这一份代码,它是属于类的而不是属于对象,编译时确定的,不能被继承,只属于该类。...友元函数 友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。 9、多态,虚函数,纯虚函数?...就是基类的指针或引用有可能指向不同的派生类对象,对于非虚函数,执行时实际调用该函数的对象类型即为该指针或引用的静态类型(基类类型);而对于虚函数,执行时实际调用该函数的对象类型为该指针或引用所指对象的实际类型
Q1:C++的多态如何实现 静态多态: 也称为编译期间的多态,编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误...(这句话刚开始还真没反应过来,也是啊,基类都不能初始化对象了,还怎么去调用基类方法啊) ---- Q3:抽象基类派生类对象可以调用基类方法吗?...所以在调用基类的析构函数时,派生类对象的数据成员已经销毁,这个时候再调用子类的虚函数没有任何意义。 ---- Q8:静态函数能定义为虚函数吗?...1、static成员不属于任何类对象或类实例,所以即使给此函数加上virutal也是没有任何意义的。 2、静态与非静态成员函数之间有一个主要的区别,那就是静态成员函数没有this指针。...1、 虚函数表是class specific的,也就是针对一个类来说的,这里有点像一个类里面的staic成员变量,即它是属于一个类所有对象的,不是属于某一个对象特有的,是一个类所有对象共有的。
那么基类不同的限定访问,在不同方式的继承之后,派生类会出现怎么样的访问限定。 结论: 基类的私有成员,无论是哪一种形式的继承,继承之后在派生类中也不能访问。...如果基类中有默认成员函数,当派生类中不显示调用的时候,会自动调用。 对于构造函数,都会在初始化列表的时候自动调用基类的构造函数。...这样才能保证先析构派生类,再析构基类 构造函数 1.当基类有默认的构造函数的时候,可以只初始化派生类新的成员变量,也可以自己调用基类的默认构造,看自己的心情。...2.当基类没有默认的构造函数的时候,必须自己要写构造函数调用基类的 派生类的构造函数先初始化基类,再初始派生类中的成员 静态成员变量不属于具体的类对象,属于该类所有对象。...对于基类的静态成员,无论它派生出多个派生类,所有继承体只要这么应该静态成员。
C++程序的内存布局与C程序布局类似,区别是C++不再区分全局变量和静态变量是否已经初始化,全部存储在静态存储区;另外堆中存放new/delete申请释放的资源,而malloc和free申请的资源存放在自由存储区...2.18 static全局变量与普通的全局变量的区别 全局变量在整个工程文件内都有效。 静态全局变量只在定义它的文件内有效。 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。...多态:通过继承同一个基类,产生了相关的不同的派生类,与基类中同名的成员函数在不同的派生类中会有不同的实现,也就是说:一个接口、多种方法。...覆盖和隐藏的区别: 派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。 派生类的函数与基类的函数同名,参数也相同。...在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
继承中的作用域 1.在继承体系中基类和派生类都有独立的作用域 2.子类和父类有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况也叫隐藏,或者重定义 (在子类成员函数中,可以使用 基类::基类成员...显示访问) 3.需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏 4.注意在实际中的继承体系里面最好不要定义同名的成员 ---- 因为父类和子类在不同的作用域,所以可以分别在父子类中创建相同的成员变量...A,两者属于不同的作用域 所以fun函数构成隐藏或者重定义 5.派生类中的默认成员函数 #include #include using namespace std;...name属于父类的成员,所以要去调用父类的构造函数初始化 ---- 如果不写,会在初始化列表去调用父类的默认构造函数(自己实现的全缺省的构造函数) 拷贝构造函数 子类的拷贝构造需要调用父类的拷贝构造...继承与静态成员 继承并不会把static修饰的静态成员变量继承下来,但是可以访问它 静态成员变量属于整个类,即属于父类,也属于子类 ---- #include #include<string
那不同的继承方式有什么不一样呢?...派生类的默认成员函数 在之前类和对象的学习中,我们学过类里面有6个默认成员函数 即我们不写,编译器可以自动生成,那在派生类中,这6个默认成员函数是如何生成的呢?...我们发现这里我们自己初始化继承下来的_name成员但是报错了。 为什么不行呢?那这里要告诉大家的是: 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。...因为这样才能保证先清理子类成员再清理父类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。 派生类对象析构清理先调用派生类析构再调基类的析构。 5....继承与静态成员 首先我们来回顾一下什么是静态成员: 静态成员不属于某个具体的对象,存放在静态区,被所有类对象所共有。
继承与静态成员 父类定义了 static 静态成员,则 整个继承体系里面中有一个这样的成员。 可以理解为共享,父类的静态成员可以在子类共享,父类和子类都能去访问它。...注意:静态成员是一定不被包含在对象中的!...派生类的默认成员函数 6个默认成员函数,“ 默认 ” 的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?...1、派生类的构造函数 ① 父类成员需调用自己的构造完成初始化。 即子类的构造函数必须调用父类的构造函数初始化父类的那一部分成员。...2、派生类的拷贝构造函数 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
如果异常发生在构造函数中,则当前的对象可能只构造了一部分(有些成员已经初始化了,另一些成员在异常发生前也许还没有初始化)。即使某个对象只构造了一部分,我们也要确保已构造的成员能被正确地销毁。...与其他函数调用一样,如果在参数初始化的过程中发生了异常,则该异常属于调用表达式的一部分,并将在调用者所在的上下文中处理。 处理构造函数初始值异常的唯一方法是将构造函数写成函数try语句块。...命名空间定义 1.1 每个命名空间都是一个作用域 同其他作用域类似,命名空间中的每个名字都必须表示该空间内的唯一实体。因为不同命名空间的作用域不同,所以在不同命名空间内可以有相同名字的成员。...,对象、指针和引用的静态类型决定了我们能够使用哪些成员。...当然,继承体系中的每个类都可能在某个时刻成为“最底层的派生类”。只要我们能创建虚基类的派生类对象,该派生类的构造函数就必须初始化它的虚基类。
三、派生类对象及派生类向基类的的类型转换 一个派生类对象包含多个组成部分:一个含有派生类自己定义的(非静态)成员的子对象,以及一个与该派生类继承的基类对应的子对象,如果有多个基类,那么这样的子类对象也有多个...五、派生类的默认成员函数 6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢? 1....派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。 2....基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子 类,都只有一个static成员实例 。...面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?
领取专属 10元无门槛券
手把手带您无忧上云