[英]Calling a virtual function statically through a function pointer
請考慮以下代碼。
#include <iostream>
#include <memory>
struct A {
A() {}
virtual void f() {
std::cout << "A::f" << std::endl;
}
private:
A(const A&);
};
struct B : public A {
virtual void f() {
std::cout << "B::f" << std::endl;
call(&A::f);
}
private:
void call(void (A::*aMethod)()) {
// ...
(static_cast<A&>(*this).*aMethod)();
//(static_cast<A>(*this).*aMethod)(); -> not allowed to copy!
// ...
}
};
void main() {
std::auto_ptr<B> b (new B);
b->f();
}
這段代碼遞歸地調用相同的B::f
方法,直到它用完堆棧,而我希望call
方法調用A::f
。 也就是說,它應該像我簡單地寫的那樣靜態地調用它:
struct B : public A {
virtual void f() {
std::cout << "B::f" << std::endl;
// ...
A::f();
// ...
}
};
我想要使用call
方法的原因是在“靜態調用”之前和之后分解一些代碼,這對於具有與f
相同簽名的幾種方法是通用的...
如何靜態調用在運行時確定的虛函數?
那是意料之中的。 對象表達式是對基類A的引用,因此當A :: f是虛擬的時,將觸發虛擬功能機制(動態綁定)。
只有::運算符可以支持虛擬函數調用機制。
$ 10.3 / 12-“使用范圍運算符(5.1)的顯式資格抑制了虛擬調用機制。”
當您獲取指針時,您的替代已解決,因此,您無法通過這種方式輕松實現此處想要的操作。 最好的辦法是調用函數的包裝器-外部函數或調用函數的非虛擬函數。 如果您具有C ++ 0x功能,則可以使用lambda,這是IMO最干凈的解決方案。
您可能想重新考慮使用前置/后置功能的方式,這是解決問題的另一種方法:可以通過重載“->”運算符來實現它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.