2009-07-13 87 views
2

我有一個轉換運算符返回一個const指針,我需要const_cast它。但是,這至少在MSVC8下不起作用。以下代碼重現了我的問題:爲什麼我不能const_cast轉換運算符的返回?

class MyClass { 
public: 
    operator const int*() { 
     return 0; 
    } 
}; 

int main() { 
    MyClass obj; 
    int* myPtr; 
    // compiles 
    const int* myConstPtr = obj; 
    // compiles 
    myPtr = const_cast<int*>(myConstPtr); 
    // doesn't compile (C2440: 'const_cast' : cannot convert from 'MyClass' to 'int *') 
    myPtr = const_cast<int*>(obj); 
} 

這是爲什麼?這似乎違反直覺。謝謝!

+1

你真的想試着用`const int *`返回一個空指針嗎?能夠默默地將類轉換爲指向原語的指針通常也是不好的做法。 (例如,`std :: string`不能轉換成`const char *`,而是提供一個`.c_str()`方法來返回一個指向它的數據的指針,這樣更安全,因爲程序員必須非常意識到他在做什麼。) – 2009-07-13 13:20:03

+0

@Seth:謝謝。這不是我真正的代碼;這只是我寫的重現我得到的錯誤!請放心,我沒有特意返回空指針:-)就我而言,這個類是一個圍繞字節數組的薄包裝,我希望它的客戶端使用它,就好像它是一個一樣。 – 2009-07-13 13:23:21

+0

如果你打算讓用戶能夠直接操作字節數組,那麼你應該給它們一個非const的操作符int *()`。一般只給出const版本意味着你允許讀取但不能修改。強迫用戶執行`const_cast`是我的書中的一個錯誤。 – 2009-07-13 13:39:56

回答

4

爲了使它工作,你需要做的:

myPtr = const_cast<int*>(static_cast<const int*>(obj)); 

當你的const_cast直接,編譯器看的類型轉換操作符爲int *。

1

您只能使用const_cast轉換爲相同類型的非常量指針(以拋棄常量)。要在不相關的類型之間進行投射,您需要reinterpret_cast。

myPtr = const_cast<int*>(obj()); 

我還沒有嘗試過呢,心想:

-1

也許如果你做類似的東西會更清楚你的編譯器。

編輯: 不應該符聲明是這樣的:

const int* operator() { 
1

思考的const_cast<>作爲一個函數模板

template <typename Target, typename Source> 
Target const_cast(Source src); 

(這不是它是如何實現的,但它可以幫助這裏想象它是)。然後Source推導爲MyClass,並沒有什麼const_cast可以做從一個MyClass獲取int *。

你想要的是以下任一:

const_cast<int*>(static_cast<const int*>(obj) /* invokes operator const int* */); 
// or 
const_cast<int*>(obj.operator const int*()); 
1

const_cast只能改變一個類型的常量。如果你想打電話給隱式算子,你需要一個static_cast然後一個const_cast。雖然它很煩人,但它確保你清楚你在做什麼。

myPtr = const_cast<int*>(static_cast<const int*>(obj)); 

您也可以使用舊學校C風格的類型轉換操作符

myPtr = (int*)(const int*)obj; 

但這種強烈鼓勵有以下幾個原因:

  • 它不是的grepable
  • 你可以非常輕鬆地做到超出您的預期。大多數情況下,您不想與const_cast類型操作混淆,並使用static_cast來強制執行此操作。實際上你很少想要一個const_cast。如果你發現自己經常做這件事,你會有一些設計錯誤。

編輯:我稍微關了一下,我現在就修好了。這使得C風格演員有點醜陋

相關問題