Han*_*lil 6 c++ forward-declaration
正如这个答案所暗示的那样,我知道允许在函数声明中使用不完整类型作为返回值.所以我写了下面的代码:
Obj.h
class Obj {
int x;
};
Run Code Online (Sandbox Code Playgroud)
FH
class Obj;
Obj f();
Run Code Online (Sandbox Code Playgroud)
f.cpp
#include "Obj.h"
Obj f() {
return Obj();
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "f.h"
int main() {
f();
return 0;
};
Run Code Online (Sandbox Code Playgroud)
使用以下编译器编译此代码:
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
使用以下编译命令:
g++ *.cpp
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
main.cpp: In function 'int main()':
main.cpp:4:7: error: invalid use of incomplete type 'class Obj'
f();
^
f.h:1:7: error: forward declaration of 'class Obj'
class Obj;
^
Run Code Online (Sandbox Code Playgroud)
因此编译器不允许在函数声明中使用不完整类型作为返回值.解释是什么?
正如你自己所说的那样"允许在函数声明中使用不完整类型作为返回值".这正是编译器允许你做的事情.您在非定义功能成功地使用一个不完整的返回类型声明 -你的声明f中f.h编译没有任何问题.
但这就是你被允许做的一切.这绝不会改变以下事实:
在您的代码中,main()您尝试调用以不完整返回类型声明的函数.因此错误.
5.2.2函数调用[expr.call]
10如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对象类型的右值引用,则为xvalue,否则为prvalue.
11如果函数调用是对象类型的prvalue:
- 如果函数调用是 - decltype-specifier的操作数或 - 作为decltype-specifier的操作数的逗号运算符的右操作数,则不为prvalue引入临时对象.prvalue的类型可能不完整.[...]
- 否则,prvalue的类型应完整.
换句话说,你被允许的是用不完整的返回类型引入你的函数的早期前向声明.但是当你定义该函数或调用它时,你应该完成返回类型.
正如您所看到的,并非所有不完整的类型都是允许的。事实上,规则是函数可以返回不完整类型的指针或引用。原因是在调用时,编译器必须能够生成代码来处理返回的对象。当没有有关对象内容的信息时,编译器无法生成代码。例如,假设Obj有一个不平凡的析构函数;如果编译器不知道这一点,它就无法生成代码来销毁该对象。当返回类型是指针或引用时,编译器拥有所需的所有信息:指针和引用通常不依赖于目标对象的详细信息。
| 归档时间: |
|
| 查看次数: |
2296 次 |
| 最近记录: |