具有基类指针的成员向量



我有一个向量如下的类:

#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的副本来初始化一个新对象,该对象的指针将是pushed_back。如果我不使用new,我将在b和向量之间共享资源(这是一个sin(。

我想保持多态性。如何确保被推回的对象保持在创建过程中指定的类型,而不将所有内容强制到基本对象中。

如果要创建传递给addObject的对象的克隆,基本上有两个选项。1( 在BaseDerived中有一个虚拟函数clone,或者更好的是2(让复制构造函数处理它

如果选择第二个选项,addObject需要知道传递对象的实际类型。这可以用一个模板来完成:

template <class T>
void addObject(const T * t)
{
Base *b = new T(*t);
}

在一个健壮的程序中,我们不想使用new/delete,而是使用std::unique_ptrstd::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);

最新更新