2010-05-19 84 views
4

學習C++,看看奠定了這樣的類:C++基本客艙佈局

class CRectangle { 
    int x, y; 
    public: 
    void set_values (int,int); 
    int area() {return (x*y);} 
}; 

void CRectangle::set_values (int a, int b) { 
    x = a; 
    y = b; 
} 

我知道Java和Java中的方法(函數)的類中寫的。該類看起來像一個Java接口。我知道我可以這樣寫班級:

class CRectangle { 
    int x, y; 
    public: 
    void set_values (int a, int b) { 
     x = a; 
     y = b; 
    }; 
    int area() {return (x*y);} 
}; 

但是有差異還是標準?

回答

8

有區別。當您在類定義中寫入函數的定義(情況2)時,則認爲該函數已被聲明爲inline。這是標準的C++。

用法是在頭文件(.h)中聲明類定義內的成員函數(Java方法),並在C++文件中定義這些成員函數(.cpp,.cc或.C ,...)這會減少編譯時間,當您更改函數的主體時,只需編譯C++文件,而如果更改​​頭文件中的某些內容,則將編譯包含此頭的所有C++文件。

4

通常的做法是將函數的實現放在一個單獨的cpp文件中,這個文件不包含在其他文件中,只是編譯完成。這樣管理依賴關係就更容易了。

如果在類定義中給出了一個函數的實現(就像在你的第二個例子中一樣),這是編譯器對該函數進行內聯的提示(最終可能會或可能不會這樣做,具體取決於例如函數的內部)。作爲一個經驗法則,長於幾行代碼的函數體更好地放入cpp文件中,因爲它們可能不會被內聯,但是這些可能會包含額外的依賴性和混亂的類定義。

例外是模板函數,其中的主體也需要在標題中,因爲編譯器必須看到它們才能實例化模板。

1

我相信,如果方法體在類定義內部,那麼它被內聯到任何地方被調用。

+1

AFAIK這只是編譯器的一個_hint_,它仍然可以自由決定該函數是否在最後被內聯。 – 2010-05-19 08:56:56

+0

也許只有在頭文件中定義類時才需要內聯?或者,也許每個編譯單元都得到它自己的代碼副本,但只有一個? – 2010-05-19 10:37:12

5

如果您只在類定義(屬於頭文件)中定義原型並在cpp文件中實現這些方法,那就更簡潔了。

當你有非常小的類來完成類定義中的所有內容聽起來更容易,因爲所有的東西都在同一個地方,但是隻要你的類增長了,任何使用它的開發者都會恨你,因爲他會讓你的代碼在方法原型,他可能會查找一些東西(不是每個人都使用IDE來顯示所有可用的方法!)。

但是,有一個例外:模板類方法需要在標題中實現,因爲它們需要針對模板的每個專業化進行編譯。

+0

+1作爲特殊情況提及模板。 – 2010-05-19 08:56:23

1

在C++中,在類中定義的成員函數隱含地是inline,在類外部定義的成員函數不是。

這會影響您的兩個示例的關聯 - 如果第一個示例在多個源文件中爲#included,則鏈接器會抱怨多個定義,而第二個示例不會。

在一個什麼樣的標準/一般條款:

  • 第一種形式是用於複雜的類,其中的功能的實現需要額外的標頭中拉
  • 第二種形式的用途。簡單的類沒有額外的依賴關係。
  • 基於開發人員的偏好,任一表單都用於模板類。
1

這裏有一個細微的差別,這個類裏面定義的函數自動地是inline。後一個定義可以放在一個單獨的文件中。否則,沒有區別或偏好。

請注意,我們通常不會在函數定義之後編寫分號(儘管它們在類定義中是允許的)。

void set_values (int a, int b) { 
    x = a; 
    y = b; 
} // no semicolon here