您的位置:首页 > 编程语言 > C语言/C++

C++静态类型、动态类型与多态性探讨

2017-04-27 17:50 253 查看

静态类型与动态类型

在C++中,我们可以将基类的指针或引用绑定到派生类的对象上,所以当我们使用基类的指针或引用时,我们并不清楚该指针或引用所绑定的真实类型。当我们使用存在继承关系的类型时,必须区分变量和表达式的静态类型与动态类型。静态类型在编译时是已知的,即变量声明时的类型或表达式生成的类型,而动态类型则是变量或表达式表示对象的类型(参考《C++
Primer 中文版第五版》15.2.3节)。

下面举例说明:

class Base
{
...
public:
virtual void func(int var = 0) = 0;
...
}
void base::func(int var)
{
...;//纯虚函数也可提供一份函数实现
}
class Dervied : public Base{ ...public: //注意,定义未写出;缺省参数值不同,该设计缺陷后面说 virtual void func(int var = 1); ...}void func2(Base & B){ int Temp = 合适值; B.func(Temp);//具体执行哪个虚函数体运行时确定}Base* pB0;//静态类型为Base*,无动态类型,因为未指向任何对象Base* pB = new Base();//静态类型为Base*,动态类型为也是Base*
pB2 = new Derived();//静态类型为Base*,动态类型为Derived*。pB->func();//调用Base::func(0)pB2->func();//调用Derived::func(0)
Base B;
Derived D;
func2(B);//调用Base::func(0)
func2(D);//调用Derived::func(0)



多态性

(参考《Effective C++中文版》第三版条款37)

在C++语言中,当使用基类的引用或指针调用一个虚函数时将发生动态绑定(或称运行时绑定)。对象的动态类型指当前所指对象的类型(如pB动态类型为Derived*),动态类型表现出一个对象将会有什么行为。Virtual函数由动态绑定而来,指当调用一个virtual函数时,究竟调用哪一份函数实现代码,取决于调用的那个对象的动态类型。

特别注意:virtual函数是动态绑定,而缺省参数值却是静态绑定。例如pB2->func()出现了“调用一个derived class内的virtual函数func(),却使用了Base class为它提供的缺省参数值”,这与我们预期的是有出入的,需特别注意。解决措施是考虑virtual函数的替代设计,如设计以个非virtual接口取调用virtual函数,而在非virual函数中实现缺省参数。

(参考《C++
Primer 中文版第五版》15.2.3节)

理解具有继承关系的类之间的类型转换,需注意:

1、从派生类向基类的类型转换只对指针或引用类型有效,在对象之间不存在类型转换。当我们用一个派生类对象为一个基类对象初始化或赋值时,只有该派生类对象中的基类部分会被拷贝、移动或赋值,它的派生类部分将被忽略掉。

2、基类向派生类不存在隐式转换。之所以存在派生类向基类的类型转换,是因为每个派生类对象都包含一个基类部分,而基类的引用或指针可以绑定到该基类部分上。但是如果基类对象不是派生类对象的一部分,则它只含有基类定义的成员,而不含有派生类定义的成员,因此不存在从基类向派生类的自动类型转换。

3、派生类向基类的类型转换也可能会由于访问受限而变得不可行。

void func2(Base & B)
{
int Temp = 合适值;
B.func(Temp);//具体执行哪个虚函数体运行时确定
}

void func2(Base & B)
{
int Temp = 合适值;
B.func(Temp);//具体执行哪个虚函数体运行时确定
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息