如何在不导出对象的情况下自动删除对象
How to delete object automatically without exporting them
我开发了一个为客户端提供各种api的库。我们有很多限制,其中之一就是我们应该尽可能地避免导出类。在某些平台上,当客户使用各种各样的编译器时,这是一个问题,这些编译器可能会以不同的方式命名。
由于这个原因,我们向客户提供接口(纯虚拟),这有效地隐藏了我们的实现。我们使用工厂方法将对象传递给客户端,例如IUtfString* createUtfString()
,它通常与某些destroyUtf8String(IUtfString* string)
函数配对。
在某些地方,我们有IUtfString* IUtfString::copy()
调用,它也与destroy函数或IUtfString::release()
函数配对。
这个工作,一切都很好,到目前为止,但它看起来如此1990 C。它完全避免了RAII,只是重用了c中的不透明指针。是否有某种习惯用法可以自动销毁那些工厂创建的对象,而不必导出大对象?pimpl习惯用法可能会有所帮助,因为它将隐藏UtfString对象的大部分,但它仍然迫使我们通过库/dll导出对象,这是我们希望避免的。
我们内部确实有boost支持,但我们也避免将这些类型暴露给客户端。
您可以尝试对shared_ptr<IUtfString>
进行类型定义,然后更改createUtfString()
函数以返回具有自定义删除器的实例。
typedef boost::shared_ptr<IUtfString> UtfString;
/*does nothing now. Designed for code compatibility*/
void destroyUtfString( IUtfString* ) {}
UtfString createUtfString( ... ) {
return boost::shared_ptr<IUtfString>(oldCreateUtfString(),oldDestroyUtfString);
}
如果您能够向客户端代码公开实际的c++类,只需像往常一样使用析构函数和复制构造函数。您仍然可以使用特殊的工厂函数来创建实例和返回指针,但是客户端将在这些指针上调用delete
,而不是调用特殊的销毁函数,因此客户端可以使用标准的智能指针类来避免资源泄漏。
但是,如果您试图避免c++名称混淆问题,则可能是您的库只公开struct
和extern "C"
函数,而不是类。这意味着你的库确实有一个C API,即使它是用c++内部实现的,而且你不能提供析构函数,因为你不能有extern "C"
析构函数。如果是这种情况,只需认识到您提供的是C API,而不必担心它缺乏c++特性。
我也用过类似的技巧。基本思想是假设虚函数表比名称混淆更稳定。
然后导出函数为extern "C"
。
我要做的是创建仅标头包装器,将这些返回值包装在std::shared_ptr
或std::unique_ptr
中。并确保你不输出它们。它们调用extern "C"
导出函数。(或boost
,或roll-your-own)
由于它们在头文件中是inline
,因此它们在"客户端一侧"编译。所以版本和变形并不重要!
这确实强制客户端在回调到你的API时使用.get()
:但是你可以使用更多的头包装器来处理这个问题,这些包装器接受智能指针和.get()
(或.release()
)。
如果你有侵入式引用计数,那么你的shared_ptr
的破坏者可以将侵入计数减少一个:这使得传入原始指针并返回shared_ptr
s更实用。
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 在这种情况下,java对象是否可以调用本机函数
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- 在不复制临时对象的情况下延长其生存期
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在不销毁对象的情况下返回对象列表
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 在没有默认构造函数的情况下创建的派生对象
- 如何在不使用new的情况下保持在其他对象中创建的对象存活?
- 如何在没有 std::move 的情况下移动临时对象
- 如何在不复制的情况下操作 QByteArray 对象?
- 在单元测试中,如何在不使用 operator== 的情况下比较两个对象,这可能会错过新成员?
- 如何在不使用 "new" 关键字的情况下解除分配创建的对象的内存?
- 如何防止类中的类对象尝试在没有默认构造函数的情况下自动构造自身?
- 在没有堆的情况下用两种方法构造对象
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C ++:如何在不创建对象的情况下在主函数中调用方法
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么