(C++,MinGW 4.4.0,Windows OS)

我的猜测是代码中注释的所有内容,除了标签和。如果您认为我在某个地方错了,请更正我:

class A {
public:
   virtual void disp(); //not necessary to define as placeholder in vtable entry will be
                        //overwritten when derived class's vtable entry is prepared after
                        //invoking Base ctor (unless we do new A instead of new B in main() below)
};

class B :public A {
public:
   B() : x(100) {}
   void disp() {std::printf("%d",x);}
   int x;
};

int main() {
   A* aptr=new B;             //memory model and vtable of B (say vtbl_B) is assigned to aptr
   aptr->disp();              //<1> no error
   std::printf("%d",aptr->x); //<2> error -> A knows nothing about x
}

是错误,很明显。为什么不是错误?我认为此调用正在发生的事情是:参数中的aptr->disp(); --> (*aptr->*(vtbl_B + offset to disp))(aptr) aptr是指向成员函数的隐式this指针。在disp()内部,我们会有std::printf("%d",x); --> std::printf("%d",aptr->x); SAME AS std::printf("%d",this->x);那么为什么没有给出错误而却给出错误?

(我知道vtables是特定于实现的东西,但我仍然认为值得提出这个问题)

最佳答案

规则是:



对于成员变量,编译器仅在该特定类或其基类中查找符号名称。

在情况1中,要获取的适当方法是通过获取vpt,获取适当方法的地址并随后调用适当的成员函数来确定的。
因此,在静态绑定(bind)的情况下,动态调度本质上是fetch-fetch-call而不是普通的call

在情况2中:编译器仅在x范围内寻找this。显然,它找不到它并报告错误。

关于c++ - C++:虚函数如何解决 “this”指针范围问题?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10292973/

10-16 04:33