函数错误的多重定义,即使使用#if guard子句也是如此

时间:2013-05-06 09:51:01

标签: c++

我正在为我的C ++项目创建一个包含aplusb(int,int)函数的简单UTIL.h文件。但是我无法编译,错误消息是关于`aplusb(int,int)'的多重定义。你能帮我纠正错误或给我一些提示吗?

我附上了我的项目,供您参考。

文件UTIL.h

#ifndef UTIL_H_
#define UTIL_H_

int aplusb(int a, int b) {
    return a + b;
}

#endif /* UTIL_H_ */

File ClassA.h

#ifndef CLASSA_H_
#define CLASSA_H_

class ClassA {
public:
    ClassA();
    virtual ~ClassA();
private:
    int sum;
};

#endif /* CLASSA_H_ */

文件ClassA.cpp

#include "ClassA.h"
#include "UTIL.h"

ClassA::ClassA() {
    // TODO Auto-generated constructor stub
    sum = aplusb(3,5);

}

ClassA::~ClassA() {
    // TODO Auto-generated destructor stub
}

文件ClassB.h

#ifndef CLASSB_H_
#define CLASSB_H_

class ClassB {
public:
    ClassB();
    virtual ~ClassB();
private:
    int sum;
};

#endif /* CLASSB_H_ */

文件ClassB.cpp

#include "ClassB.h"
#include "UTIL.h"

ClassB::ClassB() {
    // TODO Auto-generated constructor stub
    sum = aplusb(5,6);
}

ClassB::~ClassB() {
    // TODO Auto-generated destructor stub
}

编译错误消息

ClassB.o: In function `aplusb(int, int)':
/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: multiple definition of `aplusb(int, int)'
ClassA.o:/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: first defined here
collect2: error: ld returned 1 exit status
make: *** [commonfunc] Error 1

5 个答案:

答案 0 :(得分:17)

第一个变体 - 使用inline说明符

#ifndef UTIL_H_
#define UTIL_H_

inline int aplusb(int a, int b) {
    return a + b;
}

#endif /* UTIL_H_ */

第二个变体 - 在.cpp文件中写入定义。

答案 1 :(得分:4)

您在包含文件中创建了函数aplusb。这意味着对于您包含它的每个文件,将创建一个公共函数aplusb,从而导致名称冲突。

如果函数应该是内联的,那么请将其标记。如果函数应该是模板,则将其标记。如果函数应该像你编写的那样,将它放在一个cpp文件中,只需将原型保存在h文件中。

.h
#ifndef UTIL_H_
#define UTIL_H_

int aplusb(int a, int b);

#endif

.cpp
int aplusb(int a, int b)
{
    return a+b;
}

答案 2 :(得分:2)

您应该在头文件中声明您的aplusb函数,并在cpp文件中提供定义。像

这样的东西

util.h:

#ifndef UTIL_H_
#define UTIL_H_

int aplusb(int, int);

#endif /* UTIL_H_ */

错误消息告诉您每次包含util.h文件时,您都在重新定义函数,这正是您正在做的事情:-)这违反了ODR (单一定义规则),其中声明(函数的定义,在这种情况下)必须是唯一的。否则,编译器将无法在备选方案之间进行选择(即使在这种情况下,它们恰好相同)。

请注意,模板会使问题复杂化(简而言之,因为模板在实例化之前不是定义)。

答案 3 :(得分:0)

头文件不具有实际功能(某些C ++方面,例如模板不能承受)。在您的情况下的一般做法是让您将UTIL.H更改为仅对函数(int aplusb(int a, int b);)进行原型设计并将其实现移至源文件。

答案 4 :(得分:0)

您还可以创建一个Util结构,其中每个函数都声明为static。然后,您可以使用Util::<function name>

访问每个功能

文件UTIL.h

#ifndef UTIL_H_
#define UTIL_H_

struct Util{
    static int aplusb(int a, int b) {
        return a + b;
    }
};

#endif /* UTIL_H_ */

文件ClassA.cpp

#include "ClassA.h"
#include "UTIL.h"

ClassA::ClassA() {
    sum = Util::aplusb(3,5);
}

ClassA::~ClassA() {
}

文件ClassB.cpp

#include "ClassB.h"
#include "UTIL.h"

ClassB::ClassB() {
    sum = Util::aplusb(5,6);
}

ClassB::~ClassB() {
}