继承与多态

继承

final(C++11)避免被继承

class B final {};
class D : public B {};

编译后的输出是 (Visual Studio)
error C3246: “D”: 无法从“B”继承,因为它已被声明为“final”这是程序输出

派生类继承的成员

1、C++ 11派生类不继承的特殊函数:
(1)析构函数;
(2)友元函数;
2、继承基类的构造函数:
(1) using A::A; 继承所有基类ctor
(2) 不能仅继承指定的某个基类ctor

#include <iostream>
using std::cin;
using std::cout;
struct A
{
	A(int i) { cout << "construct A" << std::endl; }
	A(double d,int i){}
};
struct B:A
{
	using A::A; //继承基类ctor,除了A(int i),因为下面的B(int i)继承了A(int i)
	int d{ 0 };
	B(int i) :A{ i }, d{ i }{
		cout << "construct B" << std::endl;
	}
};
int main(void)
{
	B b(1);//先调用基类的构造函数,再调用派生类的构造函数
	cin.get();
	return 0;
}

多态:不同对象在接受相同消息时产生的不同动作

C++的多态行表现在运行和编译两个阶段:

运行时:多态性通过继承和虚函数来表示

虚函数:在基类中冠以virtual的成员函数,允许在派生类中对基类的虚函数重新定义(基类中定义了虚同名函数,派生类中的同名函数自动变为虚函数);

类中保存着一个Virtual function table (虚函数表)
Run-time binding (运行时联编/动态联编)
More overhead in run-time than non-virtual function (比非虚函数开销大)

基类与派生类中有同名函数
(1) 通过派生类对象访问同名函数,是静态联编
(2) 通过基类对象的指针访问同名函数,是静态联编
(3) 通过基类对象的指针或引用访问同名虚函数,是动态联编

eg1、静态联编(对象访问):对象是什么类型,就调用什么类型

#include <iostream>
using namespace std;
class A {
public:
	void f() { cout << "A" << endl; }
};
class B :public A {
public:
	void f() { cout << "B" << endl; }
};

int main(void)
{
	A a;
	B b;
	a.f();//A::f
	b.f();//B::f
	return 0;
}

eg2:静态联编(指针访问):指针是什么类型,就调用什么类型

#include <iostream>
using namespace std;
class A {
public:
	void f() { cout << "A" << endl; }
};
class B :public A {
public:
	void f() { cout << "B" << endl; }
};

int main(void)
{
	A a; B b; A* ptr;
	ptr = &a; (*ptr).f();//A
	ptr = &b; (*ptr).f();//A

	return 0;
}

eg3:动态联编:只看对象
(1)虚函数指针

#include <iostream>
using namespace std;
class A {
public:
	virtual void f() { cout << "A" << endl; }
};
class B :public A {
public:
	void f() { cout << "B" << endl; }
};

int main(void)
{
	A a; B b; A* ptr;
	ptr = &a; (*ptr).f();//A
	ptr = &b; (*ptr).f();//B

	return 0;
}

(2)虚函数引用

#include <iostream>
using namespace std;
class A {
public:
	virtual void f() { cout << "A" << endl; }
};
class B :public A {
public:
	void f() { cout << "B" << endl; }
};

int main(void)
{
	A a; B b;
	A& p1 = a;
	A& p2 = b;
	p1.f();
	p2.f();

	return 0;
}

纯虚函数:在基类中为其派生类保留一个函数的名字,以便派生类对其进行定义。不允许直接调用纯虚函数
从基类继承来的纯虚函数,在派生类中仍是虚函数,一个类至少有一个纯虚函数,这个类称为抽象类,抽象类必须用作派生其他类的基类,不能直接创建对象。

编译时:多态性体现在函数和运算符的重载上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值