Почему нельзя создать объекты типа void в C ++? - PullRequest
14 голосов
/ 25 марта 2011

C ++ не позволяет создавать объекты типа void.Почему это так?

Ответы [ 7 ]

13 голосов
/ 25 марта 2011

Рассмотрите код ниже.

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*, пока не приведете его к фактическому, известному типу (конечно, при условии, что приведение безопасно).

12 голосов
/ 25 марта 2011

Это потому, что void является неполным типом.

Из стандартных документов, неполные типы 3.9 гласит, что

5 Класс, который был объявлен, но не определен, или массив неизвестного размера или неполного типа элемента, является не полностью определенный тип объекта.38) Не полностью определенные типы объектов и типы void являются неполными типами (3.9.1). Объекты не должны иметь неполный тип.

38) Размер и компоновка экземпляра не полностью определенного типа объекта неизвестны.

Поскольку void является неполным типом, его размер и расположение не могут быть определены и, следовательно, не могут быть определены.

3 голосов
/ 25 марта 2011

Как примечание, вы можете создать временное устройство типа 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.
3 голосов
/ 25 марта 2011

void является заполнителем, указывающим никаких объектов любого типа не ожидается.

Как спецификация аргумента функции

Исторически C использовал пустой список аргументов в объявлении функции ala return_type f();, чтобы разрешить вызов f() с любым количеством и аргументами любого типа, указанными на каждом сайте вызова, тогда как return_type f(void); сделал его явным нет аргументы были ожидаемы или разрешены. То есть C был готов доверить программисту правильное определение количества и типов аргументов, при этом любая ошибка может повредить данные и / или привести к сбою программы.

как тип возвращаемого значения функции

В языке также могут быть некоторые неясности, если бы void не было, чтобы установить общую последовательность «переменная типа | функция», которая является частью грамматики языка. Например:

f();  // declaration of a function that returns nothing?
      // OR a function call?

Сравнение с другими типами

Это на самом деле не сам тип данных в том смысле, что он представляет собой некоторую интерпретацию области памяти, как это делают int, float, char и т. Д., Классы, объединения и т. Д.

указатели на аннулирование

Для void* это указывает на потерю понимания содержимого памяти по содержащемуся адресу, так что когда-то перед разыменованием указателя он должен быть приведен к определенному типу, отражающему побитовое расположение данных по этому адресу памяти. Затем компилятор может интерпретировать эту битовую разметку и работать с ней в соответствии с известным тогда типом данных.

2 голосов
/ 25 марта 2011

В C++ каждая вещь может быть связана с объектом. Итак, когда сказал -

void variable ;  

Сколько байт должна выделить платформа для variable, не зная, что это за тип. Это int или float или double или любой другой примитивный тип. Итак, это не разрешено.

1 голос
/ 25 марта 2011

void представляет Nothing. Даже если вы создаете функцию с типом Void, нам не нужно возвращать значение. Например, здесь Здесь также не объявляется объект типа void.

0 голосов
/ 25 марта 2011

Это просто произвольное решение от С.

В C все типы (кроме void) используются для переноса значения. void по определению не имеет никакого значения. Поэтому разработчики языка решили, что создать его экземпляр будет невозможно.

C ++ берет после C, а решение осталось. В противном случае было бы необходимо определить размер хранилища (вероятно, такой же, как bool).

В C ++ это действительно раздражает, особенно из-за специального корпуса, необходимого для шаблонных классов / функций, но никто не посчитал его достойным модификации, поскольку можно специализировать шаблоны для void и, следовательно, он не блокируется. 1011 *

...