简体   繁体   中英

How the const-ness of a class object affects members of that class?

AFAIK a const object of a class type causes its all members to be const as well. And a pointer to a plain object cannot point to a const object.

In this example I am trying to understand Pointer to Member of class:

struct Foo{
    int value_ = 1024;
};

int main(){

    int Foo::* ptr = &Foo::value_; // ptr is a pointer to any non-const non-static integer member data
    Foo f;
    ++(f.*ptr);// ok

    Foo const cf;
    // ++(cf.*ptr); // error. OK
    std::cout << cf.*ptr << '\n';

    std::cout << "\ndone!\n";
}

As you can see ptr is a pointer to a non-static non-const member data of class Foo of type int , which means it cannot point to a const integer member data.

  • cf is a const object of type class Foo , and we know that members of a constant object are themselves constant so why is this allowed:

     std::cout << cf.*ptr << '\\n'; // why allowed?
  • cf 's value_ is now constant because cf is const so why it is allowed to bind the pointer ptr to that constant member data?

Pointers to members of a class are rarely used features and are very different from normal pointers.

  • They only hold the offset to the member within the class
  • You cannot increment or decrement the pointer itself as you can do with a normal pointer

The way I look at these pointers is that they just create a new name or a new way to access the member of the class if they happen to be public members.

With your pointer to a member of a const object, the compiler knows that it is currently pointing to a member of a const object. And you will be fine, as long as you are only accessing the data member and not modifying it.

Modifying your case as below, where the data element itself is a const, in this case also you will be able to read the data member, but the compiler will not allow you to change the data member. Also, note that you will need to declare the class member pointer to be pointing to a const int.

struct Foo
{
    const int value_ = 1024;
};

int main()
{
    const int Foo::* ptr = &Foo::value_;
    Foo f;
    //++(f.*ptr);// Error
    std::cout << f.*ptr << '\n';  //OK, works

    Foo const cf;
    // ++(cf.*ptr); // error. OK
    std::cout << cf.*ptr << '\n';

    std::cout << "\ndone!\n";
}

These being said, you should rarely ever find the need to use pointers to data members of a class.

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