[英]Multiple definition exception in C++
我开始学习C ++,并从我的IDE(CodeBlocks)中收到此编译错误。 我不明白为什么会这样。
|2|multiple definition of `parser::parseFile()'
|2|first defined here|
我不知道这怎么发生。 这是我的整个代码库。
main.cpp
#include "parser/parser.cpp"
int main()
{
return 0;
}
parser/parser.cpp
namespace parser {
void parseFile() {
}
}
假设您同时编译了main.cpp
和parser/parse.cpp
,则显然有parser::parseFile()
两个定义: #include
指令仅被命名文件的内容替换(您可以将-E
标志与编译器以查看结果)。
您可能打算在头文件中 声明 parser::parseFile()
(通常后缀.h
或.hpp
或类似的名称):
// file: parser/parser.hpp
#ifndef INCLUDED_PARSER_PARSER
#define INCLUDED_PARSER_PARSER
namespace parser {
void parseFile();
}
#endif
...并将此头文件包含在两个翻译单元中。
您的程序违反了“ 一个定义规则”(也称为ODR) 。 简而言之,在两个.cpp
文件中都定义了parser::parseFile
函数,因为在编译器级别, #include <header.h>
只是意味着将整个文件内容替换就位。 但是,解决问题的方法取决于您的实际程序。 如果要为类定义求解ODR规则,则可以执行以下任一操作:
1)在标题的开头添加一次#pragma once
。 尽管所有主要编译器都支持此方法,但它不是防止重复包含标头的标准化方法。
2)添加一个包含卫队 :
#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD
// your header contents go here
#endif
如果要解决函数和数据变量的ODR问题,上述方法将不起作用,因为您仍然可以在不同的.cpp
文件中多次定义它们。 为此,您仍然有2个选择:
1)在外部某个地方(即, .cpp
文件中) 定义函数,仅将其声明保留在标头中:
// header.h
namespace parser {
void func();
}
// file.cpp
void parser::func() { ... }
2)将您的函数声明为inline ,因为C ++标准允许inline函数具有多个定义(但是,直到lexem级别,它们必须严格相同):
// header.h
namespace parser {
inline void func() { ... }
}
总结起来,我强烈建议您通过保护标头避免双重包含并确保函数为内联或在.cpp
文件中定义来进行.cpp
操作。 对于后者,如果函数的实现发生了变化,则不必重新编译包含标头的所有文件,而只需重新编译具有functon定义的文件即可。
通常以.h结尾的头文件通常用于将类和函数声明与其实现分开。
在Code :: Blocks中 ,可以通过右键单击项目名称-> '添加文件' ->创建扩展名为.h的新文件来添加头文件。 按照良好的惯例,您还应该在编写实现时使用相同的名称创建一个.cpp文件。
正如已经回答的那样,您可以在头文件中首先编写一个包含保护,然后包含您的包含 (如果有)以及函数声明。 在“ parser.cpp”和“ main.cpp”中,您将必须#include "parser.h"
因为文件彼此依赖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.