为什么前向声明在c++中是必要的
编译器希望确保您没有犯拼写错误或将错误数量的参数传递给函数。因此,它坚持在使用之前首先看到'add'(或任何其他类型、类或函数)的声明。
This really just allows the compiler to do a better job of validating the code and allows it to tidy up loose ends so it can produce a neat-looking object file. If you didn't have to forward declare things, the compiler would produce an object file that would have to contain information about all the possible guesses as to what the function add might be. And the linker would have to contain very clever logic to try and work out which add you actually intended to call, when the add function may live in a different object file the linker is joining with the one that uses add to produce a dll or exe. It's possible that the linker may get the wrong add. Say you wanted to use int add(int a, float b), but accidentally forgot to write it, but the linker found an already existing int add(int a, int b) and thought that was the right one and used that instead. Your code would compile, but wouldn't be doing what you expected.
因此,为了保持显式并避免猜测,编译器坚持在使用之前声明所有内容。
声明和定义的区别
顺便说一句,了解声明和定义之间的区别很重要。声明只是给出了足够的代码来显示一些东西的样子,所以对于一个函数,这是返回类型、调用约定、方法名、参数及其类型。但是,该方法的代码不是必需的。对于定义,您需要声明,然后还需要函数的代码。
前向声明如何能够显著减少构建时间
You can get the declaration of a function into your current .cpp or .h file by #includ'ing the header that already contains a declaration of the function. However, this can slow down your compile, especially if you #include a header into a .h instead of .cpp of your program, as everything that #includes the .h you're writing would end up #include'ing all the headers you wrote #includes for too. Suddenly, the compiler has #included pages and pages of code that it needs to compile even when you only wanted to use one or two functions. To avoid this, you can use a forward-declaration and just type the declaration of the function yourself at the top of the file. If you're only using a few functions, this can really make your compiles quicker compared to always #including the header. For really large projects, the difference could be an hour or more of compile time bought down to a few minutes.
打破两个定义相互使用的循环引用
Additionally, forward-declarations can help you break cycles. This is where two functions both try to use each other. When this happens (and it is a perfectly valid thing to do), you may #include one header file, but that header file tries to #include the header file you're currently writing... which then #includes the other header, which #includes the one you're writing. You're stuck in a chicken and egg situation with each header file trying to re #include the other. To solve this, you can forward-declare the parts you need in one of the files and leave the #include out of that file.
Eg:
文件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,而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而不会引起循环。