Сначала мы возьмем абстрактный болотный UDT (пользовательский тип):
struct foo { virtual void f() = 0; }; // normal abstract type
foo obj;
// error: cannot declare variable 'obj' to be of abstract type 'foo'
Давайте также вспомним, что мы можем создать экземпляр UDT одновременно с тем, как мы его определили:
struct foo { foo() { cout << "!"; } }; // just a definition
struct foo { foo() { cout << "!"; } } instance; // so much more
// Output: "!"
Давайте объединим примеры и напомним, что мы можем определить UDT, у которого нет имени :
struct { virtual void f() = 0; } instance; // unnamed abstract type
// error: cannot declare variable 'instance' to be of abstract type '<anonymous struct>'
Нам больше не нужны доказательства анонимного UDT, поэтому мы можем потерять чисто виртуальную функцию. Также переименовывая instance
в foo
, у нас осталось:
struct {} foo;
Как приблизиться.
Теперь, что, если этот анонимный UDT возникнет из некоторой базы?
struct bar {}; // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof
Наконец, C ++ 11 представляет расширенные инициализаторы , так что мы можем делать такие вещи, как это:
int x{0};
А это:
int x{};
И, наконец, это:
struct : bar {} foo {};
Это безымянная структура, полученная из bar, которая создается как foo с пустым инициализатором.