抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

继承

1
2
3
4
5
6
7
8
9
// 派生类 B 基类 A
class B{
public :

};
//
class A : public B {

};

继承权限影响的什么 类外对于访问子类对继承父类的方法和属性的访问权限

继承的好处:

  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
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*************************************************************************
> File Name: 继承.cpp
> Author: 秃头王
> Mail: 1658339000@qq.com
> Created Time: 2021年11月19日 星期五 19时55分12秒
************************************************************************/

#include <iostream>
using namespace std;

#define BEGINS(x) namespace x { // namesoace of x
#define ENDS(x) } // namespace of x

BEGINS(test1)

class Base {
public :
int x;
protected :
int y;
private :
int z;

};

class public_Bace : public Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
//z = 2; // no, z private
}
};

class protected_Bace : protected Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
//z = 2; // no, z private
}
};

class private_Bace : private Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
// z = 2; // no, z private
}
};

int main() {
public_Bace a;
// 都是继承父类的方法
// 继承 + x 在父类中的权限 = 表现出来的
a.x = 3; // ok, putback + public = public
// a.y = 4; // no, public + protected = protected
// a.z = 5; // no, public + private = private

protected_Bace b;
// b.x = 3; // no, protected + public = protected
// b.y = 4; // no, protected + protected = protected
// b.z = 5; // no, protected + private = private

private_Bace c;
// c.x = 3; // no, private + public = private
// c.y = 4; // no, private + protected = private
// c.z = 5; // no, private + private = private

return 0;
}
ENDS(test1)


BEGINS(test2)

class Base {
public :
Base(string name) : class_name(name){}
int x;
string class_name;
private :
int y;
};

class A : public Base {
public:
A() : Base("class_A"){}
};

class B : public Base {
public:
B() : Base("class_B"){}
};

class C : public Base {
public:
C() : Base("class_C"){}
};

void func(Base &b) {
cout << "nput class : " << b.class_name << endl;
return ;
}

int main() {
A a;
B b;
C c;
// 隐式类型转换 子类 -> 父类
func(a);
func(b);
func(c);

cout << "sizeof(Base) = " << sizeof(Base) << endl;
cout << "sizeof(A) = " << sizeof(A) << endl;
return 0;
}

ENDS(test2)

BEGINS(test3)

class Base {
public :
Base(string name) : class_name(name){}
int x;
string class_name;
private :
int y;
};

class A : public Base {
public:
A() : Base("class_A"){}
};

class B : public Base {
public:
B() : Base("class_B"){}
};

class C : public Base {
public:
C() : Base("class_C"){}
};

void func(Base *b) {
cout << "nput class : " << b->class_name << endl;
return ;
}

int main() {
A a;
B b;
C c;
// 子类的地址也是可以转换成父类的地址
func(&a);
func(&b);
func(&c);
return 0;
}

ENDS(test3)

int main() {
// test1::main();
// test2::main();
test3::main();
return 0;
}

继承-构造函数

构造顺序与析构顺序一定是相反的

先构造一定后析构

先析构子类的属性后析构父类的属性

菱形继承-多继承

是不是所有的面向对象语言都允许多继承? 不是

C#、java 是不允许多继承的

A ( run () )

B ( run () )

C ( run () )

D ( run () )

菱形继承有些场景是可以编译通过但是输出不确定

先是完成 基类构造 在完成 派生类构造

拷贝&赋值–继承

先完成父类的拷贝行为 在完成子类的拷贝行为

拷贝行为

拷贝构造函数:显示调用父类拷贝构造

赋值运算符:显示调用父类的赋值运算函数

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*************************************************************************
> File Name: 继承.cpp
> Author: 秃头王
> Mail: 1658339000@qq.com
> Created Time: 2021年11月19日 星期五 19时55分12秒
************************************************************************/

#include <iostream>
using namespace std;

#define BEGINS(x) namespace x { // namesoace of x
#define ENDS(x) } // namespace of x

BEGINS(test1)

class Base {
public :
int x;
protected :
int y;
private :
int z;

};

class public_Bace : public Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
//z = 2; // no, z private
}
};

class protected_Bace : protected Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
//z = 2; // no, z private
}
};

class private_Bace : private Base {
public :
void main() {
x = 2; // ok, x public
y = 2; // ok, y protected
// z = 2; // no, z private
}
};

int main() {
public_Bace a;
// 都是继承父类的方法
// 继承 + x 在父类中的权限 = 表现出来的
a.x = 3; // ok, putback + public = public
// a.y = 4; // no, public + protected = protected
// a.z = 5; // no, public + private = private

protected_Bace b;
// b.x = 3; // no, protected + public = protected
// b.y = 4; // no, protected + protected = protected
// b.z = 5; // no, protected + private = private

private_Bace c;
// c.x = 3; // no, private + public = private
// c.y = 4; // no, private + protected = private
// c.z = 5; // no, private + private = private

return 0;
}
ENDS(test1)


BEGINS(test2)

class Base {
public :
Base(string name) : class_name(name){}
int x;
string class_name;
private :
int y;
};

class A : public Base {
public:
A() : Base("class_A"){}
};

class B : public Base {
public:
B() : Base("class_B"){}
};

class C : public Base {
public:
C() : Base("class_C"){}
};

void func(Base &b) {
cout << "nput class : " << b.class_name << endl;
return ;
}

int main() {
A a;
B b;
C c;
// 隐式类型转换 子类 -> 父类
func(a);
func(b);
func(c);

cout << "sizeof(Base) = " << sizeof(Base) << endl;
cout << "sizeof(A) = " << sizeof(A) << endl;
return 0;
}

ENDS(test2)

BEGINS(test3)

class Base {
public :
Base(string name) : class_name(name){}
int x;
string class_name;
private :
int y;
};

class A : public Base {
public:
A() : Base("class_A"){}
};

class B : public Base {
public:
B() : Base("class_B"){}
};

class C : public Base {
public:
C() : Base("class_C"){}
};

void func(Base *b) {
cout << "nput class : " << b->class_name << endl;
return ;
}

int main() {
A a;
B b;
C c;
// 子类的地址也是可以转换成父类的地址
func(&a);
func(&b);
func(&c);
return 0;
}

ENDS(test3)

// 父类子类的构造顺序

BEGINS(test4)

class ATTR_BASE {
public:
ATTR_BASE(string name) : name(name){
cout << "construct " << name << endl;
}
~ATTR_BASE() {
cout << "destructor" << name << endl;
}
string name;
};

class ATTR1 : public ATTR_BASE{
public :
ATTR1(string name) : ATTR_BASE(name) {}
};

class ATTR2 : public ATTR_BASE{
public :
ATTR2(string name) : ATTR_BASE(name) {}
};

class Base {
public:
Base() : attr1("attr1 in Base"), attr2("attr2 in Base") {
cout << "Base constructor done" << endl;
}
~Base() {
cout << "Base destructor don" << endl;
}
private :
ATTR1 attr1;
ATTR2 attr2;
};

// Base 派生类
class A : public Base {
public :
A() : attr1("attr1 in A"), attr2("attr2 in A"){
cout << "A constructor don" << endl;
}
~A() {
cout << "A destructor don" << endl;
}
private :
ATTR1 attr1;
ATTR2 attr2;
};

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

ENDS(test4)

int main() {
// test1::main();
// test2::main();
// test3::main();
test4::main();
return 0;
}

构造析构顺序

image-20211224212305327

拷贝构造

拷贝构造行为方式 :

默认的 : 默认调用每一个属性的拷贝函数默认的调用父类的拷贝函数

评论