放在其他类定义的头文件中时"class ClassName;"是什么意思?

What does "class ClassName;" mean when put in header file of other class definition?

本文关键字:ClassName class 是什么 意思 其他 定义 文件      更新时间:2023-10-16

我对这行代码class TreeItem;有点困惑。class TreeItem;定义在该文件中未包含的其他文件中。我必须在书中查一下这个问题,但我确信这个问题的答案很简单。

#ifndef TREEMODEL_H
#define TREEMODEL_H
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
class TreeItem; //here, what does this do??
//! [0]
class TreeModel : public QAbstractItemModel
{
   ...
public:
   ...
private:
   ...
};
//! [2]
#endif // TREEMODEL_H

这是一个正向声明,在一些内部结构等中启用指向TreeItem-s的指针非常有用。

当您有共同递归定义时,特别需要正向声明;例如,包含指向struct bar的指针的struct foo,其中包含指向struct foo的指针,等等。您甚至可以声明这些struct,并在不同的翻译单元中定义对其进行操作的函数

在C和C++中,通常的做法是前向声明一些struct(或class(,并将变量作为指向它的指针,并声明(并可能调用(处理这些指针的函数。

当然,其他一些文件(或翻译单元(会声明这种不透明的数据结构,并对其执行操作

这是实现抽象数据类型的常用方法。

顺便说一句,在标准C中通常有一个非常常见的例子。<stdio.h>中的FILE类型通常是一些不透明的(或者至少被许多头文件隐藏得很好(struct(而且使用fprintf<stdio.h>函数显然不需要知道它的内部(

在您(Qt(的情况下,您不希望在此QTreeModel头文件中使用#include <QTreeItem>或声明class TreeItem的任何头文件。如果这样做,将添加额外的头依赖项(当TreeItem实现发生更改时,不需要重新编译TreeModel代码!(,并且会减慢编译速度。

在较小的软件项目中,您可能只需要有一个单独的头文件,并在其中定义所有的struct

它被称为正向声明。维基百科上这样说:

在C++中,如果只需要使用指向该类类型的指针(因为所有对象指针都相同大小,而这正是编译器所关心的(。尤其是在类定义内部有用,例如,如果类包含成员它是指向另一个类的指针;避免循环引用(即。该类可能还包含一个成员,该成员是指向类(,我们只是转发声明这些类。

如果需要使用实际的类类型,例如,如果您有一个成员的类型为直接使用该类(而不是指针(,或者如果需要将其用作基类,或者如果需要在方法