virtual function call from base class
说我们有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Class Base { virtual void f(){g();}; virtual void g(){//Do some Base related code;} }; Class Derived : public Base { virtual void f(){Base::f();}; virtual void g(){//Do some Derived related code}; }; int main() { Base *pBase = new Derived; pBase->f(); return 0; } |
哪个
谢谢。。。
将调用派生类的g。如果要调用基函数,请调用
1 | Base::g(); |
相反。如果要调用派生版本,但仍要调用基版本,请安排G的派生版本在其第一条语句中调用基版本:
1 2 3 4 | virtual void g() { Base::g(); // some work related to derived } |
模板方法设计模式中使用了这样一个事实,即来自基的函数可以调用一个虚拟方法并将控制权转移到派生类中。对于C++,它更被称为非虚拟接口。它在C++标准库中也有广泛的应用(例如C++流缓冲区)具有
它是派生的::g,除非在基的构造函数中调用g。因为在构造派生对象之前调用了基构造函数,所以不能在逻辑上调用派生::g,因为它可能操作尚未构造的变量,所以将调用基::g。
pbase是指向基的指针。pbase=new derived返回指向派生is-a基的指针。
所以pbase=new derived是有效的。
pbase引用了一个基,所以它将把派生看作是一个基。
pbase->f()将调用派生::f();
然后我们在代码中看到:
派生::f()-->base::f()-->g()-但哪个g??
好吧,它调用了派生::g(),因为这是pbase"指向"的g。
答案:派生::g()
好。。。我不确定这应该编译。以下,
1 | Base *pBase = new Derived; |
无效,除非:
1 | Class Derived : public Base |
这是你的意思吗?如果这是你的意思,
1 | pBase->f(); |
然后调用堆栈如下所示:
1 2 3 | Derived::f() Base::f() Derived::g() |
实际上,运行代码表明调用了派生的::g()。
正如您将g()定义为虚拟的那样,最派生的g()将在类的vtable中查找并调用,而不管您的代码当前访问的类型是什么。
有关虚拟函数的C++ FAQ。
将调用派生类的方法。
这是因为在具有虚拟函数的类和重写这些函数的类中包含vtables。(这也被称为动态调度。)下面是实际情况:vtable是为
1 2 3 4 5 6 | int main() { Base *pBase = new Derived; pBase->d_ptr->f(); return 0; } |
现在,d ptr调用
我想你是想发明模板方法模式