fatal error LNK1169: 找到一个或多个多重定义的符号 的解决方案

昨天,尝试一个项目,遇到了如下的问题。先来还原一下:

头文件test.h

#pragma once
#include 
#include 

using namespace Eigen;
using namespace std;

class point2
{
public:
point2(int x1,int y1):x(x1),y(y1){}
point2& operator+(point2 s);

private:
int x,y;
};


class DirectEllipseFit
{
public:

   DirectEllipseFit(const Eigen::VectorXd &xData, const Eigen::VectorXd &yData);
private:
Eigen::VectorXd m_xData;
Eigen::VectorXd m_yData;

};

DirectEllipseFit::DirectEllipseFit( const Eigen::VectorXd &xData, const Eigen::VectorXd &yData)
{
m_xData = xData;
m_yData = yData;
}

test.cpp

#include"test.h"


point2& point2::operator+(point2 s)
{
	this->x=x+s.x;
	this->y+=s.y;
	return *this;
}

main.cpp

#include "test.h"

int main(void)
{
    return 0;
}
结果程序链接阶段,出现如下错误:

1>test.obj : error LNK2005: "public: __thiscall DirectEllipseFit::DirectEllipseFit(class Eigen::Matrix const &,class Eigen::Matrix const &)" (??0DirectEllipseFit@@QAE@ABV?$Matrix@N$0?0$00$0A@$0?0$00@Eigen@@0@Z) 已经在 main.obj 中定义
1>E:\c++\testEigen\Debug\testEigen.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

开始百思不得其解,后来想到了定义类时,一般声明和实现分离,于是我将DirectEllipseFit的构造函数移到了test.cpp中,果然问题解决了。后来查看资料,终于找到了原因。
实际上,test.cpp由于包含了test.h,而test.h中包含了构造函数的实现,于是test.cpp生成目标文件的时候,包含了构造函数的实现。而main.cpp也包含了test.h,同样编译生成目标文件的时候,也会包含构造函数的实现。这样二者在链接阶段就会发现有两个一模一样的函数,出现了重定义的问题。

解决这个问题的方法,有两种:

一、添加inline关键字,这样实际上是在调用处展开函数体代码,代替函数调用。
即:

class DirectEllipseFit
{
public:

inline	DirectEllipseFit(const Eigen::VectorXd &xData,  const Eigen::VectorXd &yData);
private:
	Eigen::VectorXd m_xData;
	Eigen::VectorXd m_yData;
	
};

DirectEllipseFit::DirectEllipseFit( const Eigen::VectorXd &xData,  const Eigen::VectorXd &yData)
{
	m_xData = xData;
	m_yData = yData;
}


二、将函数实现放在test.cpp中,这样就不会出现重定义问题。


PS:

其实还有一种情况也会出现以上问题,即如果我们在test.h中定义一个全局变量,也会出现这个问题,具体可参考:

《 C++杂记:“error LNK1169: 找到一个或多个多重定义的符号”的解决方法》

《HPP定义也会出现这个问题》:由于hpp本质上是作为.h被调用者include,所以当hpp文件中存在全局对象或者全局函数,而该hpp被多个调用者include时,将在链接时导致符号重定义错误。要避免这种情况,需要去除全局对象,将全局函数封装为类的静态方法。或者声明与定义分开。


你可能感兴趣的:(C++基础算法)