С++ не позволяет создавать объекты типа void
. Почему это?
Почему в С++ не могут быть созданы объекты типа void?
Ответ 1
Рассмотрим приведенный ниже код.
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*
, пока не нарисуете его на фактический, известный тип (при условии, что бросок безопасен, конечно).
Ответ 2
Это потому, что void
является неполным типом.
Из стандартных документов. неполные типы 3.9 утверждают, что
5
Класс, который был объявлен, но не определен, или массив неизвестного размера или неполного типа элемента, является неполностью определенный тип объекта. 38) Неполно определенные типы объектов и типы пустот являются неполными типами (3.9.1). Объекты не должны быть определены как неполные.38) Размер и макет экземпляра не полностью определенного типа объекта неизвестны.
Так как void
является неполным типом, размер и макет не могут быть определены и, следовательно, не могут быть определены.
Ответ 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
void
- это заполнитель, указывающий не ожидается объект любого типа.
В качестве спецификации аргумента функции
Исторически C использовал пустой список аргументов в объявлении функции ala return_type f();
, чтобы разрешить вызов f()
с тем же - многие и любые аргументы типа были указаны на каждом сайте вызова, тогда как return_type f(void);
сделал его явным аргументы ожидались или допускались. То есть C был готов доверять программисту, чтобы получить правильное количество и типы аргументов, с любой ошибкой, которая может испортить данные и/или сбой программы.
В качестве функции типа возврата
Там также могут быть некоторые двусмысленности в языке, если void
не было, чтобы установить общую последовательность "type variable | function", которая является частью грамматики языка. Например:
f(); // declaration of a function that returns nothing?
// OR a function call?
Сравнение с другими типами
Это не сам тип данных в смысле представления некоторой интерпретации области памяти, как int, float, char и т.д., классы, союзы и т.д. все это делают.
указатели на void
Для void*
это указывает на потерю понимания содержимого памяти на указанном адресе, так что когда-то до разыменования указателя он должен быть выбран конкретным типом, отражающим побитовое расположение данных по этому адресу памяти. Затем компилятор может интерпретировать и работать с этой компоновкой бит в соответствии с известным тогда типом данных.
Ответ 5
В C++
каждая вещь может быть связана с объектом. Итак, когда сказано -
void variable ;
Сколько байтов должно быть распределено платформой для variable
без знания этого типа. Это int
или float
или double
или любой другой примитивный тип. Таким образом, это запрещено.
Ответ 6
void представляет Nothing. Даже если вы создаете функцию с типом Void, нам не нужно возвращать значение. Так же, как здесь, также не объявлен объект типа void.
Ответ 7
Это просто произвольное решение от C.
В C все типы (кроме void
) используются для переноса значения. void
, по определению, не имеет значения. Поэтому разработчики языка решили, что было бы невозможно создать его экземпляр.
С++ принимает после C, и решение остается. В противном случае было бы необходимо определить размер хранилища (вероятно, такой же, как bool
).
В С++ это действительно раздражает, особенно из-за специальной оболочки, необходимой для шаблонных классов/функций, но никто не считает ее достойной модификации, так как можно специализировать шаблоны для void
и, следовательно, не блокировать.