Base Class Pointer Member

everything. I cannot understand why the following code needs a drive to work. Can anyone explain this?

class Base {
};

class Derived : public Base {
};

class Class {
public:
    Derived member;
};

...

Derived obj;
Base *ptrObj = &obj; // ok, no cast needed

Derived Class::* ptr = &Class::member; // ok
Base    Class::* ptr = &Class::member; // wrong, need cast, why?
+3
source share
2 answers

Because, if Baseallowed (covariantly), you can do it that no-no:

Base Class::* ptr = &Class::member;
Class obj;
obj.*ptr = Base();   // <-- assigned a Base into a Derived field?!

At the same time, member pointers also cannot be contravariant, because otherwise you could do it, which is also no-no:

struct Class2 {
    Base member;
};

Derived Class2::* ptr2 = &Class2::member;
Class2 obj2;
obj2.member = Base();
Derived& d = obj2.*ptr2;  // <-- assigned a Base into a Derived

Thus, pointers to elements are neither covariant nor contravariant, but are invariant: the type must exactly match.

+4
source

, , . -? . .

Derived obj;
Base *ptr = &obj;

*ptr = Base(); // it weird, but ok

, downcasting . , .

0

Source: https://habr.com/ru/post/1730768/


All Articles