总览 封装 :我该有的
(属性)和我该做的
(方法)
继承 :叫一声爸爸,开启财富之门
多态 :我就是我,是不一样的烟火
继承 继承往往表现于概念上的递进关系
1 2 3 4 5 6 7 8 9 10 class Animal {public : string name () { return this ->__name; } private : string __name; }; class Cat : public Animal { };
继承的好处:
基类\派生类
基类(父类) -> Animal
派生类 -> Cat
后续会在代码中标注基类\派生类
继承-子类的访问权限 子类对于父类的继承权限到底影响什么?
子类继承父类的全部 <- 父类
父类\继承权限
public
protected
private
public
✅
✅
❎
protected
✅
✅
✅
private
❌
❌
❌
父类\继承权限
public
protected
private
public
public
protected
private
protected
protected
protected
private
private
❌
❌
❌
继承权限相当于两道们叠加在一起那个更严格就执行那个
继承权限的作用影响的是什么?
影响的是类外对于子类中继承于父类父类中这些属性和方法的访问权限
继承-构造函数 隐士类型转换-逻辑上的递进关系 子类 -> 父类 的隐士类型转换 但是父类到子类是不允许以隐士类型转换的, 也就是说子类一定包含父类但是父类不一定包含子类
无论是Base类的(Base &)引用也好(Base *)指针也好,都可以邦达到所有派生类中A、B、C
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 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 << "input class " << b.class_name << endl ; return ; } int main () { A a; B b; C c; func(a); func(b); func(c); return 0 ; } ENDS(test2) BEFINES(test3) using namespace test2;void func (Base *b) { cout << "input 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 () { test2::main(); return 0 ; }
继承的构造顺序
先析构子类的属性,在析构父类的
菱形继承
面向对象是允许多继承但是有语言也是不支持的如:
C#、JAVA -> 不允许多继承
D:方法是调用B类的run方法还是是C类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 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class Base {public : int x; protected : int y; private : int z; }; class public_Base : public Base {public : void main () { x = 2 ; y = 3 ; } }; class protected_Base : protected Base {public : void main () { x = 2 ; y = 3 ; } }; class private_Base : private Base {public : void main () { x = 2 ; y = 3 ; } }; int main () { public_Base a; a.x = 3 ; protected_Base b; private_Base c; 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 << "input 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 << "input 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 done" << endl ; } private : ATTR1 attr1; ATTR2 attr2; }; class A : Base {public : A() : Base(), attr1("attr1 in A" ), attr2("attr2 in A" ) { cout << "A constructor done" << endl ; } ~A() { cout << "A destructor done" << endl ; } private : ATTR1 attr1; ATTR2 attr2; }; int main () { A a; return 0 ; } ENDS(test4) int main () { test4::main(); 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 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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class ATTR_BASE {public : ATTR_BASE(string name) : name(name) { cout << "construct : " << name << endl ; } ~ATTR_BASE() { cout << "destructor : " << name << endl ; } ATTR_BASE operator =(const ATTR_BASE &a) { name = a.name; cout << "operator= : " << name << endl ; return *this ; } ATTR_BASE(const ATTR_BASE &a) : name(a.name) { cout << "default copy constructor : " << name << endl ; } string name; }; class ATTR1 : public ATTR_BASE {public : ATTR1(string name = "none" ) : ATTR_BASE(name) {} }; class ATTR2 : public ATTR_BASE {public : ATTR2(string name = "none" ) : ATTR_BASE(name) {} }; class Base {public : Base() : attr1("attr1 in Base" ), attr2("attr2 in Base" ) { cout << "Base constructor done" << endl ; } Base(const Base &b) : attr1(b.attr1), attr2(b.attr2) { cout << "Base copy constructor done" << endl ; } Base &operator =(const Base &b) { attr1 = b.attr1; attr2 = b.attr2; cout << "Base operator= done" << endl ; return *this ; } ~Base() { cout << "Base destructor done" << endl ; } private : ATTR1 attr1; ATTR2 attr2; }; class A : Base {public : A() : Base(), attr1("attr1 in A" ), attr2("attr2 in A" ) { cout << "A constructor done" << endl ; } A(const A &a) : Base(a), attr1(a.attr1), attr2(a.attr2){ cout << "A copy constructor done" << endl ; } A &operator =(const A &a) { this ->Base::operator =(a); attr1 = a.attr1; attr2 = a.attr2; cout << "A operator= done" << endl ; return *this ; } ~A() { cout << "A destructor done" << endl ; } private : ATTR1 attr1; ATTR2 attr2; }; int main () { A a; cout << " ---------------- default constructor ----------------- " << endl << endl ; A b (a) ; cout << " ---------------- copy constructor ----------------- " << endl << endl ; b = a; cout << " ---------------- operator constructor ----------------- " << endl << endl ; return 0 ; } ENDS(test1) int main () { test1::main(); 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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test2) class NoObject {public : NoObject() = delete ; NoObject(const NoObject &) = delete ; }; int main () { NoObject *p = (NoObject *)malloc (sizeof (NoObject)); return 0 ; } ENDS(test2) int main () { test2::main(); 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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class A {protected : A() : x(9973 ) {} int x; }; class B : public A {public : void setX (int x) { cout << "set x : " << &(this ->x) << endl ; this ->x = x; return ; } }; class C : public A {public : int getX () { cout << "get x : " << &(this ->x) << endl ; return this ->x; } }; class D : public B, public C {}; int main () { D d; cout << d.getX() << endl ; d.setX(10000 ); cout << d.getX() << endl ; return 0 ; } ENDS(test1) int main () { test1::main(); return 0 ; }
内存存储区-虚继承 虚继承: 当c++底层生成对象模型时候会对相同的进行合并
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 ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class A {protected : A() : x(9973 ) {} int x; }; class B : virtual public A {public : void setX (int x) { cout << "set x : " << &(this ->x) << endl ; this ->x = x; return ; } }; class C : virtual public A {public : int getX () { cout << "get x : " << &(this ->x) << endl ; return this ->x; } }; class D : public B, public C {}; int main () { D d; cout << d.getX() << endl ; d.setX(10000 ); cout << d.getX() << endl ; return 0 ; } ENDS(test1) int main () { test1::main(); return 0 ; }
功能类配合重载、不能被拷贝行为 功能类配合重载可以通过继承标记某个类的性质
STL中类型萃取就是用的这种编程技巧
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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class UNCOPYABLE {public : UNCOPYABLE(const UNCOPYABLE &) = delete ; UNCOPYABLE &operator =(const UNCOPYABLE &) = delete ; UNCOPYABLE &operator =(const UNCOPYABLE &) const = delete ; protected : UNCOPYABLE() = default ; }; class A : public UNCOPYABLE {public :}; int main () { A a; A b; return 0 ; } ENDS(test1) BEGINS(test2) class HAS_XY {public : int x, y; }; class HAS_XYZ : public HAS_XY {public : int z; }; class A : public HAS_XY {public : A() { x = y =1 ; } }; class B : public HAS_XY {public : B() { x = y = 2 ; } }; class C : public HAS_XYZ {public : C() { x = y = z = 3 ; } }; class D : public HAS_XY {public : D() { x = y = 4 ; } }; class E : public HAS_XYZ {public : E() { x = y = z = 5 ; } }; void func (HAS_XY &a) { cout << "has xy : " ; cout << a.x << ", " << a.y << endl ; return ; } void func (HAS_XYZ &a) { cout << "hax_xyz : " ; cout << a.x << ", " << a.y << ", " << a.z << endl ; return ; } int main () { A a; B b; C c; D d; E e; func(a); func(b); func(c); func(d); func(e); return 0 ; } ENDS(test2) int main () { test2::main(); return 0 ; }
源码文件*.cpp 点我跳转:https://github.com/qzwl123/C-/tree/main/%E7%BB%A7%E6%89%BF