C++类的动态加载:为什么需要"destroy"函数?
C++ dynamic loading of classes: Why is a "destroy" function needed?
这个页面检查并给出了一个关于如何动态加载和使用类的非常清晰的例子,但是有一些东西我很难理解:
我理解为什么需要"创建"函数,但为什么需要"销毁"函数?为什么将接口析构函数声明为纯虚函数还不够?
我做了一个相同的例子,除了:
~polygon() = 0;
triangle
的析构函数为:
triangle::~triangle() {
std::cout << "triangle Dtor is called" <<std::endl;
}
那么当我使用:
delete poly;
消息确实显示(linux下的GCC 5.4.0)。
我试图寻找其他的例子,但他们都提到并使用"destroy"函数,没有例子使用简单的纯虚拟析构函数,这让我相信我在这里错过了一些东西,所以…这是什么?
不想使用destroy函数的背景是我想在shared_ptr
中使用分配的对象,而不关心它的生命周期,使用"destroy"函数将是棘手的,因此我需要知道它是否必要。
在同一链接中继续阅读:
必须同时提供创建函数和销毁函数;您不能在可执行文件中使用delete来销毁实例,而是始终将其传递回模块。这是因为在c++中,new和delete操作符可能被重载;这将导致调用不匹配的new和delete,从而可能导致从什么都没有到内存泄漏和分段错误等各种问题。如果使用不同的标准库来链接模块和可执行文件,则也是如此。
这里的关键字是new and delete may be overloaded
因此做些不同的调用者的代码比共享对象的代码,如果您使用delete
从二进制将调用析构函数,它会释放内存共享对象的析构函数,但这可能不是删除运营商共享对象的行为,也许new
共享对象中没有分配任何记忆,因此你将会有一个可能的段错误,也许new
正在做的不仅仅是为该对象分配内存,而且由于没有调用共享对象中匹配的delete
,因此存在泄漏,在共享对象和二进制文件之间也存在不同堆处理的可能性。
在任何情况下,shared_ptr
都可以很容易地使用lambda函数调用自定义删除器。的确,shared_ptr
不能在其模板参数中包含删除器有点恼人,但您可以编写一个简单的包装器,使其更简单/更简洁,以便在所有位置使用一致的删除器创建它(目前没有可用的编译器,请原谅任何拼写错误):
shared_ptr<triangle> make_shared_triangle(triangle *t) {
return std::shared_ptr<triangle>(t, [](triangle *t) { destroy_triangle(t); });
}
如果你真的想按照你链接到的例子去做,你可以使用一个自定义函数,当智能指针应该删除它的对象时使用。
std::shared_ptr<class> object(create_object(), //create pointer
[=](class* ptr)
{
destroy_object(ptr);
});
用这个代替delete
,当共享指针应该删除自己时将调用lambda。
注意:我将函数指针复制到lambda中的destroy_object
函数([=]
将这样做)。只要在动态加载上下文中不调用dlclose()
,这应该是有效的。当你使用dlclose
时,这会导致错误。
然后,您需要使用显式的不想使用destroy函数的背景是,我想在shared_ptr中使用分配的对象,而不关心它的生命周期,使用"destroy"函数将是棘手的,因此我需要知道它是否必要。
Deleter
创建shared_ptr
(参见构造函数的形式4)。向下滚动到示例)。
template< class Y, class Deleter > shared_ptr( Y* ptr, Deleter d );
类似:
shared_ptr<polygon> sh_ptr_val(
my_triangle,
[](auto ptr) { destroy_triangle(ptr); }
);
struct triangle_factory {
static shared_ptr<triangle> create() {
shared_ptr<polygon> ret(
create_triangle(),
[](auto ptr) { destroy_triangle(ptr); }
);
return std::move( ret )
};
private:
static create_t* create_triangle;
static destroy_t* destroy_triangle;
}
create_t* triangle_factory::create_triangle=(create_t*) dlsym(triangle, "create");
destroy_t* triangle_factory::destroy_triangle=(destroy_t*) dlsym(triangle, "destroy");
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 为什么 C++17 个 destroy()/destroy_n() 函数向前(而不是向后)运行?
- 如果从 QObject 派生的类的构造函数抛出,则将发出 destroy()
- C++类的动态加载:为什么需要"destroy"函数?
- std::队列错误?Pop调用了错误的destroy函数