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

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

头文件test.h

#pragma once
#include <Eigen/Core>
#include <iostream>

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<double,-1,1,0,-1,1> const &,class Eigen::Matrix<double,-1,1,0,-1,1> 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时,将在链接时导致符号重定义错误。要避免这种情况,需要去除全局对象,将全局函数封装为类的静态方法。或者声明与定义分开。


  • 40
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值