Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 隐藏实现的类型转换结构与pimpl习惯用法_C_Casting_Implementation_Pimpl Idiom - Fatal编程技术网

C 隐藏实现的类型转换结构与pimpl习惯用法

C 隐藏实现的类型转换结构与pimpl习惯用法,c,casting,implementation,pimpl-idiom,C,Casting,Implementation,Pimpl Idiom,我知道关于pimpl的习语,在C中它看起来像这样: // foobar.h struct FooBar { char *someString; struct FooBarImpl *pImpl; }; // foobar.c struct FooBarImpl { char *hiddenString; }; 但是,通过类型转换,我可以摆脱不透明指针,并减少有人干扰实现的可能性: // foobar.h struct FooBar { char *someStr

我知道关于pimpl的习语,在C中它看起来像这样:

// 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,以访问“private”成员

我可以看出,如果有人想向FooBar添加一些成员,但对FooBarImpl不这样做,这将成为一个问题。然而,在我的例子中,FooBar将只包含一个成员,并且不太可能更改

当我想隐藏实现细节时,这是一个好的实践还是应该坚持使用pimpl习惯用法


谢谢。

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

在处理在结构之间进行类型转换的代码时,必须非常小心:

  • 您无法创建FooBar数组或向客户端代码提供指向此类数组的指针
  • 赋值或memcpy:ing结构(不是它们的指针)需要赋值FooBarImpl,而不是FooBar-否则特定于实现的数据将被切断
  • 从标题看,库的用户可能会错误地认为memcpying、赋值或创建FooBar结构是正确的——毕竟,它似乎只包含可以轻松填充的基本数据