2

我们在Cpp中使用 virtual 来实现动态绑定,即在运行时根据创建的实际对象而不是引用或指针变量来决定必须调用哪个函数。

class A
{
 int a;
public:
 virtual void show();
};

void A::show() { cout<<a<<endl; }

class B:public A
{
 int b;
public:
 void show() { cout<<b<<endl; }
};

class C:public A
{
 int c;
public:
 void show() { cout<<c<<endl; }
};

假设,someFunction(A& aref)。它可以采用类型BC或的对象A

注意:假设设置了数据成员的值

我的意思是定义了路径(可以是 A 或 B 或 C)。这不完全是run time dependent[就像要求用户输入年龄并且用户输入一些单词或其他一些数据类型]。

但是为什么这被称为run time binding?编译器会事先检查要分配的对象是否兼容。

是用来表示引用变量与特定类型的对象没有严格关联的术语,它是在运行时决定的。还有更多吗?

4

5 回答 5

5

虚拟方法在用于调用方法的对象中创建一个虚拟表。

在运行时查找正确的方法。

最明显的情况是,如果您有一个包含不同类型对象的基类列表:

std::list<A*> myList = new std::list<A*>();
myList.push_back(new A());
myList.push_back(new B());
myList.push_back(new C());

for (A* a : myList)
{
    a->show();
}

在这个小例子中,所有对象都是不同的类型,编译器将它们都视为A对象(有一个 A 类型的变量调用show ()),但仍然调用了正确的方法。

于 2013-05-08T15:05:02.487 回答
2

编译器不能总是确定变量的确切类型。当您使用基类的指针时,它们可以是任何派生类型。基类指针的派生类型通常只能在运行时解析。

于 2013-05-08T15:00:29.970 回答
2

其他翻译单元中可能有其他子类型。此外,即使您考虑在一批中编译的所有翻译单元,动态链接也可以在源代码和可以编译它的编译器被狼吃掉数年后引入新的子类型。它实际上是在运行时决定的:为调用virtual方法而生成的代码从对象(中的指针)获取函数指针,因此它是运行时值并且可以采用任何值。

于 2013-05-08T15:04:09.187 回答
1

您实际上需要在运行时相关上下文中使用一个类才能真正看到后期绑定。

考虑这样的事情:

// foo.hpp
struct A {
virtual void show();
virtual ~A();
};
struct B : A {
  void show();
};
A* get_stuff(std::string x);

// the implementation is in foo.cpp and doesn't interest us here


// main.cpp
#include "foo.hpp"
int main()
{
  std::string input;
  // .. read stuff from the user
  A* a = get_stuff(input);
  a->show(); // how would the compiler know which show is being called?
}
于 2013-05-08T15:07:55.370 回答
1

静态绑定和动态绑定的区别在于静态绑定是在编译时定义的——这意味着无论什么类型的对象,它总是会从编译器确定的任何类调用相同的成员函数,而动态绑定(或运行时绑定)在代码运行时定义。这意味着编译器生成的代码将根据代码所属的类在代码执行时“选择”相应的函数。

该对象显然需要兼容,但编译器不必在编译期间确切知道该对象是哪个类。想象一下,我们有一个程序可以从文件中读取“形状、中心点和大小”,其中 size 只是一个“1-5”,用于超小到超大,以及一个可以创建类对象的函数square,circletriangle. 现在喂它:

Square 300, 300, 5
Circle 120, 300, 2
Circle 240, 300, 2
Triangle 300, 300, 1

当然,编译器不知道你是要画正方形、圆形还是三角形,或者它们的顺序是什么。每个形状的虚拟“绘图”功能显然是不同的。

这可能(如果坐标匹配)画出看起来像一张脸的东西(至少,两只眼睛和一个鼻子在一个正方形中)。

于 2013-05-08T15:10:17.643 回答