
继承的引出
网页有很多公共部分
导致实现时候有很多重复的代码
引出继承,基类(父类) 公共网页
具体子类 实现不同的内容
语法:class 子类 :继承方式 父类
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
|
using namespace std; class { private: public: BasePage(){} ~BasePage(){} void header() { cout<<"公共头部"<<endl; } void footer() { cout<<"公共底部"<<endl; } void left() { cout<<"左侧列表"<<endl; } };
class News :public BasePage { private: public: News (){} ~News (){} void content() { cout<<"新闻播放"<<endl; } };
class YULE :public BasePage { public: YULE(){} ~YULE(){} void content() { cout<<"娱乐项目"<<endl; } };
void test() { cout<<"新闻网页内容: "<<endl; News news; news.header(); news.footer(); news.left(); news.content();
cout<<"娱乐网页内容: "<<endl; YULE yl; yl.header(); yl.footer(); yl.left(); yl.content(); } int main(void) { test(); return 0; }
|
继承方式
不管是公共继承、保护继承还是私有继承,基类中的私有属性,都不可以继承下去
公有继承:父类中的public在子类中是public,父类中的protected在子类中还是protected
保护继承:父类中的public在子类中是protected,父类中的protected在子类中还是protected
私有继承:父类中的public在子类中是private,父类中的protected在子类中还是private
继承中的对象模型
子类会继承父类中所有的内容,包括了私有属性
只是我们访问不到,被编译器隐藏了
继承中的构造和析构
子类创建对象时,先调用父类的构造,然后调用自身的构造,析构顺序相反
子类不会继承父类的构造函数和析构函数
如果父类中没有合适的默认构造,那么子类可以利用初始化列表的方式显示的调用父类的其他构造
继承中的同名处理
成员属性:直接调用先调用子类,如果想调用父类的,需要作用域
成员函数:直接调用先调用子类,父类的所有版本(如默认和有参)都会被隐藏,除非加上作用域运算符去调用
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
|
using namespace std;
class Base { private: public: Base() { m_A = 100; }
void fun() { cout<<"Base fun调用"<<endl; }
void fun(int a) { cout<<"Base fun(int a)调用"<<endl; } int m_A; };
class Son:public Base { private: public: Son() { m_A = 200; }
void fun() { cout<<"Son fun调用"<<endl; } int m_A; };
void test() { Son s1; cout<<s1.m_A<<endl;
cout<<s1.Base::m_A<<endl;
s1.fun(); s1.Base::fun(10); s1.Base::fun(); }
int main(void) { test(); return 0; }
|
继承中静态成员的处理
类似非静态成员函数、属性的处理
如果想访问父类中的成员,加作用域即可
多继承的概念以及问题
class A : public B1, puublic B2 …;
引发二义性问题,要通过作用域解决
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
|
using namespace std;
class Base1 { private: public: Base1() { m_A = 10; } ~Base1() {}
int m_A; };
class Base2 { private: public: Base2() { m_A = 20; } ~Base2() {} int m_B; int m_A; };
class Son:public Base1, public Base2 { private: public: Son() {} ~Son() {}
int m_C; int m_D; }; void test() { cout<<sizeof(Son)<<endl;
Son s1; cout<<s1.Base1::m_A<<endl; cout<<s1.Base2::m_A<<endl; } int main(void) { test(); return 0; }
|
菱形继承问题以及解决
解决问题利用虚基类
vbptr 虚基类指针
指向一张虚基类表
通过表找到偏移量
找到共有的数据
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
|
using namespace std;
class Animal { private: public: Animal() {} ~Animal() {} int m_Age; };
class Sheep: virtual public Animal { private: public: Sheep() {} ~Sheep() {} };
class Tuo: virtual public Animal { private: public: Tuo() {} ~Tuo() {} };
class SheepTuo: public Sheep, public Tuo { private: public: SheepTuo() {} ~SheepTuo() {} }; void test() { SheepTuo st; st.Sheep::m_Age = 10; st.Tuo::m_Age = 20; st.m_Age = 100; cout<<st.Sheep::m_Age<<endl; cout<<st.Tuo::m_Age<<endl; cout<<st.m_Age<<endl;
cout<<*(int *)((int *)*(int *)&st + 1)<<endl;
} int main(void) {
test(); return 0; }
|
近期评论