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

Coa*_*ial 4 c++ qt

我对这行代码感到有点困惑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
Run Code Online (Sandbox Code Playgroud)

Ste*_*hen 6

它被称为前向声明.维基百科说如下:

在C++中,如果只需要使用指向该类的指针类型,则可以向前声明类(因为所有对象指针的大小都相同,这就是编译器所关心的).这在类定义中特别有用,例如,如果一个类包含一个指向另一个类的指针的成员; 为了避免循环引用(即该类可能还包含一个指向该类的指针的成员),我们只需转发声明类.

如果需要使用实际的类类型,则前向声明类是不够的,例如,如果您的类型是直接类型的成员(不是指针),或者您需要将其用作基类,或者如果您需要在方法中使用类的方法.

  • @Coaxial是创建指向引用类的指针并避免额外依赖的最低要求 (2认同)

Bas*_*tch 6

它是一个前向声明,它可以TreeItem在某些内部结构中指向-s.

当你有共同递归的定义时,显然需要前向声明; 例如,struct foo包含指向struct bar其中包含指针的指针struct foo等等...您甚至可以声明这些struct-s并在不同的翻译单元中定义对它们进行操作的函数.

在C和C++中,通常的做法是转发声明一些struct(或class)并拥有指向它的变量,并声明(并且可能调用)处理这些指针的函数.

当然,其他一些文件(或翻译单元)会声明这种不透明的数据结构并在其上实现操作.

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

顺便说一句,在标准C中通常有一个非常常见的例子.FILE来自的类型<stdio.h>通常是一些不透明的(或者至少被许多头文件很好地隐藏)struct(你显然不需要知道它的内部结构)使用<stdio.h>功能像fprintf)

在你的(Qt)的情况下,你不想#include <QTreeItem>- 或者class TreeItem在这个QTreeModel头文件中声明的头文件.如果你这样做,那将增加一个额外的头依赖项(你不需要TreeModelTreeItem实现发生变化时重新编译代码!)并且会减慢编译速度.

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