Wie unterscheidet sich die Initialisierung von {} in einer Konstruktorinitialisierungsliste von der Initialisierung von() beim Initialisieren des Verweises auf abstrakte Typen? Nehmen Klasse Bar unten:Warum funktioniert C++ 11 geschweifte Klammerinitialisierung in der Konstruktorinitialisierungsliste nicht, wenn Parens initialisiert wird?
class AbstractBase
{
public:
AbstractBase() {}
virtual ~AbstractBase() = default;
virtual void ab() = 0;
};
class Foo : public AbstractBase
{
public:
Foo() {}
void ab() {}
};
class Bar
{
public:
Bar(const AbstractBase& base) : myBase{base} {}
private:
const AbstractBase& myBase;
};
int main()
{
Foo f{};
Bar b{f};
}
Beim Kompilieren, erhalte ich die Fehler
test5.cpp: In constructor ‘Bar::Bar(const AbstractBase&)’:
test5.cpp:22:48: error: cannot allocate an object of abstract type ‘AbstractBase’
Bar(const AbstractBase& base) : myBase{base}
^
test5.cpp:2:7: note: because the following virtual functions are pure within ‘AbstractBase’:
class AbstractBase
^
test5.cpp:8:18: note: virtual void AbstractBase::ab()
virtual void ab() = 0;
Ändern der Linie
Bar(const AbstractBase& base) : myBase(base) {}
es kompiliert und läuft gut.
Beim Lesen von Stroustrups C++ 11-Buch hatte ich den Eindruck, dass {} in fast allen Fällen dasselbe war(), mit Ausnahme von Zweideutigkeiten zwischen Konstruktoren, die std :: initializer_list <> und andere annehmen Konstruktoren und Fälle, in denen Auto als Typ verwendet wird, von denen ich hier keine mache.
Meine Faustregel: Verwenden Sie '{}' für Listen von Elementen (einschließlich Null) und '()', um explizit einen anderen Konstruktor aufzurufen. –
Dies ist eigentlich ein Problem mit der Initialisierung der Liste von Referenzen zu tun –
Das gleiche Problem wie hier - http://StackOverflow.com/Questions/19347004/Copy-Constructor-Curly-Braces-Initialization –