c++中与继承相关的概念

1. c++继承的访问权限

 c++中继承有三种:共有继承、保护继承、私有继承,三个关键字分别是:public、protected、private。每种继承的访问权限不一样,谈到继承的访问权限首先得清楚一个类中public、protected、private关键字修饰的属性和方法其对类创建出来的对象的访问权限。
  • [ 1]成员访问权限

     #include<iostream>
     using namespace std;
     
     class A
     {
     public:
     	int aPublic;
     	void funPublic() 
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     		funaPrivate();
     	};
     protected:
     	int aProtected;             
     	void funaProtected()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     
     	};
     private:
     	int aPrivate;
     	void funaPrivate()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     
     	};
     };
     
     int main()
     {
     	A a;
     
     	a.aPublic;             //OK, 类实例可以访问public成员
     	a.funPublic();         //OK, 类实例可以访问public方法
     
     	a.aProtected;          //ON, 类实例可以不访问protect属性
     	a.funaProtected();     //NO, 类实例可以不访问protect方法
     
     	a.aPrivate;            //NO, 类实例可以不访问private属性
     	a.funaPaPrivate();     //OK, 类实例可以不访问private方法
     
     	return 0;
     }
    

小结: 类的内部之间可以访问其属性和方法(不管是public、protected、private修饰即”同类无私有”)。类创建的实例,类的实例可以访问public属性和方法,不能访问protected和private属性和方法。

  • [ 2] 公有继承

     #include<iostream>
     using namespace std;
     
     class A
     {
     public:
     	int aPublic;
     	void funPublicA() 
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     		funaPrivateA();
     	};
     protected:
     	int aProtected;             
     	void funaProtectedA()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     
     	};
     private:
     	int aPrivate;
     	void funaPrivateA()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     	};
     };
     
     class B:public A
     {
     public:
     	int bPublic;
     	void funPublicB()
     	{
     		int b1 = aPublic;        //OK
     		int b2 = aProtected;     //OK
     		//int b3 = aPrivate;     //NO
     		//funaPrivate();         //NO
     	};
     protected:
     	int bProtected;
     	void funaProtectedB()
     	{
     		int b1 = aPublic;        //OK
     		int b2 = aProtected;     //OK
     		//int b3 = aPrivate;      //NO
     
     	};
     private:
     	int bPrivate;
     	void funaPrivateB()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		//int a3 = bPrivate;     //NO
     	};
     };
     
     int main()
     {
     	B b;
     	b.aPublic;                    //OK  
     	b.funPublicA();               //OK  
     
     	//b.aProtected;               //NO   
     	//b.funaProtectedA();         //NO     
     
     	//b.aPrivate;                 //NO
     	//b.funaPrivateA();           //NO  
     	 
     	return 0;
     }
    

    小结:子类通过public继承,基类的各种权限不变 。子类创建的实例依然可访问父类的公有属性和方法,无法访问protected、private修饰的属性和方法。子类的内部可以访问父类的public、protected修饰的属性和方法。

  • [3 ] 保护继承
    #include
    using namespace std;

     class A
     {
     public:
     	int aPublic;
     	void funPublicA() 
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     		funaPrivateA();
     	};
     protected:
     	int aProtected;             
     	void funaProtectedA()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     
     	};
     private:
     	int aPrivate;
     	void funaPrivateA()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		int a3 = aPrivate;       //OK
     	};
     };
     
     class B:protected A
     {
     public:
     	int bPublic;
     	void funPublicB()
     	{
     		int b1 = aPublic;        //OK
     		int b2 = aProtected;     //OK
     		//int b3 = aPrivate;     //NO
     		//funaPrivate();         //NO
     	};
     protected:
     	int bProtected;
     	void funaProtectedB()
     	{
     		int b1 = aPublic;        //OK
     		int b2 = aProtected;     //OK
     		//int b3 = aPrivate;      //NO
     
     	};
     private:
     	int bPrivate;
     	void funaPrivateB()
     	{
     		int a1 = aPublic;        //OK
     		int a2 = aProtected;     //OK
     		//int a3 = bPrivate;     //NO
     	};
     };
     
     int main()
     {
     	B b;
     	//b.aPublic;                    //NO  
     	//b.funPublicA();               //NO  
     
     	//b.aProtected;               //NO   
     	//b.funaProtectedA();         //NO     
     
     	//b.aPrivate;                 //NO
     	//b.funaPrivateA();           //NO  
     	 
     	return 0;
     }
    

    小结:子类通过protected继承,父类的public降为protected属性,其他不变 。子类创建的实例不在能够访问父类的公有属性和方法,也无法访问protected、private修饰的属性和方法。子类的内部可以访问父类的public、protected修饰的属性和方法。

  • [ 4] 私有继承
    子类通过private继承,父类的所有属性和方法的权限变成了private。同公有继承一样,子类创建的实例不能访问父类的任何成员和方法。子类的内部可以访问父类的public、protected修饰的属性和方法。如果后面又有C子类继承B类的话,那么C类的内部都将不再能够访问A类的属性和方法,但是是保护继承的话C的内部是可以访问A的属性和方法的。

2.多继承和虚继承

一个类有多个直接基类的继承关系称为多继承

#include<iostream>
using namespace std;

class  A
{
public:
	int m;
	int a[9];
};

class B: public A
{

};
class C: public A
{

};

class D: public B,  public C
{

};

int main()
{
	cout << "A所占字节的大小:" << sizeof(A) << endl;
	cout << "B所占字节的大小:" << sizeof(B) << endl;
	cout << "C所占字节的大小:" << sizeof(C) << endl;
	cout << "D所占字节的大小:" << sizeof(D) << endl;
	D d;
	//d.m = 10;    //NO  存在二义性,编译器不知道m是属于A还是B
	d.B::m = 10; //OK
	d.C::m = 10; //OK
	return 0;

}

如果一个子类继承了多个父类,而这些父类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性,并且在子类中进行多分拷贝,浪费存储空间。

程序编译结果如下:
在这里插入图片描述
为解决多继承中存在的二义性问题,c++提供了虚继承
在这里插入图片描述
虚继承可以解决多种继承的二义性及浪费存储空间的问题,那么B,C,D为什么所占的字节大小是44,44,48呢?
虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。
详细可以看:
https://blog.youkuaiyun.com/bxw1992/article/details/77726390

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值