繁体   English   中英

C ++中的多定义异常

[英]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.cppparser/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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM