编程语言
首页 > 编程语言> > Forward declaration in C++ (C++的前置声明)

Forward declaration in C++ (C++的前置声明)

作者:互联网

 

前置声明其实只是一个普通声明,当声明的种类从一个变量变成了一个类,那就变成前置声明,所以前置声明这个叫法并不合适。 所以理解前置声明的时候,当成普通声明就好。

我对声明的理解是:声明就是让编译器(Compiler)相信这个变量是存在的,至于是否真的存在,存在哪里,以何种形式存在,编译器不会去追究了(它是如此信任你)。编译之后到了链接(Link)阶段,连接器(Linker)会在其他对象文件(.obj)里面寻找这个声明(Declaration)的定义(Definition)。当链接器找不到定义,或者找到不止一个定义时它就会报错啦(LNK in Visual Studio)。

所以,按照这样的说法看来,前置声明可以节约编译时间(因为#include 其实就是把这个包含过来的文件以纯文本的形式复制粘贴进来)。

但需要注意的是,前置声明并不能代替#include,因为前置声明是不完整类型(Incomplete type), 编译器只知道这个类型存在,但不知道这个类型的大小(size),成员(members)或者方法(methods)(这就是为什么它被叫做非完整类型)。

以下是一些总结

你能对非完整类型(Incomplete type)做:

 1 class X; // This is a forward declaration 

 1 // 声明一个非完整类型的成员指针或者引用(reference)
 2 class Foo {
 3     X *p;
 4     X &r;
 5 }
 6 
 7 // 声明一个以非完整类型为参数,或者返回非完整类型的函数
 8 void f1(X);
 9 X f2();
10 
11 // 定义以非完整类型为参数或者返回非完整类型指针,引用的函数 (但是不能用它的成员)
12 void f3(X*, X&) {}
13 X& f4() {}
14 X* f5() {}

你不能做的:

 1 // 用作基类
 2 class Foo : X {}; // 编译错误
 3 
 4 // 声明一个成员
 5 class Foo {
 6     X m; // 编译错误
 7 }
 8 
 9 // 定义返回或者以它为参数的函数
10 void f1(X x) {}
11 X f2()          {} // 均为编译错误
12 
13 // 使用它的成员方法(实际上是对它取消引用(dereference))
14 class Foo {
15     X *m;
16     void method()
17     {
18         m->someMethod();
19         int i = m->someField;
20     }
21 }; //编译错误

 引用:

https://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration

https://stackoverflow.com/questions/3632818/forward-declaration-vs-include

https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration/1410632#1410632

https://stackoverflow.com/questions/4757565/what-are-forward-declarations-in-c

标签:编译,前置,C++,类型,declaration,Forward,声明,class
来源: https://www.cnblogs.com/alexxql/p/15957980.html