类和类型
**类型** 变量int a;long long b;char c;double d;float e;类 对象Cat cat; 栈空间,编译器保护Cat * ptr_cat = new cat(); 堆空间, 程序员本人保护
内存区:代码区 常量区, 堆, 栈
一个类在内存中须要占多大的内存空间呢:是由成员变量的动态属性决定的, 还有一个额定的因素占用内存空间: 虚办法(TODO)编译器主动创立一个八字节的虚函数表,是链表的构造
1231123
内存对齐
内存对齐基本上是通明的,这是编译器该干的活,编译器为程序中的每个数据单元安顿在适合的地位上,从而导致了雷同的变量,不同申明程序的构造体大小的不同。
缩小不必要的内存开销, int放在一起 double 放在一起采纳#pragma pack(1) 解决序列化和反序列化带来的内存对齐问题//52个字节了,
减少成员办法不影响类对象的内存大小(虚办法除外),为什么要这么设计呢?成员办法存在代码段的,
class People{string name;int age;double height;double weight;};//56个字节 //加上一行后变成了52对齐class People{string name;int age;double height;double weight;int children;};//64个字节class People{string name;int age;int children;double height;double weight;void say(string word);};//56个字节编译后存在内存中say变成了 void say(People * this, string word);
类封装
class默认private, struct 默认public
私有继承(public)
私有继承在C++中是最罕用的一种继承形式,咱们先来看一个示例:
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"调用Father类的public办法:Father_show1"<<endl; 8 } 9 protected:10 void Father_show2(){11 cout<<"调用Father类的protected办法:Father_show2"<<endl;12 }13 private:14 void Father_show3(){15 cout<<"调用Father类的private办法:Father_show3"<<endl;16 }17 }; 18 19 class Son:public Father{20 public:21 Son()=default;22 void Son_fun1(){23 cout<<"调用Son类的public办法:Son_fun1"<<endl;24 Father_show1();25 Father_show2();26 //Father_show3(); //谬误:无奈调用Father类的private办法 27 }28 protected:29 void Son_fun2(){30 cout<<"调用Son类的protected办法:Son_fun2"<<endl;31 Father_show1();32 Father_show2();33 //Father_show3(); //谬误:无奈调用Father类的private办法 34 }35 private:36 void Son_fun3(){37 cout<<"调用Son类的private办法:Son_fun3"<<endl;38 Father_show1();39 Father_show2();40 //Father_show3();//谬误:无奈调用Father类的private办法 41 }42 };43 44 int main(){45 Son s;46 s.Son_fun1(); //正确,只能调用对象的public办法47 s.Father_show1();48 //s.Son_fun2(); //谬误:不能调用对象的protected办法49 //s.Father_show2();50 //s.Son_fun3(); //谬误:不能调用对象的private办法51 //s.Father_show3();52 return 0;53 }
对私有继承的了解:
- 三种属性能力的强弱:public<protected<private
在C++的继承中,子类会继承父类中除构造函数和析构函数之外的所有成员(正所谓儿子无奈继承父亲的生死) 。而私有继承(public)就相当于先将从父类那里继承的全副成员放到子类的public局部,如下:
1 class Son:public Father{ 2 // 从Father类中继承的所有成员 3 public: 5 void Father_show1(){ 6 cout<<"调用Father类的public办法:Father_show1"<<endl; 7 } 8 protected:
- cout<<"调用Father类的protected办法:Father_show2" <<endl;}
- private:
- void Father_show1(){
- cout<<"调用Father类的public办法:Father_show1"<<endl;
- }
- public:
- Son()=default;
- void Son_fun1(){
- cout<<"调用Son类的public办法:Son_fun1"<<endl;
- Father_show1();
- Father_show2();
- //Father_show3();//谬误:无奈调用Father类的private办法
- }
- protected:
- void Son_fun2(){
- cout<<"调用Son类的protected办法:Son_fun2"<<endl;
- Father_show1();
- Father_show2();
- //Father_show3();//谬误: 无奈调用Father类的private办法
- }
- private:
- void Son_fun3(){
- cout<<"调用Son类的private办法:Son_fun3"<<endl;
- Father_show1();
- Father_show2();
- //Father_show3();//谬误: 无奈调用Father类的private办法
- }
};
而后依据三种属性能力的强弱决定成员的属性在子类中到底是public、protected还是private:
• Father_show1():在Father类中属于public办法,继承到子类Son后放在类的public局部,因为public=public,因而在子类Son中Father_show1()办法仍是public办法
• Father_show2():在Father类中属于protected办法,继承到子类Son后放在类的public局部,因为protected>public,因而子类Son中Father_show2()办法是protected办法
• Father_show3():在Father类中属于private办法,能够了解为“父亲的隐衷”,继承到子类Son后放在类的public局部,因为private>public,因而子类Son中Father_show3()办法是private办法。然而正所谓“儿子即便继承了父亲的财产,也无奈通晓父亲的隐衷”,因而不论儿子以何种形式(public/protected/private)继承父亲的“财产”也无奈利用父亲的“隐衷”去进行“交易”,换句话说就是父类的private成员尽管能够被子类继承,但子类中的任何成员办法都不能在其函数体中调用这些从父类中继承而来的private成员。因而Son类中的成员办法不论其为与什么局部,都无奈调用Father_show3
3.对象只能调用其public局部的成员,而不能调用protected和private局部的成员。因而上例中Son类的对象s能够调用办法Son_fun1()和办法Father_show1(),而无奈调用办法Son_fun2()、Son_fun3()、Father_show2()和Father_show3()
爱护继承(protected)
将下面的示例改为爱护继承:
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"调用Father类的public办法:Father_show1"<<endl; 8 } 9 protected:10 void Father_show2(){11 cout<<"调用Father类的protected办法:Father_show2"<<endl;12 }13 private:14 void Father_show3(){15 cout<<"调用Father类的private办法:Father_show3"<<endl;16 }17 }; 18 19 class Son:protected Father{20 public:21 Son()=default;22 void Son_fun1(){23 cout<<"调用Son类的public办法:Son_fun1"<<endl;24 Father_show1();25 Father_show2();26 //Father_show3(); //谬误:无奈调用Father类的private办法 27 }28 protected:29 void Son_fun2(){30 cout<<"调用Son类的protected办法:Son_fun2"<<endl;31 Father_show1();32 Father_show2();33 //Father_show3(); //谬误:无奈调用Father类的private办法 34 }35 private:36 void Son_fun3(){37 cout<<"调用Son类的private办法:Son_fun3"<<endl;38 Father_show1();39 Father_show2();40 //Father_show3(); //谬误:无奈调用Father类的private办法 41 }42 };43 44 int main(){45 Son s;46 s.Son_fun1(); //正确,只能调用对象的public办法47 //s.Son_fun2(); //谬误:不能调用对象的protected办法48 //s.Father_show1();49 //s.Father_show2();50 //s.Son_fun3(); //谬误:不能调用对象的private办法51 //s.Father_show3();52 return 0;53 }
对爱护继承的了解:
1.三种属性能力的强弱:public<protected<private
2.爱护继承相当于先将从父类继承的所用成员都放在子类的protected局部:
1 class Son:public Father{ 2 /* 3 protected: 4 public: 5 void Father_show1(){ 6 cout<<"调用Father类的public办法:Father_show1"<<endl; 7 } 8 protected: 9 void Father_show2(){10 cout<<"调用Father类的protected办法:Father_show2"<<endl;11 }12 private:13 void Father_show1(){14 cout<<"调用Father类的public办法:Father_show1"<<endl;15 } 16 */ 17 public:18 Son()=default;19 void Son_fun1(){20 cout<<"调用Son类的public办法:Son_fun1"<<endl;21 Father_show1();22 Father_show2();23 //Father_show3();//谬误:无奈调用Father类的private办法 24 }25 protected:26 void Son_fun2(){27 cout<<"调用Son类的protected办法:Son_fun2"<<endl;28 Father_show1();29 Father_show2();30 //Father_show3();//谬误: 无奈调用Father类的private办法 31 }32 private:33 void Son_fun3(){34 cout<<"调用Son类的private办法:Son_fun3"<<endl;35 Father_show1();36 Father_show2();37 //Father_show3();//谬误: 无奈调用Father类的private办法 38 }39 };
而后和私有继承一样,依据三种属性能力的强弱决定成员的属性在子类中到底是public、protected还是private:
• 因为public<protected,因而办法Father_show1()在类Son中是protected办法
• 因为protected=protected,因而办法Father_show2()在类Son中是protected办法
• 就像在私有继承中剖析的那样,Father_show3()在类Son中尽管是private办法,但Son类中的任何成员办法都不能在其函数体中调用办法Father_show3()
3.对象只能调用public局部的成员,此时办法Father_show1()是对象的protected办法,因而无奈像私有继承那样再被显式调用了
• 公有继承
将下面的示例改为公有继承:
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"调用Father类的public办法:Father_show1"<<endl; 8 } 9 protected:10 void Father_show2(){11 cout<<"调用Father类的protected办法:Father_show2"<<endl;12 }13 private:14 void Father_show3(){15 cout<<"调用Father类的private办法:Father_show3"<<endl;16 }17 }; 18 19 class Son:private Father{20 public:21 Son()=default;22 void Son_fun1(){23 cout<<"调用Son类的public办法:Son_fun1"<<endl;24 Father_show1();25 Father_show2();26 //Father_show3(); //谬误:无奈调用Father类的private办法 27 }28 protected:29 void Son_fun2(){30 cout<<"调用Son类的protected办法:Son_fun2"<<endl;31 Father_show1();32 Father_show2();33 //Father_show3(); //谬误:无奈调用Father类的private办法 34 }35 private:36 void Son_fun3(){37 cout<<"调用Son类的private办法:Son_fun3"<<endl;38 Father_show1();39 Father_show2();40 //Father_show3(); //谬误:无奈调用Father类的private办法 41 }42 };43 44 int main(){45 Son s;46 s.Son_fun1(); //正确,只能调用对象的public办法47 //s.Son_fun2(); //谬误:不能调用对象的protected办法48 //s.Son_fun3(); //谬误:不能调用对象的private办法49 //s.Father_show1();50 //s.Father_show2();51 //s.Father_show3();52 return 0;53 }
对公有继承的了解:
1.三种属性能力的强弱:public<protected<private
2.公有继承相当于先将从父类继承的所用成员都放在子类的private局部:
1 class Son:public Father{ 2 /* 3 private: 4 public: 5 void Father_show1(){ 6 cout<<"调用Father类的public办法:Father_show1"<<endl; 7 } 8 protected: 9 void Father_show2(){10 cout<<"调用Father类的protected办法:Father_show2"<<endl;11 }12 private:13 void Father_show1(){14 cout<<"调用Father类的public办法:Father_show1"<<endl;15 } 16 */ 17 public:18 Son()=default;19 void Son_fun1(){20 cout<<"调用Son类的public办法:Son_fun1"<<endl;21 Father_show1();22 Father_show2();23 //Father_show3();//谬误:无奈调用Father类的private办法 24 }25 protected:26 void Son_fun2(){27 cout<<"调用Son类的protected办法:Son_fun2"<<endl;28 Father_show1();29 Father_show2();30 //Father_show3();//谬误: 无奈调用Father类的private办法 31 }32 private:33 void Son_fun3(){34 cout<<"调用Son类的private办法:Son_fun3"<<endl;35 Father_show1();36 Father_show2();37 //Father_show3();//谬误: 无奈调用Father类的private办法 38 }39 };
而后和私有继承一样,依据三种属性能力的强弱决定成员的属性在子类中到底是public、protected还是private:
• 因为public<private,因而办法Father_show1()在类Son中是private办法,但类Son中的成员办法能够在函数体内调用该办法
• 因为private>protected,因而办法Father_show2()在类Son中是prijvate办法,但类Son中的成员办法能够在函数体内调用该办法
• 就像在私有继承中剖析的那样,Father_show3()在类Son中尽管是private办法,但Son类中的任何成员办法都不能在其函数体中调用办法Father_show3()
3.对象只能调用public局部的成员,此时办法Father_show1()是对象的private办法,因而无奈像私有继承那样再被显式调用了
QUESTION:爱护继承(protected)和公有继承(private)有何不同?
ANSWER:在下面的例子中,咱们发现爱护继承形式和公有继承形式达到的成果齐全一样,难道这两中继承形式没有任何区别吗?咱们先来看一个例子:
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父类 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"调用GrandFather类的办法:GrandFather_show"<<endl; 8 } 9 };10 class Father:protected GrandFather{ //父类 11 public:12 Father()=default;13 };14 class Son:public Father{ //子类15 public:16 Son()=default;17 void Son_show(){18 cout<<"调用Son类的办法:Son_show"<<endl;19 GrandFather_show(); 20 }21 }; 22 23 int main(){24 Son s;25 s.Son_show();26 return 0;27 }
咱们发现下面的程序能够顺利运行。这是因为当Father类以保护方式(protected)继承GrandFather类时,GrandFather类中的私有办法GrandFather_show()会以protected办法的模式存在于类Father中,当类Son再以私有形式(public)继承类Father时,办法GrandFather_show()会仍以protected办法的模式存在与类Son中,因为一个类中的成员办法容许在其函数体内调用protected局部的成员,因而零碎容许在Son类的成员办法Son_show()调用办法GrandFather_show(),从而使程序顺利运行。
当初咱们将程序改为Father类以公有继承的形式继承GrandFather类:
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父类 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"调用GrandFather类的办法:GrandFather_show"<<endl; 8 } 9 };10 class Father:private GrandFather{ //父类 11 public:12 Father()=default;13 };14 class Son:public Father{ //子类15 public:16 Son()=default;17 void Son_show(){18 cout<<"调用Son类的办法:Son_show"<<endl;19 GrandFather_show(); 20 }21 }; 22 23 int main(){24 Son s;25 s.Son_show();26 return 0;27 }
咱们发现程序报错。这是因为当Father类以公有(private)继承GrandFather类时,GrandFather类中的私有办法GrandFather_show()会以private办法的模式存在于类Father中,换句话说办法GrandFather_show()变成了类Father的“隐衷”;当类Son再以私有形式(public)继承类Father时,因为“儿子无奈利用父亲的“隐衷”进行交易”,因而无奈在Son类中的任何成员办法中调用GrandFather_show()办法,包含Son_show()。此时如果咱们将类Son中成员函数Son_show()中的语句“GrandFather();"正文掉,程序便能够从新顺利执行。
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父类 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"调用GrandFather类的办法:GrandFather_show"<<endl; 8 } 9 };10 class Father:private GrandFather{ //父类 11 public:12 Father()=default;13 };14 class Son:public Father{15 public:16 Son()=default;17 void Son_show(){18 cout<<"调用Son类的办法:Son_show"<<endl;19 //GrandFather_show(); 20 }21 }; 22 23 int main(){24 Son s;25 s.Son_show();26 return 0;27 }#**友元**