2016-04-24 215 views
0

我有以下代碼:調用從const成員函數非const成員函數指針

class MyClass; 
typedef void(MyClass::*func_ptr)(); 
class MyClass 
{ 
public: 

MyClass() 
{ 
    f = &MyFunc1; 
} 

void MyFunc1() 
{ 
    // ... 
} 

void MyFunc2() const 
{ 
    (this->*f)(); 
} 

func_ptr f; 

}; 

如果我嘗試編譯,它失敗,因爲myfunc2所(中),這是試圖調用函數一個const方法類型爲非const的func_ptr指針。

我想弄明白這個最好的方法。我可以用一個標準的C風格的轉換:

typedef void(MyClass::*func_ptr2)() const; 
    func_ptr2 f2 = (func_ptr2)f; 
    (this->*f2)(); 

但我寧願使用C++投(即的static_cast,reinterpret_cast的,或者的const_cast)。我得到這個與reinterpret_cast編譯,但我不能讓它與const_cast一起工作。我認爲const_cast不適合用於這種情況?另外,有沒有更簡單的方法來做到這一點,而無需創建另一個typedef?

+4

哪有一個** **清潔方式從'const'一個調用非'const'功能。可能有一個原因是爲什麼其中一個函數是'const',另一個不是。如果不是這樣,只需修改'const'限定符。 –

+0

上面的評論(by @FrankPuffer)應該被認爲是IMO這個問題的正確答案。如果這些函數的「常量」確實不同,那麼**不要在const函數內調用非const函數。如果他們沒有不同,那麼只需更改(不正確)的聲明。 –

回答

1

這段代碼有幾個問題。

f = &MyFunc1; 

不能很好地形成的C++,因爲服用的非靜態成員函數的地址需要一個完全合格的名稱:

f = &MyClass::MyFunc1; 

this處於const成員函數MyClass const*。您可能需要拋棄那const

(const_cast<MyClass*>(this)->*f)(); 

一個更好的解決方案可能是重新思考設計,以避免與const_cast戰鬥類型系統。

2

典型的解決方案是(const_cast<MyClass*>(this)->*f)();

只要MyClass實例被創建爲非const,這是合法的。 否則,這會調用未定義的行爲。

0

下看起來編譯:

MyClass() 
{ 
    f = &MyClass::MyFunc1; 
} 

void MyFunc1() 
{ 
    // ... 
} 

void MyFunc2() const 
{ 
    MyClass* mc = const_cast<MyClass*>(this); 
    (mc->*f)(); 
} 
+2

僅僅因爲一個程序編譯並不意味着它是有效的,或者一個好主意。 –

+0

這是一個公平點。我不是故意這麼說,因爲它編譯起來很好。與此同時,我正在撰寫這篇文章,其他兩人正在提供答案。閱讀他們的代碼部分似乎有點類似。 –