2016-08-03 81 views
0

我給下面的代碼來說明我的問題:如果類中沒有保持類的狀態的變量,函數應該聲明爲靜態函數?

class Abc 
{ 
    public: 
     void do_something() {}; 

}; 

class Def 
{ 
public: 
     static void do_something() {}; 

}; 

兩個類AbcDef不變量來之類的狀態。在這種情況下,定義功能do_something哪種方式更好?將它作爲靜態函數更好?

+6

如何使它成爲非會員功能? –

+3

如果你有所有的靜態函數,爲什麼不使用命名空間? –

+1

如果你沒有任何字段,你可能不需要這個類。如果你正在做一些與類對象相關的事情,那麼靜態函數是適當的。你可能不會有這些類的對象。 –

回答

-2

static功能用於

  1. 調用類本身(而不是類的實例)
  2. 擴展函數能見度同一翻譯單元

回答你的問題,在「 Abs'的情況更爲可取。

  1. 如果該類有內部非靜態狀態變量,則無法爲您的靜態函數訪問它們。靜態函數只訪問靜態變量。
  2. 它也不可能從你的靜態函數中調用普通的非靜態類函數。
  3. 不可能使工廠功能等無法使用new調用private/protected構造函數來創建實例。
5

不,你有完全錯誤的。是否有任何實例變量保持狀態是您在界面設計中不應該關心的實現細節。

如果方法應用於類而不是類的實例,則可以使用靜態方法(別的稱爲「類方法」,這是一個更好的詞)。如果要創建作爲該類實例的對象,則使用實例方法。

由於您甚至沒有提及您應該使用的標準,因此您的案例中沒有人會告訴您哪種更好。另一方面,如果你正在談論「班級地位」(這是人們不經常談論的事情),似乎表明你應該使用類方法或單例。

3

它完全取決於你的課堂設計和這些功能的目的。 例如,如果你想跟着open-closed principle你可能要問自己一個問題:

「難道我想允許擴展(即派生類)以這樣的方式,他們將成爲有狀態的擴展這些功能的行爲(即取決於一些不是在這些派生類中添加的靜態成員)?「

根據您的設計,答案可能是「是」或「否」(這意味着這些函數根據其原始目的定義是無狀態的)。請注意,如果您還想允許dynamic polymorphism,則不僅需要使這些功能不是靜態的,而且還要使它們變爲虛擬。

所以,要回答這個問題,你首先需要仔細設計你的班級。給出設計決定的答案將變得更具體。

1

如果你需要的唯一功能是do_something(),沒有類中的任何其他字段,那麼最好的方式,IMO,根本沒有類。簡單地定義

void do_something() {...} 

而且它會更容易調用,只是do_something()就是這樣。

如果該功能需要在memeber類的變量進行操作,那麼它應該是一個正常的成員函數,在這種情況下,您從一個實例調用它:

ABC a; 
a.do_something() 

靜態方法,而另一方面,是一種使代碼更加組織化的方法,在具有完整功能類的成員變量和成員函數對其起作用的特定情況下,還需要一個或多個與特定實例無關的函數變量狀態根本不存在,但是以合乎邏輯的方式與班級相關。也就是說,你可以在不附加到類的情況下編寫函數。例如,如果您需要一個創建類的特定實例的函數,例如使用特定的構造函數參數組合,否則每次調用都會很麻煩,您可以將其編寫爲獨立函數,它通過調用具有參數組合的構造函數來創建並返回該類的一個實例。但明確地將其與班級聯繫起來更合理。在這種情況下,您可以將其設爲靜態成員函數。