2012-12-02 65 views
1

我在寫一個遊戲,其中每個數據對象都由ControlView顯示。當ControlView設置爲顯示數據對象時,它不應該改變它。我想用const來執行這個約定。但是,爲了響應稍後用戶與ControlView的交互,數據可能會被修改。所以需要存儲一個非const指針。我想知道這是否被接受並正確使用了const_cast ?.骨骼代碼如下我應該使用const如果傳遞的對象現在不會被修改,但可以稍後修改

class Data 
{ 
    int m_int; 
    public: 
    void add(int i) { m_int += i ; }; 
}; 

class ControlView 
{ 
Data* m_data; 
public: 
void set_data(const Data* d) //this call should not change d 
     { 
      m_data=const_cast<Data*>(d); //cast needed to compile 
     }; 

     void manipulate_data(int x) 
     { 
      m_data->add(x); 
     } 
}; 

回答

2

在這種情況下,不,不要使用const。如果你這樣做,你讓任何人傳遞一個const作爲參數,最終可能會運行到未定義行爲算賬:

const Data d; 
ControlView c; 
c.setData(&d); //legal, because setData takes a const as parameter 
c.manipulateData(0); //undefined behavior, modifying an originally const object 
+0

謝謝。這就說得通了。我想執行的「合同」,在該呼叫的方法不應該改變過的數據,我可以把它與它的工作之前,爲const: 無效set_data(數據* in_d) \t \t \t { \t \t \t \t const Data * d = in_d; //傳遞的數據不會在此呼叫 \t \t \t \t //....work與d被改變 \t \t \t \t M_DATA = in_d; \t \t \t}; – user1057165

+0

@ user1057165我會遠離const施放。 –

2

如果您想要修改對象,請不要使它成爲const。修改const對象,例如通過const_cast,是未定義的行爲。

所以不要使用constm_data,但也有其他幾個const S的,你可以在你的代碼中使用:

  • 可以保護功能參數與const。這通常不是很有意義,因爲您通常不關心指針,而是關注它指向的對象。但它可以幫助您避免像在你的代碼不小心repointing d錯誤:
void set_data(Data * const d); // const pointer to (non-const) Data 
// this means the function can not change d (the pointer), but it can 
// change the object that d points to. 
  • 你可以不修改功能const。這聲明函數不會以任何方式更改對象(除非有成員mutable)。如果您嘗試修改此功能中的任何成員,編譯器將會報錯。這些功能也是唯一可以在const對象上調用的功能。
Data * get_data() const; // this function doesn't change anything 

需要注意的是,如果你有mutable成員,他們可以從const函數改變,但是這不應該被濫用。這是爲了內部的東西,如互斥或緩存。

還要注意引用總是const - 它們不能被重新分配指向另一個對象。它們引用的對象可以是const或非const。

最後的技巧:閱讀聲明從右到左:

Data  *  d; // pointer to Data (both can be changed) 
Data  * const d; // const pointer to Data (data can be changed) 
Data const *  d; // pointer to const Data (pointer can be changed) 
Data const * const d; // const pointer to const Data (neither can be changed) 

Data   &  d; // reference to non-const Data 
//Data  & const d; // invalid - all references are const 
Data const &  d; // reference to const Data 
//Data const & const d; // invalid - all references are const 
0

你需要認識什麼const data *d手段。這意味着可以改變指針d,但是指針d指向Data類型的對象,它們是const,即不可變的。

你應該有什麼是

void set_data(Data * const d) //this call should not change d 
{ 
    m_data=d; 
}; 

代碼Data * const d位意味着該指針d無法通過該方法改變,但d點是可以改變的對象。

我的理念是,當你使用演員時,你可能做錯了什麼。儘量避免它們。

+0

我想他已經知道這一點。但是你知道'const'對於一個非參考值是有點多餘的,不是嗎?即使你沒有製作實際的指針'const'並且你修改了它,這個改變在函數外部是不可見的,對吧?就像'const'和value傳遞'int'一樣 - 並沒有真正完成任何事情。 –

+0

@LuchianGrigore - 這只是一個好習慣。同時它也爲編譯器提供了一個額外的優化機會。此外,對於較大的功能,作爲編碼人員不會犯愚蠢的錯誤,確實爲您提供了一些保護。 –

+0

我認爲'const'值只是爲了語義的目的。程序員可以在沒有將const應用於值的情況下做出錯誤,因爲這是一個值。也沒有追求優化的機會(但如果你能證明有,那會很棒)。同樣,我們在這裏談論的是關於價值傳遞,而不是參考 - 這是完全不同的。 –

相關問題