6

我正在为我的 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_ */

文件类A.h

#ifndef CLASSA_H_
#define CLASSA_H_

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

#endif /* CLASSA_H_ */

文件类A.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
}

文件类 B.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
4

5 回答 5

18

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

#ifndef UTIL_H_
#define UTIL_H_

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

#endif /* UTIL_H_ */

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

于 2013-05-06T09:53:10.073 回答
5

您在包含文件中创建了函数 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;
}
于 2013-05-06T09:55:27.337 回答
2

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

实用程序.h:

#ifndef UTIL_H_
#define UTIL_H_

int aplusb(int, int);

#endif /* UTIL_H_ */

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

请注意,模板使事情变得有点复杂(简而言之,因为模板在实例化之前不是定义)。

于 2013-05-06T10:01:42.710 回答
0

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

于 2013-05-06T09:53:26.550 回答
0

您还可以创建一个 Util 结构,其中每个函数都声明为静态的。然后,您可以使用访问每个功能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_ */

文件类A.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() {
}
于 2016-08-26T13:20:18.787 回答