В одном из моих классов заголовочный файл Lfo.h
, У меня есть определение класса, где я помещаю определение функции-члена вне класса (может быть, лучше иметь отдельный файл .cpp, но это должно быть хорошо, поместите здесь?):
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Затем у меня есть еще один класс под названием CVibrato:
// Vibrato.h
class CVibrato
{
public:
static int create (CVibrato*& pCVibrato);
private:
CVibrato();
};
и файл .cpp (в файл cpp я включаю Lfo.h, потому что позже у класса vibrato будет элемент lfo, но я не реализовал его сейчас):
// Vibrato.cpp
#include "Lfo.h"#include "Vibrato.h"int CVibrato::create(CVibrato *&pCVibrato)
{
pCVibrato = new CVibrato();
return 0;
}
CVibrato::CVibrato()
{
}
Затем я хочу создать экземпляр класса вибрато в main ()
#include "Vibrato.h"#include "Lfo.h" // if comment this line out there will be no error, why is that?
int main()
{
CVibrato *vibrato = 0;
CVibrato::create(vibrato);
return 0;
}
Однако я получаю 1 duplicate symbol for architecture x86_64
ошибка. Что дублируется? Кажется, причина в Lfo.h, я помещаю определение функции-члена вне класса, если я помещаю его внутрь, программа работает правильно. Но я не могу понять. Разве мы не можем делать это в C ++? Кстати, если один из моих классов (в моем случае вибрато) будет иметь член класса другого класса (в данном случае lfo), я должен включить заголовочный файл класса члена в файл .h (vibrato.h) или .cpp (vibrato.cpp) файл?
Классы являются объявлениями. Код не создается из декларации. Даже если у вас есть функция-член в классе, она рассматривается как inline
компилятором. Тела функций могут быть помещены в заголовок, но всегда должны быть объявлены как inline
, Компилятор может на самом деле не встроить его, но он будет рассматривать его как отдельный экземпляр для создания кода.
В любое время вы:
void function( ) { }
Код создан для этой функции. Если заголовок включен более одного раза, компилятору предлагается создать код более одного раза. Но все функции должны иметь уникальные имена! Таким образом, вы получаете дубликат ошибки. Вот почему строки генерации кода принадлежат .cpp
файлы.
«inline» говорит компилятору не создавать немедленный код, а создавать код в точке использования.
Вы не можете поместить определение метода класса непосредственно в заголовочный файл, если вы явно не пометите его как встроенный. Как следующее:
// Lfo.h
class CLfo
{
public:
inline static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Или же,
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
inline int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}