C++:继承、继承对象模型、多继承、菱形继承 、虚继承的实现

继承

●当定义一个新的类时,发现该类具备之前某一个类的基本属性及方法时,就可使用继承技术.

●意义:减少代码重复率,增加代码利用率

一、继承对象模型

(1)C++对象中,成员属性与成员函数是分开存储的,对象的内存大小和成员函数没有关系,但是成员函数在逻辑上是属于类的.

(2)继承关系中,子类会继承所有父类的==成员属性以及成员函数.==但是私有属性被继承后被编译器屏蔽,所以私有成员是不能访问的.

(3)继承关系中,先构造父对象、再构造子对象,析构顺序相反.

(4)如果出现子类成员与父类成员同名情况,则父类的成员会被隐藏,对象直接访问的话,访问到的是子类自己的成员。则需要使用作用域符号::

(5)●在继承模型中,父类中的静态成员变量以及静态成员函数,也会被子类的所有对象共享。(static)--à菱形继承

访问子类:

obj . age

访问父类:

obj. Base: :age  

代码1):成员属性与成员函数是分开存储

#include <iostream>
using namespace std;
class Data
{
	int _data1;
	int _data3;


	static int _data2;  //不占空间

	//不占空间
	void fun()
	{
		cout<<"fun"<<endl;
	}
};

int Data::_data2=0;


int main(int argc, char *argv[])
{
	cout<<"sizeof(Data):"<<sizeof(Data)<<endl;
	return 0;
}

代码2):继承关系

#include <iostream>
using namespace std;
class Data
{
private:
    int _data1;
protected:
    int _data3;
public:
    int _data4;
    static int _data2;

    void fun1()
    {
        cout << "fun1" << endl;
    }
    void fun2()
    {
        cout << "fun2" << endl;
    }
};
int Data::_data2 = 0;

class SonData:protected Data
{
public:
    void Visit()
    {
        cout << _data4 << endl;
        cout << _data3 << endl;
        //cout << _data1 << endl;
        cout << _SonData << endl;
    }
private:
    int _SonData;
};

int main()
{
    cout << "sizeof(Data): " << sizeof(Data) << endl;
    cout << "sizeof(SonData): " << sizeof(SonData) << endl;
    SonData s1;
    s1.Visit();
    //s1._data4;
    return 0;
}

二、多继承

(1)当一个类继承多个类时,被称为多继承关系.

class A: <继承权限> <类名>, <继承权限> <类名>

{

}

●注意:实际开发应该减少多继承方式  

代码3):多继承

#include <iostream>
using namespace std;
class Sheep
{
	public:
		Sheep():s_kind("羊")
	{
		age=12;
	}
		int age;
		string s_kind;
};

class Cow
{
	public:
		Cow():c_kind("牛")
	{
		age=3;
	}
		int age;
		string c_kind;

};
class SiBuXiang:public Sheep,public Cow
{
	public:
		int age;
};

void test01()
{
	SiBuXiang s1;
	cout<<s1.c_kind<<endl;
	//cout<<s1.age<<endl;
	cout<<s1.Sheep::age<<endl;
}
int main(int argc, char *argv[])
{
	test01();
	return 0;
}

三、虚继承

(1)在多继承基础上,如果多个父类又是继承于同一个父类,那么成员访问就会出现问题,这种继承方式又称菱形继承  

代码4):菱形继承  

#include <iostream>
using namespace std;
class A
{
	public:
		static int dataA;
};

int A::dataA=1;

class B:public A
{

};
int main(int argc, char *argv[])
{
	B b1;
	B b2;
	b1.dataA=6;
	cout<<b1.dataA<<endl;
	cout<<b2.dataA<<endl;
	cout<<&(B::dataA)<<endl;

	A a1;
	a1.dataA=78;
	cout<<&(a1.dataA)<<endl;
	cout<<&(A::dataA)<<endl;
	

	cout<<a1.dataA<<endl;
	cout<<b1.dataA<<endl;

	return 0;
}

(2)虚继承方式:

class B:virtual public A

{
}

(3)作用:虚继承不是真正的继承成员属性,而是生成一个虚基类指针(vbptr),该指针可以实现访问同一个属性,而不出现二义性.

(4)原理:虚基类指针vbptr指向一个虚基类表,表中记录了到虚基类中成员变量的偏移量,通过偏移量就能够量就能够正确找到同一个成员变量.  

代码4):虚继承

#include <iostream>
using namespace std;
class Animal
{
	public:
	Animal():age(23)
	{

	}
		int age;
		static int n;
};

int Animal::n=10;

class Sheep:virtual public Animal    //virtual
{
	public:
		int SNum;
};

class Cow:virtual public Animal     //virtual
{
	public:
		int CNum;
};

class SiBuXiang:public Cow,public Sheep
{
	public:

};

void test01()
{

	SiBuXiang s1;
	cout<<s1.age<<endl;

	cout<<s1.n<<endl;   //static 共享

}

void test02()
{
	SiBuXiang s2;
	s2.age=9;

	cout<<s2.age<<endl;
	cout<<s2.Sheep::age<<endl;
}
int main(int argc, char *argv[])
{
	test01();

	test02();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

এ᭄星辰

混口饭吃。。。。。

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

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

打赏作者

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

抵扣说明:

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

余额充值