C++, Classes, Const, and strange syntax

2020-03-02 02:53发布

I was re-reading c++ primer(4th ed.) today - the section on member functions and const references etc, and I came up with this wierd little program:

using std::cout;
using std::endl;

class ConstCheater
{
public:
    ConstCheater(int avalue) : ccp(this), value(avalue) {}
    ConstCheater& getccp() const {return *ccp;}
    int value;
private:
    ConstCheater* ccp;
};

int main()
{
    const ConstCheater cc(7); //Initialize the value to 7
    cout << cc.value << endl;
    cc.getccp().value = 4;    //Now setting it to 4, even though it's const!
    cout << cc.value << endl;
    cc.value = 4;             //This is illegal
    return 0;
}

My question is - why does c++ allow syntax such as this? Why can I edit normal data members in a class when it's declared const? Isn't the POINT of const to make it so that you can't modify values?

8条回答
SAY GOODBYE
2楼-- · 2020-03-02 03:56

The constructor is allowed to modify the value of a const object, yes. But if it weren't, what could it do?

Since the constructor has such access, it can "forward" it to someone else or "save" it for later. Of course, doing so might be a bad idea.

This is one instance where the safety mechanisms of C++ do not prevent you from building an ill-formed program. C++ is anything but foolproof. So, just be careful!

查看更多
Melony?
3楼-- · 2020-03-02 03:57

The real issue isn't the behavior of ConstCheater::getccp() - it's that there's no error on the line:

const ConstCheater cc(7);

which initializes a non-const pointer with what should be a const this pointer. However, constructors cannot be const (9.3.2/5, but a bit of thought should make it obvious why). So the constructor is allowed to initialize a non-const pointer with a pointer to a const object (or an object that's 'about to become' const). That's the hole you're driving though.

As to why it's allowed, I imagine it would be difficult for the standard to try to close the hole since it would have to enumerate all the ways that a constructor's this would have to be treated const and all the ways it would have to be treated non-const when constructing a const object. That seems like a pretty difficult task.

查看更多
登录 后发表回答