C ++不允许创建void
类型的对象。那是为什么?
答案 0 :(得分:13)
请考虑以下代码。
class Foo
{
// etc ...
};
int main()
{
// Declaring an object...
Foo foo;
// foo has been created.
// etc ...
return 0; // When function returns, foo will be destroyed.
}
为了知道如何实际创建对象,编译器必须知道类型。非正式地,您可以将void
视为表示缺少类型的“类型”。因此,编译器可能不知道如何创建void
对象。您无法创建不知道如何创建的对象。
int main()
{
void v; // "I don't know how to create this!"
}
话虽如此,还有其他情况void
有意义。例如,void
函数没有返回值。您不能为不存在的事物(如返回值)指定类型。
您还可以指向void
或void*
。与普通void
不同,void*
有效且简单地表示“指向某种未知类型的对象的指针”。显然你不能用void*
做很多事情,直到你把它变成一个实际的已知类型(当然假设演员是安全的)。
答案 1 :(得分:12)
这是因为void
是一个不完整的类型。
从标准文档中,不完整类型 3.9 表明,
5
已声明但未定义的类,或未知大小或元素类型不完整的数组,是 未完全定义的对象类型.38)不完全定义的对象类型和 void类型是不完整类型(3.9.1)。 对象不应被定义为具有不完整的类型。38)未完全定义的对象类型的实例的大小和布局未知。
由于void
是一个不完整的类型,因此无法确定其大小和布局,因此无法定义。
答案 2 :(得分:3)
void
是一个占位符,表示没有任何类型的对象。
历史上,C在函数声明ala return_type f();
中使用了一个空参数列表,以允许调用f()
,但是在每个调用站点都指定了许多和任何类型的参数,而{{1明确没有预期或允许的参数。即C准备信任程序员正确获取参数的数量和类型,任何错误都可能破坏数据和/或使程序崩溃。
如果return_type f(void);
没有建立整体“类型变量|函数”序列,那么语言中也会有一些歧义,这是语言语法的一部分。例如:
void
在表示内存区域的某种解释的意义上,它本身并不是一种数据类型,如int,float,char等,类,联合等都可以。
对于f(); // declaration of a function that returns nothing?
// OR a function call?
,它表示无法深入了解所包含地址的内存内容,因此在取消引用指针之前的某个时刻,它必须转换为特定类型,以反映该内存中数据的按位布局地址。然后,编译器可以根据当时已知的数据类型解释和操作该位布局。
答案 3 :(得分:3)
作为旁注,您可以创建void
类型的临时文件:
void f()
{
return void();
}
void g()
{
return cout << "hi", f();
}
这是有效的代码。它在通用代码中非常有用。它甚至被认为允许在某些地方使用内置类型(包括void):
template<class T> class A : T { };
A<string> x; // works
A<int> y; // error, but could be usefull
A<void> z; // error, but could be usefull.
答案 4 :(得分:2)
在C++
中,每件事都与对象有关。所以,当说 -
void variable ;
平台必须为variable
分配多少字节而不知道它的类型。是int
还是float
还是double
还是其他任何原始类型。所以,这是不允许的。
答案 5 :(得分:1)
void表示Nothing。即使您正在使用Void类型创建函数,我们也不需要返回值。这里也没有声明类型为void的对象。
答案 6 :(得分:0)
简单来说,这是一个任意的决定,来自C。
在C中,所有类型(void
除外)都用于携带值。根据定义,void
没有任何价值。因此语言设计者决定不可能实例化它。
C ++在C之后,决定仍然存在。否则,有必要定义存储大小(可能与bool
相同)。
在C ++中它确实很烦人,特别是因为模板类/函数需要特殊的外壳,但是没有人认为它值得修改,因为它可以专门化void
的模板,因此它不会阻塞