使用 #ifdef 时的多个定义



我在编译时遇到问题:Multiple definitions of "myFunction()"我将大大简化这里的问题。基本上,我有 3 个文件:"主"、"标题"和"我的库"。

  • 主.cpp
#include "header.hpp"
int main() {  }
  • 标题.hpp
#ifndef HEADER_HPP
#define HEADER_HPP
#include "myLibrary.hpp"
// ...
#endif
  • 标头.cpp
#include "header.hpp"
// ...
  • 我的图书馆.hpp
#ifndef LIB_HPP
#define LIB_HPP
#if defined(__unix__)
#include <dlfcn.h>
std::string myFunction() { return std::string(); }
#endif
#endif
  • 我的图书馆.cpp
#include "myLibrary.hpp"
//...

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

我发现的一个线索是:当我获取标头.cpp并删除显示#include "header.hpp"的行时,程序编译时不会抱怨。另一方面,如果我删除myFunction(从myLibrary.hpp(,该程序也可以毫无怨言地编译

您正在头文件中定义函数的主体。 因此,您包含该标头的每个翻译单元(在本例中为main.cppheader.cpp(最终都会得到该函数体的自己的副本。 当您尝试将这些多个单元链接在一起时,会出现"重复定义"错误。

该函数需要在 hpp 文件中声明,并在 cpp 文件中定义

我的图书馆.hpp

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

我的图书馆.cpp

#include "myLibrary.hpp"
#if defined(__unix__)
std::string myFunction()
{
return std::string();
}
#endif
//...

包含保护只能防止同一标头在同一翻译单元中包含两次,这实际上通常是单个.cpp文件。例如,它可以防止执行此操作时出现错误:

#include "header.h"
#include "header.h"
int main()
{
}

但是,更一般地说,这意味着是否包含已作为另一个标头的依赖项包含的标头并不重要。

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

最简单的方法是在标头中声明函数,它告诉包含标头的每个文件该函数存在于某个位置,然后在.cpp文件中定义它,以便只定义一次。

您应该在.cpp文件中定义函数,而不是在头文件中定义函数。在头文件中声明它们。您正在做的是在头文件中定义它,因此当它包含在多个文件中时,该函数会变得重复。跨文件重复的符号将引发错误,除非它们static

我的图书馆.cpp:

#include "myLibrary.hpp"
#ifdef(__unix__)
std::string myFunction() { return std::string(); }
#endif

myLibrary.hpp:

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

相关内容

  • 没有找到相关文章

最新更新