demo:
#include<iostream>
struct A { int i = 10; };
struct B : A { };
int main(){
std::cout << "decltype(&B::i) == int A::* ? " << std::boolalpha
<< std::is_same<decltype(&B::i), int A::*>::value << '\n'; //#1
A a;
std::cout << a.*(&A::i) << '\n';
std::cout << "decltype(&B::i) == int B::* ? "
<< std::is_same<decltype(&B::i), int B::*>::value << '\n'; //#2
B b;
std::cout << b.*(&B::i) << '\n';
}
The code prints
decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false
10
I used the example in [expr.unary.op]/3, where the standard says that the type of &B::i
is int A::*
, but that is not normative.
Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.
So, a pointer is type of base class, and it can access all, public function and variables of base class since pointer is of base class, this is known as binding pointer. In this pointer base class is owned by base class but points to derived class object. Same works with derived class pointer, values is changed.
Derived class pointer cannot point to base class.
The Base class members and member functions are inherited to Object of the derived class. A base class is also called parent class or superclass. Derived Class: A class that is created from an existing class. The derived class inherits all members and member functions of a base class.
From the paragraph you link to, emphasis mine:
If the operand is a qualified-id naming a non-static or variant member
m
of some classC
with typeT
, the result has type “pointer to member of classC
of typeT
” and is a prvalue designatingC::m
.
"Some class C
" means it need not be the same class as the one mentioned by the qualified-id. In this case, i
is a member of A
, and remains a member of A
even when named by &B::i
. The type of &B::i
is therefore int A::*
, which you can verify by the test
std::is_same<decltype(&B::i), int A::*>::value
According to [class.qual]/1, member lookup follows the algorithm detailed in [class.member.lookup]. It is according to the rules there, which inspect the sub-object from which the member i
comes from, that the class C
is determined. Since i
is a member of the sub-object A
, the class of the pointer to member is determined to be A
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With