Спочатку ми візьмемо базовий абстрактний UDT (User-Defined Type):
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;
Наближаючись.
А що робити, якщо ця анонімна УДТ отримана з якоїсь бази?
struct bar {}; // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof
Нарешті, C ++ 11 представляє розширені ініціалізатори , щоб ми могли робити такі плутані речі:
int x{0};
І це:
int x{};
І, нарешті, ось що:
struct : bar {} foo {};
Це неназвана структура, що походить від рядка, інстанціюється як foo з порожнім ініціалізатором.