Имеем иерархию классов. Base <|- Derived <|- FinalClass <|- FinalClassEx
Почему при виртуальном наследовании Derived от Base нельзя возвратить объект из функции, а без него можно ?
class Base
{
public:
explicit Base(char const*) {}
Base() {}
Base(const Base&) = delete;
Base& operator=(const Base&) = delete;
};
class Derived : virtual public Base // Compiles without virtual
{
public:
Derived() {}
Derived(Derived&&) {}
Derived& operator=(Derived&&) { return *this; }
Derived(const Derived&) = delete;
Derived& operator=(const Derived&) = delete;
};
class FinalClass : public Derived
{
public:
FinalClass() {}
FinalClass(FinalClass&&) {}
FinalClass& operator=(FinalClass&&) { return *this; }
FinalClass(const FinalClass&) = delete;
FinalClass& operator=(const FinalClass&) = delete;
};
FinalClass f1()
{
FinalClass f;
return f;
}
class FinalClassEx : public FinalClass
{
public:
using FinalClass::FinalClass;
};
FinalClassEx f2()
{
FinalClassEx f;
return f;
}
int main()
{
auto v1 = f1();
auto v2 = f2();
return 0;
}
root@ubuntu64:~# c++ t.cpp -std=c++17
t.cpp: In function ‘FinalClassEx f2()’:
t.cpp:52:12: error: use of deleted function ‘FinalClassEx::FinalClassEx(FinalClassEx&&)’
return f;
^
t.cpp:43:7: note: ‘FinalClassEx::FinalClassEx(FinalClassEx&&)’ is implicitly deleted because the default definition would be ill-formed:
class FinalClassEx : public FinalClass
^~~~~~~~~~~~
t.cpp:43:7: error: use of deleted function ‘Base::Base(const Base&)’
t.cpp:7:5: note: declared here
Base(const Base&) = delete;
^~~~
root@ubuntu64:~# vi t.cpp +7
# comment line 7 //Base(const Base&) = delete;
root@ubuntu64:~#
root@ubuntu64:~# c++ t.cpp -std=c++17
root@ubuntu64:~#
all ok
Здравствуйте, _NN_, Вы писали:
_NN>Имеем иерархию классов. Base <|- Derived <|- FinalClass <|- FinalClassEx _NN>Почему при виртуальном наследовании Derived от Base нельзя возвратить объект из функции, а без него можно ?
. . .
A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, reversecode, Вы писали:
R>>all ok _NN>Это то понятно. _NN>Эта строка убивает перемещение сгенерированное компилятором. _NN>
Base(const Base&) = delete;
_NN>Вопрос как влияет виртуальное наследование.
влияет прямо
очень рекомендую не пользоваться тем чего не понимаете
в данном случае вы не понимаете как инициализируется виртуальное наследование
и без того конструктора оно не работает в вашем случае
Здравствуйте, reversecode, Вы писали:
R>Здравствуйте, _NN_, Вы писали:
_NN>>Здравствуйте, reversecode, Вы писали:
R>>>all ok _NN>>Это то понятно. _NN>>Эта строка убивает перемещение сгенерированное компилятором. _NN>>
Base(const Base&) = delete;
_NN>>Вопрос как влияет виртуальное наследование.
R>влияет прямо R>очень рекомендую не пользоваться тем чего не понимаете
Я им и не пользуюсь, это стандартная библиотека пользуется
R>в данном случае вы не понимаете как инициализируется виртуальное наследование R>и без того конструктора оно не работает в вашем случае
Ок, тогда другой вопрос.
Почему using FinalClass::FinalClass не работает, а явно объявить конструкторы работает ?
class FinalClassEx : public FinalClass
{
public:
FinalClassEx() {}
FinalClassEx(FinalClassEx&&) {}
}
Разве компилятор не должен брать конструкторы из класса FinalClass ?
Здравствуйте, _NN_, Вы писали:
_NN>Разве компилятор не должен брать конструкторы из класса FinalClass ?
Должен. Но фишка в том, что подобъект виртуального базового класса инициализируется только в most derived классе. Он не может быть проинициализирован в не most derived классе. Поэтому конструктор перемещения, объявленный в FinalClass не оказывает никакого влияния на удаленный конструктор перемещения класса Base. И тот отстается быть удаленным аж до самого FinalClassEx. А вместе с ним оказывается удаленным и конструктор перемещения класса FinalClassEx, если его не определить.
P.S. Вот смотри, все сказанное можно показать и на более простом примере конструктора по умолчанию: