我正在寻找当我被允许在另一个类的头文件中做类的前向声明的定义:
我是否可以为基类,为作为成员持有的类,为通过引用传递给成员函数的类,等等这样做?
我正在寻找当我被允许在另一个类的头文件中做类的前向声明的定义:
我是否可以为基类,为作为成员持有的类,为通过引用传递给成员函数的类,等等这样做?
当前回答
在文件中,只使用指向类的指针或引用。指针/引用不能调用任何成员/成员函数。
//前向声明
我们可以声明类型为Foo*或Foo&的数据成员。
我们可以声明(但不能定义)带有Foo类型的参数和/或返回值的函数。
可以声明类型为Foo的静态数据成员。这是因为静态数据成员定义在类定义之外。
其他回答
只要不需要定义(比如指针和引用),就可以使用前向声明。这就是为什么大多数情况下你会在头文件中看到它们,而实现文件通常会为适当的定义拉出头文件。
假定前向声明将使代码得到编译(obj被创建)。但是,除非找到定义,否则链接(exe创建)将不会成功。
除了指向不完整类型的指针和引用外,还可以声明函数原型来指定不完整类型的参数和/或返回值。但是,不能定义具有不完整形参或返回类型的函数,除非它是指针或引用。
例子:
struct X; // Forward declaration of X
void f1(X* px) {} // Legal: can always use a pointer
void f2(X& x) {} // Legal: can always use a reference
X f3(int); // Legal: return value in function prototype
void f4(X); // Legal: parameter in function prototype
void f5(X) {} // ILLEGAL: *definitions* require complete types
我只是想补充一件重要的事情,你可以用Luc Touraille的回答中没有提到的转发类来做。
使用不完整类型可以做什么:
定义接受/返回的函数或方法 指向不完整类型的指针/引用并转发该指针/引用 到另一个函数。
void f6(X*) {}
void f7(X&) {}
void f8(X* x_ptr, X& x_ref) { f6(x_ptr); f7(x_ref); }
模块可以将前向声明类的对象传递给另一个模块。
我遵循的一般规则是除非必须,否则不包含任何头文件。所以除非我将一个类的对象存储为我的类的成员变量,否则我不会包括它,我只会使用前向声明。