Sell me on const correctness

2019-01-01 05:15发布

So why exactly is it that it's always recommended to use const as often as possible? It seems to me that using const can be more of a pain than a help in C++. But then again, I'm coming at this from the python perspective: if you don't want something to be changed, don't change it. So with that said, here are a few questions:

  1. It seems like every time I mark something as const, I get an error and have to change some other function somewhere to be const too. Then this causes me to have to change another function somewhere else. Is this something that just gets easier with experience?

  2. Are the benefits of using const really enough to compensate for the trouble? If you don't intend on changing an object, why not just not write code that doesn't change it?

I should note that at this point in time, I'm most focused on the benefits of using const for correctness and maintainability purposes, although it is also nice to have an idea of the performance implications.

16条回答
只靠听说
2楼-- · 2019-01-01 06:04

When you use the "const" keyword, you're specifying another interface to your classes. There is an interface that includes all methods, and an interface that includes only the const methods. Obviously this lets you restrict access to some things that you don't want changed.

Yes, it does get easier with time.

查看更多
人气声优
3楼-- · 2019-01-01 06:05

const helps you isolate code that "change things" behind your back. So, in a class, you'd mark all methods that don't change the state of the object as const. This means that const instances of that class will no longer be able to call any non-const methods. This way, you're prevented from accidentally calling functionality that can change your object.

Also, const is part of the overload mechanism, so you can have two methods with identical signatures, but one with const and one without. The one with const is called for const references, and the other one is called for non-const references.

Example:

#include <iostream>

class HelloWorld {
    bool hw_called;

public:
    HelloWorld() : hw_called(false) {}

    void hw() const {
        std::cout << "Hello, world! (const)\n";
        // hw_called = true;  <-- not allowed
    }

    void hw() {
        std::cout << "Hello, world! (non-const)\n";
        hw_called = true;
    }
};

int
main()
{
    HelloWorld hw;
    HelloWorld* phw1(&hw);
    HelloWorld const* phw2(&hw);

    hw.hw();    // calls non-const version
    phw1->hw(); // calls non-const version
    phw2->hw(); // calls const version
    return 0;
}
查看更多
回忆,回不去的记忆
4楼-- · 2019-01-01 06:05

There is a nice article here about const in c++. Its a pretty straight forward opinion but hope it helps some.

查看更多
其实,你不懂
5楼-- · 2019-01-01 06:08

I like const correctness ... in theory. By every time I have tried to apply it rigourously in practice it has broken down eventually and const_cast starts to creep in making the code ugly.

Maybe it is just the design patterns I use, but const always ends up being too broad a brush.

For example, imagine a simple database engine ... it has schema objects, tables, fields etc. A user may have a 'const Table' pointer meaning that they are not allowed to modify the table schema itself ... but what about manipulating the data associated with the table? If the Insert() method is marked const then internally it has to cast the const-ness away to actually manipulate the database. If it isn't marked const then it doesn't protect against calling the AddField method.

Maybe the answer is to split the class up based on the const-ness requirements, but that tends to complicate the design more than I would like for the benefit it brings.

查看更多
登录 后发表回答