2012-03-06 89 views
90

我很困惑如何將簡單類的實現和聲明代碼分離爲新的頭文件和cpp文件。例如,我將如何區分以下類的代碼?將類代碼分離爲頭文件和cpp文件

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int getSum() 
    { 
    return gx + gy; 
    } 
}; 
+6

只是一對夫婦的意見:構造應該總是使用初始化列表,而不是設置的身體中的成員。對於一個很好的和簡單的解釋,請參見:http://www.codeguru.com/forum/showthread.php?t = 464084至少在大多數地方,慣例是將公共領域置於頂端。它不會影響任何內容,但是由於公共字段是您班級的文檔,因此將它放在頂部是很有意義的。 – martiert 2012-03-06 08:14:55

+1

@martiert如果用戶根據此建議移動了它們,但頂部的'public:'成員可能會影響_lot_,但卻訂購了成員之間的依賴關係,但尚未意識到成員是按其聲明的順序初始化的; - ) – 2016-04-16 15:00:37

+1

@underscore_d這是真的。但是,再次,我們都將警告編譯爲錯誤和我們可以想到的所有警告,對嗎?這至少會告訴你,你搞砸了,但是,是的,人們使用的方式來警告,只是忽略它們:( – martiert 2016-04-19 07:58:57

回答

138

類聲明進入頭文件。添加#ifndef包括警衛很重要,或者如果您在MS平臺上,也可以使用#pragma once。另外我省略了私有,默認情況下C++類成員是私有的。

// A2DD.h 
#ifndef A2DD_H 
#define A2DD_H 

class A2DD 
{ 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 
    int getSum(); 

}; 

#endif 

和實現雲在CPP文件:

// A2DD.cpp 
#include "A2DD.h" 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
+27

請記住,如果您正在進行模板編程,則必須將所有內容保存在.h文件中,以便編譯器在編譯時將實例化正確的代碼。 – linello 2012-03-06 08:14:01

+0

即時消息得到一個錯誤的重複符號im不知道如何解決它.ld:重複符號A2DD :: A2DD(int,int)在./src/rstring.o和./src/A2DD.o體系結構x86_64 – drdrdr 2012-03-06 08:21:56

+1

你在頭文件中有'#ifndef'的東西嗎? – fritzone 2012-03-06 08:24:55

5

基本的函數聲明/定義修改語法:

a2dd.h

class A2DD 
{ 
private: 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

a2dd.cpp

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
2

你留在頭文件中的聲明:

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); // leave the declarations here 
    int getSum(); 
}; 

然後將這些定義放在執行文件中。

A2DD::A2DD(int x,int y) // prefix the definitions with the class name 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 

你可以混合使用這兩種(離開例如頭getSum()定義)。這很有用,因爲它給編譯器提供了更好的內聯機會。但是這也意味着更改實現(如果保留在標題中)可能會觸發重新生成包含標題的所有其他文件。

請注意,對於模板,您需要將其全部保留在標題中。

+1

將私有成員和函數放在頭文件中不被視爲泄漏實現細節? – Jason 2016-09-15 22:46:39

+0

@Jason,有點。這些是必要的*實施細節。例如,我必須知道一個類將在堆棧上消耗多少空間。其他編譯單元不需要函數實現。 – 2016-09-17 22:53:16

3

A2DD.h

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

A2DD.cpp

A2DD::A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int A2DD::getSum() 
    { 
    return gx + gy; 
    } 

的想法是讓所有的函數簽名和成員在頭文件。
這將允許其他項目文件在不需要知道實現的情況下查看該類的外觀。

除此之外,你可以在實現中包含其他頭文件而不是頭文件。這很重要,因爲頭文件中包含的任何頭文件將包含(繼承)在包含頭文件的任何其他文件中。

1

通常你只放聲明和頭文件非常短的內聯函數:

例如:

class A { 
public: 
    A(); // only declaration in the .h unless only a short initialization list is used. 

    inline int GetA() const { 
    return a_; 
    } 

    void DoSomethingCoplex(); // only declaration 
    private: 
    int a_; 
}; 
9

一般而言,您的.h包含班級defing,這是您的所有數據和所有你的方法聲明。像這樣在你的情況:

A2DD.h: 

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y);  
    int getSum(); 
}; 

然後你的.cpp包含這樣的方法實現:

A2DD.cpp: 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
}