面向对象的三大特征之一——继承

如图所示:派生类B以3种方式继承父类A。

  • 如果是public继承,父类中的成员属性到子类中仍然是是真名属性,不变。
  • 如果是protected继承,在子类中继承得到的父类属性会变化,保护继承,最低的访问权限的就是保护属性(指的是继承得到的属性)
  • 如果是private继承,这种继承方式,得到的父类所有的属性都将变成私有属性
  • 父类中的私有成员,除了友元,用继承的方式,是访问不到的

父类中私有属性的继承问题

class A
{
public:
	int a;
protected:
	int b;
private:
	int c;
};
class B : public  A
{
public:
	int d;
};
void text()
{
	B b;
	cout << sizeof(b);
}

在这里插入图片描述
如上图所示,虽然继承无法使用父类中的私有成员变量,但是仍然是会被继承过来的

继承时,构造函数和析构函数的调用顺序

在创建子类对象之前,会创建父类对象,所以会先调用父类的构造函数再调用子类的构造函数,析构的顺序与构造相反

继承时遇到同名的成员/同名函数怎么办

class A
{
public:
	int a;
	A()
	{
		this->a = 100;
	}
protected:
	int b;
private:
	int c;

};
class B : public  A
{
public:
	int a;
	B()
	{
		this->a = 200;
	}
};
void text()
{
	B b;
	cout << b.a << endl;
	cout << b.A::a << endl;
	//cout << sizeof(b);
}

在这里插入图片描述
当父类和子类中出现同名成员或函数时,默认访问的是子类成员,想要访问父类的成员必须加上作用域。

  • 对于同名函数,比较特殊。子类和父类中出现同名函数,子类的成员函数会隐藏掉父类中的所有同名函数(包括重载的版本,就是带参数的),即使父类中有同名的重载函数,也是访问不到的,必须加作用域。

同名的静态成员

class A
{
public:
	int a;
	static int item;
	A()
	{
		this->a = 100;
	}
protected:
	int b;
private:
	int c;

};
int A::item = 1;
class B : public  A
{
public:
	static int item;
	int a;
	B()
	{
		this->a = 200;
	}
};
int B::item = 2;
void text()
{
	B b;
	cout << b.a << endl;
	cout << b.A::a << endl;
	//cout << sizeof(b);
	//访问静态成员函数,静态成员可以用对象也可以用类名去访问\
	用对象和普通的方式相同,直接距离通过类名访问的方式
	cout << "访问子类" << B::item << endl;
	cout << "通过子类访问父类" << B::A::item << endl;
}

在这里插入图片描述
静态成员有两种访问方式,用对象访问时和非静态成员相同。也能直接使用类名去访问。
静态成员函数也是一样的,子类中的静态成员函数会隐藏掉父类中所有的同名静态成员函数(包括重载版本),想要去调用父类中带参的版本,就必须加作用域,都是差不多的,大同小异

多继承

多继承语法:冒号 继承方式 类名,继承方式……

class Base1
{
public:
	int a;
	Base1()
	{
		this->a = 100;
	}
};
class Base2
{
public:
	int a;
	Base2()
	{
		this->a = 200;
	}
};
class Persion : public Base1, public Base2
{
	//分别访问BASE1和BASE2中的属性a
};
void text()
{
	Persion p;
	cout << "Base1中的a:" << p.Base1::a << endl;
	cout << "Base2中的a:" << p.Base2::a << endl;
}

上图列出的是多继承的二义性问题,如果在继承的多个父类中,有相同的属性,则在子类中不能直接访问改属性,必须加上类的作用域,明确是访问哪个类的成员

多继承特例——菱形继承问题

菱形继承案例描述:
在这里插入图片描述
羊和驼共同继承了动物类,动物类中有一个属性:叫年龄。
羊和驼有一个儿子:叫羊驼。也就是说羊驼多继承了羊和驼这两个类
问题来了,动物中的age属性被继承成了两份,在羊驼多继承的时候,age属性又产生了二义性。多继承确实能用添加类名的方式去区分,但是实际上我们知道,age属性的值只能有一份。就是你的羊驼到底多大了。
这个问题是在羊和驼继承动物属性的时候,age属性随之也被一分为二。解决办法就是不让他一分为二。虚继承可以解决这个问题。
上代码:

class ainamal
{
public:
	int age;
};
class Sheep : virtual public ainamal
{

};
class Tuo : virtual public ainamal
{

};
class SheepTuo : public Sheep, public Tuo
{

};
void text()
{
	SheepTuo st;
	//虚继承之后,age不在具有二义性,因为虚继承之后有一个结果
	st.age = 100;
	st.Sheep::age = 300;
	st.Tuo::age = 400;
	cout << "羊驼的年龄:" << st.age << endl;
}

在这里插入图片描述
代码看出,虚继承之后即使对两个类中的age属性单独赋值,也不会有两个值,只会覆盖掉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值