标签:std 其他 不能 通过 定义 value 类构造 成员 移动
继承的构造函数
-
一个类只继承其直接基类的构造函数,默认/拷贝/移动构造函数是不能被继承的;
-
继承Father的构造函数
using Father::Father;
//继承Father的构造函数 using让某个名字在当前的作用域可见;
//编译器遇到这条代码的时候,会把基类的每个构造函数都生成一个与之对应的派生类构造函数
-
如果基类A的构造函数有默认参数的话,那么编译器遇到这种using A::A的时候,就会帮咱们在派生类B中构造出多个构造函数来;
- 第一个构造函数时带有所有参数的构造函数;
- 其余的构造函数,每个分别省略掉一个默认参数;
//示例:
Son(int i, int j, int k = 5) :Father(i, j, k){};
Son(int i, int j, int k):Father(i,j,k){};
Son(int i, int j):Father(i,j){};
-
如果基类含多个构造函数,则多数情况下,派生类会继承所有这些构造函数,但如下情况例外:
- 如果在派生类中定义的构造函数与基类构造函数有相同的参数列表,那么从基类中继承来的构造函数会被你在派生类中定义的覆盖掉,相当于只继承了一部分构造函数;
- 默认/拷贝/移动构造函数是不会被继承的;
- 如果子类,只含有using Father::Father从Father继承来的构造函数的话,那么编译器会给它合成默认的构造函数;
#include
using namespace std;
class Father
{
public:
Father(int i, int j, int k)
{
}
};
class Son : public Father
{
public:
using Father::Father; //继承Father的构造函数 using让某个名字在当前的作用域可见;
//编译器遇到这条代码的时候,会把基类的每个构造函数都生成一个与之对应的派生类构造函数
};
int main()
{
Son son(3, 4, 5);
}
多重继承
从多个父类产生出子类,多重继承;
多重继承概述
#include
using namespace std;
class Base
{
public:
Base(int i) :m_value_base(i) {};
public:
int m_value_base;
virtual ~Base()
{
}
void my_info()
{
cout
静态成员变量
静态成员属于类,不属于对象;
为了能够使用,需要定义静态成员变量;如果代码中不用该静态变量,可以不定义;如果用到该静态变量,可以定义;否则,链接出错;
#include
using namespace std;
class Base
{
public:
Base(int i) :m_value_base(i) {};
public:
virtual ~Base()
{
}
void my_info()
{
cout
派生类构造函数和析构函数
- 构造一个派生类对象将同时构造并初始化所有基类子对象;
- 派生类的构造函数初始化列表只初始化它的直接基类,每个类的构造函数都负责初始化它的直接基类,就会让所有类都初始化;
- 派生类构造函数初始化列表将实参分别传递给每个直接基类;基类的构造顺序跟派生列表(继承的顺序 )中基类的出现顺序保持一致;
- 析构函数的调用顺序与构造函数的顺序完全相反;
显示的初始化基类和隐式的初始化基类
- 隐式的初始化基类: 派生类的构造函数初始化列表中没有调用带参数的基类构造函数,而是调用的基类的默认构造函数来实现基类的初始化;
#include
using namespace std;
class Base
{
public:
Base(int i) :m_value_base(i)
{
cout
从多个父类继承构造函数
如果一个类从它的基类中继承了相同的构造函数,这个类必须为该构造函数定义它的自己的版本;
子类要定义同参数的构造函数的自己的版本;
#include
using namespace std;
class Father_A
{
public:
Father_A(int tv) {};
};
class Father_B
{
public:
Father_B(int tv) {};
};
class Son :public Father_A, public Father_B
{
using Father_A::Father_A;//继承Father_A的构造函数 Son(int tv):Father_A(tv){}
using Father_B::Father_B;//继承Father_B的构造函数 Son(int tv):Father_B(tv){}
Son(int tv) :Father_A(tv), Father_B(tv) {};
};
int main()
{
}
类型转换
基类指针可以指向一个派生类对象:编译器隐式执行这种派生类到基类的转换,转换成功的原因是每个派生类对象都包含一个基类对象部分;所以基类的引用或者指针是可以绑定到基类对象这部分;
上述对于多重继承同样成立;
#include
using namespace std;
class Base
{
public:
Base(int i) :m_value_base(i)
{
cout
虚基类,虚继承
派生列表中,同一个基类只能出现一次,但是如下两种情况例外;
-
派生类可以通过它的两个直接基类分别继承同一个间接基类;
-
直接继承某个基类,然后通过另一个基类间接继承
虚基类和虚继承
- 无论这个类在继承体系中出现多少次,派生类中,都只会包含唯一一个共享的虚基类字内容;不会出现访问不明确的问题;
- 虚继承只是对孙子类有意义,对孙子类的直接基类没有意义;例Son继承Father_A和Father_C,Father_A和Father_C继承Base;那么Father_A和Father_B虚继承Base,对Son有意义,避免它间接继承Base两次;
- 虚继承:表示后续从本类派生的类应该共享虚基类Base的同一份实例;
- 虚继承之后:虚基类的初始化使用孙子类;
说明
- 现在是Son类初始化虚基类,如果Son有了子类,那么由Son的子类初始化虚基类;虚基类是由最底层的派生类来初始化;
- 初始化顺序:先初始化虚基类,然后按照派生列表中出现的顺序来初始化其他类;多个虚基类的话,按照派生列表中直接基类往回追溯,看是否这些直接基类中是否含有虚基类,反正是先追溯到哪个,先构造那个虚基类;析构顺序和构造顺序相反;
#include
using namespace std;
class Base
{
public:
Base(){}
Base(int i) :m_value_base(i)
{
cout
总结
- 不太提倡使用多重继承;简单,不容易出现二义性,使用多重继承;
- 使用单一继承能解决的尽量不要用多重继承;
【C/C++】【类和对象】多重继承和虚继承
标签:std 其他 不能 通过 定义 value 类构造 成员 移动
原文地址:https://www.cnblogs.com/Trevo/p/13363941.html