C++ 在C++;?

C++ 在C++;?,c++,C++,好的,我最近了解了编译器的工作原理以及“链接器”是什么。从我观看的教程视频中,我清楚地看到,如果我包含不止一次声明,可以说: void Log(const char* message); 我会得到一个错误,因为我多次声明它。但目前,在测试时,我创建了一个头文件,其中包含特定的声明,并且在我的主编译单元中包含了几次,如下所示: #include "Log.h" #include "Log.h" 我已经删除了#pragma once语句,也没有编写头保护程序,但我的程序仍然运行良好,没有任何问

好的,我最近了解了编译器的工作原理以及“链接器”是什么。从我观看的教程视频中,我清楚地看到,如果我包含不止一次声明,可以说:

void Log(const char* message); 
我会得到一个错误,因为我多次声明它。但目前,在测试时,我创建了一个头文件,其中包含特定的声明,并且在我的主编译单元中包含了几次,如下所示:

#include "Log.h"
#include "Log.h"

我已经删除了#pragma once语句,也没有编写头保护程序,但我的程序仍然运行良好,没有任何问题。由于这些视频已经有2-3年的历史了,我想可能已经有了更新,这些更新一起消除了对警卫和布拉格的需求,但我不确定。

您看到的教程是正确的。除非使用特殊技术,否则不能对某事物有多个定义

在这种情况下,虽然您没有定义

void Log(const char* message); 
是一个声明,您可以拥有这些声明的倍数。如果您将代码更改为

void Log(const char* message) {}
然后您将有一个函数定义,并将得到一个错误

我会得到一个错误,因为我多次声明它

通常允许重新声明,只要您不使用相同的名称混合使用不同类型的声明。下面是完全合法的C++,并且一直是:

void Log(const char* message); 
void Log(const char* message);
您可能会被一个定义规则所迷惑,该规则不允许多次定义事物

我已经删除了#pragma once语句,也没有编写头保护程序,但我的程序仍然运行良好,没有任何问题

如果你的标题没有定义任何东西,那么它就不需要标题保护。然而,按照惯例总是保持警惕更简单,这样就不需要跟踪是否有定义


额外的回答:所有的定义都是声明。通常很容易区分类和函数的定义与前向声明:

return_type function_name(argument_list);        // not a definition of function
return_type function_name(argument_list) { ... } // is  a definition of function

class class_name;                                // not a definition of class
class class_name {                               // is  a definition of class
    void member_function();                      // not a definition of function
    void inline_member_function() { ... };       // is  a definition of function
};
void class_name::member_function() { ... }       // is  a definition of function
区分变量定义有点困难。不确定时,请始终检查规则。

Cherno的教程

我认为视频中清楚地表明,一个函数不能有多个定义。您创建的自定义头文件基本上是粘贴的代码副本块,因此,如果它们包含同一函数或类的不同定义,则会导致歧义,并按预期抛出错误

编辑:他想表达的观点- 如果您将这两个相同的函数定义一起写入一个文件,那么很明显,它将抛出一个错误,因为正如我前面提到的那样,这是由编译器检测到的,因为它只在一个文件中

但是,当您将这两个相同的定义放在不同的文件中时,请说您自定义创建的头“log.h”,然后当您将它们导入到cpp文件中两次时(或者说您将它们导入到另一个cpp文件中并像在visual studio中一样构建解决方案),当涉及到链接器时,它将抛出链接器错误(多个文件-其中链接器的任务是将它们链接到一个组合的可执行文件中),并且它无法选择不同文件中存在的多个定义。因此,在这种情况下,您将得到多个定义/签名错误。(包括杂注抑制警告)


一种解决方案,将函数设置为静态,以便在内部定义函数或仅为其编译所依据的文件定义函数。这使得同一函数的多个函数定义在不同的文件中成为可能,而不会出现链接错误。另一种选择是将其设置为串联。这些情况为您提供了多个定义时不要出错,否则它会抛出错误。

这是一个错误,你只需要让编译器知道函数X将在以后定义。在一些参考资料中,你会发现它写了/说不允许多重声明,但我认为这是因为干净的代码方法,而不是编译器的问题。在你的案例中,你只包括声明两次,如果在两个不同的头文件中声明函数并将它们都包含在源文件中,则相同。

void Log(const char*message);
是声明,而不是定义。请尝试将
替换为
{}
您将得到错误。对不起,我的错误。我的意思是声明,而不是定义。我将立即编辑它。但是,多个声明从来都不是问题,因此此更正将使您的问题的前提无效。您可以有任意多个关于所有符号的声明,问题在于定义。请阅读关于。我还建议您了解,因为一个定义规则是针对每个程序的,并且跨越多个翻译单元。我肯定会查看它。除此之外,我还知道基本的翻译单元是什么。基本上是转换为.obj文件,然后由链接器使用以创建.exe文件的.cpp文件。它不会不知道其他的.CPP直到链接器进入播放。在阅读了我的所有线程的答案后,我回去查看视频,看到程序员在头文件中包含了那个函数的完整定义。我只是认为它是一个声明,并记住它。我的错误。我对编程和C++的编程很陌生。还有,请不要打扰我,但是这个函数来自一个头,所以它应该是
内联的
或函数模板。如果不能重用,就没有必要将一个函数提取到头中。@MaximeGroushkin很抱歉,但我没有收到你的评论。我正在展示一个操作,如果他们做了
无效日志(const char*message){}
,然后他们会看到他们期望得到的多定义错误。我记错了昨天在做测试时看到的教程。我想