Прежде чем что-либо еще, так как вы находитесь на C++, нет абстрактного класса без чистых виртуальных функций. Это просто не вещь.
Тогда ваша проблема заключается в том, что ссылка должна быть инициализирована. Посмотрите на этот код:
Bar myBar;
Bar& bar; // Error
bar = myBar; // don't do what you think
Здесь, на линии, где я комментировал «Error», это потому, что вы не можете отложить инициализацию ссылки. Ссылка похожа на псевдоним на другую переменную. Ссылка должна быть инициализирована значением.
Строка с комментарием «не делай, что думаешь», потому что она не будет перепроверять ссылку. Он вызывается функцией Bar::operator=(const Bar&)
. Это сделает bar
значение myBar
.
Хорошо, с объяснением, будет легче понять, что происходит в вашем классе.
В вашем конструкторе Foo
скрыты все происходящее.
В самом деле, он будет инициализировать Foo::baz
со значением, попавшим в конструкторе, но он также будет инициализировать другие переменные ваш класс, немного напоминает, что:
// implicit --v---v
Foo(int baz_) : baz(baz_), bar() {}
Смотрите эту проблему? Вы инициализируете ссылку iwth no variable для ссылки. Вам нужно передать переменную, на которую нужно привязать.
Вторая проблема, вы делаете что-то здесь не так:
Kappa() : Foo(10)
{
bar = Asd(); // Asd is a Bar
}
Вы имели в виду, что Asd
тип, который расширяет Bar
? Если это так, вы должны изменить экземпляр bar
на то же значение пустого Asd
. Да, он скопирует содержимое пустого Asd
на ваш bar
. Это семантика значений. Определенные пользователем типы ведут себя так же, как основы.
Хорошо, так что теперь, как исправить этот код?
Предполагаете, что вы хотите создать новый экземпляр базового класса и привязать ссылку к родительскому объекту этому новому экземпляру. Если да, то вам нужна переменная, которая может жить мимо рамки конструктора:
Kappa() : Foo(10)
{
Asd myAsd;
bar = /* somehow bind bar to myAsd */
} // myAsd destroyed here!
Как вы можете видеть, вы должны создать переменную, которая должна жить мимо }
. Идеал был бы переменной, которая живет достаточно долго, чтобы остаться в живых, пока Kappa
останется в живых. Введите std::unique_ptr
!
Вместо ссылки, не требующей права собственности, используйте std::unique_ptr
. Это класс, который представляет переменную, которая выделяется в свободном хранилище, иначе. переменная, выделенная кучей. Он будет вести себя аналогично объекту в java или C# или < вставить имя управляемого языка>. Обычно используется std::unique_ptr
наряду с std::make_unique
для распределения.
Вы можете использовать его так:
'Bar & bar' является ссылкой, поэтому он должен быть инициализирован в списке инициализации конструктора непосредственно перед' baz'. – Galik
Конструктор 'Foo' должен инициализировать' bar'. Обычно это делается путем передачи 'Bar &' конструктору. –
У вас есть ошибка дизайна. Если только дети Foo знают, как установить 'bar', чем' bar' не принадлежит Foo. – SergeyA