0

Suppose I have the following code. I have expected that this has to at least give me a warning.

#include <iostream>

struct test
{
    int whatever;
};

int main()
{
    int test::* p = &test::whatever;    
    std::cout << p;
}

However, I was surprised to find out that this code compiles without complaints. So I would like to know, what is actually printed in this case, how is the test::whatever stored, so we can access its address?

Karen Baghdasaryan
  • 2,407
  • 6
  • 24

3 Answers3

3

how is the test::whatever stored

This is not specified in the language. But we can make a reasonable guess that it stores an offset from the beginning of the object to the pointed member.

so we can access its address?

No.

what is actually printed in this case

1 is printed.

There is no operator overload for member pointers. But there is an overload for bool and member pointers are convertible to bool. They convert to true when they aren't null. p isn't null, so it converts to true which prints as 1.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Here p is pointer to member. It is like an offset of the class member relative to the object base address. It doesn't point to anywhere in memory by itself. It needs a base object pointer to point somewhere. Therefore it is not illegal to have a pointer to member without an object, just the opposite: it is the use case of this type.

You can use it like:

#include <iostream>

struct test
{
    int whatever;
};

int main()
{
    int test::* p = &test::whatever;

    test t = {5};
    std::cout << t.*p << std::endl; // prints 5
}

However, I don't know what is printed out in the example you gave.

See Pointer-to-Member ->* and .* Operators in C++.

0

It is member pointer, as already pointed in first answer. You can use it to point to different members of different objects:


struct test
{
    int whatever;
};

int main()
{
    int test::* p = &test::whatever;
    test w1{ 123 }, w2{ 234 };
    std::cout << p<< endl; //point to member
    std::cout << w1.*p << endl; //value of first whatever
    std::cout << w2.*p << endl; //value of second whatever

    //real address of whatever of w1 and w2, compare
    std::cout << &(w1.*p) << "=="<< &w1.whatever<< endl;
    std::cout << &(w2.*p) << "=="<< &w2.whatever<< endl;

    std::cout << p << endl; //yet pointer did not change
    return 0;
}
armagedescu
  • 1,758
  • 2
  • 20
  • 31