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学习之-----面向对象编程(继承与动态绑定)

     面向对象编程基于三个基本概念:数据抽象(类)、继承(用类派生从一个类继承另一个)和动态绑定(使得编译器能够在运行时决定是使用基类中定义的函数还是使用派生类中定义的函数。     面向对象编程...

C++多重继承下的函数动态绑定问题分析

问题前段时间看到了一个比较有趣的问题,多重继承中某种情况动态绑定的行为比较违反直觉,实例代码如下:#include using namespace std;class Base1 { public:...
  • just0kk
  • just0kk
  • 2017年01月26日 14:42
  • 106

C++基类和派生类私有、保护、公有成员访问控制以及动态绑定、三种继承

1.类的一个特征就是封装,public和private作用就是实现这一目的。所以: 用户代码(类外)可以访问public成员而不能访问private成员;private成员只能由类成员(类内)和友元...

C++动态绑定及继承

在C++中,通过基类的引用(或指针)调用虚函数,发生动态绑定。引用(或指针)既可以指向基类对象,也可以指向派生类对象。用引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实...
  • buaalei
  • buaalei
  • 2011年11月07日 10:02
  • 1066

C++ - 继承(inheritance) 和 动态绑定(dynamic binding) 简介

继承(inheritance) 和 动态绑定(dynamic binding) 简介   继承(inheritance)和动态绑定(dynamic binding) 是面向对象的重要组成部分, 即继承...

C++继承中构造函数、析构函数调用顺序及虚函数的动态绑定

昨天面试被问到这些,惭愧的很,居然搞混了,悔恨了一把。决定要彻底搞清楚。也算是有所收获。     首先说说构造函数,大家都知道构造函数里就可以调用成员变量,而继承中子类是把基类的成员变成自己的成员,那...
  • ameyume
  • ameyume
  • 2011年03月29日 13:22
  • 3106

C++知识点复习——继承关系&动态绑定&虚函数

1、什么是继承继承是实现代码服用的重要手段,在层次关系的顶部有一个基类,其它类则是直接或者间接从基类继承而来的,这些继承而来的类称为派生类。基类负责定义继承的层次关系中所有类公有的成员,而派生类则可以...

逆向分析 C++继承内存分布(带虚函数) 及动态绑定实现

昨晚断网,于是乎闲来无事,想彻底研究一下C++的继承关系下的内存结构(带虚函数的),开IDA分析,经过不断的分析,发现C++的内存结构很是复杂,很多东西都是我以前完全不知道的,以下所有内容均是个人午夜...
  • kalrey
  • kalrey
  • 2011年08月02日 19:20
  • 478

C++primer--lambda表达式-参数绑定之bind

在绑定参数这一节,C++11有了新的特性,由于旧版本的绑定参数的语言特性限制更多,也更复杂,所以标准库定义了两个分别名为bind1st和bind2nd的函数,类似bind,这两个函数接受一个函数作为参...
  • VCCTor
  • VCCTor
  • 2015年11月13日 18:10
  • 333

C++动态绑定解密

  • 2008年07月31日 15:34
  • 56KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ primer 继承与动态绑定
举报原因:
原因补充:

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