链接C++项目时出现多重定义错误
multiple definition error while linking C++ project
我在重新安排C++项目以避免文件名和命名空间冲突时遇到了这个问题。
所以,我在一个简单的项目上复制了这个问题,这是它的文件
文件客户端.hpp:-
#ifndef CLIENT_HPP
#define CLIENT_HPP
namespace work { namespace test {
int get_age(){
return 33;
}
}
}
#endif
文件工作.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
文件工作.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
我发现的一件事是,如果我让函数工作::test::get_age()到static
,那么它编译和链接就没有任何问题。我不明白为什么它能和static
一起工作。
头文件的保护是正确的,所以不可能多次包含它,或者我在这里遗漏了什么?
谢谢你,
Haridas N.
您在标头中定义了get_age
。这意味着它被复制到每个翻译单元中,由每个.cpp
中的#include
复制。
当您在名称空间范围中将其标记为static
时,这将使每个副本都成为该翻译单元的"本地"副本,这样就不会发生冲突。
如果您将其标记为inline
,您将向编译器和链接器承诺,每个翻译单元中的定义都是相同的(我们可以看到这一点),因此多个副本将神奇地汇总为一个。
不过,正确的方法是在头中声明,并在一个源文件中定义。
当包含client.hpp
文件时,get_age
函数是定义的。如果您将头文件包含在多个源文件中,那么您将拥有该函数的多个定义。
您应该做的是在头文件中声明函数,然后在单个源文件中定义它。
所以在头文件中只做
namespace work {
namespace test {
int get_age();
}
}
并在源文件中创建定义
int work::test::get_age() {
...
}
声明函数inline
(正如您在标头中提供的实现…)
相关文章:
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件