“const”有多少种用途以及哪些用途? 在 C++ 中?
作为一名新手 C++ 程序员,有些结构对我来说仍然非常晦涩难懂,其中之一就是 const。 你可以在很多地方使用它,并产生很多不同的效果,这对于初学者来说几乎是不可能的。 一些 C++ 大师会永远解释一下各种用途以及是否和/或为什么不使用它们吗?
As a novice C++ programmer there are some constructs that look still very obscure to me, one of these is const
. You can use it in so many places and with so many different effects that is nearly impossible for a beginner to come out alive. Will some C++ guru explain once forever the various uses and whether and/or why not to use them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试收集一些用途:
将一些临时对象绑定到常量引用,以延长其生命周期。引用可以是基类 - 并且它的析构函数不需要是虚拟的 - 正确的析构函数仍然被调用:
解释,使用代码:
这个技巧用在 Alexandrescu 的 ScopeGuard 实用程序类中。 一旦临时超出范围,Derived 的析构函数就会被正确调用。 上面的代码遗漏了一些小细节,但这才是最重要的。
使用const告诉其他方法不会改变这个对象的逻辑状态。
对写时复制类使用const,让编译器帮助你决定什么时候当不需要时,您需要复制。
说明:当您复制某些内容时,您可能希望共享数据,只要原始对象和复制对象的数据保持不变即可。 然而,一旦其中一个对象更改数据,您现在需要两个版本:一个用于原始版本,一个用于副本。 也就是说,您将写入复制到任一对象,以便它们现在都有自己的版本。
使用代码:
上面的代码片段在我的 GCC 上打印了相同的地址,因为使用的 C++ 库实现了写时复制
std::string
。 尽管两个字符串是不同的对象,但它们的字符串数据共享相同的内存。 使b
成为非 const 将更喜欢使用operator[]
的非 const 版本,并且 GCC 将创建后备内存缓冲区的副本,因为我们可以更改它并且它一定不能影响a
的数据!用于复制构造函数从 const 对象和临时对象进行复制:
用于制作一般无法更改的常量
用于通过引用而不是通过值传递任意对象 - 防止可能昂贵或不可能的按值传递
Trying to collect some uses:
Binding some temporary to reference-to-const, to lengthen its lifetime. The reference can be a base - and the destructor of it doesn't need to be virtual - the right destructor is still called:
Explanation, using code:
This trick is used in Alexandrescu's ScopeGuard utility class. Once the temporary goes out of scope, the destructor of Derived is called correctly. The above code misses some small details, but that's the big deal with it.
Use const to tell others methods won't change the logical state of this object.
Use const for copy-on-write classes, to make the compiler help you to decide when and when not you need to copy.
Explanation: You might want to share data when you copy something as long as the data of the originally and the copie'd object remain the same. Once one of the object changes data, you however need now two versions: One for the original, and one for the copy. That is, you copy on a write to either object, so that they now both have their own version.
Using code:
The above snippet prints the same address on my GCC, because the used C++ library implements a copy-on-write
std::string
. Both strings, even though they are distinct objects, share the same memory for their string data. Makingb
non-const will prefer the non-const version of theoperator[]
and GCC will create a copy of the backing memory buffer, because we could change it and it must not affect the data ofa
!For the copy-constructor to make copies from const objects and temporaries:
For making constants that trivially can't change
For passing arbitrary objects by reference instead of by value - to prevent possibly expensive or impossible by-value passing
const 在 C++ 中实际上有 2 个主要用途。
常量值
如果某个值采用变量、成员或参数的形式,并且在其生命周期内不会(或不应)更改,则应将其标记为常量。 这有助于防止对象发生突变。 例如,在下面的函数中,我不需要更改传递的 Student 实例,因此我将其标记为 const。
至于你为什么要这样做。 如果您知道基础数据无法更改,那么推理算法就会容易得多。 “const”有帮助,但不能保证这一点能够实现。
显然,将数据打印到 cout 不需要太多思考:)
将成员方法标记为 const
在前面的示例中,我将 Student 标记为 const。 但是 C++ 如何知道调用 Student 的 GetName() 方法不会改变对象呢? 答案是该方法被标记为const。
将方法标记为“const”有两件事。 主要是它告诉 C++ 这个方法不会改变我的对象。 第二件事是所有成员变量现在都将被视为被标记为 const。 这会有所帮助,但不会阻止您修改类的实例。
这是一个非常简单的例子,但希望它能帮助回答您的问题。
There are really 2 main uses of const in C++.
Const values
If a value is in the form of a variable, member, or parameter that will not (or should not) be altered during its lifetime you should mark it const. This helps prevent mutations on the object. For instance, in the following function I do not need to change the Student instance passed so I mark it const.
As to why you would do this. It's much easier to reason about an algorithm if you know that the underlying data cannot change. "const" helps, but does not guarantee this will be achieved.
Obviously, printing data to cout does not require much thought :)
Marking a member method as const
In the previous example I marked Student as const. But how did C++ know that calling the GetName() method on student would not mutate the object? The answer is that the method was marked as const.
Marking a method "const" does 2 things. Primarily it tells C++ that this method will not mutate my object. The second thing is that all member variables will now be treated as if they were marked as const. This helps but does not prevent you from modifying the instance of your class.
This is an extremely simple example but hopefully it will help answer your questions.
请注意理解这 4 个声明之间的区别:
以下 2 个声明在语义上是相同的。 您可以更改 ccp1 和 ccp2 指向的位置,但无法更改它们所指向的内容。
接下来,指针是 const,因此为了有意义,必须将其初始化为指向某个内容。 你不能让它指向其他东西,但是它指向的东西可以被改变。
最后,我们将两者结合起来——这样所指向的东西就不能被修改,并且指针也不能指向其他任何地方。
顺时针螺旋法则可以帮助理清声明 http://c-faq.com/decl/ spiral.anderson.html
Take care to understand the difference between these 4 declarations:
The following 2 declarations are identical semantically. You can change where ccp1 and ccp2 point, but you can't change the thing they're pointing at.
Next, the pointer is const, so to be meaningful it must be initialised to point to something. You can't make it point to something else, however the thing it points to can be changed.
Finally, we combine the two - so the thing being pointed at cannot be modified, and the pointer cannot point to anywhere else.
The clockwise spiral rule can help untangle a declaration http://c-faq.com/decl/spiral.anderson.html
需要注意的是,当我阅读此处时,注意到这一点很有用
As a little note, as I read here, it's useful to notice that