命名空间函数的多重定义

时间:2018-05-23 07:37:42

标签: c++ include multiple-definition-error ifndef

我无法理解为什么这不会编译。

我有三个文件:

的main.cpp

#include "expression.h"

int main(int argc, char** argv)
{

    return 0;
}

expression.h

#ifndef _EXPRESSION_H
#define _EXPRESSION_H

namespace OP
{
  char getSymbol(const unsigned char& o)
  {
    return '-';
  }
};

#endif /* _EXPRESSION_H */

和expression.cpp

#include "expression.h"

(Ofc里面有更多内容,但即使我评论除了#include以外的所有内容都不起作用)

我用

编译它
g++ main.cpp expression.cpp -o main.exe

这是我得到的错误:

C:\Users\SCHIER~1\AppData\Local\Temp\ccNPDxb6.o:expression.cpp:(.text+0x0): multiple definition of `OP::getSymbol(unsigned char const&)'
C:\Users\SCHIER~1\AppData\Local\Temp\cc6W7Cpm.o:main.cpp:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

问题是,似乎两次解析expression.h。如果我只是使用main.cpp OR expression.cpp进行编译,我就不会收到错误。编译器只是忽略了我的#ifndef并继续......

任何线索?

1 个答案:

答案 0 :(得分:1)

  

问题是,似乎两次解析expression.h。

当然可以。您将其包含在两个不同的 cpp文件中。每个包含都将标题的内容转储到该转换单元中,因此您获得相同函数的两个定义,使链接器正确地抱怨。这与包含防护无关,它可以防止你在同一个文件中意外包含两次

但是,您可以在标题中定义一个函数。只要它标记为内联。所以这样做:

namespace OP
{
  inline char getSymbol(const unsigned char& o)
  {
    return '-';
  }
}

inline这里承诺所有这些功能与字母完全相同。因此,多个定义实际上被认为是同一个。但是要注意不要违背这个承诺(不要使用任何可以改变功能体的构造,具体取决于它所包含的位置)。

顺便说一句,命名空间不需要以;终止,所以我冒昧地删除它。