C++多重继承、纯虚函数和抽象类

重载继承的初始化

1)如果类A和类B都同时继承自类X,类C继承自A和B,那么在创建类C的时候,类X的构造和析构函数

会被执行两次,因为类C在创建的时候,分别会去创建类A和类B,而类A和类B又会去创建类X,所以

就类X会被创建两次

2)如果类X中有函数Fun,那么类C在调用的时候需要指定调用哪个父类所继承的Fun函数,例如:c->A::Fun()

class X
{
public:
	X(){}
	virtual ~X(){}
	virtual void Fun()
	{
		cout<<"Class X"<<endl;
	}
};
class A:public X
{
public:
	A(int i):a(i){}
	virtual ~A(){}
	virtual void print()
	{
		cout<<"Class A - "<<a<<endl;
	}
private:
	int a;
};

class B:public X
{
public:
	B(int i):a(i){}
	virtual ~B(){}
	virtual void print()
	{
		cout<<"Class B - "<<a<<endl;
	}
private:
	int a;
};

class C:public A, public B
{
public:
	//基类A和B的构造函数都是带参的,所以子类需要对其初始化,顺序随意
	C(int i, int j, int k):A(i),B(j),a(k){}
	virtual ~C(){}
	virtual void print()
	{
		cout<<"Class C - "<<a<<endl;
	}
private:
	int a;
};

int main()
{
	C *c = new C(1,2,3);
	//如果多个基类中拥有相同的函数名,需要用::作用域标识符指出调用哪一个基类的函数,避免二义性
	c->A::print();
	c->B::print();
	c->print();
	//如果类A和类B都同时继承自类X,那么在创建类C的时候,类X的构造和析构函数会被执行两次,因为
	//类C在创建的时候,分别会去创建类A和类B,而类A和类B又会去创建类X,所以就类X会被创建销毁两次
	//如果类X中有函数Fun,那么类C在调用的时候需要指定调用哪个父类所继承的Fun函数
	c->A::Fun();
	//c->B::Fun();
	delete c;
	return 0;
}

再谈虚基类 前往以前的笔记

虚基类可以避免多重继承时函数调用的二义性,同理,也可以避免最上层的基类(这里指类X)被创建销毁两次

class X
{
public:
	X(){cout<<"X构造函数"<<endl;}
	virtual ~X(){cout<<"X析构函数"<<endl;}
	virtual void Fun()
	{
		cout<<"Class X"<<endl;
	}
};

//说明类X为虚基类
class A:virtual public X
{
public:
	A(int i):a(i){cout<<"A构造函数"<<endl;}
	virtual ~A(){cout<<"A析构函数"<<endl;}
private:
	int a;
};

class B:virtual public X
{
public:
	B(int i):a(i){cout<<"B构造函数"<<endl;}
	virtual ~B(){cout<<"B析构函数"<<endl;}
private:
	int a;
};

class C:public A, public B
{
public:
	//基类A和B的构造函数都是带参的,所以子类需要对其初始化,顺序随意
	//因为类X被限定只为子类产生一个实例,所以这里也可以对类X进行初始化
	C(int i, int j, int k):/*X(...),*/A(i),B(j),a(k){cout<<"C构造函数"<<endl;}
	virtual ~C(){cout<<"C析构函数"<<endl;}
private:
	int a;
};

int main()
{
	//类X只会被创建销毁一次,
	C *c = new C(1,2,3);
	//虚基类可以避免继承中的函数二义性
	c->Fun();
	delete c;
	return 0;
}

纯虚函数和抽象类

将一个虚函数初始化为0,这个函数就变成了纯虚函数,例如:

virtual int fun() = 0;

这种函数没有任何具体功能,不能直接调用它,有纯虚函数的类是抽象的,所以也不能实例化

一个类如果继承了抽象类,那么这个类就必须实现该抽象类中的方法

如果这个子类没有全部覆盖抽象基类的方法,那么这个子类也会变成一个抽象类

class X
{
public:
	virtual void print() = 0;
};
class A:public X
{
public:
	A(){}
	~A(){}
	//类A必须实现抽象类里面的纯虚函数
	void print(){cout<<"Class A"<<endl;}
	//或者继续把这个函数设为虚函数,那此时类A也属于抽象类
	//void print() = 0;
};
int main()
{
	A *pA = new A();
	pA->print();
	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、付费专栏及课程。

余额充值