2

经常将指针作为函数 args 传递给只读参数(例如结构等)。例如在这个构造函数中:

Chunk::Chunk(const string& text, COLOR * background, COLOR * foreground);

我以前更喜欢这种方式(不是 const-correct),因为我认为它更容易阅读。但是,我开始觉得这很脏,而是这样做:

Chunk::Chunk(const string& text, const COLOR * const background, 
                          const COLOR * const foreground);

一开始似乎很难理解,但直到你习惯它。我的问题:

为什么没有人做对?(我见过这样的小代码)编译得更好/更小/更快?

确实知道有什么区别,但我真的不在乎不同的语义,因为任何阅读代码的人都可以看到 args 是只读的。(谁会改变指针地址?)

知道我可以使用引用来代替,但是假设我不想(或者我在纯 C 中)。

4

4 回答 4

3

在您列出的示例中

Chunk::Chunk(string text, const COLOR * const background, 
                          const COLOR * const foreground);

const&除非您故意想要该字符串的本地副本,否则您可能还应该传递字符串。另外,在我看来,颜色参数应该被声明为const COLOR *而不是const COLOR * const. 第二个const只是表明该函数不会在本地重新指向backgroundforeground指向其他一些内存块的指针。它不会影响调用者,因此它是一个实现细节。因此,即使实现文件明确将它们列为const COLOR * const标头中的原型,也应该读取

Chunk::Chunk(string text, const COLOR *background, 
                          const COLOR *foreground);
于 2011-08-04T20:24:39.110 回答
1

const 关键字是针对人类的,它非常强大。

看看这个http://www.gotw.ca/gotw/081.htm了解更多关于 const 优化的信息。

于 2011-08-04T20:15:47.450 回答
0

我相信 const 的主要特点是编译时正确性检查,性能提升更像是一个令人愉快的副作用。

于 2011-08-04T20:24:36.550 回答
0

const 正确性有助于编译器生成更快的代码。例如,如果您将非常量指针传递给函数编译器可能会假定该函数已修改已引用的内存块。

编辑:(来自 Exceptional C++ Style 40 New Engineering Puzzles, Programming Problems, and Solutions)

将参数和/或返回值声明为 const 是否有助于编译器生成更优化的代码或以其他方式改进其代码生成?

简而言之,不,它可能不会。

为什么或者为什么不?

编译器可以做得更好吗?它可以避免参数或返回值的副本吗?不,因为参数已经通过引用传递,返回已经是引用。它可以将 x 或 someY 的副本放入只读存储器吗?不,因为 x 和 someY 都存在于其范围之外,并且来自和/或被给予外部世界。即使 someY 是在 f 本身内部动态分配的,它和它的所有权都交给了调用者。

但是出现在 f 的主体中的代码的可能优化呢?由于 const,编译器能否以某种方式改进它为 f 的主体生成的代码?

仅仅因为 x 和 someY 被声明为 const 并不一定意味着它们的位在物理上是 const。为什么不?因为任何一个类都可能具有可变成员或其道德等价物,即成员函数内部的 const_casts。实际上, f 本身内部的代码可能会执行 const_casts 或 C 风格的强制转换,从而将 const 声明变成谎言。

在一种情况下,说 const 可以真正意味着什么,那就是当对象在它们被定义的时候变成 const 时。在这种情况下,编译器通常可以成功地将这些“真正的 const”对象放入只读内存,特别是如果它们是 POD,其内存映像可以在编译时创建,因此可以直接存储在程序的可执行映像本身中。这样的对象通俗地称为“ROM-able”。

人们普遍认为 const 正确性有助于编译器生成更紧凑的代码。是的,const 确实是一件好事,但是这个 Item 的重点是 const 主要是为人类服务的,而不是为编译器和优化器服务的。

于 2011-08-04T20:08:32.603 回答