Инициализация переменной (указатель и значение) - PullRequest
4 голосов
/ 01 ноября 2011
Foo f1 = Foo();      // (1) Ok
Foo f2 = Foo;        // (2) Compiler error

Foo *p1 = new Foo(); // (3) Ok
Foo *p2 = new Foo;   // (4) Ok. Why??

Мне было интересно, почему существует два способа инициализации указателей.Это выглядит немного противоречивым.Есть ли логическая причина, и если да, то что?Или, может быть, это какое-то наследие?И если да, то каково происхождение таких обозначений?

Ответы [ 3 ]

4 голосов
/ 01 ноября 2011

Это немного ... сложно, если не сказать больше.

При работе с объектами обе нотации эквивалентны. При работе с примитивными типами (такими как int) (3) будет инициализировать (заполнять нулями) значение, а (4) - нет (значение останется неопределенным).

Для автоматически размещаемых объектов это:

Foo f1;

Объявляет и инициализирует объект Foo, используя конструктор по умолчанию. Это:

Foo f2 = Foo();

Объявляет и инициализирует объект Foo, используя конструктор копирования, по существу копируя значение временного объекта (Foo()), который создается с помощью конструктора по умолчанию.

1 голос
/ 01 ноября 2011

Эквивалент 4 для ресурсов на основе области действия на самом деле просто

Foo f;

Унаследованная причина различий состоит в основном в том, что в C примитивные типы, такие как int, не были инициализированы по умолчаниюк чему-то полезному.C ++ унаследовал это поведение по причинам производительности - в то время.Конечно, теперь это тривиальное время процессора.В C ++ они ввели новый синтаксис, с помощью которого он всегда будет инициализироваться - скобки.

int i = int();

i всегда гарантированно равно 0.

int i;

Значениеi не определено.

Это то же самое, что и для указателя, только с некоторыми new:

int* i = new int(); // guaranteed 0
int* i = new int; // undefined
1 голос
/ 01 ноября 2011

Я даю вам, что это кажется нелогичным, но если вы думаете о возможных значениях, это имеет большой смысл.

Не зная, что может быть Foo, ни человек, ни компилятор (здесьчеловеческая перспектива более важна) сможет определить, является ли Foo f2 = Foo; а) созданием нового временного объекта Foo и копированием создания другого с ним или б) присвоением копии значения переменной Fooпостроенный объект (f2).Для нас это может показаться очевидным, потому что наше соглашение говорит нам, что Foo должен быть типом с заглавной буквы, но в целом это не так просто (опять же: это в основном относится к читателю-человеку, который не обязательно имеет весь источниккод запоминается).

Разница между (2) и (4) заключается в том, что для последнего допустима только одна интерпретация, поскольку new var (где var - переменная) не является допустимым выражением.

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