简体   繁体   中英

Able to change private const class member

Why does c++ allow changing private member(const or not) from outside class. No one outside the class should be able to change a const member. This seems to be breaking the c++ encapsulation.

#include <iostream>
#include <cstdlib>
#include <string>

class A
{
    const std::string s;
    public:

    A():s{"abcd"}{};
    const std::string& f()
    {
        return s;
    }
};

int main()
{
    A a;
    std::string &s = const_cast<std::string&>(a.f());
    s="efgh";
    std::cout<<s<<std::endl;
    std::cout<<a.f()<<std::endl;
    return 0;
}

Compilation was done using c++11 on wandbox online compiler.

g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.69.0/gcc-head/include -std=c++11

Output is:

efgh
efgh

I expected compilation error on: std::string &s = const_cast(af());

I should not be allowed to change a private class member(const or non const) from outside in any way if there are no methods to do so.

That's undefined behavior.

The fact that it allows you to do it doesn't mean that is right, modifying a const object through a non const one is undefined behavior, anything can happen, including the appearance of working.

I should not be allowed to change a private class member(const or non const) from outside in any way if there are no methods to do so.

Accessibility of data members is somewhat unrelated to accessibility of member functions and what they do, you can have private members and public functions that alter or give certain access to them without violating the inherent properties of the members. In your example foo is returning a ref to const std::string which express clearly the intent ( it's a const object ) but then outside you're violating that intent.

It doesn't.

When you stripped away the const with a const_cast , you literally turned off the protection that you're asking about. That was your responsibility. C++ has to permit this to allow "hacks" in the general case; per its philosophy, it makes no serious effort to stop you from breaking the contract. But, ultimately, you did break a contract, so it's your fault!

Your program has undefined behaviour as a result; ie the code is broken.

The bypassing of private is totally fine as you directly exposed the member through a member function. (Access specifiers protect names , not objects, and your main does not use the private name.) Again, that was your choice. You broke the class's encapsulation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM