Forward declaration in C++ (C++的前置声明)
2022/3/3 9:15:21
本文主要是介绍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
这篇关于Forward declaration in C++ (C++的前置声明)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享