簡體   English   中英

通過函數指針靜態調用虛擬函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM