(C++)C++多态性中的静态绑定和动态绑定

静态绑定和动态绑定是C++多态性的一种特性。

1、对象的静态类型和动态类型:

  • 对象的静态类型:

对象在声明是采用的类型,在编译期确定;

  • 对象的动态类型:

当前对象所指的类型,在运行期决定,对象的动态类型可以更改,但静态类型无法更改。

class B{

};

class C: public B{

};

class D: public B{

};

D* pD=new D();
// pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB=pD;
// pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*
c* pC=new C();
// pC的静态类型是它声明的类型C*,动态类型也是C*
pB=pC;
// pB的动态类型可以改变,现在它的动态类型为C*

2、静态绑定和动态绑定

  • 静态绑定:

绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。

  • 动态绑定:

绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

class B{
    void DoSomething();
    virtual void vfun();
};

class C: public B{
    //首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。
    void DoSomething();
    virtual void vfun();
};

class D: public B{
    void DoSomething();
    virtual void vfun();
};

D* pD=new D();
// pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB=pD;
// pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*

pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?

答案:不是的,虽然pD和pB指向同一对象,但函数DoSomething是一个non-virtual函数,它是静态绑定的,也就是编译器会在编译器根据对象的静态类型来选择函数,pD的静态类型是D*,那么编译器在处理pD->DoSomething()的时候会将它指向D::DoSomething()。同理,pB的静态类型是B*,那么pB->DoSomething()调用的就是B::DosSomething()。

pD->vfun()和pB->vfun()调用的是同一函数吗?

答案:是的,vfun是个虚函数,它是动态绑定的,也就是它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但他们同时指向一个对象,他们的动态对象是相同的,都是D*,所以,他们调用的是同一个函数:D::vfun()。

上面都是针对对象指针的情况,对于引用(reference)的情况同样适用。

指针和引用的动态类型和静态类型可能会不一致,但是对象的动态类型和静态类型是一致的。
D D;
D.DoSomething()和D.vfun()永远调用的都是D::DoSomething()和D::vfun()。

总结:只有虚函数才使用的是动态绑定,其他的全部是静态绑定。

当缺省参数和虚函数一起出现的时候情况有点复杂,极易出错。我们知道,虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的

class B{
    void DoSomething();
    virtual void vfun(int i=10);
};

class D: public B{
    void DoSomething();
    virtual void vfun(int i=20);
};

D* pD=new D();
// pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB=pD;
// pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*
pD->vfun();
pB->vfun();

有上面的分析可知,pD->vfun()和pB->vfun()调用都是函数D::vfun(),但是他们的缺省参数是多少?

分析一下,缺省参数是静态绑定的,pD->vfun(),pD的静态类型是D*,所以它的缺省参数是20;而pB的静态类型是B*,所以pB->vfun()的缺省参数是10.

对于这个特性,估计没有人会喜欢。所以,永远记住:
“绝不重新定义继承而来的缺省参数(Never redefine function’s inherited default parameters value.)”

参考文章:

http://blog.csdn.net/chgaowei/article/details/6427731

时间: 2024-07-29 02:10:34

(C++)C++多态性中的静态绑定和动态绑定的相关文章

Java中的重载、重写、多态,静态绑定、动态绑定

重载,英文名是overload,是指在一个类中定义了一个以上具有相同名称的方法,这些方法的参数个数.参数类型和顺序不能相同.返回类型可以相同,也可以不同. public class TstaticOverload { static int height; TstaticOverload() { System.out.println ("Planting a seedling"); height = 0; } TstaticOverload(int initialHeight) { he

C++中虚函数的动态绑定和多态性

目录 静态类型VS动态类型,静态绑定VS动态绑定两组概念 虚函数的实现机制 多态性 一.静态 vs 动态 静态类型 VS 动态类型.静态类型指的是对象声明的类型,在编译器确定的.动态类型指的是对象的所指向的类型,动态类型是可以更改的,静态类型无法更改.继承关系会导致对象的指针和引用具有静态类型和动态类型,因为继承关系的存在中可能会存在类型之间的向上向下类型转换.静态绑定 VS 动态绑定.某特性(函数)依赖与对象的静态类型,在编译期确定,某特性(函数)依赖于对象的动态类型,在运行期确定.只有通过基

Java方法的静态绑定与动态绑定讲解(向上转型的运行机制详解)

一:绑定 把一个方法与其所在的类/对象 关联起来叫做方法的绑定.绑定分为静态绑定(前期绑定)和动态绑定(后期绑定). 二:静态绑定 静态绑定(前期绑定)是指:在程序运行前就已经知道方法是属于那个类的,在编译的时候就可以连接到类的中,定位到这个方法. 在Java中,final.private.static修饰的方法以及构造函数都是静态绑定的,不需程序运行,不需具体的实例对象就可以知道这个方法的具体内容. 三:动态绑定 动态绑定(后期绑定)是指:在程序运行过程中,根据具体的实例对象才能具体确定是哪个

Java : 多态表现:静态绑定与动态绑定(向上转型的运行机制)

本来想自己写写的,但是看到有人分析的可以说是很清晰了,故转过来. 原文地址:http://www.cnblogs.com/ygj0930/p/6554103.html 一:绑定 把一个方法与其所在的类/对象 关联起来叫做方法的绑定.绑定分为静态绑定(前期绑定)和动态绑定(后期绑定). 二:静态绑定 静态绑定(前期绑定)是指:在程序运行前就已经知道方法是属于那个类的,在编译的时候就可以连接到类的中,定位到这个方法. 在Java中,final.private.static修饰的方法以及构造函数都是静

Java静态绑定和动态绑定

程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定 静态绑定(早绑定 编译器绑定): 在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现.例如:C .针对java可以理解为程序编译期的绑定:特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定 动态绑定(迟绑定 运行期绑定): 后期绑定:在运行时根据具体对象的类型进行绑定. 若一种语言实现了后期绑定

C++ 静态绑定与动态绑定------绝不重新定义继承而来的缺省参数

在了解静态绑定和动态绑定之前,先了解什么是对象的静态类型,什么是对象的动态类型. 对象的静态类型:对象在声明时采用的类型.是在编译器决定的. 对象的动态类型:目前所指对象的类型.是在运行期决定的. 动态类型可以更改,而静态类型不可更改.看一个示例 class Base { public: void setData(int i=10) { cout <<" virtual int Base::setData()"<<endl; } virtual int getD

C++调用空指针对象的成员函数——静态绑定与动态绑定

最近代码中看到调用空指针对象的成员函数的写法,联想起上次碰到的问题: C++类的成员函数存储方式(是否属于类的对象) 两者的本质是一样的,上次只是简单地讨论了下,这次从编译器的角度,来谈一谈这个知识点. 一个简单的例子: class MyClass { public: int i; void hello() { printf("hello\n"); } void print() { printf("%d\n", i); } }; void main() { MyCl

“全栈2019”Java第五十五章:方法的静态绑定与动态绑定

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第五十五章:方法的静态绑定与动态绑定 下一章 "全栈2019"Java第五十六章:多态与字段详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&q

有关于多态和静态绑定与动态绑定的知识

一.多态 事物出现的多种体现形态(Java中指同一对象可以有不同类型的指向.) 1.多态的体现: 父类的引用指向了自己的子类的(或孙类)的对象. 父类的引用也可以接受自己的子类对象. 2.多态的前提: 1).必须是类与类之间有关系,要么继承.要么实现. 2).存在继承.  存在方法重写.   存在父类引用指向子类对象. 3.多态的好处: 提高了代码的复用性. 4.多态的弊端: 但是只能是父类的引用指向父类的成员. 5.多态的应用: 6.多态的代码特点(代码的注意事项) 1).多态中成员函数的特点