Что может быть создано? - PullRequest
       39

Что может быть создано?

5 голосов
/ 17 ноября 2009

Какие типы в C ++ могут быть созданы?

Я знаю, что каждый из них непосредственно создает отдельный экземпляр Foo:

Foo bar;
Foo *bizz = new Foo();

Однако как быть со встроенными типами? Создает ли следующее два экземпляра int, или это неправильное слово для использования, а память просто выделяется?

int bar2;
int *bizz2 = new int;

Как насчет указателей? Вышеприведенный пример создал экземпляр int * или просто выделил память для int *?

Будет ли использование таких литералов, как 42 или 3.14, также создавать экземпляр?

Я видел аргумент, что если вы не можете создать подкласс типа, он не является классом, и если это не класс, его нельзя создать. Это правда?

Ответы [ 5 ]

4 голосов
/ 17 ноября 2009

Пока мы говорим о C ++, единственным авторитетным источником является стандарт ISO. Это никогда не использует слово «создание экземпляров» для чего-либо, кроме шаблонов классов и функций.

Однако оно использует слово «экземпляр». Например:

Экземпляр каждого объекта с автоматической продолжительностью хранения (3.7.2) связан с каждой записью в его блоке.

Обратите внимание, что на языке C ++ значение int l также является "объектом":

Конструкции в программе на C ++ создают, уничтожают, обращаются к объектам и обращаются к ним, а также управляют ими. Объект является областью хранения.

Поскольку new четко создает области хранения, все, что создано таким образом, является объектом, и, следуя прецеденту спецификации, можно назвать экземпляром.

3 голосов
/ 17 ноября 2009

Насколько я могу судить, вы действительно просто спрашиваете здесь о терминологии. Единственное реальное различие, сделанное стандартом C ++, - это типы POD и не POD-типы, где не-POD-типы имеют такие функции, как определяемые пользователем конструкторы, функции-члены, частные переменные и т. Д., А типы POD - нет. Основные типы, такие как int и float, являются, конечно, POD, как и массивы POD и C-структуры POD.

Помимо (и перекрытия) C ++, концепция «экземпляра» в объектно-ориентированном программировании обычно относится к выделению пространства для объекта в памяти, а затем к его инициализации с помощью конструктора. Делается ли это в стеке, в куче или в каком-либо другом месте памяти в этом отношении, в значительной степени не имеет значения.

Однако стандарт C ++, похоже, рассматривает все типы данных как «объекты». Например, в 3.9 написано:

"Объект представления типа T последовательность N беззнаковых символов объекты, захваченные объектом типа T, где N равно sizeof (T) ... "

Таким образом, по сути, единственное различие, сделанное самим стандартом C ++, это POD и не POD.

2 голосов
/ 17 ноября 2009

Понятие «экземпляр» не является чем-то действительно присущим C ++ - в основном у вас есть «вещи, которые имеют конструктор, и вещи, которые не имеют».

Итак, все типы имеют размер, например int обычно составляет 4 байта, структура с парой целых чисел будет 8 и так далее. Теперь наденьте конструктор на эту структуру, и он начнет выглядеть (и вести себя) как класс. Более конкретно:

int foo; // <-- 4 bytes, no constructor

struct Foo
{
  int foo;
  int bar;
}; // <-- 8 bytes, no constructor

struct Foo
{
  Foo() : foo(0), bar(0) {}
  int foo;
  int bar;
}; // <-- 8 bytes, with constructor

Теперь вы можете использовать любой из этих типов в стеке или в куче . Когда вы создаете что-то в стеке , например, "int foo;" выше, исчезает после того, как исчезает его область действия (например, в конце вызова функции). Если вы создаете что-то с помощью «new», оно попадает в кучу 1013 * и занимает свое место в памяти, пока вы не вызовете delete . В обоих случаях конструктор, если он есть, будет вызываться при создании экземпляра.

2 голосов
/ 17 ноября 2009

в C ++ «экземпляр» и «экземпляр» связаны только с классами

обратите внимание, однако, что это также английские слова, которые могут иметь разговорное значение. «указатель» - это, безусловно, класс вещей в английском языке, и указатель, безусловно, является экземпляром этого класса

но в c ++ говорят, что «указатель» не является классом, а указатель не является экземпляром класса

см. Также - сколько ангелов на булавочных головках

1 голос
/ 17 ноября 2009

Это необычно делать "new int", но это разрешено. Вы даже можете передать 0 или 1 аргумент в конструктор. Я не уверен, что "new int ()" означает, что он инициализирован 0 (я бы предположил, да) в отличие от "new int".

Когда вы определяете значение в стеке, оно обычно не называется «распределением памяти» (хотя теоретически оно получает память в стеке, возможно, что значение живет только в регистрах ЦП).

Литералы не обязательно получают адрес в памяти программы; Команды CPU могут напрямую кодировать данные (например, помещать 42 в регистр B). Вероятно, произвольные константы с плавающей точкой имеют адрес.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...