[英]one question about C++ virtual function
我的朋友問我一個虛函數問題。
如果子對象調用虛擬函數,那么在什么條件下,該虛擬函數實際上是在父親的實現中執行的?
我認為您需要發布一些代碼來澄清您的要求,但是(析構函數除外)除非子級從其自己的函數中顯式調用它,否則不會調用基類函數。 例如,在:
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()。
無法理解當前形式的問題到底暗示了什么。
如果從字面上看,這個問題有一個明顯而直接的答案:如果父代的實現是相關函數的最終替代者,即子代未提供其自身的實現,則調用父代的版本。
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 */ }
};
但是,為此問題的措詞不正確。 在調用時的最后一個示例中,子對象尚不存在。 它的內存已分配,但其生命期尚未開始。 說虛函數的調用是由子對象執行的,這是不正確的。 它由父對象執行。
因此,請繼續以上內容:這個問題的措詞含糊不清,以目前的形式沒有任何意義。
Base::f();
) 如果已經調用了子類的析構函數,則該對象現在是父類的類型,因此將調用父類的虛函數。
如果此調用在構造函數中進行,則調度將是靜態的。 請閱讀以下詳細信息: 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的對象調用。
已經提供了答案,這可能在構造過程中發生:
它也可能是運行時錯誤的有趣來源,因此請特別注意基類中的構造函數和純虛方法調用;)
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()
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.