栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++中前置声明(前向声明)用法的思考

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++中前置声明(前向声明)用法的思考

前两天因为修改自己文章《个人对QT中的namespace Ui的理解》遇到前置声明的概念,很陌生就好奇的自己码了点代码,谁知编译报错,改来改去却百思不得其解。代码如下:

#include 
using namespace std;
class SayHi;

int main()
{
	SayHi * stu = new SayHi;
	cout<<"Hello!"< Say();
	return 0;
}

class SayHi
{
public:
	SayHi() {};
	void Say()
	{
		cout << "Hi" << endl;
	}
};

编译报错为:

1>  main.cpp
1>d:vs2015demo2demo2main.cpp(6): error C2512: “SayHi”: 没有合适的默认构造函数可用
1>d:vs2015demo2demo2main.cpp(8): error C2027: 使用了未定义类型“SayHi”
1>  d:vs2015demo2demo2main.cpp(3): note: 参见“SayHi”的声明
1>d:vs2015demo2demo2main.cpp(8): error C2227: “->Say”的左边必须指向类/结构/联合/泛型类型
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

 我对类前置声明的理解是:如果在一处使用到一未定义的类时,只需在使用该类之前声明一下即可。刚开始我没定义构造函数,指望系统自己添加不带参的构造函数,但报错。可明明我定义了不带参的构造函数啊,为什么还报故呢?并且如果我将类的定义放到主函数之前,再编译运行就very good!这说明我类的定义没有问题。故感觉不对,应该哪里理解的不对,赶紧查资料。综合几篇文章,我明白了:C++的类应当是先定义,然后使用。但在处理相对复杂的问题、考虑类的组合时,很可能遇到俩个类相互引用的情况(这种情况称为循环依赖),这时就可以使用前置声明来解决问题。使用前置引用声明虽然可以解决一些问题,但它并不是万能的。需要注意的是,尽管使用了前置引用声明,但是在提供一个完整的类声明之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。具体到我的这个例子,我错的地方是1、在未提供完整的类声明之前,在SayHi * stu = new SayHi这一句中用new SayHi来定义类的匿名对象并返回其指针给stu;2、SayHi类的对象未定义之前使用stu -> Say()。

C++的类可以进行前置声明。但是,仅仅进行前置声明而没有定义的类是不完整的,这样的类,只能用于定义指针、引用、以及用于函数形参的指针和引用。而不能定义对象(因为此时编译器只知道这是个类,还不知道这个类的大小有多大),也不能访问类的对象,任何形式的访问都不允许(因为此时根本不知道有些什么成员)。我的理解是,只有前置声明时,因为不能确定该类的数据结构和所占大小,所以无法提前分出一段内存空间预留给该类待定义后使用,故凡是涉及堆上内存分配(实例化对象、访问其对象的成员)的操作都是非法的。等到类正式定义以后,就可以以各种方式使用该类了。

前向声明的作用是:

1.不必在include头文件了,相对会省点编译时间。

2.方便的解决两种类类型互相使用的问题。针对接口编程常常会遇到这种互相使用类型的场景。

参考来源:

C++ 类的前向声明的用法 - 王陸 - 博客园 (cnblogs.com)

C++中类的前向声明的用法 - 飞翔雨 - 博客园 (cnblogs.com)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/630624.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号