C++ 三大特性之一 继承

本文详细介绍了C++中的继承特性,包括公共继承、保护继承和私有继承的使用,以及它们对成员访问权限的影响。同时,探讨了对象模型、构造与析构的顺序、同名成员的处理、静态成员的处理,以及多继承和菱形继承的问题。强调了多继承可能导致的同名成员冲突和资源浪费,并提出了虚继承作为解决方案。

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

1.继承是C++三大特性之一

   减少代码量

语法   class  类名1:继承方式(public /protected/private)   类名2

类名1:子类  /  派生类

类名2:父类 / 基类

2.三种继承方式:

#include <iostream>
using namespace std;

//三种继承方式
class Father
{
public:
	int A;
protected:
	int B;
private:
	int C;   
};

class Son1 :public Father		 //公共继承
{
public:
	void show1()
	{
		A = 20;   //public
		B = 30;   //protected
		//C = 40;父类私有权限,不可访问
	}
};

class Son2 :protected Father    //保护继承
{
public:
	void show2()
	{
		A = 20;   //protected
		B = 30;   //protected
		//C = 40;父类私有权限,不可访问
	}
};

class Son3 :private Father	   //私有继承
{
	void show3()
	{
		A = 20;   //private
		B = 30;   //private
		//C = 40;父类私有权限,不可访问
	}
};

void test1()
{
	Son1 son1;
	son1.A = 10;
	//son1.B = 20;  //保护权限,类外不可访问
	//son1.C = 30;  //父类私有权限,不可访问
}

void test1()
{
	Son2 son2;
	//son2.A = 10;	//保护权限,类外不可访问
	//son2.B = 20;  //保护权限,类外不可访问
	//son2.C = 30;  //父类私有权限,不可访问
}

void test1()
{
	Son3 son3;
	//son3.A = 10;	//私有权限,类外不可访问
	//son3.B = 20;  //私有权限,类外不可访问
	//son3.C = 30;  //父类私有权限,不可访问
}
int main()
{

}

3.继承中的对象模型

#include <iostream>
using namespace std;

//三种继承方式
class Father
{
public:
	int A;
protected:
	int B;
private:
	int C;   
};

class Son1 :public Father		 //公共继承
{
public:
	int D;
private:
	int E;
};


int main()
{
	Son1 son1;
	cout << sizeof(son1)<<endl;
}

输出为20,也就是父类中private 也被继承了,只是被隐藏了 

我们可以利用 命令行 来查看对象模型

4.构造与析构顺序

 创建子类对象,必须先创建父类对象

构造先父类后子类

析构顺序相反

5.同名成员处理

1.子类对象可以直接子类中的同名成员

2.子类对象加作用域可以访问父类中的同名成员

3. 当子类和父类拥有同名成员函数时,子类会隐藏父类中同名成员函数

   需加作用域才能访问父类同名成员函数

 6.同名静态成员处理

静态成员属性和静态成员函数的特性前面提过

处理方式同非静态同名成员一样,只是可以通过对象和类名两种方式访问

代码如下:

#include <iostream>
using namespace std;

class Father
{
public:
	static int a;
	static void show()
	{
		cout << "father" << endl;
	}
};
int Father::a = 10;

class Son :public Father
{
public:
	static int a;
	static void show()
	{
		cout << "son" << endl;
	}
};
int Son::a = 20;

void test1()//成员变量
{
	Son son;//通过对象访问
	cout << son.a << endl;
	cout << son.Father::a << endl;

	//通过类名访问
	cout << Son::a << endl;
	cout << Son::Father::a << endl;//通过Son访问Father中的a
}

void test2()//成员函数
{
	Son son;//通过对象访问
	son.show();
	son.Father::show();
	//通过类名访问
	Son::show();
	Son::Father::show();
}

int main()
{
	test1();
	test2();
}

7.多继承

一个子类继承多个父类

#include <iostream>
using namespace std;

class Father1
{
public:
	int a;
};

class Father2
{
public:
	int b;
};

class son :public Father1, Father2
{

};

int main()
{
	cout << sizeof(son) << endl;
}

 

当多个父类出现同名成员时,要加作用域 

很造成麻烦,所以不建议使用多继承

 8.菱形继承

#include <iostream>
using namespace std;

class GrandFather
{
	int a;
};

class Father1 :public GrandFather
{
};

class Father2:public GrandFather
{
};

class Son :public Father1, Father2
{
};

int main()
{
	Son son;
}

菱形继承会造成资源浪费

 所以要利用虚继承

class Father1 :  virtual  public GrandFather
{
};

class Father2:  virtual  public GrandFather
{
};

这时,Father1 和Father2 共用一个a

底层实现

底层是靠vbptr  virtual   base  pointer  虚基类指针实现的

两个指针偏移量不同,指向同一份数据

直接用Son类对象访问a,也不会有歧义 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值