error LNK2005: “找到一個或多個多重定義的符號” 已經在 xxxx.obj 中定義 的解決方法


 

1 問題還原

這里我有三個源文件:Base.hpp, Base.cpp 和 main.cpp

在Base.hpp里面定義一個基類,注意,基類只包含構造函數和析構函數的聲明,函數在Base.cpp里實現。

此外在Base.hpp中還有一個函數的定義(函數聲明和定義都在Base.hpp文件中)三個文件代碼如下。

Base.hpp
#ifndef VIRTUAL_H
#define VIRTUAL_H
 
#include<iostream>
#include<string>
 
using namespace std;
 
class Base{
public:
	Base();
 
	~Base();
 
private:
	char *p;
};
 
void platform(Base *pBase){
	cout << "this is just a function..." << endl;
}
 
#endif

  

Base.cpp
#include"Base.hpp"
 
Base::Base(){
	cout << "construction function..." << endl;
}
 
Base::~Base(){
	cout << "destructor function..." << endl;
	delete p;
}

  

main.cpp
#include"Base.hpp"
#include<iostream>
using namespace std;
 
int main(){
	cout << "main..." << endl;
 
	Base * pBase = new Base;
	delete pBase;
 
	system("pause");
	return 0;
}

  

2 分析與解決方案

2.1 分析

定義類時,一般聲明和實現分離,於是可將頭文件中定義的類的構造函數,移到其對應的xxxx.cpp中,你會發現果然問題解決了。
實際上,xxxx.cpp由於包含了xxxx.h,而xxxx.h中包含了構造函數的實現,於是xxxx.cpp生成目標文件的時候,包含了構造函數的實現。而類的調用函數,如main.cpp也包含了xxxx.h,同樣編譯生成目標文件的時候,也會包含構造函數的實現。這樣二者在鏈接階段就會發現有兩個一模一樣的函數,出現了重定義的問題。

確定了這是由於兩個實現文件(main.cpp 和 base.cpp)中重復包含了頭文件而造成的。
要注意的是,在這里,在頭文件中加入#ifndef……#endif這樣的預編譯命令是沒用的,因為這是防止嵌套包含頭文件的,而本例中並沒有嵌套包含,是 在兩個文件中分別包含。

 

 

2.2 解決

方法1:
只在頭文件中聲明函數,把函數定義都放到cpp文件中,本例中把platform函數的定義從Base.hpp文件中移到Base.cpp文件中。

把函數體放到cpp文件中后確實可行。

 

同理:如果在頭文件中再定義一個變量:int a = 10; 那么由於頭文件在兩個cpp文件中都有被包含,也會出現類似的錯誤。

此時,需要把變量的定義放到Base.cpp文件中。

 

 方法2:

在xxxx.h的類的函數定義處,加上inline。這樣實際上是在調用處展開函數體代碼,代替函數調用。從而避免重復定義的問題。

頭文件

class xxxxx
{
public:
 
inline xxxxx(const Eigen::VectorXd &xData,  const Eigen::VectorXd &yData);
private:
	Eigen::VectorXd m_xData;
	Eigen::VectorXd m_yData;
	
};
 
xxxxx::xxxxx( const Eigen::VectorXd &xData,  const Eigen::VectorXd &yData)
{
	m_xData = xData;
	m_yData = yData;

}

 

 

 

參考文章

fatal error LNK1169: 找到一個或多個多重定義的符號 的解決方案xiamentingtao,2017-1

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM