【问题标题】:Using an opaque pointer to a non struct type使用指向非结构类型的不透明指针
【发布时间】:2017-11-13 17:22:02
【问题描述】:

在我的 C 编程中,我使用 opaque-pointers 来构建结构,以这种方式强制对我的代码进行抽象和封装:

interface_header.h:

 typedef struct s_mytype t_mytype;

defs_header.h:

struct s_mytype
{
/* Actual definition of the struct */
};

我的问题是我想使用一个简单的类型作为t_mytype(例如char),但不通知接口。我不能只使用typedef char t_mytype,因为这会暴露类型的内部。 我可以只使用 void 指针,但要以类型检查为代价,我宁愿避免这样做。

执行两个 typedef 也不起作用,因为这会从编译器中抛出一个 typedef redefinition with different types

我也在考虑做一个只有一个成员的结构,这将是我的简单类型,但这会不会有点矫枉过正?

感谢您的回答。

【问题讨论】:

  • 如果你需要一个不透明的类型,结构是必要的。决定是不透明还是简单更重要。请记住,您将传递指针。
  • 使用单个成员。这是您的源代码 中的一些样板,但编译后的代码应该不会有所不同。
  • 你能做类似sockaddrsockaddr_in的实现方式吗?
  • @MFisherKDX Ewww! (以及如何解决问题?)
  • @FelixPalmen -- 在您的 API 中公开 sockaddr 并在您的实现中使用 sockaddr_in ??.

标签: c typedef encapsulation opaque-pointers


【解决方案1】:

你必须做出决定。使用这样的代码:

typedef char myHandle;

frobnicate(myHandle *obj);

您已经记录了 intent 客户端代码应该只使用指向 myHandle 的指针,并且永远不要假设任何关于底层类型的内容,因此您应该能够稍后更改 typedef -- 除非有“草率”的客户端代码做出不应该的假设。


如果您想完全隐藏 myHandle 背后的内容,struct 是您在 C 中的唯一选择:

typedef struct myHandle myHandle;

frobnicate(myHandle *obj);

并且只有在私有头文件或实现文件中,你才会放

struct myHandle
{
    char val;
};

第一个选项更简单,因为在frobnicate() 的实现中,您可以简单地使用*obj 访问您的值,而第二个选项需要编写obj->val。第二个版本的好处是您强制正确编写客户端代码。

就生成的可执行文件而言,两个版本是等效的。

【讨论】:

  • 我会选择第二个版本。这将与我的其余代码更加一致,而且我总是更喜欢强制执行我的意图而不是仅仅陈述它。无论如何,添加obj->val 的语法开销并不多,因为那里不会有太多代码,预计解引用部分。感谢您的回答,这帮助我下定了决心!
  • @VannTen 不透明的句柄/指针总是需要取消引用,而使用obj->val,编译器只会找到要添加到指针的0 的偏移量,这当然被消除了,所以你在二进制文件中不会有额外的开销。我个人更喜欢强制正确使用我的界面(尽可能),但这是一个品味问题;)顺便说一句,我遇到了同样的设计决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
  • 2021-10-16
  • 2019-03-18
  • 1970-01-01
相关资源
最近更新 更多