使用#ifdef时有多个定义

问题描述 投票:0回答:3

编译时出现问题:Multiple definitions of "myFunction()"我将在这里大大简化问题。基本上,我有3个文件:“ main”,“ header”和“ myLibrary”。

  • main.cpp
    #include "header.hpp"

    int main() {  }
  • header.hpp
    #ifndef HEADER_HPP
    #define HEADER_HPP

    #include "myLibrary.hpp"

    // ...

    #endif
  • header.cpp
    #include "header.hpp"

    // ...
  • myLibrary.hpp
    #ifndef LIB_HPP
    #define LIB_HPP

    #if defined(__unix__)
    #include <dlfcn.h>
    std::string myFunction() { return std::string(); }
    #endif

    #endif
  • myLibrary.cpp
    #include "myLibrary.hpp"

    //...

所以,为什么编译器说我有Multiple definitions of "myFunction()"

我发现的一个线索:当我使用header.cpp并擦除显示#include "header.hpp"的行时,程序在编译时没有抱怨。另一方面,如果我改写myFunction(来自myLibrary.hpp),该程序也将进行编译而不会产生任何抱怨

c++ definition include-guards
3个回答
2
投票

您正在头文件中定义函数的主体。因此,您在其中包含该标头的每个翻译单元(在本例中为main.cppheader.cpp)将以该函数体的自身副本结尾。当您尝试将这些多个单元链接在一起时,会出现“重复定义”错误。

该功能需要在hpp文件中declared,在cpp文件中defined

myLibrary.hpp

#ifndef LIB_HPP
#define LIB_HPP

#if defined(__unix__)
#include <dlfcn.h>
#include <string>
std::string myFunction();
#endif

#endif

myLibrary.cpp

#include "myLibrary.hpp"

#if defined(__unix__)
std::string myFunction()
{
    return std::string();
}
#endif

//...

0
投票

include防护仅防止同一标头在同一translation unit中两次被包含,实际上通常是单个.cpp文件。例如,这样做可以防止错误:

#include "header.h"
#include "header.h"

int main()
{
}

但是,更一般而言,这意味着是否包含已经作为另一个标头的依赖项包含的标头都没有关系。

但是,如果您有two .cpp文件包含相同的标头,并且该标头包含函数的定义(例如myLibrary.hpp),则每个.cpp文件将具有其自己的定义(包括后卫将无济于事,因为标头包含在两个单独的翻译单元/ .cpp文件中。)

最简单的方法是在标头中声明该函数,它告诉包含标头的每个文件该函数存在somewhere

,然后在.cpp文件中对其进行定义,以便仅定义一次。

0
投票

您想在.cpp文件中定义函数,而不是在头文件中定义函数。同样,您似乎没有为函数定义类型。我认为它应该返回string

© www.soinside.com 2019 - 2024. All rights reserved.