C++ 中的静态绑定和动态绑定

C++ 在面向对象编程中,有着静态绑定动态绑定的定义,为了了解这两个概念,首先先简单阐述一些名词:

  • 静态类型:对象在声明时使用的类型,在编译期就已经确定
  • 动态类型:指针变量或引用变量所指向对象的类型,在运行期才能确定
  • 静态绑定:绑定的是静态类型,对象的函数和属性依赖于绑定的静态类型,发生在编译期
  • 动态绑定:绑定的是动态类型,对象的函数和属性依赖于绑定的动态类型,发生在运行期

而非虚函数一般都是静态绑定,虚函数则是动态绑定

举一个例子来说明静态类型和动态类型:

class Shape {//用于描述几何形状的类
public:
    enum ShapeColor  { Red, Green, Blue };
    //所有形状都必须提供一个函数来绘制自己
    virtual void draw(ShapeColor color = Red) const = 0;
	void draw() const;
    ...
};
class Rectangle : public Shape {
public: 
    //注意,与基类的默认参数值不同
    virtual void draw(ShapeColor color = Green) const;
    ...
};
class Circle : public Shape  {
public:
    //没有默认参数值,调用该函数一定要赋予参数,因为静态绑定下,这个函数并不从其基类继承默认参数值
    //但若以指针或引用调用此函数,可以不指定参数值,因为动态绑定下,这个函数会从其基类继承默认参数值
    virtual void draw(ShapeColor color) const;
    ...
};

int main(){
	// 静态类型都为 Shape* 。注意,不论它们真正指向什么,它们的静态类型都是 Shape*
	Shape* ps;					// ps 没有指向,所以它没有动态类型
	Shape* pNull = nullptr;		// pNull 没有指向,所以它没有动态类型
	Shape* pc = new Circle;		// pc 的动态类型为 Circle*
	Shape* pr = new Rectangle;	// pr 的动态类型为 Rectangle*
	ps = pc;					// ps 的动态类型如今是 Circle*
	ps = pr;					// ps 的动态类型如今是 Rectangle*
	
	return 0;
}

由于 虚函数 是动态绑定的,所以调用一个 虚函数 时,究竟调用哪个函数取决于发出调用的那个对象的 动态类型

pc->draw(Shape::Red);	// 调用 Circle::draw(Shape::Red)
pr->draw(Shape::Red);	// 调用 Rectangle::draw(Shape::Red)
pNull->drwa();			// 调用 Shape::draw() ,空指针可以调用非虚函数,因为静态绑定在编译期就确定了,和指针空不空没关系

总结一下静态绑定和动态绑定的区别:

  1. 静态绑定发生在编译期,动态绑定发生在运行期
  2. 对象的动态类型可以更改,但是静态类型无法更改
  3. 要想实现动态,必须使用动态绑定
  4. 在继承体系中只有虚函数使用的是动态绑定,其他的全部是静态绑定;
  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值