5.19
1、继承的基本内容
//继承 //继承的基本语法 class 子类:继承方式 父类 //继承方式的注意事项 //——继承方式包含公共、保护、私有三种方式 //————父类中的私有属性子类无论哪种继承方式均不可继承 //————父类中的公共和保护属性在子类公共继承的方式下属性不发生改变,保护的属性在子类类外依旧不可访问 //————父类中的公共和保护属性在子类保护继承的方式下公共属性变为保护属性,保护属性不变 #includeusing namespace std; class father { public: string m_fname; protected: string m_car; private: int m_money; }; class son :public father { public: void func() { m_fname = "张"; m_car = "bmw"; } }; void test1() { son s1; //公共继承只能访问父类的公共属性 s1.m_fname = "王"; cout << "儿子的姓:" << s1.m_fname << endl; } class son2 :protected father { public: void func() { m_fname = "张"; m_car = "bmw"; } }; void test2() { son2 s2; //保护继承父类的任何属性子类类外均无法访问 } class daughter:private father { void func() { m_fname = "张"; m_car = "bmw"; } }; void test3() { daughter d1; //私有继承父类的任何属性都无法类外访问 } int main() { test1(); test2(); test3(); system("pause"); return 0; }
2、继承的对象模型
//继承的对象模型 #includeusing namespace std; class Base { public: int m_a; protected: int m_b; private: int m_c; }; class Son :public Base { public: int m_d; }; void test1() { Son s1; cout << sizeof(s1) << endl; //16字节,根据内存显示得知子类实际上将父类的三个属性都继承了下来,只不过私有的属性编译器会隐藏 //其次子类的字节大小包含父类的字节和子类自身的字节 //通过开发工具查看子类对象模型 跳转盘符 D: 跳转文件路径 cd 具体路径下 查看命令 c1/d1 reportSingleClassLayout类名 文件名 } int main() { test1(); system("pause"); return 0; }
3、继承中的构造和析构顺序
//析构和构造的顺序 #includeusing namespace std; class Base { public: Base() { cout << "父类Base构造函数" << endl; } ~Base() { cout << "父类Base析构函数" << endl; } }; class Son :public Base { public: Son() { cout << "子类Son构造函数" << endl; } ~Son() { cout << "子类Son析构函数" << endl; } }; void test1() { Son s1; } int main() { test1(); system("pause"); return 0; }
构造函数先父后子
析构函数先子后父
4、继承中的同名成员处理
//同名成员的处理 #includeusing namespace std; class Base { public: void func() { cout << "Base—func调用" << endl; } void func(int) { cout << "Base—func(int)调用" << endl; } Base() { m_a = 15; } int m_a; }; class Son :public Base { public: void func() { cout << "Son—func调用" << endl; } Son() { m_a = 10; } int m_a; }; void test1() { Son s1; //子类中的同名属性直接访问 cout << s1.m_a << endl; //父类中的同名属性需加作用域 cout << s1.Base::m_a << endl; } void test2() { Son s1; //子类直接访问 s1.func(); //父类加作用域 s1.Base::func(); //子类中的同名函数会隐藏父类中的所有同名函数 s1.Base::func(10); } int main() { //test1(); test2(); system("pause"); return 0; }
父类中的成员属性经过引用后,子类中同名的属性直接访问,父类中需要加作用域
父类中的成员函数经过引用后,子类中同名函数直接访问,父类中的同名函数需要加作用域,子类中的同名函数会隐藏父类中的所有同名函数
5、静态同名成员的处理
静态不同于非静态,所有对象公用一个数据
//同名静态成员变量 #includeusing namespace std; class Base { public: static void func() { cout << "static void func()" << endl; } static void func(int) { cout << "static void func(int)" << endl; } static int m_a; }; int Base::m_a = 10;//静态成员属性类内声明、类外初始化 class Son :public Base { public: static void func() { cout << "static void func()—son" << endl; } }; void test1() { Son s1; //对象访问 s1.m_a = 20; cout << s1.m_a << endl; s1.func(); //类名访问 cout << Son::m_a << endl; Son::func(); //访问父类需加作用域 cout << s1.Base::m_a << endl; Base::func(); Base::func(10); } int main() { test1(); system("pause"); return 0; }
6、多继承问题,记得加一下作用域即可
//多继承问题 #includeusing namespace std; class Base1 { public: Base1() { m_a = 10; } int m_a; }; class Base2 { public: Base2() { m_a = 20; } int m_a; }; class Son :public Base1, public Base2 { public: int m_a; }; void test1() { Son s1; cout << sizeof(s1) << endl; cout << s1.Base1::m_a << endl; cout << s1.Base2::m_a << endl; } int main() { test1(); system("pause"); return 0; }



