智能指针和派生类
Smart pointers and derived classes
我要在 std::list
中存储大量对象。
因为我需要这些对象来存储不同类型的数据,所以我存储了指向一个基 class 的指针,它只包含一个 enum
类型的属性,它告诉对象到哪个derived classes 它应该被转换成。每个派生的 class 都有自己的数据类型:
struct Base {
enum class Type {
D1,
D2,
...
} type;
Base(Type new_type):
type(new_type) {}
};
struct D1: public Base {
std::string data;
D1(std::string new_data):
Base(Base::Type::D1), data(new_data) {}
};
struct D2: public Base {
double data;
D2(double new_data):
Base(Base::Type::D2), data(new_data) {}
};
为了保存指向这些对象的指针,我使用了智能指针:
std::list<std::unique_ptr<Base>> list;
list.push_back(std::unique_ptr<Base>(new D1("Somestring")));
list.push_back(std::unique_ptr<Base>(new D2(3.14)));
然而,虽然每个 Base 对象都知道应该将其转换为哪种类型才能正确删除,但智能指针只知道它必须调用 Base 的析构函数。这将使每个 subclass 分配的内存保持未删除状态。
我如何将自定义删除器传递给智能指针,以便它们知道如何正确转换和释放每个对象的内存?我应该如何实施该自定义删除器?
只需将Base
的析构函数标记为virtual
即可。然后默认删除器将调用 delete pointer_to_raw_object;
,它将根据 object
.
的动态类型调用正确的析构函数
示例:
#include <iostream>
#include <memory>
#include <list>
struct Base
{
virtual ~Base(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
struct Derived : Base
{
~Derived() override {std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
int main()
{
std::list<std::unique_ptr<Base>> l;
l.emplace_back(new Base);
l.emplace_back(new Derived);
}
PS:考虑使用 std::list::emplace_back
以获得更清晰(和更高效)的代码。
我要在 std::list
中存储大量对象。
因为我需要这些对象来存储不同类型的数据,所以我存储了指向一个基 class 的指针,它只包含一个 enum
类型的属性,它告诉对象到哪个derived classes 它应该被转换成。每个派生的 class 都有自己的数据类型:
struct Base {
enum class Type {
D1,
D2,
...
} type;
Base(Type new_type):
type(new_type) {}
};
struct D1: public Base {
std::string data;
D1(std::string new_data):
Base(Base::Type::D1), data(new_data) {}
};
struct D2: public Base {
double data;
D2(double new_data):
Base(Base::Type::D2), data(new_data) {}
};
为了保存指向这些对象的指针,我使用了智能指针:
std::list<std::unique_ptr<Base>> list;
list.push_back(std::unique_ptr<Base>(new D1("Somestring")));
list.push_back(std::unique_ptr<Base>(new D2(3.14)));
然而,虽然每个 Base 对象都知道应该将其转换为哪种类型才能正确删除,但智能指针只知道它必须调用 Base 的析构函数。这将使每个 subclass 分配的内存保持未删除状态。
我如何将自定义删除器传递给智能指针,以便它们知道如何正确转换和释放每个对象的内存?我应该如何实施该自定义删除器?
只需将Base
的析构函数标记为virtual
即可。然后默认删除器将调用 delete pointer_to_raw_object;
,它将根据 object
.
示例:
#include <iostream>
#include <memory>
#include <list>
struct Base
{
virtual ~Base(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
struct Derived : Base
{
~Derived() override {std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
int main()
{
std::list<std::unique_ptr<Base>> l;
l.emplace_back(new Base);
l.emplace_back(new Derived);
}
PS:考虑使用 std::list::emplace_back
以获得更清晰(和更高效)的代码。