Что означает инстанцировать объекта с помощью фигурных скобок в C++?

PowerShell также запускает собственные команды непосредственно из командной строки PowerShell, что означает, что ваша команда

setup.exe -inputFile C:\my_installer_input.txt

должна работать непосредственно из командной строки PowerShell.

Если вы выполняете на удаленном компьютере, вы можете запустить его с помощью Invoke-Command, как показано ниже.

Invoke-Command -Session $session -ScriptBlock { <YOUR CODE HERE> }

или

Invoke-Command -ComputerName <remote-computername> -ScriptBlock { <YOUR CODE HERE> }
9
задан 21 April 2009 в 23:08
поделиться

7 ответов

It's not calling the default ctor, as others have written. Conceptually it's the same, but in practice, you'll find no function call in the assembly code.

Instead, the members remain uninitialized; you're initializing them with the curly-brace construct.

Interestingly enough, this:

PhoneNumber homePhone = {858, 555, 1234};

Results in this assembly (GCC 4.0.1, -O0):

movl  $858, -20(%ebp)
movl  $555, -16(%ebp)
movl  $1234, -12(%ebp)

Not many surprises there. The assembly is inline the function containing the above C++ statement. The values (starting with $) are moved (movl) into offsets into the stack (ebp register). They're negative because the memory locations for the struct members precede the initialization code.

If you don't fully initialize the struct, i.e. leave out some members like so:

PhoneNumber homePhone = {858, 555};

... then I get the following assembly code:

movl  $0, -20(%ebp)
movl  $0, -16(%ebp)
movl  $0, -12(%ebp)
movl  $858, -20(%ebp)
movl  $555, -16(%ebp)

Seems as if the compiler then actually does something very similar to calling the default constructor, followed by assignment. But again, this is inline in the calling function, not a function call.

If on the other hand you define a default constructor that initializes the members, to the given values, like so:

struct PhoneNumber {
  PhoneNumber()
    : areaCode(858)
    , prefix(555)
    , suffix(1234)
  {
  }

  int areaCode;
  int prefix;
  int suffix;
};

PhoneNumber homePhone;

Then you get assembly code that actually calls a function, and initializes the data members via a pointer to the struct:

movl  8(%ebp), %eax
movl  $858, (%eax)
movl  8(%ebp), %eax
movl  $555, 4(%eax)
movl  8(%ebp), %eax
movl  $1234, 8(%eax)

Each line that goes movl 8(%ebp), %eax sets the pointer value (eax register) to the beginning of the struct's data. In the other lines, eax is used directly, with an offset of 4 and an offset of 8, similar to the direct stack addressing in the previous two examples.

Of course all of this is specific to the compiler implementation, but I'd be surprised if other compilers did something extraordinarily different.

3
ответ дан 4 December 2019 в 19:36
поделиться

The members are actually copy-initialized. The default constructor for each one is not called and no operator= is involved contrary to what some other answers suggest. It can be shown by a software called geordi - alternatively by reading through the Standard. I'll show the "fun" way using that software. It has got a class tracked::B that can show us when constructors/copy-constructors or destructors/copy assignment operators are called. The output it shows is (TRACK limits tracking to the statement following it):

B1*(B0) B1~

I used this code

struct T { tracked::B b; }; int main() { tracked::B b; TRACK T t = { b };  }

As you see, the second B object - which is the member within the local variable t, is copy initialized from the other object b. Of course, no assignment operator is activated. You can read about it in 12.6.1/2 in the Standard, if you wish.

The same, by the way, is true with arrays (which are likewise aggregates). Many people believe that objects that are member of arrays must have a type that has a default constructor. But that's not true. They can just be copy initialized by another object of their type and it will work fine.

All other elements that were not explicitly initialized in the aggregate are value initialized. Value-initialization is a mixture of default initialization and zero initialization. Actually, if a member has a type that has a user declared constructor, then that constructor is invoked. If it has a type that does not have a user declared constructor, then each member of it is value initialized. For built-in types (int, bool, pointers, ...) a value initialization is the same as zero initialization (that means that such a variable will become zero). The following will initialize each member to zero - except the first (a), which will be one:

struct T { int a, b, c; }; int main() { T t = { 1 }; }

Those initialization rules are scary, indeed - especially because the 2003 revision of C++ introduced that value initialization. It wasn't part of the Standard as of 1998. If you are more interested in those brace enclosed initializations, you can read How to initialize nested structures in C++?.

4
ответ дан 4 December 2019 в 19:36
поделиться

Это фактически вызывает ctor по умолчанию; происходит то, что структура распределяется, и каждому значению присваивается значение по умолчанию "=".

1
ответ дан 4 December 2019 в 19:36
поделиться

Структура в C ++ похожа на класс. По умолчанию вызывается конструктор. После этого каждое поле копируется с его оператором присваивания.

2
ответ дан 4 December 2019 в 19:36
поделиться

Однако у меня есть сотни таких Экземпляры PhoneNumber уже созданы только с 3 полями (ххх, ххх, хххх). Так что я не хочу проходить и изменить КАЖДЫЙ единственный экземпляр мой объект PhoneNumber, который уже определены.

Нет проблем, вы просто вызываете update-instance-for-redefined-class и ..... er, nevermind. Перейдите к пометке "бесполезно"

0
ответ дан 4 December 2019 в 19:36
поделиться

Инициализация - это, по крайней мере, для меня, одна из самых сложных частей стандарта C ++. Используемый синтаксис: Aggregate x = {1, 2, 3, 4}; определяет инициализацию агрегатного типа с первыми четырьмя членами, которым присвоены значения 1, 2, 3 и 4.

Как примечание к вашему конкретному случаю (структура выросла с 3 до 4 элементов), поля, отсутствующие в списке инициализации между фигурными скобками, будут иметь значение initialized , что, в частности, для скалярных типов эквивалентно к нулевой инициализации , что само по себе совпадает с присвоением 0. Таким образом, ваш четвертый элемент будет инициализирован равным 0.

Ссылки

Все это определено в стандарте C ++, глава 8.5, и более точно в 8.5.1 Агрегаты. Агрегаты не будут инициализированы каким-либо неявно объявленным конструктором по умолчанию. Если вы используете синтаксис выше, вы просите компилятор инициализировать заданные поля указанными значениями. Любое дополнительное поле в агрегате должно быть , значение инициализировано

. Теперь, значение инициализации определяется как вызов определяемого пользователем конструктора по умолчанию, если тип является классом с таким конструктором. Если это массив или класс без объединения, без определяемого пользователем конструктора, то каждый из атрибутов-членов будет инициализирован значением . В противном случае объект будет инициализирован нулями , который затем снова определяется как ...

Инициализация нуля определяется как установка значения 0 для скалярных типов. Для классов каждый член данных класса и базовый класс будут инициализированными нулями .

2
ответ дан 4 December 2019 в 19:36
поделиться

Конструктор вашего типа не задействован, поэтому необходимо изменить существующий трехпараметрический синтаксис на сайте инициализации агрегата.

Если только не семантика вашего нового поля, т.е. что этот новый тип поля «учитывает нулевое значение при проектировании» (идиома, рекомендованная программированием на .NET, Brad и Co и т. д. в бессмысленных руководящих принципах проектирования), вы

не можете:

a) предоставить что-то более значимое в качестве параметров по умолчанию для C ++ если с какой-то магией был задействован какой-то метод (скоро / по умолчанию параметры будут доступны в магазине C # для массового рынка рядом с сетью бакалейных лавок 4). 0 и для старого COM)

также нельзя

b) следовать шаблону, подобному C #, при проектировании типов значений с недопустимыми маркерами значений в виде 0 (что в данном случае, вероятно, очень плохо и в целом плохо, если у вас нет контроль над константами - то, что библиотеки уровня источника делают очень хорошо, и все-JavaTM MS-подобные фреймворки сосут).

Короче говоря, если 0 - допустимое значение, вы набиты и что-то, что большинство авторов компиляторов сочли полезным перед любым управляемый стиль или идиома когда-либо существовали; но это не обязательно правильно.

В любом случае, ваш лучший шанс - не C ++ или C #. Это генерация кода, т.е. более либеральное метапрограммирование, чем современный C ++, запускает «шаблонизацию». Вы найдете, что это похоже на аннотацию массива JSON и может использовать либо дух, либо (я бы посоветовал) прокрутить ваши собственные утилиты. Это помогает в долгосрочной перспективе, и в конечном итоге вы

[подобные проблемы распространены во многих языках, это недостаток всех языков в стиле C (C, C ++, Java, C #, вы называете это); очень похож на хакерские массивы массивов, необходимые для любого типа междоменной или семантической работы ввода-вывода и очевидные даже в веб-технологиях, таких как SOAP и т. д. новые переменные биты C ++ 0x здесь тоже мало помогают, но, видимо, могут увеличьте время компиляции, если вы решите поиграть с некоторыми шаблонами Кому интересно :)]

0
ответ дан 4 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: