01、继承:
/* 回顾上节的内容: 1.继承 1.1 吸收 父类成员 1.2 调整 父类成员(访问权限 公有 私有 受保护/隐藏) 1.3增加子类的新成员 实现更多功能 2.多继承 -->继承所有父类所有成员 菱形继承 -->虚继承 virtual 今晚 补充 复习 回顾: 继承 吸收成员 --> 对象大小 1.类中 成员变量-->对象大小只和成员变量有关 成员函数-->包含一个this指针 指向当前对象 成员 变量和函数并不在一起 static -->全局 father类的对象 -->int 如果调用成员函数 传递这个对象地址 给fun函数 void fun(father*this,int y); 如果能找到成员函数地址 也可以用这个方式去调用成员函数 1.成员变量 -->继承过来 2.成员函数 -->通过传递父类对象的地址去调用父类的成员函数 虚继承 -->只在孙子类中保留一份祖父的成员的拷贝 子类构造 一定会调用父类构造函数(调用无参构造) 重点: **多继承 子类的构造要调用全部父类的构造函数 菱形继承中 调用父类的构造函数后 还需要调用祖父类的构造函数 父类没有写构造 -->默认构造函数 没有参数 类中有一个 没有参数的构造的话 会在没有写构造的时候 自动调用这个函数 想要知道什么地方需要调用构造 -->可以写一个有参构造 看什么地方出粗就行 父类 没有默认构造(无参构造) 子类 必须显性调用父类的构造函数 参数不需要统一 去掉无参构造 就只能调用有参构造 --> 什么时候必须调用构造函数: 1.定义对象 2.函数传递参数(传递不是引用) 3.子类继承父类的时候,调用父类的构造函数 虚继承 -->只留一份拷贝 多继承 不推荐使用 学习的知识 分类 整理 FBI warning 什么 error 继承 什么时候调用父类的构造 warning 内存分布 protected --> 传家宝 可以传给儿子 private --> 私有的小秘密 可以传 但是儿子不能访问 继承之后里面的内容都会继承过去 能不能访问看权限(继承过后成员属性的表格) 如果说一些原理 想不明白 可以直接记结论 拷贝构造 -->参数必须引用 多继承 -->虚继承 只会留一份祖父的拷贝 重点: 调用:构造函数 调用时机 --> 继承时候 子类必须调用父类构造函数 (一般情况 子类调用父类 父类会调用祖父类 子类不需要单独调用祖父类) 补充 菱形继承的时候 虚继承 需要单独调用祖父的构造函数 其余(不重要) 内存分布 (想要了解可以了解)不要求掌握 */ #include <iostream> using namespace std; class father // 父类 { public: int x; father(int x) :x(x){} ~father(){} void fun(int y){} }; class son :public father // 子类 { public: int y; son(int x, int y) :y(y), father(x){} // 子类的构造函数 需要调用父类的构造函数 只能写在初始化形参列表 ~son(){} }; int main() { son st(2, 3); cout << st.x << st.y << endl; cout << hex << &st.x << &st.y << endl; getchar(); return 0; } /* 继承之后的数据部分的关系 */ struct fat { int x; }; struct so { struct fat da; int y; }; /* 虚继承 */ /* 原有的作业上还成所有构造函数全部换成由参数的构造(选做) 输入输出格式 cout IO流: 1.文件操作 2.cin cout */
02、虚继承:
#include <iostream> using namespace std; class A { public: int x; A(int x) :x(x){} // A中的构造 private: }; class B :virtual public A { public: B(int x) :A(x){} }; class C :virtual public A { public: C(int x) :A(x){} }; class D :public B, public C { public: D(int x) :C(0), B(1), A(2){} // 子类的话 需要全部父类的构造函数 以及调用祖父类的构造 void fun() { B::x = 0x12; C::x = 0x34; // 0x34 -->52 } }; // 类的成员指针 偏移量 了解(指针大小 4个不同) int main() { int A::*p = &A::x; cout << sizeof(D) << endl; // D d(232); d.fun(); cout << d.x << endl; /*d.fun(); int *p = (int*)&d; // 强转 cout << p[0] << ‘\t‘ << p[1] << ‘\t‘ << p[2] << ‘\t‘ << endl; */ getchar(); return 0; }
03、实例:
#include <iostream> using namespace std; class grandfather // 祖父类 { public: int x; }; class father :virtual public grandfather // 父类 { }; class mother :public grandfather { }; class son :public father, public mother { }; int main() { cout << sizeof(son) << endl; son summer; int *p = (int*)&summer; cout << &p[0] << endl; cout << hex << p[0] << endl; cout << p[2] << endl; cout << &p[2] << endl; getchar(); return 0; }