C++06

Day06总结

为什么要继承

02继承的基本语法

1
2
3
4
5
6
7
语法  class 子类:继承方式
//利用继承,可以减少重复代码出现
//先把公共的部分建立一个类
//基类——派生类
class BasePage
class GamePage: public BasePage
class NewsPage: public BasePage

03继承方式

继承方式

image-20200417131702116

1
2
3
4
5
6
//公共继承
class Son1:public base1
//保护继承
class Son2:protected base1
//私有继承
class Son3:private base1

04继承中的对象模型

1
父类的私有属性,子类继承了,但是编译器给隐藏了因此访问不到

05继承中的构造与析构函数

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
/*
*继承中的构造与析构函数
*
* 初始化列表
* 可以用初始化列表语法显示制定出调用父类的哪个构造函数
* 子类不会继承父类中的构造和析构函数,只有父类自己才知道如何构造和析构函数
* */
class Base
{
public:
Base()
{cout<<"Base构造函数的调用"<<endl; }
~Base()
{cout<<"Base析构函数的调用"<<endl;}
};
//继承中,先调用父类的构造,在调用子类构造
//析构中,顺序相反
class Son1:public Base
{
public:
Son1()
{cout<<"Son构造函数的调用"<<endl; }
~Son1()
{cout<<"Son析构函数的调用"<<endl;}
};
/*********************************/
class Base2{
public:
Base2(int a)
{
this->m_A = a;
}
int m_A;
};
class Son2:public Base2
{
public:
//初始化列表
//可以用初始化列表语法显示制定出调用父类的哪个构造函数
Son2(int a):Base2(a)
{}
};
/*****************************************/
void test01()
{
Son1 s;//现有爸爸后有儿子
}
void test02()
{
//Son2 s;//报错,因为父类里面没有默认构造
Son2 s(100);
cout<<s.m_A;
}

06继承中同名函数的处理

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
*如果子类和父类拥有同名成员
*优先调用子类成员,可以通过作用域调用父类成员
*同名的成员函数,子类会隐藏父类中的所有同名版本,需要用作用域调用
class Base
{
public:
Base()
{this->m_A=100;}
void func(int i)
{
cout<<"Base 中的Func调用"<<endl;
}
int m_A;
};
class Son:public Base
{
public:
Son()
{
this->m_A = 200;
}
void func()
{
cout<<"Son 中的Func调用"<<endl;
}
void func(int a)
{
cout<<"Base 中Function(int a)调用"<<endl;
}

int m_A;
};
void test01()
{
Son s;
cout<<s.m_A<<endl;
cout<<"Base m_A = "<<s.Base::m_A <<endl;

s.func();
// s.Base::func();
//同名的成员函数,子类会隐藏掉父类所有重名的版本
//只能调用自己的
//可通过作用域来调用s.Base::func(10);
}

07继承中同名静态成员处理

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
*过类名访问
*同名成员函数进行调用
class Base
{
public:
static int m_A;//共享数据,编译阶段分配内存,类内声明类外初始化
static void func()
{
cout<<"BaseFUNC"<<endl;
}
static void func(int a)
{
cout<<"BaseFUNCINT"<<endl;
}
};
int Base::m_A= 100;
class Son:public Base
{
public:
static int m_A;

};
int Son::m_A = 29;
void test01()
{
//对A进行访问
Son s;
cout<<s.m_A<<endl;
cout<<s.Base::m_A<<endl;
//通过类名访问
cout<<Son::m_A<<endl;
cout<<Son::Base::m_A<<endl;
cout<<Base::m_A<<endl;
//同名成员函数进行调用
s.func();
Son::func(1);
//子类中同名成员函数会隐藏掉父类中同名成员函数的重载版本。(但是CLion好像会优化)
s.Base::func();
Son::Base::func();
Base::func();
}

08多继承语法

1
2
3
4
5
*  使用时不太方便,尽量不要写
* 当两个父类中有同名的成员被子类继承后,需要加上作用域
//如果两个父类有同名,需要加作用域
cout<<"Base1 中的m_A= "<<s.m_A<<endl;
cout<<"Base2 中的m_B= "<<s.m_B<<endl;

多继承、、

09菱形继承

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
*  Animal 父类 Sheep和Camel 同时继承animal,sheepcamel进行多继承,父类是sheep和camel
* 问题:访问父类中的数据,需要加作用域区分具体数据
* 问题二:由于菱形继承,导致继承的数据有一份是浪费的
* 解决方案:利用虚继承
* virtual Animal 类属于虚基类
class Animal
{
public:
int m_Age;

};
//virtual加上以后,继承方式:数据虚继承
//animal 类变为虚基类
class Sheep:virtual public Animal
{

};
class Camel:virtual public Animal
{

};
class sheepCamel:public Sheep,public Camel
{

};
void test01()
{
sheepCamel st;
st.Sheep::m_Age= 10;
st.Camel::m_Age= 12;
//m_Age只需要一份即可,用虚继承
}

菱形继承

-------------本文结束,感谢您的阅读-------------