使用#ifdef 时的多个定义
Multiple definitions when using #ifdef
编译时遇到问题: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),程序也可以毫无抱怨地编译
您应该在 .cpp 文件中 定义 函数,而不是在头文件中。您在头文件中声明 它们。您正在做的是在头文件中定义它,因此当它被包含到多个文件中时,该函数就会重复。跨文件重复符号将引发错误,除非它们是 static
.
myLibrary.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
您正在 header 文件中定义函数的 body。因此,您在其中包含 header 的每个翻译单元(在本例中为 main.cpp
和 header.cpp
)最终都会得到该函数 body 的副本。当您尝试 link 将这些多个单元放在一起时,您会收到 "duplicate definition" 错误。
函数需要在hpp文件中声明,在cpp文件中定义:
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
//...
Include guards 仅防止相同的 header 在同一个 翻译单元 中被包含两次,这实际上通常是一个 .cpp
文件。例如,这样做可以防止错误:
#include "header.h"
#include "header.h"
int main()
{
}
但是,更一般地说,这意味着您是否包含一个已经作为另一个 header 的依赖项包含的 header 并不重要。
但是,如果您有 两个 .cpp 文件包含相同的 header,并且 header 包含函数的定义(例如您的myLibrary.hpp
) 那么每个 .cpp 文件都会有自己的定义(include guard 无济于事,因为 header 被包含在两个单独的翻译单元/.cpp 文件中)。
最简单的做法是在 header 中声明该函数,它告诉包含您的 header 的每个文件该函数存在于 某处 ,然后在.cpp文件中定义,这样只定义一次。
编译时遇到问题: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),程序也可以毫无抱怨地编译
您应该在 .cpp 文件中 定义 函数,而不是在头文件中。您在头文件中声明 它们。您正在做的是在头文件中定义它,因此当它被包含到多个文件中时,该函数就会重复。跨文件重复符号将引发错误,除非它们是 static
.
myLibrary.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
您正在 header 文件中定义函数的 body。因此,您在其中包含 header 的每个翻译单元(在本例中为 main.cpp
和 header.cpp
)最终都会得到该函数 body 的副本。当您尝试 link 将这些多个单元放在一起时,您会收到 "duplicate definition" 错误。
函数需要在hpp文件中声明,在cpp文件中定义:
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
//...
Include guards 仅防止相同的 header 在同一个 翻译单元 中被包含两次,这实际上通常是一个 .cpp
文件。例如,这样做可以防止错误:
#include "header.h"
#include "header.h"
int main()
{
}
但是,更一般地说,这意味着您是否包含一个已经作为另一个 header 的依赖项包含的 header 并不重要。
但是,如果您有 两个 .cpp 文件包含相同的 header,并且 header 包含函数的定义(例如您的myLibrary.hpp
) 那么每个 .cpp 文件都会有自己的定义(include guard 无济于事,因为 header 被包含在两个单独的翻译单元/.cpp 文件中)。
最简单的做法是在 header 中声明该函数,它告诉包含您的 header 的每个文件该函数存在于 某处 ,然后在.cpp文件中定义,这样只定义一次。