C++ 为什么创建一个存储基本对象的向量,但使用派生对象进行初始化会因删除的移动构造函数而失败?
我正在尝试创建一个C++ 为什么创建一个存储基本对象的向量,但使用派生对象进行初始化会因删除的移动构造函数而失败?,c++,containers,C++,Containers,我正在尝试创建一个std::vector类成员,该类成员存储多个系统,这些系统都是从SystemBase派生的。但是,此类有一个引用,因此没有合理的默认构造函数: class系统库{ 公众: SystemBase()=删除; 显式SystemBase(entt::registry®istry):注册表{registry}{ virtual~SystemBase()=默认值; SystemBase(const SystemBase&)=删除; SystemBase(SystemBase&&)
std::vector
类成员,该类成员存储多个系统,这些系统都是从SystemBase
派生的。但是,此类有一个引用,因此没有合理的默认构造函数:
class系统库{
公众:
SystemBase()=删除;
显式SystemBase(entt::registry®istry):注册表{registry}{
virtual~SystemBase()=默认值;
SystemBase(const SystemBase&)=删除;
SystemBase(SystemBase&&)=删除;
自动运算符=(const SystemBase&)->SystemBase&=delete;
自动运算符=(SystemBase&)->SystemBase&=delete;
虚拟自动更新(常量sf::时间增量)常量->无效;
受保护的:
entt::registry®istry;
};
继承的系统如下所示:
class LocalToWorldSystem final:公共系统库{
公众:
显式LocalToWorldSystem(entt::registry®istry):SystemBase{registry}{};
自动更新(常数sf::时间增量)常数->无效覆盖;
};
尝试初始化系统向量时,我得到一个错误:
std::向量系统{LocalToWorldSystem{Registry};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//错误:调用已删除的“const SystemBase”构造函数。
为什么会发生这种情况?我目前的解决方法是使用<代码> STD::vector < /Cord>。但是我想知道为什么这个问题首先出现。C++中的变量/对象实际上是X的对象。它们不是派生类型的对象。 指向基的指针可以指向派生的。派生对象中有一个基类子对象。但是foo的向量包含实际的foo
在许多C++派生语言中,对象类型的变量实际上是指向对象的指针(通常称为引用)。这通常导致基元类型具有值语义,而对象类型具有引用或指针语义
一个唯一的PTR向量,同时可以存储指向该点的指针。C++中的
< P>,X的变量和对象实际上是X的对象。它们不是派生类型的对象。 指向基的指针可以指向派生的。派生对象中有一个基类子对象。但是foo的向量包含实际的foo在许多C++派生语言中,对象类型的变量实际上是指向对象的指针(通常称为引用)。这通常导致基元类型具有值语义,而对象类型具有引用或指针语义
同时,唯一PTR的向量可以存储指向要导出的基点的指针 我想知道为什么这个问题首先会出现 如果您来自Java和类似语言,则需要实现Java中的对象是隐式引用或指针。他们有一种间接性 <>在C++对象中没有间接的,它们是对象本身。因此,SystemBase
只有SystemBase
的存储空间。它对派生类所需的空间一无所知
因此,您需要std::unique\u ptr具有与Java中相同的间接寻址。这会带来运行时成本,就像在Java中一样
我想知道为什么这个问题首先会出现
如果您来自Java和类似语言,则需要实现Java中的对象是隐式引用或指针。他们有一种间接性
<>在C++对象中没有间接的,它们是对象本身。因此,SystemBase
只有SystemBase
的存储空间。它对派生类所需的空间一无所知
因此,您需要std::unique\u ptr具有与Java中相同的间接寻址。这会带来运行时成本,就像在Java中一样。std::vector不能包含任何派生类型的对象,只能包含类型
SystemBase
本身。@JerryJeremiah否,std::vector
在不需要或未使用内存时不使用默认构造函数。它可能是在抱怨移动构造函数,而不是默认构造函数。@如果你说得对,它是在抱怨SystemBase(SystemBase&&)=delete代码>。刚刚验证过。@aschepler出于测试目的,我将move-and-copy构造函数设置为默认值,它似乎可以工作,但在语义上并不是我想要的。对,如果基类允许复制,那么该向量将只从你试图给它的基部分切掉。使用std::vector
可能是正确的做法,而不仅仅是一种解决办法。std::vector
不能包含任何派生类型的对象,只能包含类型SystemBase
本身。@JerryJeremiah不,std::vector
在不需要或未使用内存时不使用默认构造函数。它可能是在抱怨移动构造函数,而不是默认构造函数。@如果你说得对,它是在抱怨SystemBase(SystemBase&&)=delete代码>。刚刚验证过。@aschepler出于测试目的,我将move-and-copy构造函数设置为默认值,它似乎可以工作,但在语义上并不是我想要的。对,如果基类允许复制,那么该向量将只从你试图给它的基部分切掉。使用std::vector
可能是正确的做法,而不仅仅是一种变通方法。