2013-02-15 50 views
1

C++更新值或更改指針會更好嗎?

更新指針的值還是更改指針指向其他內容會更好嗎?

假設我們有兩個類:球和座標。

class ball 
{ 
    Coordinates *ballCurrent; 
    public: 
     ball(int); 
     ~ball(); 
     void setLoc(Coordinates&); // OR void setLoc(int, int); 
}; 

class Coordinates 
{ 
    int x, y; 
    public: 
     Coordinates(int, int); 
     void setCoordinates(int, int); 
}; 

對於ball類中的setLoc方法,哪個參數應該更好?使用(* ballCurrent).setCoordinates(int,int)或者通過使用(ballCurrent).setLoc((new Coordinates(int,int))),setLoc會更好嗎?請儘可能詳細說明每種情況的原因。兩種方式由函數重載

class ball 
{ 
    Coordinates coordinate_;  // better name than ballCurrent? 
    public: 
     explicit ball(int)  // add explicit to avoid implicit converting 
     : coordinate_(0,0)  // initialize corrdinate_ properly 
     { 
     } 
     ~ball(); 
     void setLoc(const Coordinates& co) // add const 
     { 
      coordinate_ = co; 
     } 

     void setLoc(int x, int y) 
     { 
      coordinate_.setCoordinates(x,y); 
     } 
}; 

無需擔心動態內存的問題,可能setLoc

+0

爲什麼在存在現有對象時創建另一個對象? – 2013-02-15 05:03:54

+0

我有點想知道什麼時候使用每種情況更好。 – dalawh 2013-02-15 05:04:16

+2

和座標需要是一個指針嗎? – billz 2013-02-15 05:05:20

回答

1

我可能會,如果我能寫這樣。沒有野蠻的指針,不用擔心。

1

如果你使用一個新的對象,它將需要爲自己分配的內存,它也需要被初始化(構造器/運行,屬性賦值等)。與僅僅改變已有的對象(以及爲此目的而創建的對象)的值相比,這會帶來很多開銷。

此外,如果您創建一個新對象,則需要釋放先前指針的內存,這又是開銷......因此只需更改現有對象。

0

只需更改指向的對象的值即可。每當你想更新一個值時,創建一個全新的對象是沒有意義的。

一種情況下,如果Coordinates具有const x和y值並且沒有setCoordinates函數,您可能必須創建一個新對象而不是更改值。但是如果你需要經常更新座標,那麼這很可能是一個糟糕的設計決定。

此外,而不是這樣的:

(*ballCurrent).setCoordinates(int, int); 

您可以使用此:

ballCurrent->setCoordinate(int, int); 

哪個做同樣的事情,但只是更容易編寫和很多人會發現它更具可讀性。

3

更新指針的值還是更改指針 指向其他內容更好?

這不是沒有一定背景下可以回答的問題。知道一個對象是不可變的 - 只要你有一個指向該對象的指針,這個對象不會在你的鼻子下面改變。例如,如果一個函數或方法將一個指向不可變類型的指針作爲參數,就知道可以將對象傳遞給該函數,而不必擔心該函數會更改該對象。

另一方面,可變對象也有自己的位置。首先,你有時希望能夠通過幾個步驟構建一個對象,而不是一次完成所有對象,並且您可能不想一直創建幾個中間對象,以便到達最終對象。

所以,這取決於上下文。我看到你提供了一個簡單的例子,但我認爲即使你的例子也不一定有正確的答案。這取決於對你來說什麼是重要的,以及有問題的對象將如何與系統的其他部分進行交互。我認爲,我傾向於可變對象,因爲在一場比賽中,很可能有幾個對象需要了解球。如果移動球的唯一方法是創建一個新球並將其傳遞給所有關心它的其他物體,那麼這很容易成爲一個巨大的問題。座標對象很容易變成不可變的,任何需要知道球的位置的人都應該問球的位置。一旦他們得到它,他們可能會期望位置不會每隔幾毫秒改變一次。如果你不把座標對象設置爲不可變的,那麼處理這個問題的另一種方式是讓球在有人問起時複製它的位置,並交出該副本而不是返回一個指向它自己的位置對象的指針。

0

SetLoc(int,int)的情況下,你是在Coordinates構造函數創建ballCoordinates之間的依賴關係,更重要的是,它代表什麼。如果構造函數簽名發生更改,則必須將這些更改轉換爲ball::SetLoc。這個參數在一般情況下是有效的,在這種情況下你確實想避免傳遞一組參數來初始化一個對象組件。

在這種特殊情況下,Coordinates體現了空間中的位置,並且可能應該附帶一組方法來操作它,以便保留其貫穿程序其餘部分的實現細節。如果你想移動到三維座標系,理想情況下,你只需要修改構造函數調用和類實現。所以你真的想把班級以外的必要變革減少到最低限度,這意味着避免前面解釋的問題。

您提出了兩種不同的解決方案來設置ball對象的位置。實際上這些解決方案會出現嗎?在一個簡單的程序中,球位置硬編碼,這是一種可能性,任何解決方案都可以工作。但是在一個更復雜的軟件中,球的位置可能最初由配置文件設置,並且在一些不重要的計算之後進行任何後續的位置更新。在這種情況下,將所有與座標相關的邏輯封裝在類中可以更好地維護,並避免傳遞參數(int, int)

如果您擔心內存分配開銷(例如函數返回結果生成的臨時對象),可以通過使用明智的const,引用甚至指針來減輕它們,並定義合理的拷貝構造函數。