編輯: @juanchopanza告訴我,我是混淆了術語聲明和定義,所以我輸入了一個不完全正確的整體解釋。我在這裏主要糾正它,所以我不會忘記聲明和定義之間的區別。
您的第一個樣本是一個聲明,第二個樣本是聲明和定義之一。
這兩個示例都定義了Foo
。不同的是,在你的第一個文件中,你只是聲明瞭成員函數,但在第二個文件中,實際上是在定義它們。
實際申報Foo
的方法是class Foo;
。要定義Foo
,請使用class Foo { ... };
。
請注意,定義可以代替聲明,即當您定義X時,您還在聲明它。
以下是聲明和定義通常在實踐中如何跨標頭和源文件對進行分割。
foo。HPP(定義Foo
,但只能宣佈其功能)
#ifndef __FOO__
#define __FOO__
class Foo
{
int foo, bar;
public:
Foo();
Foo(int arg1, int arg2);
void doSomething();
int returnSomething();
~Foo();
};
#endif
Foo.cpp中(成員函數定義)
#include "foo.h"
Foo::Foo()
{
}
Foo::Foo(int arg1, int arg2) :
foo(arg1),
bar(arg2)
{
//body
}
Foo::~Foo()
{
// e.g. free the memory
}
void Foo::doSomething()
{
//body
}
int Foo::returnSomething()
{
return 0;
};
這不要緊,(foo.hpp
或foo.cpp
)定義每個特定函數,只要你只定義一次函數即可。請將其定義爲foo.hpp
或foo.cpp
,,但不能同時包含。
你在初始化的問題列出
想想看:如果你把一個初始化列表構造函數的聲明,它已成爲這兩個聲明和定義。
代替在源文件中定義
Foo::Foo(int arg1, int arg2) :
foo(arg1),
bar(arg2)
{
//body
}
例如,我可以在報頭中定義的那樣:
class Foo
{
...
Foo(int arg1, int arg2) :
foo(arg1),
bar(arg2)
{
//body
}
...
};
唯一的區別是,我沒有使用::
,範圍操作符。您不要將ClassName::
放在您聲明的函數或定義在類定義內的定義之前,因爲編譯器已經將它們識別爲被定義爲類的範圍。
您正在使用內聯方法。只使用他們簡單的東西(例如getters/setters)。否則將它們放在一個.cpp文件中,而不是頭文件 –
@ TomDavies92我的答案顯示了將類的聲明和定義分別拆分爲頭文件和源文件的規範方法。 – Keeler
這裏的術語存在一些混淆。我添加了一個答案,以澄清什麼類的聲明和定義。你的聲明都是定義,因此技術上你可以在被要求「定義一個類」時提供。 – juanchopanza