说我们有:
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()
将调用哪个Base::f()
? Base::g()
或Derived::g()
?
谢谢...
答案 0 :(得分:52)
将调用派生类的g。如果要调用基础中的函数,请调用
Base::g();
代替。如果要调用派生版,但仍希望调用基本版本,请安排派生版本的g在其第一个语句中调用基本版本:
virtual void g() {
Base::g();
// some work related to derived
}
在模板方法设计模式中使用以下事实:来自基础的函数可以调用虚方法并将控制转移到派生类中。对于C ++,它更好地称为Non-Virtual-Interface。它也广泛用于C ++标准库(例如,C ++流缓冲区具有函数pub...
,它们调用实现真正工作的虚函数。例如pubseekoff
调用受保护的seekoff
)。我在这个答案中写了一个例子:How do you validate an object’s internal state?
答案 1 :(得分:6)
它是Derived :: g,除非你在Base的构造函数中调用g。因为在构造Derived对象之前调用了Base构造函数,所以Derived :: g无法在逻辑上被调用,因为它可能会操作尚未构造的变量,因此将调用Base :: g。
答案 2 :(得分:5)
pBase是指向基础的指针。 pBase = new Derived返回指向Derived - Derived is-a Base的指针。
所以pBase = new Derived是有效的。
pBase引用一个Base,因此它将Derived视为Base。
pBase-> f()将调用Derive :: f();
然后我们在代码中看到:
Derive :: f() - > Base :: f() - > g() - 但是哪个g ??
嗯,它调用Derive :: g(),因为这是pBase“指向”的那个。
答案:Derive :: g()
答案 3 :(得分:2)
嗯......我不确定这应该编译。以下,
Base *pBase = new Derived;
除非您拥有:,否则无效
Class Derived : public Base
它想要你的意思吗?如果这是你想要的意思,
pBase->f();
然后调用堆栈会像这样:
Derived::f()
Base::f()
Derived::g()
答案 4 :(得分:1)
由于您已将g()定义为虚拟,因此无论您的代码当前正在访问它的类型如何,都会在类的vtable中查找派生得最多的g()并调用它。
答案 5 :(得分:1)
实际运行代码会显示Derived :: g()被调用。
答案 6 :(得分:0)
我认为你试图发明Template Method Pattern
答案 7 :(得分:0)
将调用派生类'方法。
这是因为在包含虚函数的类中包含了vtable,并且这些类覆盖了这些函数。 (这也称为动态调度。)以下是真正发生的事情:为Base
创建了一个vtable,为Derived
创建了一个vtable,因为只有一个每班vtable。因为pBase
正在调用虚拟和覆盖的函数,所以会调用指向Derived
的vtable的指针。称之为d_ptr
,也称为vpointer:
int main()
{
Base *pBase = new Derived;
pBase->d_ptr->f();
return 0;
}
现在d_ptr调用Derived::f()
,调用Base::f()
,然后查看vtable以查看要使用的g()
。因为vpointer只知道g()
中的Derived
,所以我们使用的是Derived::g()
。因此,ps aux | bla bal | xargs kill || true
被调用。
答案 8 :(得分:0)
g()。
如果在构造函数或析构函数中,将调用基类的g()。
https://www.geeksforgeeks.org/calling-virtual-methods-in-constructordestructor-in-cpp/
// calling virtual methods in constructor/destructor
#include<iostream>
using namespace std;
class dog
{
public:
dog()
{
cout<< "Constructor called" <<endl;
bark() ;
}
~dog()
{
bark();
}
virtual void bark()
{
cout<< "Virtual method called" <<endl;
}
void seeCat()
{
bark();
}
};
class Yellowdog : public dog
{
public:
Yellowdog()
{
cout<< "Derived class Constructor called" <<endl;
}
void bark()
{
cout<< "Derived class Virtual method called" <<endl;
}
};
int main()
{
Yellowdog d;
d.seeCat();
}
输出:
Constructor called
Virtual method called
Derived class Constructor called
Derived class Virtual method called
Virtual method called