gpt4 book ai didi

c++ - C++ 中的前向声明是什么?

转载 作者:IT老高 更新时间:2023-10-28 11:27:47 28 4
gpt4 key购买 nike

在:http://www.learncpp.com/cpp-tutorial/19-header-files/

提到了以下内容:

添加.cpp:

int add(int x, int y)
{
return x + y;
}

主.cpp:
#include <iostream>

int add(int x, int y); // forward declaration using function prototype

int main()
{
using namespace std;
cout << "The sum of 3 and 4 is " << add(3, 4) << endl;
return 0;
}

We used a forward declaration so that the compiler would know what "add" was when compiling main.cpp. As previously mentioned, writing forward declarations for every function you want to use that lives in another file can get tedious quickly.



您能否进一步解释“ 前向声明”?如果我们在 main()中使用它有什么问题功能?

最佳答案

为什么在 C++ 中需要前向声明

编译器希望确保您没有出现拼写错误或将错误数量的参数传递给函数。因此,它坚持在使用之前首先看到“add”(或任何其他类型、类或函数)的声明。

这实际上只是允许编译器更好地验证代码,并允许它整理松散的末端,以便它可以生成一个整洁的目标文件。如果您不必转发声明,编译器将生成一个目标文件,该文件必须包含有关“add”函数可能是什么的所有可能猜测的信息。并且链接器必须包含非常聪明的逻辑来尝试找出您实际打算调用的“添加”,当“添加”函数可能存在于不同的目标文件中时,链接器将与使用添加生成的目标文件连接起来一个 dll 或 exe。链接器可能会得到错误的添加。假设您想使用 int add(int a, float b),但不小心忘记写它,但链接器发现一个已经存在的 int add(int a, int b) 并认为这是正确的,并使用它代替。您的代码可以编译,但不会按照您的预期运行。

因此,为了使事情明确并避免猜测等,编译器坚持要求您在使用之前声明所有内容。

声明与定义的区别

顺便说一句,了解声明和定义之间的区别很重要。声明只是提供足够的代码来显示某些东西的样子,因此对于函数,这是返回类型、调用约定、方法名称、参数及其类型。但是不需要该方法的代码。对于定义,您需要声明,然后还需要函数的代码。

前向声明如何显着减少构建时间

您可以通过#includ'ing 已包含函数声明的 header ,将函数声明添加到当前的 .cpp 或 .h 文件中。但是,这可能会减慢您的编译速度,尤其是如果您将头文件 #include 到 .h 而不是程序的 .cpp 中,因为所有 #includes .h 您正在编写的内容最终都会 #include'ing 所有头文件你也写了#includes。突然之间,即使您只想使用一两个函数,编译器也需要编译 #included 页和代码页。为避免这种情况,您可以使用前向声明并在文件顶部自己键入函数的声明。如果您只使用几个函数,与始终使用 #include 头文件相比,这确实可以使您的编译速度更快。对于非常大的项目,差异可能是一个小时或更长时间的编译时间缩短到几分钟。

中断循环引用,其中两个定义都相互使用

此外,前向声明可以帮助您打破循环。这是两个函数都试图相互使用的地方。发生这种情况时(这是一件完全有效的事情),您可以 #include 一个头文件,但该头文件会尝试 #include 您当前正在编写的头文件....然后 #includes 另一个头文件, 其中 #includes 您正在编写的那个。您陷入了鸡与蛋的困境,每个头文件都试图重新#include 另一个。为了解决这个问题,您可以在其中一个文件中预先声明您需要的部分,并将#include 保留在该文件之外。

例如:

文件 Car.h

#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Car
{
std::vector<Wheel> wheels;
};

文件 Wheel.h

嗯...这里需要声明 Car ,因为 Wheel 有一个指向 Car 的指针,但是 Car.h 不能包含在这里,因为它会导致编译器错误。如果包含 Car.h,则将尝试包含 Wheel.h,后者将包含 Car.h,而 Car.h 将包含 Wheel.h,这将永远持续下去,因此编译器会引发错误。解决方案是转发声明 Car :
class Car;     // forward declaration

class Wheel
{
Car* car;
};

如果类 Wheel 有需要调用 car 方法的方法,这些方法可以在 Wheel.cpp 中定义,Wheel.cpp 现在可以包含 Car.h 而不会导致循环。

关于c++ - C++ 中的前向声明是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4757565/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com