编译器什么情况下,合成构造函数

scorlw 发布于

编译器什么情况下,合成构造函数

c++

我们知道,当我们要生成对象时,如果我们没有显式的定义构造函数,但是对象还是生成成功了。因为编译器会自动的为我们合成构造函数,然后调用构造函数生成对象。

第一种情况:

A类有构造函数,B类中没有构造函数,B类中有A类对象作为私有成员。如果这时候,我们需要生成一个B类对象时,编译器会为B类合成构造函数,并在初始化成员时,在初始化列表调用A类的构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A 
{
public:
A() //A类有构造函数
{}
private:
int _a;
};
class B
{
public: //B类没有显式定义构造函数
private:
int _b;
A a;
};

int main()
{
B b; //构建B类
return 0;
}

第二种情况:

A类为基类,B类是A类的子类,A类中有缺省的构造函数,则在生成B类的对象的时候,编译器会为B类合成构造函数,且调用。并在初始化列表里调用A类的构造函数。在调用析构函数时,先调用B类的析构函数,再调用A类的析构函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A 
{
public:
A()
{}
private:
int _a;
};
class B :public A //B是A的子类
{
public: //B类没有显式定义构造函数
private:
int _b;
};
int main()
{
B b; //构建B类
return 0;
}

第三种情况:

虚拟继承,A类,B类中都没有显式定义构造函数。但在生成B类对象时,编译器会自动合成构造函数。目的:要把基类的偏移量表格地址放到对象地址的前4个字节中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A 
{
public:
private:
int _a;
};
class B :virtual public A
{
public:
private:
int _b;
};
int main()
{
B b;
return 0;
}

第四中情况:

A类中带有虚函数,但是该类没有显式定义构造函数。编译器会自动合成构造函数。构造函数的操作:会把虚表的地址放到对象的前四个字节中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A 
{
public:
virtual void FunTest()
{
cout << "FunTest()" << endl;
};
private:
int _a;
};

int main()
{
A a;
return 0;
}

原文地址:https://www.cnblogs.com/bigbigtree/p/3540984.html