【发布时间】:2016-01-21 16:34:56
【问题描述】:
我遇到了以下情况。(更新:称为不透明类型;感谢@iharob 提供信息)
类型 P 是 public_api.h 中的 typedef-ed 以及一些创建、修改和销毁它的函数,例如。 createP 在下面的 sn-p 中。
但是,它的实现是基于隐藏类型的。隐藏,因为它是在源代码中定义的,通常作为已编译的二进制文件可用,可以安装。每个这样的操作都依赖于指针类型转换。
我的用例简化如下:
#include <iostream>
using std::cerr;
#include <boost/shared_ptr.hpp>
/* defined in **public** api */
// _PUB_API_ {{{
typedef struct P P;
P* createP();
// }}} _PUB_API_
/* defined in **implementation** files, that are compiled to binary */
// HID_IMPL {{{
typedef struct P_ P_;
struct P_ {};
P* createP() { return (P*) new P_(); }
// }}} HID_IMPL
/* **Use case** */
int main(int argc, char *argv[])
{
P* p = createP();
if (p == NULL)
{ /* does not execute */
cerr << "Unable to create P" << '\n';
return 1;
}
typedef boost::shared_ptr<P> PpointerT;
//typedef boost::scoped_ptr<P> PpointerT;
PpointerT ptr = PpointerT(createP(), &deleteP); // compilation error
if (!ptr)
{
cerr << "Error creating shared pointer PpointerT" << '\n';
return 2;
}
cerr << "P created!" << '\n'
<< "PpointerT created!" << '\n';
return 0;
}
我想使用智能指针而不是原始指针。在这里,我被困住了。因为,智能指针要求类型在实例化时是完整的(在 boost 中使用checked_delete.hpp 实现)
我可能必须围绕类型 P(可能是每个此类类型)创建一个包装类,该类使用构造函数、成员函数和析构函数来合理地创建、修改和销毁函数。 是否值得麻烦而不是继续使用原始指针?
有没有其他方法可以解决这个库施加的限制?
更新:
上述情况确实可以使用 shared_ptr 库解决,如@Richard 的答案所示。总而言之,构造函数需要一个删除器类,它充当OpaqueType* 的销毁函子,例如:
// Update:PUB_API
void deleteP(P* p);
// Update:HID_IMPL
void deleteP(P* p) { delete (P*) p; } // I don't know if type casting
// here is necessary?
PpointerT ptr = Ppointer(createP(), &deleteP);
然后整个程序运行良好。并且确实满足用例。
【问题讨论】:
-
你想要的词是opaque -> 是基于一个隐藏类型
-
由于智能指针需要能够创建和删除对象,因此模板类型的构造函数和析构函数的声明需要可见
-
@iharob 感谢您提供的术语,我将使用它并更新帖子
标签: c++ pointers boost smart-pointers