类型结构隐藏实现与pimpl-idiom

时间:2011-07-31 23:58:15

标签: c casting implementation pimpl-idiom

我知道在C中看起来像这样的pimpl-idiom:

// foobar.h
struct FooBar {
    char *someString;
    struct FooBarImpl *pImpl;
};
// foobar.c
struct FooBarImpl {
    char *hiddenString;
};

然而,通过类型转换,我可以摆脱不透明的指针并减少有人因实现而混淆的几率:

// foobar.h
struct FooBar {
    char *someString
};
// foobar.c
struct FooBarImpl {
    // FooBar members
    char *someString
    // FooBarImpl members
    char *hiddenString
};

在后一种情况下,任何在FooBar上执行操作的函数都会简单地对FooBarImpl进行类型转换,以便访问“私有”成员。

我可以看到,如果有人将某些成员添加到FooBar而不是为FooBarImpl做同样的事情,这将会成为一个问题。但是在我的情况下,FooBar只包含一个成员,不太可能改变。

当我希望隐藏实施细节时,这会被视为良好做法还是我应该坚持使用pimpl-idiom?

谢谢。

2 个答案:

答案 0 :(得分:2)

编译器是你的朋友;不要通过使用显式类型转换来欺骗它,尤其是在复合类型之间。坚持使用第一种方法,如果你转发声明实现结构,你将永远不必透露它的内容。

答案 1 :(得分:0)

在使用在结构体之间进行类型转换的代码时,您必须非常小心:

  1. 您无法创建FooBar数组或向客户端代码提供指向此类数组的指针。
  2. 分配或memcpy:结构(不是它们的指针)需要分配FooBarImpl,而不是FooBar - 否则特定于实现的数据将被切断。
  3. 从标题中查看,库的用户可能会错误地认为memcpying或分配或创建FooBar结构是正确的 - 毕竟,它似乎包含的所有内容都是可以轻松填充的基本数据。