我的朋友问我虚拟功能问题。
如果一个子对象调用一个虚函数,在什么条件下,这个虚函数实际上是在父实现中执行的?
答案 0 :(得分:3)
我认为你需要发布一些代码来澄清你的要求,但是(除了析构函数)基类函数不会被调用,除非子函数从它自己的函数中显式调用itt。例如,在:
struct A {
virtual ~A() {}
virtual void f() {}
};
struct B : public A {
virtual void f() {}
};
int main() {
A * a = new B;
a->f();
delete a;
}
只调用B的虚函数f()。如果你想要调用A :: f(),你必须明确地这样做:
struct B : public A {
virtual f() {
A::f(); // explicit call
}
};
哦,当然在B没有声明函数的情况下 - 在这种情况下,将始终调用A :: f()。
答案 1 :(得分:2)
无法理解当前形式的问题究竟隐含的内容。
如果按字面意思理解,问题有一个明显而直接的答案:如果父母的实现是相关函数的最终覆盖,即如果孩子没有提供自己的实现,则调用父版本
class parent {
public:
virtual void foo() { /* whatever */ }
};
class child : parent {
public:
void bar() {
foo(); /* call the parent's implementation, as requested */
}
};
所以,这是你的答案。
当然,对于任何最有可能不是这个问题所隐含的内容的人来说,这是直观明显的。很可能暗示子类覆盖了父类的功能。在这种情况下,还有另一个明显的答案:如果孩子使用函数的完全限定名称,将调用父版本
class parent {
public:
virtual void foo() { /* whatever */ }
};
class child : parent {
public:
virtual void foo() { /* whatever */ }
void bar() {
parent::foo(); /* call the parent's implementation, as requested */
}
};
另一个可能的答案是,调用该函数的对象实际上具有parent
类型(因为它在问题中没有说明孩子应该为this
对象调用它)
class parent {
public:
virtual void foo() { /* whatever */ }
};
class child : parent {
public:
virtual void foo() { /* whatever */ }
void bar() {
parent p;
p.foo(); /* call the parent's implementation, as requested */
}
};
同样,直觉上感觉这不是问题所在。最有可能的问题是关于构造函数和析构函数的虚拟调用
class parent {
public:
parent() {
foo(); /* always calls `parent::foo` */
}
virtual void foo() { /* whatever */ }
};
class child : parent {
public:
child() : parent() /* `parent::parent` will call `parent::foo` */
{}
virtual void foo() { /* whatever */ }
};
然而,问题的措辞不正确。在调用时的最后一个示例中,子对象尚不存在。它的内存已经分配但其生命周期尚未开始。说对虚拟函数的调用是由子对象执行的,这是不正确的。它由父对象执行。
所以,要恢复上述内容:这个问题含糊不清,措辞模糊,以现在的形式没有任何意义。
答案 2 :(得分:1)
Base::f();
)答案 3 :(得分:0)
如果已经调用了子类的析构函数,那么该对象现在是父类型,因此将调用父类的虚函数。
答案 4 :(得分:0)
如果此调用在构造函数中,则调度将是静态的。阅读本文以获取更多信息:http://cplusplus.co.il/2009/09/30/virtual-dispatching-within-a-constructor-or-a-destructor/
以下是我链接到的文章中的示例:
struct A {
A () { f(); }
virtual void f () { }
};
struct B : A {
B () :member(0) {}
void f () { std::cout << member; }
private:
int member;
};
int main () {
B b;
return 0;
}
调用的f是A :: f,尽管它是虚拟的并且由具有自己实现的类型B的对象调用。
答案 5 :(得分:0)
已经提供了答案,这可能在施工期间发生:
它可能也是运行时错误的一个有趣来源,所以要特别注意构造函数&amp;基类中的纯虚方法调用;)
http://support.microsoft.com/kb/125749
class A;
void fcn( A* );
class A
{
public:
virtual void f() = 0;
A() { fcn( this ); }
};
class B : A
{
void f() { }
};
void fcn( A* p )
{
p->f();
}
// The declaration below invokes class B's constructor, which
// first calls class A's constructor, which calls fcn. Then
// fcn calls A::f, which is a pure virtual function, and
// this causes the run-time error. B has not been constructed
// at this point, so the B::f cannot be called. You would not
// want it to be called because it could depend on something
// in B that has not been initialized yet.
B b;
void main()
{
}