[英]member vector with base class pointers
我有一個帶有向量的類,如下所示:
#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
的對象的克隆,則基本上有兩種選擇。 1) 在Base
和Derived
有一個虛函數clone
,或者更好 2) 讓復制構造函數處理它。
如果你選擇第二個選項, addObject
需要知道傳遞對象的實際類型。 這可以通過模板來完成:
template <class T>
void addObject(const T * t)
{
Base *b = new T(*t);
}
在健壯的程序中,我們不想使用new
/ delete
而是使用std::unique_ptr
或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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.