2012-02-28 19 views
3

我有一個備份數據的副本,我想保護所以我做它const。我需要違反該const內斯兩個occassions,一旦處女數據存儲到它:你怎麼拋棄const'ness時,該功能將對象(和訪問非const方法)的參考?

fgBlocks.CopyInto((BlkArray&)backUpCopy); 

w.r.t.

result CopyInto(BlkArray &replica) const {/**/} 

並再次當我在其上調用RemoveAll()這是一個非const方法:

((BlkArray)backUpCopy).RemoveAll(true); 

是對第一鑄造(如上所示,(BlkArray&))正確的嗎?這是我之前沒有投入的間接方面之一。然後再次我將添加另一個未使用的方面中,鑄造遠const岬用於調用對象的方法,其中所述編譯器不接受如上所示的。

成員被聲明如下:

BlkArray fgBlocks; 
const BlkArray backUpCopy; 

我試圖延長科雷亞的解決方案,因此有:

BlkArray *pBUCopy = (BlkArray *)&backUpCopy; 
    fgBlocks.CopyInto(*pBUCopy); 

唯一的問題是現在的編譯器未能由於

未初始化構件 'MyClass的:: backUpCopy' 與 'const的' 類型 '常量BlockArray'

+0

最好使用'const_cast',而不是C風格的轉換。對讀者而言,這比讀者更爲明顯。 – Wyzard 2012-02-28 00:53:56

回答

6

請注意,如果您這樣做並且對象確實是const,那麼在丟棄const之後修改它是未定義的行爲。正在取得

const_cast<BlkArray&>(backUpCopy).RemoveAll(true); 
+0

該對象確實是'const'。除了上面的調用之外,我將它作爲'const'成員,並且只能以只讀方式使用。對RemoveAll的調用進入包含類的析構函數。 – John 2012-02-28 00:50:10

+1

@John不幸的是,你不能做我發佈的內容,而不會導致UB。你可能想要做的是使實際變量'private'和_not_'const',然後做一個'const' _reference_吧'public'。通過這種方式,它所屬的類可以對其進行修改,但外部世界只能通過'const'引用來查看,因此無法對其進行更改。 – 2012-02-28 00:51:16

+0

@John:你爲什麼需要調用'RemoveAll'?只要讓'BlkArray'的析構函數處理刪除數據。 – Xeo 2012-02-28 00:54:16

0

您可以通過簡單的標記所有方法爲const解決這個問題,除了RemoveAllCopyFrom,後者是BlkArray的方法是:

fgBlocks.CopyInto(const_cast<BlkArray&>(backUpCopy)); 

爲另一個同樣的事情要麼實現邏輯或傳遞到*thisCopyInto

更安全的關於誰可以清除數據/新的東西複製到它,你可以讓這些方法私人和朋友宣佈必要的類,或使用passkey pattern來保護這兩個方法。

0

有一個小竅門我學會了看Qt的內部:

MyClass:circunventConst() const 
{ 
    MyClass* that = const_cast<MyClass*>(this); 
    that->myProtectedVariable = value; 
} 
+0

這是比我希望的幾行,但似乎對我來說,謝謝,我會給它一個去。 – John 2012-02-28 01:07:31

+0

這完全沒有幫助(如果像海報所說的那樣,'myProtectedVariable'是'const',不管'* this'是否是'const',都是'const')。此外,如果'* this'實際上是一個'const'對象,則會導致未定義的行爲。 Qt是愚蠢這樣做很愚蠢。 – 2012-02-28 01:11:37

+0

嗯,我是從記憶中談起的,所以不能給出具體細節爲什麼它已經完成或者它是否還在Qt的代碼中。但這確實是我第一次看到那個。當然,對於這個簡單的例子,正確的方法是myProtectedVariable是可變的,所以對於const方法來改變它是有效的。這可能是因爲他們在編譯器中看到了可變的bug,並且正在努力解決這個問題,但隨後我只是在期待。 – Correa 2012-02-28 01:18:12