2016-05-15 31 views
-4

我會描述這個問題。我有一個API類,它調用一個大型的類成員函數層次來完成一些邏輯。現在,我更新了邏輯,以便層次結構中的每個函數都需要額外的參數(API不會更改)。有一個修改'scratchpad'變量的const函數是否正確?

一個想法 - 不是給每個方法增加一個額外的參數,我可以爲該類添加一個'scrathpad'成員,即一個只用於臨時計算的變量,並且只在時間範圍內有效的API調用,並且一旦調用完成就是'垃圾'。

例子:

void A::api() 
{ 
    scratch_pad = get_some_value_once(); 
    foo1(); 
} 
void A::foo1() { ...; foo2(); } 
void A::foo2() { ...; foo3(); } 
... 
void A::fooN() /* Called 100000000 times */ 
{ 
    ...; 
    // Do something with scratch_pad. 
    // I would realy like to avoid adding 'scratch_pad' parameter to all the foos(). 
} 

這是一種有效的方法?

如果我的API被聲明爲const,它仍然有效嗎?

+5

WTH是_ 「暫存」 _變量?你能用一些(僞)代碼示例來說明嗎? –

+0

如果它不改變對象的可觀狀態,我認爲它沒有問題。 – songyuanyao

+0

_「現在,我更新了邏輯,因此層次結構中的每個函數都需要額外的參數(API沒有更改)。」_聽起來像繼承應該用於替換接口定義,但實際上不可能從您的不明確的背景。 –

回答

2

通常,當該成員不是該類的可觀察狀態的一部分時,在const方法中更改成員的值是可以的。

您必須使用mutable關鍵字標記您的'暫存區'成員。
否則,如果您在const方法中指定它,則會出現編譯錯誤。

退房的isocpp常見問題 - 用作臨時存儲與類成員https://isocpp.org/wiki/faq/const-correctness#mutable-data-members

4

請不要這樣做。

即使您只需要變量來實現內部函數調用的生命週期,您也可以使對象實例更大(佔用更多內存)。

您正在使您的函數本質上是多線程不安全的,或者在以前不需要時需要鎖定。

你讓代碼本質上不太明顯/可維護。

如果你想在你的API調用中使用const,那麼你需要開始添加可變變量(ugh)。

改爲使用局部變量。檢查Basilevs的答案是一種方法來做到這一點。

1

主要問題是線程安全的。當從另一個線程調用方法時,內部數據的成員存儲將以不可預知的方式重用。它也暗示了方法之間隱藏的耦合。

實際上,您需要的是一個額外的(可能是不可變的)狀態,並且您的API調用的生命週期。在C++中處理狀態和生命週期的常用方法是使用類。

我建議爲新的不可變類提取新參數,將所需方法移至新類並使API實現創建此類並調用它們。

相反的:

class API { 
    private: 
    int state; 
    void implement() { 
    cout << state << endl; 
    } 
    public: 
    void execute() { 
     state = 1; 
     implement(); 
    } 
} 

務必:

class State { 
    int value; 
    public: 
    State(int valueArg): value(valueArg) {} 
    void implement() const { 
    cout << state << endl; 
    } 

} 

class API { 
    public: 
    void execute() const { 
     State(1).implement(); 
    } 
} 
+0

這個答案似乎走在正確的軌道上。 –

+0

這比使用提議的'scratchpad'變量方法好得多。儘管如此,我建議讓國家成爲私人內部類的API。 – jtlim

相關問題