c++ - 链接 C++ 项目时出现多重定义错误

标签 c++ c++11

我在重新安排我的 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/

相关文章:

c++ - 将字符串作为对函数指针 C++ 的引用传递

c++ - 对具有不同值的图像的每个 channel 进行归一化的快速有效方法

c++ - 嵌套在其他任何类别中的已知类名称的C++模板 friend 声明

c++ - 使用 new 动态分配字符是否需要编译器将它们初始化为零

c++ - 如何为小数点分隔符和位数调整 std::stod(字符串加倍)

c++ - 模板类返回元组或值,取决于参数包

c++ - 在 C++11 中,可以在同一行声明全局变量和函数原型(prototype)吗?

c++ - 是否有标准的 C++11 解决方案来转义单引号?

c++ - 如何将奇怪的重复模板模式用于桥接模式?

c++ - 我不小心调用了一个没有自己的类对象的成员函数。但这是如何工作的?