2013-01-24 57 views
0

這是我的問題。我有一個持有對象數組的類(在std :: vector中) 這些對象可以從客戶端代碼中修改,所以我創建了一個私有getter,它返回一個指向我需要修改的對象的指針。公共方法使用此getter來修改數組中的對象。C++ const getters的正確性問題

私有getter也用於其他成員函數,它將數組中的對象的特定值返回給客戶端代碼。我希望這些函數能夠返回const,但是我不能這麼做,因爲我使用了前面提到的非const getter。

我知道我可以做一個其他的const getter,但那隻會重複代碼。

如何正確實施?

代碼示例:

class Object; 

class Inventory 
{ 
    Object* GetObject(int id); 
    void AddObjectProp(int id, int amount) { 
     Object* x = GetObject id); 
     x->prop += amount; 
    } 

    //using const here is not posible because GetObject is not const 
    int GetObjectProp(int id) { 
     Object* x = GetObject id); 
     return x->prop; 
    }  

} 

謝謝。

+2

是不是http:// stackoverflow。com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func?rq = 1解決同一個問題? – anumi

+0

const的正確性似乎總是​​要求你重複你的getters(至少返回指針或引用的那些)。由於重複是不正確的,所以必須去做:或者那些討厭的getter,或者const正確性... –

回答

2

我相信你可以做一個

const Object* GetObject(int id) const; 

,那麼你可以:

int GetObjectProp(int id) const { 
    const Object* x = GetObject(id); 
    return x->prop; 
}  

或者:

int GetObjectProp(int id) const { 
    return GetObject(id)->prop; 
}  

(也用GetObject()固定失蹤括號 「ID」 之前)

+0

+1。由於沒有顯示'GetObject'的定義,因此無法判斷定義一個const版本是多麼容易或困難。這可能是不可能的 - 如果由於一些令人信服的原因(儘管被稱爲「get」),「GetObject」是一個非const函數,那麼也許'GetObjectProp'確實不應該首先調用它。 –

+0

噢,當然,這可能有多種原因,實際上並不奏效。此外,還可能有一些解決方法,例如GetObject在某個不存在的時候調用一些「創建新對象」,或者做一些其他的「修改類」 - 雖然這可能會成爲使用「可變」的候選對象 - 不知道是否有人會立即罷免我說可變...;) –

+0

嘿。我懷疑mutable會在'Inventory'提供對其所有具有對象id的列表的訪問(因爲那麼函數不是邏輯上的const,它改變了列表)的情況下可能會變得狡猾,在這種情況下,庫存就像一種透明的緩存。還應該考慮到非線程安全的'const'函數正在尋求麻煩。就像你說有很多的機會搞砸了:-) –

3

我知道你說你不想這樣做,但乾淨的解決方案是使用兩個干將:

class Inventory 
{ 
    Object* GetObject(int id); 
    const Object* GetObject(int id) const; 

    void AddObjectProp(int id, int amount) { 
     Object* x = GetObject(id); 
    } 

    int GetObjectProp(int id) const { 
     const Object* x = GetObject(id); 
    }  
}; 

至於複製GetObject()實現,你既可以

  • 因素出大部分代碼;或
  • 實施一個吸氣劑的另一方面。
+0

OP提到這一點,但不想重複代碼。 –

0

我不認爲有一個雙重getter可以被視爲代碼重複在這裏。 這兩個getter都會有自己的用例。

一個getter被設計爲供需要const引用的客戶端使用。

另一個getter(我會調用訪問器,使它在代碼中隱含我們正在尋找一個非const引用),這可以讓任何可能願意修改對象的客戶端使用。

這將是我的做法:

class Inventory 
{ 
    Object& accessObject(int id); 
    const Object& getObject(int id) const; 

    ... 
}; 

如果你真的不希望有兩個干將,怎麼樣一個常量吸氣其中const_cast可以用於拋棄常量性在需要的情況下?

+0

我想在這種情況下,獲得者是更好的解決方案。我認爲const_cast會更加混亂,不是嗎? –

+0

是的,我同意,如果你不想複製代碼,'const cast'解決方案是一種糟糕的做法。 這兩個getter解決方案是我會使用的。 – codeJack