【C++】类和对象-继承

0.前言

1.基本语法


继承的用处就是极大的减少代码的重复性,如果没有用继承,看看以下代码,你知道了。。。。

基本实现代码:

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/

void test01();

/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

//Java页面
class Java {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Java学科视频" << endl;
	}
};
//Python页面
class Python {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Python学科视频" << endl;
	}
};
//Cpp页面
class Cpp {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Cpp学科视频" << endl;
	}
};

void test01() {
	//Java页面
	cout << "Java下载视频页面如下:" << endl;
	Java ja;
	ja.header();
	ja.footer();
	ja.left();
	ja.content();
	cout << "------------------------------------------------------------------------------" << endl;

	//Python页面
	cout << "Python下载视频页面如下:" << endl;
	Python py;
	py.header();
	py.footer();
	py.left();
	py.content();
	cout << "------------------------------------------------------------------------------" << endl;

	//Cpp页面
	cout << "Cpp下载视频页面如下:" << endl;
	Cpp cpp;
	cpp.header();
	cpp.footer();
	cpp.left();
	cpp.content();
	cout << "------------------------------------------------------------------------------" << endl;
}

继承实现代码

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/

void test01();

/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

//公共页面
class BasePage {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
};

//Java页面
class Java : public BasePage {
public:
	void content() {
		cout << "Java学科视频" << endl;
	}
};
//Python页面
class Python : public BasePage {
public:
	void content() {
		cout << "Python学科视频" << endl;
	}
};
//Cpp页面
class Cpp :public BasePage {
public:
	void content() {
		cout << "Cpp学科视频" << endl;
	}
};

void test01() {
	//Java页面
	cout << "Java下载视频页面如下:" << endl;
	Java ja;
	ja.header();
	ja.footer();
	ja.left();
	ja.content();
	cout << "------------------------------------------------------------------------------" << endl;

	//Python页面
	cout << "Python下载视频页面如下:" << endl;
	Python py;
	py.header();
	py.footer();
	py.left();
	py.content();
	cout << "------------------------------------------------------------------------------" << endl;

	//Cpp页面
	cout << "Cpp下载视频页面如下:" << endl;
	Cpp cpp;
	cpp.header();
	cpp.footer();
	cpp.left();
	cpp.content();
	cout << "------------------------------------------------------------------------------" << endl;
}

2.继承方式


cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/

//公共继承
class Base1 {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son1 :public Base1 {
public:
	void func() {
		m_A = 100;//父类中的公共权限成员 到子类中依然是公共权限
		m_B = 100;//父类中的保护权限成员 到子类中依然是保护权限
		//m_C = 100;//父类中的私有权限成员 子类访问不到
	}
};
void test01() {
	Son1 s1;
	s1.m_A = 100;  //到Son1中 m_B是公共权限 类外可以访问
	//s1.m_B = 100;//到Son1中 m_B是保护权限 类外访问不到
	//s1.m_C = 100;//到Son1中 m_B是私有权限 类外访问不到
}

//保护继承
class Base2 {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son2 :protected Base2 {
public:
	void func() {
		m_A = 100;//父类中公共成员,到子类中变为了保护权限
		m_B = 100;//父类中保护成员,到子类中变为了保护权限
		//m_C = 100;//父类中私有成员 子类访问不到
	}
};
void test02() {
	Son2 s2;
	//s2.m_A = 100;//在Son2中 m_A变为保护权限 ,因此类外访问不到
	//s2.m_B = 100;//在Son2中 m_B保护权限 不可以访问
	//s2.m_C = 100;//在Son2中 m_B私有权限 不可以访问
}

//私有继承
class Base3 {
public:
	int m_A = 100;
protected:
	int m_B = 100;
private:
	int m_C = 100;
};
class Son3 :private Base3 {
public:
	void func() {
		m_A = 100;//父类中公共成员,到子类中变为了私有权限
		m_B = 100;//父类中保护成员,到子类中变为了私有权限
		//m_C = 100;//父类中私有成员 子类访问不到
	}
};
void test03() {
	Son3 s3;
	//s3.m_A = 100;//在Son3中 m_A变为私有权限 ,因此类外访问不到
	//s3.m_B = 100;//在Son3中 m_A变为私有权限 ,因此类外访问不到
	//s3.m_C = 100;//在Son3中 m_B私有权限 不可以访问
}

//孙类访问父类
class GrandSon2 :public Son2 {
public:
	void func() {
		m_A = 100;//在Son2中 m_A变成了保护权限 孙类可以类内访问
		m_B = 100;//在Son2中 m_B仍然为保护权限 孙类可以类内访问
		//m_C = 100;//父类中私有成员 子类访问不到 孙类也访问不到
	}
};

class GrandSon3 :public Son3 {
public:
	void func() {
		//m_A = 100;//在Son3中 m_A变成了私有权限 孙类访问不到
		//m_B = 100;//在Son3中 m_B变成了私有权限 孙类访问不到
		//m_C = 100;//父类中私有成员 子类访问不到 孙类也访问不到
	}
};

/******************************************/
int main()
{
	/******************************************/
	test01();
	test03();
	test02();

	/******************************************/
	system("pause");

	return 0;
}

3.继承中的对象模型


代码

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
//继承中的对象模型
class Base {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son :public Base {
public:
	int m_D;
};

//利用开发人员命令提示工具查看对象模型
//跳转盘符 E:
//跳转文件路径 cd 具体路径下
//查看命名
//cl /d1 reportSingleClassLayout类名 文件名
//然后按tab健

void test01() {
	//输出为:16
	//父类中所有非静态成员属性都会被子类继承下去
	//父类中私有成员属性 是被编译器给隐藏了,因此是访问不到,但是确实是被继承下去了
	cout << "size of Son = " << sizeof(Son) << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

利用开发人员命令提示工具查看对象模型:

其具体步骤如下:

如果不清楚,去跳转网址:

https://www.bilibili.com/video/BV1et411b73Z?p=129\&spm_id_from=pageDriver\&vd_source=fb8dcae0aee3f1aab700c21099045395

从05:55开始观看

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

**总结:**继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
//继承中的构造和析构函数
class Base {
public:
	Base() {
		cout << "Base的构造函数!" << endl;
	}
	~Base() {
		cout << "Base的析构函数!" << endl;
	}
};

class Son:public Base {
public:
	Son() {
		cout << "Son的构造函数!" << endl;
	}
	~Son() {
		cout << "Son的析构函数!" << endl;
	}
};

void test01() {
	//继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
	Son s;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

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



代码

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
class Base {
public:
	Base() {
		m_A = 100;
	}
	void func() {
		cout << "Son-func()调用" << endl;
	}
	void func(int a) {
		cout << "Base-func(int a)调用" << endl;
	}
public:
	int m_A;
};

class Son :public Base {
public:
	Son() {
		m_A = 200;
	}

	//当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
	//如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
	void func() {
		cout << "Son-func()调用" << endl;
	}

public:
	int m_A;
};

void test01() {
	Son s;
	//子类对象加作用域才可以访问到父类同名成员
	cout << s.m_A << endl << s.Base::m_A << endl;
	s.func();
	s.Base::func();
	s.Base::func(12);
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

结果

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



代码

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
class Base {
public:
	static int m_A;

	static void func() {
		cout << "Base-func()调用" << endl;
	}

	static void func(int a) {
		cout << "Base-func(int a)调用" << endl;
	}
};
int Base::m_A = 100;
class Son :public Base {
public:
	static int m_A;

	static void func() {
		cout << "Son-func()调用" << endl;
	}
};
int Son::m_A = 200;

void test01() {
	cout << "同名成员属性:" << endl;
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s;
	cout << "Son m_A = " << s.m_A << endl;
	cout << "Base m_A = " << s.Base::m_A << endl;

	//2、通过类名访问
	cout << "通过类名访问:" << endl;
	cout << "Son m_A = " << Son::m_A << endl;
	//第一个::代表通过类名方式访问  第二个::代表访问父类作用域下的m_A
	cout << "Base m_A = " << Son::Base::m_A << endl << endl << endl;;

	cout << "同名函数属性:" << endl;
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s2;
	s2.func();
	s2.Base::func();
	//2、通过类名访问
	cout << "通过类名访问:" << endl;
	Son::func();
	Son::Base::func();
	//出现同名,子类会隐藏掉父类中所有同名成员函数,需要加作用域访问
	Son::Base::func(100);
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

结果:

7.多继承语法



代码:

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
class Base1 {
public:
	Base1() {
		m_A = 100;
	}
public:
	int m_A;
};
class Base2 {
public:
	Base2() {
		m_A = 200;//开始是m_B 不会出问题 ,但是改为m_A就出现不明确
	}
public:
	int m_A;
};

//语法: class 子类:继承方式 父类1,继承方式 父类2,.....
class Son :public Base1, public Base2 {
public:
	Son() {
		m_A = 300;
		m_D = 400;
	}
public:
	int m_A;
	int m_D;
};

//多继承容易产生成员同名的情况
//通过使用类名作用域可以区分调用哪个基类的成员
void test01() {
	Son s;
	cout << "size of Son = " << sizeof(s) << endl;
	cout << "Base1:m_A = " << s.Base1::m_A << endl;
	cout << "Base2:m_A = " << s.Base1::m_A << endl;
	cout << "Son:m_A = " << s.m_A << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

结果:

利用开发人员命令提示工具查看对象模型:

8.菱形继承



如果没有用虚继承,会导致有歧义,相当于两个父类、多继承的不明确问题

代码

cpp 复制代码
#include <iostream>
using namespace std;
/******************************************/
class Animal {
public:
	int m_Age;
};
//继承前面加virtual关键字后,变为虚继承
//此时公开的父类Animal称为虚基类
class Sheep :virtual public Animal {};
class Tuo :virtual public Animal {};
class SheepTuo :public Sheep, public Tuo {};

void test01() {
	SheepTuo st;
	st.Sheep::m_Age = 19;
	st.Tuo::m_Age = 29;
	
	cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
	cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
	cout << "st.m_Age = " << st.m_Age << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}


结果:

相关推荐
坊钰1 分钟前
【Java 数据结构】合并两个有序链表
java·开发语言·数据结构·学习·链表
神经网络的应用43 分钟前
C++程序设计例题——第三章程序控制结构
c++·学习·算法
工业甲酰苯胺1 小时前
聊一聊 C#线程池 的线程动态注入
java·开发语言·c#
zfenggo1 小时前
c/c++ 无法跳转定义
c语言·开发语言·c++
图灵猿1 小时前
【Lua之·Lua与C/C++交互·Lua CAPI访问栈操作】
c语言·c++·lua
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇30】C#常用泛型数据结构类——list<T>列表、`List<T>` 和数组 (`T[]`) 的选择
java·开发语言·数据结构·unity·c#·游戏引擎·list
hakesashou1 小时前
python怎么看矩阵维数
开发语言·python
daopuyun1 小时前
GB/T34944-2017 《Java语言源代码漏洞测试规范》解读——安全功能
java·开发语言·安全
A懿轩A2 小时前
C/C++ 数据结构与算法【树和二叉树】 树和二叉树,二叉树先中后序遍历详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·二叉树·
qh0526wy2 小时前
pyqt5冻结+分页表
开发语言·python·qt