【C++第二阶段】继承&多态&电脑组装实例

该博客围绕C++的继承和多态展开。继承部分介绍了语法、方式、对象模型等内容,还提及菱形继承问题及解决办法;多态部分阐述了概念、原理,以及重写计算器、纯虚函数等知识。此外,通过电脑组装需求案例,探讨了多重继承时的资源管理和内存释放问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

你好你好!
以下内容仅为当前认识,可能有不足之处,欢迎讨论!



继承

继承语法

目的:减少代码复用

语法:在类后面写一个class 子类 : 继承方式 父类,就算继承了。

案例:

#include<iostream>
#include<string>

using namespace std;

class BasePage {
   
   

	
public:
	void header() {
   
   
		cout << "==========网页头部==========" << endl;
	}
	void footer() {
   
   
		cout << "**********网页尾部**********" << endl;
	}
};

class PythonPage :public BasePage {
   
   
public:
	PythonPage() {
   
   
		python();
	}
	void python() {
   
   
		BasePage().header();
		cout << "~~~~~~~~~~python网页~~~~~~~~~~" << endl;
		BasePage().footer();
	}
};


class CPPPage :public BasePage {
   
   
public:
	CPPPage() {
   
   
		CPP();
	}
	void CPP() {
   
   
		BasePage().header();
		cout << "~~~~~~~~~~CPP网页~~~~~~~~~~" << endl;
		BasePage().footer();
	}
};


class JavaPage :public BasePage {
   
   

public:
	JavaPage() {
   
   
		Java();
	}
	void Java() {
   
   

		BasePage().header();
		cout << "~~~~~~~~~~Java网页~~~~~~~~~~" << endl;
		BasePage().footer();
	}
};

void test_0217_0() {
   
   
	PythonPage python_page;

	CPPPage cpp;

	JavaPage java;
}

int main() {
   
   
	cout << "hello ! world ! " << endl;
	test_0217_0();
	system("pause");
	return 0;
	}

运行结果:

image-20240217224729737

此处有疑惑,继承的父类不能有构造函数?

继承方式

公有继承:父类里面成员属性是什么权限,之后仍然是什么权限。

保护权限:父类里面的public&protected变为子类的protected权限。

私有继承:父类里面的public&protected变为子类的private权限。

父类的private权限内容,其他都无法访问。

代码说明:

①公有权限

class BaseClass {
   
   
public:
	int class_a;
protected:
	int class_b;
private:
	int class_c;
};

class PublicSon :public BaseClass {
   
   
	PublicSon() {
   
   
		class_a = 100;
		class_b = 200;
		//class_c = 300;
	}
};

image-20240218202109122

根据图可以看出,在继承方式为public时,无法访问父类中private权限下的内容,只能访问权限为publicprotected下的内容。此时,父类与子类的权限变化如下表格

继承方式为public权限/类 父类 子类
继承方式为public权限 public public
继承方式为public权限 protected protected
继承方式为public权限 private 无法访问

②保护权限

继承方式为protected时,代码:

class BaseClass {
   
   
public:
	int class_a;
protected:
	int class_b;
private:
	int class_c;
};

class ProtectedSon :protected BaseClass {
   
   
	ProtectedSon() {
   
   
		class_a = 100;
		class_b = 200;
		//class_c = 300;
	}
};

此时,父类为private权限下的内容仍然无法访问。

image-20240218202758809

权限变化如下表格:

继承方式为protected权限/类 父类 子类
继承方式为protected权限 public protected
继承方式为protected权限 protected protected
继承方式为protected权限 private 无法访问

③私有权限

私有权限将父类中的所有成员属性在子类继承时转换为了private权限,在孙类继承时无法获得子类成员属性。

class BaseClass {
   
   
public:
	int class_a;
protected:
	int class_b;
private:
	int class_c;
};

class PrivateSon :private BaseClass {
   
   
	PrivateSon() {
   
   
		class_a = 100;
		class_b = 200;
	}
};

class GrandSon :public PrivateSon {
   
   
	void print() {
   
   
		cout << "class_a = " << class_a << endl;
		cout << "class_c = " << class_b << endl;
	}
};

如图所示:

image-20240218203216049

可以看到无法访问class_a的值。

继承中的对象模型

问题:

子类对于父类中的成员是都继承吗?

回答:

对于非静态成员变量,都继承。

验证:

解决办法:①在程序中打印出所占内存大小;②利用开发人员命令提示工具查看对象模型。

①代码

#include<iostream>
using namespace std;
#include<string>

class BaseClass {
   
   
public:
	int class_a;
protected:
	int class_b;
private:
	int class_c;
};

class SonClass : public BaseClass {
   
   
public:
	int class_d;
};

void test_0218_0() {
   
   
	cout << "the SonClass size = " << sizeof(SonClass) << "." << endl;
}


int main() {
   
   
	cout << "hello ! world ! " << endl;
	test_0218_0();
    system("pause");
    return 0;
}

运行结果:

image-20240218211808554

可以看到,只是编译器以及协议说明父类的私有权限下的内容无法访问,但是子类仍然有其成员属性。

②利用开发人员命令提示工具查看对象模型(开始菜单中)

进入当前文件所在文件夹后,用cl /d1 reportSingleClassLayout类名 "文件名"查看当前类的排列信息。

image-20240218212407495

可以看到SonClass占16字节,因为有4个整型构成。

同样,查看BaseClass。

image-20240218212526728

最后结论:父类中私有成员也被子类继承,只是由编译器隐藏后无法访问。

继承中构造和析构顺序

在父类和子类初始化时,它们的构造顺序和析构顺序是怎样的?

代码验证:

#include<iostream>
using namespace std;
#include<string>

class BaseClass {
   
   
public:
	BaseClass() {
   
   
		cout << "==父类==构造==函数==" << endl;
	}
	~BaseClass() {
   
   
		cout << "==父类==析构==函数==" << endl;
	}
public:
	int class_a;
protected:
	int class_b;
private:
	int class_c;
};

class SonClass : public BaseClass {
   
   
public:
	SonClass() {
   
   
		cout << "==子类==构造==函数==" << endl;
	}
	~SonClass() {
   
   
		cout << "==子类==析构==函数==" << endl;
	}
public:
	int class_d;
};

void test_0218_0() {
   
   
	SonClass sc;
	cout << "the SonClass size = " << sizeof(SonClass) << "." << endl;
}


int main() {
   
   
	cout << "hello ! world ! " << endl;
	test_0218_0();
    system("pause");
    return 0;
}

运行结果

image-20240218213014038

由运行结果可以看出,是父类先构造,子类再构造,而释放时,是由子类先释放,父类后释放。

同名成员处理

问题:父类和子类若有同名的成员属性和成员函数,如何分别访问?有何区别?

结论:子类继承父类后,新建子类对象,会访问到子类成员属性和成员函数。如需访问父类成员属性或成员函数,需加作用域。

延申提问:①重名但是不重类型的成员属性,是否会冲突?②重名成员函数若在父类中重载,重载为有参的成员函数,是否能访问到父类成员函数?

对应结论:①②不可以,发生重名成员函数,即编译器隐藏掉父类所有对应成员函数,除非加上作用域访问。

成员属性&成员函数举例:

#include<iostream>
#include<string>
using namespace std;

class BaseClass {
   
   

public:
	BaseClass() {
   
   
		class_a = 100;
	}
	int class_a;

	void print() {
   
   
		cout << "Base Class print() function 调用." << endl;
	}

	//void print(int a):class_a(a) {//这个只有在构造函数成员函数初始化时才能用
	void print(int a ){
   
   
		cout << "Base Class print ( int a ) function 调用." << endl;
	}

};

class SonClass:public BaseClass {
   
   
public:
	SonClass() {
   
   
		class_a = 200;
	}
	int class_a;

	void 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘义申汉

随缘惜缘不攀缘。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值