2011-05-07 85 views
1

我有這個示例代碼(下面),example1()方法工作沒有問題,example2()是相似的,但我必須強制const_char使它編譯,雖然我認爲是example1()方法是不需要,example2()也不需要。正確使用const C++

我的問題是,我怎樣才能修改add()方法,使兩個編譯或如何在不強制const_cast的情況下正確調用example2()中的buffer.add()? add()方法不修改項目,所以const_cast是不必要的。哪一種是正確的或合適的形式?

這裏的示例代碼:

template <class Item> 
class Buffer 
{ 
public: 
    Item *  _pItems; 
    int   _nItems; 
    // ... constructor/destructors etc 
    void add(const Item & item) // or maybe Item const & item 
    { 
     _pItems[_nItems++] = item; 
    } 
}; 
class MyClass 
{ 
public: 
    // data 
}; 
void example1(const MyClass & item) 
{ 
    Buffer<MyClass>  buffer; 
    buffer.add(item); // WORKS, no problem 
} 
void example2(const MyClass & item) 
{ 
    Buffer<MyClass *>  buffer; // NOW with pointers to MyClass 
    //buffer.add(item); // ERROR: 'Buffer<Item>::add' : cannot convert parameter 1 from 'const MyClass' to 'MyClass *const &' 
    buffer.add(const_cast<MyClass *>(&item)); // forcing const_cast WORKS 
} 
+2

'//強制const_cast WORKS'是的,但現在你的編譯器不會阻止你修改對象,這是_still UB_。這是一個粗糙的黑客,導致問題;它並沒有解決它們。 (有時候你需要這個破解來傳遞給舊的C函數,這些函數只有一個寫在註釋中的可變性契約,而不是'const'。) – 2011-05-07 16:47:24

回答

4

你應該這樣做:

Buffer<MyClass const*> 

因爲&項目上一個const MyClass的是MYCLASS常量*不是MyClass的*

+3

作爲一個推論,如果你不能這樣做,因爲你的其他部分代碼依賴於包含非const的MyClass *的緩衝區,然後通過添加一個const來做錯誤的事情。 – Omnifarious 2011-05-07 16:39:06

0

Buffer類模板可以被認爲是正確的,它是你的example2函數是不正確的。我將在此基礎上繼續。

example1中,該函數對MyClass的實例具有const引用參數。然後Bufferadd方法複製實例的值,將其放入其自己的內存緩衝區(我希望Buffer正在跟蹤所有這些內存)。因此,example接受const引用的事實與Buffer無關,因爲該值是一個副本。

example2,的Bufferadd方法以指針的副本的MyClass實例,並存儲在其自己的存儲器緩衝器。在example2在實例化Buffer爲持有非const指針MyClass,所以這是什麼,你應該給它,所以example2應該是:

void example2(MyClass & item) 
{ 
    Buffer<MyClass *> buffer; // NOW with pointers to MyClass 
    buffer.add(&item); 
} 

現在,你必須意識到,如果buffer將被使用,item必須保持固定在內存中,直到完成。而在example1中,由於您已安全地將副本存儲在buffer中,因此這些項目可能會消失。