C不透明指针陷阱

时间:2011-03-14 21:14:23

标签: c++ c typedef opaque-pointers

我正在使用传统的C库接口(到C ++),将不透明的指针公开为

typedef void * OpaqueObject

在图书馆:

OpaqueObject CreateObject()
{
   return new OurCppLibrary::Object();
}

这当然为该库的客户提供绝对的类型安全性。应该将typedef从void指针更改为结构指针的工作方式完全相同,但是提供少量类型的安全吗?

typedef struct OpaqueObjectInternal_ *OpaqueObject 
// OpaqueObjectInternal_ is NEVER defined anywhere in client or library code

我是否有任何对齐问题或其他陷阱,我现在明确指向一个结构,即使我真的没有指向一个结构?

3 个答案:

答案 0 :(得分:7)

没有陷阱;因为类型安全,这种形式是首选。

不,对齐不是问题。指针本身具有已知的对齐方式,它指向的对象的对齐仅与库实现有关,而与用户无关。

答案 1 :(得分:2)

实际上,C ++类也是一个C结构。所以你可以这样做:

struct Object;
struct Object* Object_Create(void);

并且,库中的C包装器因此:

struct Object* Object_Create(void)
{
    return new Object;
}

方法调用可能如下所示:

uint32_t Object_DoSomething( struct Object* me, char * text )
{
    return me->DoSomething( text );
}

我试过这个,我没有看到任何缺点。

答案 2 :(得分:1)

您建议的课程首先要考虑的是您与其他人沟通的内容可能需要维护您正在编写的代码。最重要的是,不透明对象是C方式向库的用户指示库维护者绝对不能保证对象的实现,除了该对象可以与记录的函数一起使用。删除虚空*你基本上向全世界宣告,“我宣布这个曾经不透明的实现是稳定的。”这可能不是你想要的。

其次,你提出的恕我直言是一种半人解决方案,没有人开心,更好的方法是开发一个包装类。这有一个额外的好处,允许你包装init和destroy函数,这些函数不可避免地伴随着你的类的构造函数和析构函数中的C风格不透明对象。这将使您能够为您的客户提供资源管理和类型安全,而且还需要做更多的工作。