0

在我的一个类头文件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 因为稍后颤音类将有一个 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++ 中,我们不允许这样做吗?顺便说一句,如果我的一个类(在我的情况下为 vibrato)将有另一个类的类成员(在这种情况下为 lfo),我是否应该在 .h (vibrato.h) 文件中包含成员类的头文件或 .cpp (vibrato.cpp) 文件?

4

2 回答 2

1

您不能将类方法定义直接放在头文件中,除非您明确将其标记为内联。如下所示:

// 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;
}
于 2018-03-04T21:41:47.137 回答
1

类是声明。声明不会产生任何代码。即使您在类中有成员函数,inline编译器也会将其视为一个。函数体可以放在头文件中,但应始终声明为inline. 编译器可能实际上并没有内联它,但它会将其视为用于代码创建的单个实例。

任何时候你:

void function( ) { }

为该功能创建代码。如果头文件被多次包含,编译器会被告知多次创建代码。但是所有函数都必须有唯一的名称!所以你得到重复的错误。这就是为什么代码生成行属于.cpp文件的原因。

'inline' 告诉编译器不要立即创建代码,而是在使用点创建代码。

于 2018-03-04T21:45:33.487 回答