C++多态和继承

C++的多态性

简单来说就是一个接口,多种方法。多态性是通过虚函数实现的,在基类的函数前加上virtual关键字,在派生类中重写该函数,运行的时候会根据对象的实际类型来调用相应的函数。如果对象是基类就调用基类的函数,对象是派生类就调用派生类的函数。

比如声明基类的指针,利用该指针指向随意一个子类对象,调用对应的虚函数,能够依据指向的子类的不同而实现不同的方法。假设没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用对应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。由于没有多态性,函数调用的地址将是一定的,而固定的地址将始终调用到同一个函数,这就无法实现一个接口,多种方法的目的了。

基类不含虚函数的情况

类A为基类,类B继承A,类C继承B,没有利用c++的多态性

class A {
public:
	A() { cout << "in A()" << endl; }
	void fun() { cout << "in A::fun()" << endl; }
	~A() { cout << "in ~A()" << endl; }
};

class B : public A {
public:
	B() { cout << "in B()" << endl; }
	void fun() { cout << "in B::fun()" << endl; }
	~B() { cout << "in ~B()" << endl;}
};

class C : public B {
public:
	C() { cout << "in C()" << endl; }
	void fun() { cout << "in C::fun()" << endl; }
	~C() { cout << "in ~C()" << endl; }
};

main函数里面代码如下,新建一个派生类赋给基类实例:

	A* test = new C();
	test->fun(); //注意:这里调用的是A::fun()
	delete test;

运行结果:
在这里插入图片描述

将main函数代码改成,新建一个派生类赋给派生类实例:

	C* test = new C();
	test->fun();
	delete test;

运行结果:
在这里插入图片描述

基类包含虚函数的情况

class A {
public:
	A() { cout << "in A()" << endl; }
	virtual void fun() { cout << "in A::fun()" << endl; }
	~A() { cout << "in ~A()" << endl; }
};

class B : public A {
public:
	B() { cout << "in B()" << endl; }
	void fun() { cout << "in B::fun()" << endl; }
	~B() { cout << "in ~B()" << endl;}
};

class C : public B {
public:
	C() { cout << "in C()" << endl; }
	void fun() { cout << "in C::fun()" << endl; }
	~C() { cout << "in ~C()" << endl; }
};
	A* test = new C();
	test->fun();
	delete test;

运行结果:
在这里插入图片描述
但如果将A的析构函数变为虚函数,所有类的析构函数又都会被调用

	virtual ~A(){ cout << "in ~A()" << endl; }

在这里插入图片描述

public继承和private继承

上面的例子都是public继承

如果将B对A的继承改成private继承,

class B : private A { //私有继承
public:
	B() { cout << "in B()" << endl; }
	void fun() { cout << "in B::fun()" << endl; }
	~B() { cout << "in ~B()" << endl;}
};

main函数里就会显示出错
在这里插入图片描述
具体错误为
在这里插入图片描述

虚函数表

如果一个类中包含虚函数,那么这个类就会包含一张虚函数表,虚函数表存储的每一项是一个虚函数的地址。这个类的每一个对象都会包含一个虚指针指向虚函数表(虚指针存在于对象实例地址的最前面,保证虚函数表有最高的性能)。对象不包含虚函数表,只有虚指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。
在这里插入图片描述

原始基类的虚函数表

在这里插入图片描述

单继承时的虚函数表

没有重写基类函数的情况
在这里插入图片描述
重写了基类函数的情况
在这里插入图片描述

多重继承时的虚函数表

class C : public A, public B
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值