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