Чем инициализация {} в списке инициализации конструктора отличается от инициализации () при инициализации ссылки на абстрактные типы? Возьмите класс Bar ниже:
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};
}
При компиляции получаю ошибку
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;
Изменение линии
Bar(const AbstractBase& base) : myBase(base) {}
он компилируется и работает нормально.
Прочитав книгу Страуструпа по C++11, у меня сложилось впечатление, что {} было тем же, что и () в большинстве случаев, за исключением случаев, когда существовала двусмысленность между конструкторами, принимающими std::initializer_list‹>, и другими конструкторами, а также случаи где используется auto в качестве типа, ни то, ни другое я здесь не делаю.
{}
для списков элементов (включая ноль) и()
для явного вызова любого другого конструктора. - person Mooing Duck   schedule 30.10.2014S() {}
! - person M.M   schedule 30.10.2014