我在重新安排我的 C++ 项目以避免文件名和命名空间冲突时遇到了这个问题。
所以,我在一个简单的项目中复制了这个问题,这是它的文件。
文件client.hpp:-
#ifndef CLIENT_HPP
#define CLIENT_HPP
namespace work { namespace test {
int get_age(){
return 33;
}
}
}
#endif
文件 work.hpp:-
#ifndef WORK_HPP
#define WORK_HPP
#include <iostream>
#include "client.hpp"
namespace work { namespace test {
class NewWork{
public:
NewWork(std::string name);
std::string getName();
int getAge();
private:
std::string _name;
};
}
}
#endif
文件 work.cpp :-
#include "work.hpp"
using namespace work::test;
NewWork::NewWork(std::string name) : _name(name) {}
std::string NewWork::getName() { return _name; }
int NewWork::getAge() { return get_age(); }
文件 main_fun.cpp :-
#include "work.hpp"
using namespace work::test;
int main(int argc, char **argv){
NewWork w = NewWork("hari");
std::cout << "Name: " << w.getName()
<< " Age: " << w.getAge()
<< std::endl;
return 0;
}
文件 CMakeLists.txt : -
cmake_minimum_required(VERSION 2.6)
project(work)
set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set ( SRC_FILES
${PROJECT_DIR}/work.cpp
${PROJECT_DIR}/main_fun.cpp
)
include_directories(${PROJECT_DIR})
add_executable(${PROJECT_NAME} ${SRC_FILES})
所以在构建这个时我遇到了以下错误:-
Linking CXX executable work
CMakeFiles/work.dir/main_fun.cpp.o: In function `work::test::get_age()':
main_fun.cpp:(.text+0x0): multiple definition of `work::test::get_age()'
CMakeFiles/work.dir/work.cpp.o:work.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [work] Error 1
make[1]: *** [CMakeFiles/work.dir/all] Error 2
make: *** [all] Error 2
我发现的一件事是,如果我将函数 work::test::get_age() 设置为 static
,那么它可以毫无问题地进行编译和链接。我不明白为什么它适用于 static
。
头文件的保护是正确的,所以它不可能被多次包含,或者我在这里遗漏了什么?
谢谢,
Haridas N.
最佳答案
您在 header 中定义了 get_age
。这意味着它会通过每个 .cpp
中的 #include
复制到每个翻译单元中。
当您在命名空间范围内将其标记为 static
时,这会使每个拷贝都成为该翻译单元的“本地”拷贝,因此不会发生冲突。
如果您将其标记为inline
,您将向编译器和链接器保证每个翻译单元中的定义都是相同的(我们可以看到它是),因此多个拷贝将神奇地卷成一个。
不过,正确的方法是在您的 header 中声明并在一个源文件中定义,就像您对类的成员函数所做的那样。
关于c++ - 链接 C++ 项目时出现多重定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20070680/