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
}
相关推荐
布莱克60517 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
前进的李工19 小时前
Agent 学习笔记 05:系统提示词应该怎么写
笔记·学习·prompt·agent·个人开发·few-shot·ai应用开发
正在走向自律21 小时前
【3/5】人工智能训练师 三级/高级工 考证学习方向:从“独立执行”到“设计、归因与全链条负责”
人工智能·学习·人工智能训练师·注方案设计·数据质控负责人·模型评测与调优辅助·ai训练项目交付
沫璃染墨1 天前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Session
linux·服务器·c++·tcp/ip·ubuntu·http·交互
CCIE-Yasuo1 天前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
xiaoye-duck1 天前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(下):流式响应实现和测试
开发语言·网络·c++·语言模型
La Pulga1 天前
【FreeRTOS源码学习笔记】任务切换
单片机·mcu·学习·嵌入式·freertos·实时操作系统
li星野1 天前
【学习记录】逻辑分析仪完全入门:从品牌方案到采样率、存储深度的核心概念解析
学习
旖旎夜光1 天前
【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针
开发语言·c++·笔记·学习
小超人诞生日记1 天前
C++ 智能指针的使用及其原理详解
c++·算法