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
}
相关推荐
陈天伟教授6 分钟前
机器学习方法(4)强化学习(试错学习)
人工智能·学习·机器学习
代码游侠3 小时前
日历的各种C语言实现方法
c语言·开发语言·学习·算法
草莓熊Lotso3 小时前
unordered_map/unordered_set 使用指南:差异、性能与场景选择
java·开发语言·c++·人工智能·经验分享·python·网络协议
咔咔咔的5 小时前
1930. 长度为 3 的不同回文子序列
c++
一只侯子10 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
Cinema KI10 小时前
吃透C++继承:不止是代码复用,更是面向对象设计的底层思维
c++
烤麻辣烫11 小时前
黑马程序员大事件后端概览(表现效果升级版)
java·开发语言·学习·spring·intellij-idea
烤麻辣烫12 小时前
黑马程序员苍穹外卖(新手)DAY6
java·开发语言·学习·spring·intellij-idea
Dream it possible!12 小时前
LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230_C++_中等)
c++·leetcode·面试
Xudde.14 小时前
Quick2靶机渗透
笔记·学习·安全·web安全·php