基数 class 指针的成员向量
member vector with base class pointers
我有一个 class,向量如下:
#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 和 vector 之间共享资源(这是一个罪过)。
我想保持多态性。我如何确保被推回的对象保持它们在创建期间分配的类型,而不是将所有内容都强制到 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);
我有一个 class,向量如下:
#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 和 vector 之间共享资源(这是一个罪过)。
我想保持多态性。我如何确保被推回的对象保持它们在创建期间分配的类型,而不是将所有内容都强制到 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);