C++ primer 继承与动态绑定

原创 2016年06月01日 23:06:57

数据抽象(data abstraction),继承(inheritance)与动态绑定(dynamic binding)是面向对象编程(object-oriented programming)的三大核心思想(key ideas)。

数据抽象好理解,就是使得我们将类的接口与实现分离

继承与动态绑定在使用上是相关的


这里我们注意几点:

1.继承类(derived class)需要在自己内部(就是class{...}内部)有它打算自己实现的(defile it self)虚函数(virtual function) 的声明(declaration).这句话听起来好像是废话,我当然要声明了 ,但我感觉想表达的重点是这样的:你需要自己内部(own class body)声明,你想修改的基类function,当然基类中你想要修改的function 都是virtual function ,如果没有内部声明基类中的部分virtual function ,那么对于继承类来讲就相当于无修改直接继承这个函数(inherit without change)


2.动态绑定dynamic binding  or  run-time binding

C++ primer原文是这样说的:

In C++ ,dynamic binding happens when a virtual funtion is called through a reference(or a pointer)to a base class

.在C++中,动态绑定发生的场景的两个条件: virtual funtion    和 a reference(or a pointer)to a base class 。

首先你调用的要是一个虚函数,其次是引用或者指针调用的。

所以在实际工程中,要实现动态绑定,我们传的参数都是用引用或者指针。


3.作为基类,它的function ,需要区分为期望继承类override的(即继承类自己define it self的)和期望继承类能够 无修改直接继承的(inherit without change)。

对于期望继承类override的function,我们要在基类中,将这项function 定义为virtual ,具体操作就是在声明前加上关键字virtual , 也就是所谓的将这个function定义为了虚函数。就像2中说讲的,我们使用引用或者指针call 虚函数,实现动态绑定


A function this is declared as virtual in the base class is implictly virtual in derived class as well.

4.一个在基类中声明的虚函数,在继承类中会隐式地(implicitly)为virtual

下面我们举几个例子说明,并观察结果

例1:

class A{
public :
	void Print()
	{
		printf("A\n");
	}
};


class B :public A{
public:
	void Print()
	{
		printf("B\n");
	}
};


void Show(A &a)
{
	a.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
	A a;
	B b;
	Show(a);
	Show(b);
	return 0;
}
运行的结果为:

A

A

因为基类A 中的Print函数并没有声明为virtual ,所以无法实现动态绑定,所以a.Print都是调用A的function 。

例2:

不同于例1的地方就是在A 的Print 函数前加上virtual keyword

class A{
public :
	virtual void Print()
	{
		printf("A\n");
	}
};

class B :public A{
public:
	void Print()
	{
		printf("B\n");
	}
};

void Show(A &a)
{
	a.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
	A a;
	B b;
	Show(a);
	Show(b);
	return 0;
}

运行的结果为:

A

B

base class A函数Print 已经被声明为virtual ,可以进行动态绑定,且Show中的传入参数a为引用。在调用Show(b)时,这时候Show里面的a.Print,调用的其实是class B中的Print

例3:

不同于例2的地方是show函数的传入参数不用引用 而是普通形参

class A{
public :
	virtual void Print()
	{
		printf("A\n");
	}
};

class B :public A{
public:
	void Print()
	{
		printf("B\n");
	}
};

void Show(A a)
{
	a.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
	A a;
	B b;
	Show(a);
	Show(b);
	return 0;
}

运行的结果为:

A

A

结果与例2不同,这是因为Show的传入参数不是引用或者指针,这样,show中的a,一定是A类型 ,无法改变,脱离的动态二字。

具体原因就是传参类型不同,这里需要理解传参的机制是如何的,其实引用是变相的传递指针,只是比指针更加安全,不容易引起崩溃问题,具体原因请看引用的原理。


动态绑定时,调用时的类都是较底层类型,就是在这个继承层次(hierarchy)中,都是 较底层类型(基类) 动态调用 较高层类型(继承类)


今天写到这里,后面继续补充...

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++ Primer笔记(十七)多重继承与虚继承

多重继承是从多于一个直接基类派生类的能力。多重继承的派生类继承其所有父类的属性。 为了支持多重继承,应扩充派生列表,多个类用逗号分割。如: class panda:public bear,publ...
  • woshibendangao
  • woshibendangao
  • 2014年04月27日 11:11
  • 1003

21天学通C++之--继承实战练习

继承与派生的概念 继承所表达的是对象类之间的一种关系。它使得某类对象可以继承另外一类对象的特征和能力。 继承使得程序员对共同的属性及操作只需说明一次,减少了相似类的重复说明,并且在具体情况下可以扩展和...
  • qq_24052051
  • qq_24052051
  • 2017年05月03日 18:32
  • 280

C++ Primer学习笔记(13)——封装、继承、多态

C++ 是一种典型的面向对象的编程语言,其最显著地特点是封装、继承和多态。充分理解封装、继承、多态是如何实现的,学好C++就不是难事了。...
  • zhangyumumu
  • zhangyumumu
  • 2015年07月08日 16:45
  • 829

[阶段总结]写在C++ Primer Plus后,C++ Primer前

这篇总结分为三个部分 一、总结这半年的学习生活情况。 二、总结学习C++ Primer Plus的一些收获 三、展望一下接下来半年应该如何开展学习工作 Ⅰ前半年的学习生活 1.参加了一次网易游戏...
  • xy_cpp
  • xy_cpp
  • 2017年06月07日 09:17
  • 834

C++动态绑定和虚函数表vtable (动态实现原理)

关于C++内部如何实现多态,对程序员来说即使不知道也没关系,但是如果你想加深对多态的理解,写出优秀的代码,那么这一节就具有重要的意义。 我们知道,函数调用实际上是执行函数体中的代码。函数体是内存中的一...
  • zhanghow
  • zhanghow
  • 2016年12月12日 21:38
  • 774

真希望我不是从这本书开始学习C++的 《C++Primer Plus(第五版)中文版》书评

这本书是我在大二的那个暑假和大三第一个学期时候看的。现在回想起来,这本书看的时间真是长啊。当然这么长是有原因的,这本书有一个特点,每一章都有一些简单的课后题目。题目都是非常简单的,不过真的完成每一个题...
  • aquanga
  • aquanga
  • 2011年08月29日 00:55
  • 4465

C++ primer 模板与泛型编程

c++ primer 模板与泛型编程 Queue模板的实现
  • jsjliuyun
  • jsjliuyun
  • 2014年05月14日 11:34
  • 1189

【C++基础】 继承与动态绑定

C++中触发动态绑定条件:1、虚函数成员   2、通过基类类型的引用或指针进行函数调用 例子说明: #include #include using namespace std; cla...
  • u012494481
  • u012494481
  • 2013年12月26日 19:55
  • 381

Primer c++ 第5版pdf

下载地址:网盘下载 内容简介  · · · · · · 这本久负盛名的 C++经典教程,时隔八年之久,终迎来史无前例的重大升级。除令全球无数程序员从中受益,甚至为之...
  • cf406061841
  • cf406061841
  • 2017年07月18日 20:55
  • 671

C++ primer:命名空间与多重继承

1.库倾向于定义许多全局名字——主要是模板名、类型名或函数名。在使用来这些名字中有一些几乎不可避免地会发自多个供应商的库编写应用程序的时候,生冲突,这种名字冲突问题称为命名空间污染问题。 2.命名空...
  • a81895898
  • a81895898
  • 2012年03月29日 19:46
  • 1964
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ primer 继承与动态绑定
举报原因:
原因补充:

(最多只允许输入30个字)