This answer建议使用指针来克服向量中的对象切片。从我的测试来看,当使用基类和派生类之间共享的变量时,这是正确的。例如,给定以下类:
class Base {
public:
int x = 1;
};
class Derived : public Base {
public:
Derived() : Base() {
x = 2;
}
int y;
};
可以看出,Derived在构造时将x重新定义为2。2当被放入基类的向量中时,x变量的行为与预期的一样。
vector<unique_ptr<Base>> baseVec; // Vector of pointers to Base objects
unique_ptr<Derived> derivedPtr(new Derived()); // Pointer to Derived object
baseVec.push_back(std::move(derivedPtr)); // Add pointer with std::move()
std::cout << baseVec[0]->x << std::endl; // Outputs 2
但是,尝试使用仅属于Derived的y
变量会导致错误C2039: 'y' is not a member of 'Base'
,如下所示:
std::cout << baseVec[0]->y << std::endl;
有没有一种方法可以绕过这个问题,同时保留派生类的唯一成员变量,如果没有,有没有更好的方法将对象存储在有序容器中?
- 编辑**
之前编辑的相关内容已经移到下面我的答案中。在我找到使用智能指针的方法之前(或者确保我的原始指针实现没有内存问题),我不打算接受这个答案。
2条答案
按热度按时间nxowjjhe1#
有没有一种方法可以绕过这个问题,同时保留派生类的唯一成员变量,如果没有,有没有上级的方法将对象存储在有序容器中?
有很多技术可以让你达到类似的效果,所有这些技术都已经在SO的不同答案中提到了。
简历:简短的(可能不完整的)简历:
std::variant
,这是一种类型安全的标记联合,你可以通过一个专门的访问者来访问。我不认为重复SO上已有的例子是值得的。你可以使用上面的关键字搜索它们,得到你想要的。
每种技术都有其优点和缺点。其中一些技术允许您在调用者的上下文中提取原始类型,这样您就可以在需要时将对象传递给其他函数。其他一些技术则完全删除类型,并提供 * handler * 来对原始类型执行操作。但是在调用者的上下文中却永远无法将其恢复。这些差异通常会影响性能(在某种程度上你很难观察到)因为所使用的语言的特点和它们所吸引的演员。
0s7z1bwu2#
改变课程
Base
和Derived
的类定义应更改为:值得注意的是增加了虚函数
void f()
,它允许dynamic_cast
处理指针的强制转换。使用唯一指针
唯一指针可用于存储、检索、修改和安全删除指向
Derived
对象的指针,这些指针驻留在指向Base
对象的指针向量中。下面的示例使用堆分配对象。按预期运行并输出
255
和65535
。