我能找到的所有相关问题都没有详细说明我的具体情况,所以我希望这不是一个重复的问题。
我有一个A类(使用A.h来声明和A.cpp来定义),它包含和使用Math.h中的函数。
当我尝试构建我的main.cpp以使用#includes A类头的对象A时,我得到了Math.h中定义的每个数学函数的多重定义错误(Math.h没有。 cpp,所有函数/变量都在标题中定义。
A.H
#ifndef A_H
#define A_H
#include "Math.h"
//Other #includes
namespace MY_NAMESPACE
{
class A
{
public:
A();
//Variable/Function declarations
private:
//Variable/Function declarations
};
}
#endif
A.cpp
#include "A.h"
void MY_NAMESPACE::A::Func1()
{
//define
}
ect...
的main.cpp
#include "A.h"
int main()
{
MY_NAMESPACE::A* a = new MY_NAMESPACE::A();
delete a;
return 0;
}
Math.h(仅在标题中声明和定义)
#ifndef MATH_H
#define MATH_H
float DotProduct(Vector3 v1, Vector3 v2)
{
return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
}
#endif
etc...
我是linux / g ++的新手。在Windows平台上使用Visual Studio进行编程时,这从未引起过任何问题。
这是非常基本的东西,所以我感到很困惑。
生成文件
CC =克++ FLAGS = -std = c ++ 11 -g
build: clean A.o main clean: rm -f -v bin/*.* A.o: $(CC) -c $(FLAGS) A.cpp main: $(CC) $(FLAGS) main.cpp A.o
有什么建议吗?
编辑实际错误snippit
在函数
WF_RPI::MATH::Normalize(WF_RPI::MATH::Vector3)': /home/pi/projects/WFRPI/TPx2SController/../WFStandard/WFSMath.h:574: multiple definition of
WF_RPI :: MATH :: Normalize(WF_RPI :: MATH :: Vector3)' Arcus.o:/家庭/ PI /项目/ WFRPI /弓/../ TPx2SController /../ WFStandard / WFSMath.h:574: 首先在这里定义bin // libtpx2s.a(tpx2s.o):在函数中WF_RPI::MATH::Normalize(WF_RPI::MATH::Vector2)': /home/pi/projects/WFRPI/TPx2SController/../WFStandard/WFSMath.h:590: multiple definition of
WF_RPI :: MATH ::正常化(WF_RPI :: MATH :: Vector2)' Arcus.o:/家庭/ PI /项目/ WFRPI /弓/../ TPx2SController /../ WFStandard / WFSMath.h:590: 首先在这里定义bin // libtpx2s.a(tpx2s.o):在函数中 `WF_RPI :: MATH ::幅度(WF_RPI :: MATH :: Vector2)':
答案 0 :(得分:2)
Math.h中的函数需要内联...
inline float DotProduct(Vector3 v1, Vector3 v2)
{
return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
}
C / C ++目前使用包含文件的文本插入。这意味着对于每个.cpp文件,它由所有包含的所有文本和它自己的代码组成。
当编译器看到
时 int funName( int param ) {
// something...
}
它声明了一个外部函数。当它将C ++文件链接在一起时,它会发现导致该问题的多个定义。
修复(如右上方所述)是将函数标记为inline
。这允许链接多个定义。
错误描述的问题比您描述的更复杂。它提到了一个存档(.a)文件,其中包含头文件WFSMath.h
的重复定义。
存档需要重新构建,因为它可能嵌入了非内联实现,并且一些make系统在发现库时不太完美,如果头文件发生更改,则需要重新构建。