一、构造/析构顺序及继承性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class A
{
private:
int _a;
public:
A(int a = 0): _a(a)
{
cout << "A()" << this << endl;
}
~A()
{
cout << "~A()"<< this <<endl;
}
};

class B : public A
{
private:
int _b;
public:
B(int b): _b(b), A()
{
cout << "B()" << this << endl;
}
~B()
{
cout << "~B()"<< this <<endl;
}
};

在这里插入图片描述
结论:

  1. 构造顺序:先构造基类,后构造派生类
  2. 析构顺序:先析构派生类,后析构基类

二、拷贝构造的继承性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class A
{
private:
int _a;
public:
A(int a = 0): _a(a)
{
cout << "A()" << this << endl;
}
A(const A& src): _a(src._a)
{
cout << "A(const A& src)"<< this << endl;
}
~A()
{
cout << "~A()"<< this <<endl;
}
};

class B : public A
{
private:
int _b;
public:
B(int b): _b(b), A()
{
cout << "B()" << this << endl;
}
B(const B& src): _b(src._b)
{
cout << "B(const B& src)" << this << endl;
}
~B()
{
cout << "~B()"<< this <<endl;
}
};

在这里插入图片描述
结论:

  1. 先调用基类缺省的构造函数,后调用派生类的拷贝构造函数
  2. 若派生类没有缺省构造函数A(),就会报错

疑惑:如何去调用基类的拷贝构造而不是缺省构造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<iostream>
using namespace std;

class A
{
private:
int _a;
public:
A(int a = 0) : _a(a)
{
cout << "A()" << this << endl;
}
A(const A& src) : _a(src._a)
{
cout << "A(const A& src)" << this << endl;
}
~A()
{
cout << "~A()" << this << endl;
}
};

class B : public A
{
private:
int _b;
public:
B(int b) : _b(b), A()
{
cout << "B()" << this << endl;
}
B(const B& src) : _b(src._b), A(src) //发生赋值兼容规则(切片)
{
cout << "B(const B& src)" << this << endl;
}
~B()
{
cout << "~B()" << this << endl;
}
};
int main()
{
B b(10);
B b1(b);
return 0;
}

在这里插入图片描述
结果:

将B类型src传递给A类型的A(const A& src)拷贝构造函数,发生了赋值兼容规则(切片现象)


三、赋值重载不具有继承性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<iostream>
using namespace std;

class A
{
private:
int _a;
public:
A(int a = 0) : _a(a)
{
cout << "A()" << this << endl;
}
A(const A& src) : _a(src._a)
{
cout << "A(const A& src)" << this << endl;
}
A& operator=(const A& src)
{
if(this != &src)
{
_a = src._a;
cout << "A& operator=(const A& src)" << endl;
}
}
~A()
{
cout << "~A()" << this << endl;
}
};

class B : public A
{
private:
int _b;
public:
B(int b) : _b(b), A()
{
cout << "B()" << this << endl;
}
B(const B& src) : _b(src._b), A(src) //发生赋值兼容规则(切片)
{
cout << "B(const B& src)" << this << endl;
}
B& operator=(const B& src)
{
if(this != &src)
{
_b = src._b;
cout << "B& operator=(const B& src)" << endl;
}
}
~B()
{
cout << "~B()" << this << endl;
}
};
int main()
{
B b1(10);
B b2(20);
b1 = b2;
return 0;
}

在这里插入图片描述
结论:默认情况下仅仅调用了派生类的对象的赋值重载,并未调用基类的赋值重载。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<iostream>
using namespace std;

class A
{
private:
int _a;
public:
A(int a = 0) : _a(a)
{
cout << "A()" << this << endl;
}
A(const A& src) : _a(src._a)
{
cout << "A(const A& src)" << this << endl;
}
A& operator=(const A& src)
{
if(this != &src)
{
_a = src._a;
cout << "A& operator=(const A& src)" << endl;
}
}
~A()
{
cout << "~A()" << this << endl;
}
};

class B : public A
{
private:
int _b;
public:
B(int b) : _b(b), A()
{
cout << "B()" << this << endl;
}
B(const B& src) : _b(src._b), A(src) //发生赋值兼容规则(切片)
{
cout << "B(const B& src)" << this << endl;
}
B& operator=(const B& src)
{
if(this != &src)
{
*(A*)this = src; //将调用基类赋值重载
_b = src._b;
cout << "B& operator=(const B& src)" << endl;
}
}
~B()
{
cout << "~B()" << this << endl;
}
};
int main()
{
B b1(10);
B b2(20);
b1 = b2;
return 0;
}

在这里插入图片描述