常量正确性——C API shim 层

Posted

技术标签:

【中文标题】常量正确性——C API shim 层【英文标题】:Const correctness -- C API shim layer 【发布时间】:2013-03-20 03:33:18 【问题描述】:

在编写用作其他库(C 风格)API 包装器的类时,确保 const 正确性的相关做法是什么。 我正在编写一个类(Renderer),它将应用程序特定的渲染调用转换为相应的 OpenGL(可能还有 DirectX)调用。这个类实际上并没有自己的状态,它通过调用 Renderer::applyTransform(const Matrix&) 来修改,而是在内部调用改变 OpenGL 状态的 API。在这种情况下,将此类 API 标记为 const 是正确的做法,还是“修改可观察状态”也扩展到此类包装的 OpenGL 状态,要求我使其成为非成本?

这类似于Const-correctness and hardware writes,但也许这是一个更具体的用例。

【问题讨论】:

【参考方案1】:

如果您正在调用通过非 const 指针获取成员变量的 C 函数,那么这些包装函数可能不应该是 const。如果他们只是观察状态而不修改它,您可以将您的方法设为 const——即使 C API 不是 const 正确的,您也可以根据需要在成员变量上使用 const_cast<>mutable

从语义的角度考虑它——如果一个方法不改变世界的状态,就让它成为常量。如果它确实改变了世界的状态,它可能不应该是 const,除非改变的状态类似于缓存,它只是导致改变的优化而不是必要的东西。

【讨论】:

谢谢。这有点帮助。对此没有严格的指导方针,这就是导致我的问题的原因。我想我会坚持 Ben 所说的——这取决于整体设计。将此标记为答案,因为您非常彻底。【参考方案2】:

您是否需要将它们设为非const?没有。

如果语义是有效状态将被修改,这会是一个好主意吗?可能是的,但这取决于您的整体设计。

【讨论】:

【参考方案3】:

方法只是一个函数,this 只是另一个函数参数。任何参数都可以是指向const的指针,这只影响对应的参数,与修改任何其他参数或全局状态的函数无关。

所以是的,const 方法可以修改全局状态,这没有错。

【讨论】:

以上是关于常量正确性——C API shim 层的主要内容,如果未能解决你的问题,请参考以下文章

C中的常量正确性

C语言的switch case 语句的case 常量 能匹配字符串常量吗?

为啥我不能从 Golang 正确读取 C 常量?

在C#中命名Windows API常量

C语言实型常量

在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是啥