c++ - 带有基类指针的成员向量
问题描述
我有一个带有如下向量的类:
#include <vector>
class Base{};
class Derived: public Base{};
class Foo{
private:
std::vector<Base*> vec;
public:
Foo() = default;
void addObject(const Base* b){
// vec.push_back(new Base(*b));
// vec.push_back(new Derived(*b));
}
};
int main(){
Derived* d = new Derived();
Base* b = new Base();
Foo f;
f.addObject(d);
f.addObject(b);
delete d;
delete b;
return 0;
}
函数addBase可以接收Derived 的指针。行vec.push_back(new Base(b)); 预计将使用 b 的副本来初始化其指针将被push_back的新对象。如果我不使用 new,我将在 b 和向量之间共享资源(这是一个罪过)。
我想保持多态性。如何确保被推回的对象保持它们在创建过程中分配的类型,而不强制将所有内容都放入 Base 对象。
解决方案
如果要创建传递给的对象的克隆,addObject
则基本上有两个选择。clone
1)在Base
and中有一个虚函数Derived
,或者更好 2)让复制构造函数处理它。
如果您选择第二个选项,addObject
则需要知道传递对象的实际类型。这可以通过模板来完成:
template <class T>
void addObject(const T * t)
{
Base *b = new T(*t);
}
在一个健壮的程序中,我们不想使用new
/delete
而是使用std::unique_ptr
or std::shared_ptr
。t
作为参考传递,而不是指针,也被认为是一种更好的做法。
#include <vector>
#include <memory>
#include <iostream>
class Base
{
public:
virtual void cname() { std::cout << "Base" << std::endl;}
};
class Derived: public Base
{
public:
virtual void cname() { std::cout << "Derived" << std::endl;}
};
class Foo
{
private:
// You may switch to `std::shared_ptr` if that better fits your use case
std::vector<std::unique_ptr<Base> > vec;
public:
template <class T>
void addObject(const T & t)
{
vec.push_back(std::make_unique<T> (t));
}
void dump()
{
for (auto &bp: vec)
bp->cname();
}
};
int main(){
Derived d;
Base b;
Foo f;
f.addObject(d);
f.addObject(b);
f.dump();
return 0;
}
自然地,要使其工作,传递给的引用addObject
必须是正确的类型。这将创建一个类型的克隆Base
,而不是Derived
:
Derived d;
Base &e = d;
f.addObject(e);
推荐阅读
- android - 具有多个实例的导航视图模型
- xcode - 如何在 RATs 软件中为 MGARCH 运行 Ljung-Box 或任何其他诊断测试?
- c++ - 是否可以从 DUMPBIN /SYMBOLS 命令派生声明的函数?
- triggers - 无法绑定到用户控件内的工具提示
- mariadb - 从 SELECT 或 UPDATE 中的不同行中查找值
- javascript - Flatlist 无法呈现项目
- r - 无法预测 tslm
- elasticsearch - Elastic SIEM - 警报和关联
- r - 变量中每个因子的 p 值
- json - Angular 11 上的 rss-parser(TypeError:get 不是函数)