2012-09-07 70 views
1

我有一些問題,使用const_cast刪除常量。錯誤味精說「轉換爲有效的標準轉換......」C++。爲什麼我無法編譯此代碼?使用const_cast去除常量有什麼問題?

是什麼這個問題的本質是什麼?爲什麼我應該使用C風格演員? 「

」錯誤C2440:'const_cast':無法從'const size_t'轉換爲'size_t'「 」轉換是一種有效的標準轉換,可以隱式執行或使用static_cast,C風格轉換或函數式的鑄造」

template<typename T> 
const IFixedMemory* FixedMemoryPkt<T>::operator=(const IFixedMemory* srcObj) 
{ 
    // doesn't remove constness this way. why? 
    const_cast<char*> (this->m_Address) = (char*)srcObj->GetAddress(); 

    // compile this way, but maybe(?) undefined behaviour 
    // const_cast<char*&> (this->m_Address) = (char*)srcObj->GetAddress(); 

    // doesn't doesn't work too 
    const_cast<size_t> (this->m_Size) = (size_t)(srcObj->GetSize()); 
    // const_cast<size_t> (this->m_Size) = 0; 

    return this; 
} 

template<typename T> 
class FixedMemoryPkt : public IFixedMemory 
{ 
private: 
    const size_t m_Size; 
    const char* m_Address; 
} 

class IFixedMemory 
{ 
public: 
    virtual const char* GetAddress() const = 0; 
    virtual size_t GetSize() const = 0; 
} 
+0

所以你的*固定的內存包*也不是那麼固定畢竟?從名字來看,這個類似乎不應該是可複製/賦值的。 – Praetorian

+1

你的對象沒有'm_Memory'成員。請發佈真實的代碼,而不是假的。 – AnT

+1

或者無論如何,請在發佈前爲自己編譯僞代碼,以確認它顯示的是與真實代碼相同的問題。 –

回答

8

const_cast用於從指針或引用轉換爲const物體,它們的非const當量。但是,如果對象本身是const,則不能使用它們來修改它們引用的對象。沒有有效的方法來修改m_Size;如果你想修改它,那麼不要聲明它const

你並不需要強制轉換爲分配給指針,因爲指針本身是不是const

this->m_Memory = srcObj->GetAddress(); 

如果你確實想指針本身是const,那麼const將來後*

char * const m_Address; 

和,與const size_t,你將無法重新分配它。

由於錯誤的說法,你可以在const轉換成不進行強制轉換該值的非const臨時副本;但你無法分配到臨時的。

+1

但從'產生的代碼的const_cast (這 - > m_Size)='有未定義的行爲(修改常量限定數據成員'm_Size'),所以有比只是它不更錯與詢問的代碼不會編譯。 –

+0

@SteveJessop:好點,星期五爲時已晚,正確地思考這個問題。 –

+0

謝謝邁克!在這種情況下,我嘗試添加重載操作符=一些方便...原來這些成員只能通過構造函數設置。現在我看到我需要改變一些設計,否則我會在運行時遇到一些麻煩。 – adspx5

2

你試圖施放的size_t事情的r值,你不能分配給r值。

我不得不說,虛擲你的size_t成員的常量性是相當邪惡。這是可變的。而AFAICS你的第一個const cast沒有任何用處。

+1

這裏你不需要'mutable',只需刪除'const'即可。 'mutable'用於當你需要從'const'成員函數修改它時。 –

0

作品現在這樣......

template<typename T> 
const IFixedMemory* FixedMemoryPkt<T>::operator=(const IFixedMemory* srcObj) 
{ 
    this->m_Address = srcObj->GetAddress(); 
    this->m_Size = srcObj->GetSize(); 
    return this; 
} 

template<typename T> 
class FixedMemoryPkt : public IFixedMemory 
{ 
private: 
    const char* m_Address; 
    size_t  m_Size; 
};