c++学习第八讲---类和对象---继承

继承:

使子类(派生类)拥有与父类(基类)相同的成员,以节约代码量。

1.继承的基本语法:

class 子类名:继承方式 父类名{} ;

例:

cpp 复制代码
class father
{
public:
	int money;
	int debt;
};

class son :public father
{
private:
	int id;
};
int main()
{
	son s;
	s.debt = 20;//可以访问父类中的成员
}

从父类继承来的成员表现其共性,子类独有的成员表现其个性。

2.继承方式:

继承方式共有三种:

公共继承:public;保护继承:protected;私有继承:private。

总结:

1.父类中私有成员子类一定无法访问。

2.public > protected > private

父类中更公开的权限,如果比继承方式还要公开,则降为继承方式对应权限。

3.继承中的对象模型:

如果父类中的私有成员,子类访问不到,那这个成员是否属于子类呢?

看下面代码:

cpp 复制代码
//继承中的对象模型
class father
{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son :public father
{
public:
	int m_D;
};
int main()
{
	cout << sizeof(Son) << endl;//结果为16
	return 0;
}

可以看到结果为16,说明父类中非静态的成员属性,都会被子类继承下去,只是父类中私有属性被隐藏了。

4.继承中的构造和析构顺序:

先构造父类,再构造子类;先析构子类,再析构父类

cpp 复制代码
//继承中的构造和析构顺序
class father
{
public:
	father()
	{
		cout << "father构造函数" << endl;
	}	
	~father()
	{
		cout << "father析构函数" << endl;
	}
};
class Son :public father
{
public:
	Son()
	{
		cout << "Son构造函数" << endl;
	}
	~Son()
	{
		cout << "Son析构函数" << endl;
	}
};
int main()
{
	Son s;
}

5.继承同名成员处理方式:

访问子类同名成员,直接访问即可;

访问父类同名成员,需加作用域;

cpp 复制代码
class father
{
public:
	father()
	{
		m_A = 100;
	}
	int m_A;
};
class Son :public father
{
public:
	Son()
	{
		m_A = 200;
	}
	int m_A;
};
int main()
{
	Son s;
	cout << s.m_A << endl;//200
	cout << s.father::m_A << endl;//访问父类,100
}

注:如果子类中出现了和父类同名成员函数,子类的桶面成员会隐藏掉父类中所有的同名成员函数,包括重载。

cpp 复制代码
class father
{
public:
	void func()
	{
		cout << "father::func调用" << endl;
	}
	void func(int a)
	{
		cout << "father::func(int a)调用" << endl;
	}
};
class Son :public father
{
public:
	void func()
	{
		cout << "son::func调用" << endl;
	}
};
int main()
{
	Son s;
	s.func();
	s.func(100);//报错,父类重载同名函数被隐藏,需加作用域
}

6.继承同名静态成员处理方式:

cpp 复制代码
class Father
{
public:
	static int m_A;
};
int Father::m_A = 100;
class Son :public Father
{
public:
	static int m_A;
};
int Son::m_A = 200;

(1)通过对象访问:

原理同上

cpp 复制代码
int main()
{
	Son s;
	cout << s.m_A << endl;//200
	cout << s.Father::m_A << endl;//100
	return 0;
}

(2)通过类名进行访问:

Son : : Father : : m_A;

//第一个 : : 代表通过类名的方式访问,第二个 : : 代表访问父类作用域下的成员

cpp 复制代码
int main()
{
	Son s;
	cout << Son::m_A << endl;//200
	//第一个::代表通过类名的方式访问,第二个::代表访问父类作用域下的成员
	cout << Son::Father::m_A << endl;//100
	return 0;
}

7.多继承语法:

class 子类 : 继承方式 父类1,继承方式 父类2 ......

(注:会有多个父类有同名成员的问题,不建议使用)

cpp 复制代码
class Father1
{
public:
	int A;
};
class Father2
{
public:
	int B;
};
class Son :public Father1, public Father2
{
	int C;
};
int main()
{
	cout << sizeof(Son) << endl;//3个int类型,结果为12
	return 0;
}

同名问题:需加作用域加以区分。

8.菱形继承:

两个子类继承同一个父类,又有一个类继承这两个子类,这种继承方式叫做菱形继承。

(1)菱形继承的问题:

1.两个子类都继承了父类的属性,当"孙子类"调用数据时,会产生二义性。

2.孙子类继承自两个子类的相同属性,只需一份即可。

(2)解决方法:虚继承

1.语法:在两个子类的继承方式前加上关键字 virtual ,父类称为虚基类。

2.作用:使两个子类继承的实际为指针,创建孙子类时两个子类的指针都指向同一块数据。

cpp 复制代码
class Father
{
public:
	int m_age;
};
class Son1 :virtual public Father{};
class Son2 :virtual public Father{};
class GrandSon :public Son1, public Son2{};
void test01()
{
	GrandSon p;
	p.Son1::m_age = 18;
	p.Son2::m_age = 20;
	cout << p.m_age << endl;//虚继承后,只有一份数据,结果为20
	cout << p.Son1::m_age << endl;//20
	cout << p.Son2::m_age << endl;//20
}
相关推荐
ThreeYear_s1 小时前
基于FPGA的PID算法学习———实现PI比例控制算法
学习·算法·fpga开发
银色的白3 小时前
工作记录:人物对话功能开发与集成
vue.js·学习·前端框架
新中地GIS开发老师4 小时前
三维GIS开发cesium智慧地铁教程(4)城市白模加载与样式控制
学习·arcgis·智慧城市·webgl·gis开发·webgis·地理信息科学
Studying 开龙wu4 小时前
机器学习监督学习实战五:六种算法对声呐回波信号进行分类
学习·算法·机器学习
软件开发技术深度爱好者5 小时前
HTML版英语学习系统
学习·html
曼巴UE55 小时前
UE5 音效系统
c++·游戏·ue5·虚幻·音效
nenchoumi31195 小时前
UE5 学习系列(二)用户操作界面及介绍
windows·学习·ue5·机器人
NULL指向我5 小时前
香橙派3B学习笔记9:Linux基础gcc/g++编译__C/C++中动态链接库(.so)的编译与使用
笔记·学习
无影无踪的青蛙5 小时前
[C++] list双向链表使用方法
c++·链表·list
ThreeYear_s6 小时前
基于FPGA的PID算法学习———实现PID比例控制算法
学习·算法·fpga开发