2

I have this simple testing code:

class father{
    public:
        father()= default;
        virtual void func(){
            cout <<"father" << endl;
        }
};

class child:public father{
    public:
        child() = default;
        void func(){
            cout << "child" << endl;
        }
};

int main(){
    father* fptr = new child;
    auto s = *fptr; //why type of s will be father?
    (*fptr).func(); //child
    s.func(); //father
    return 0;
}

I don't know why type s will be father. If dereference a pointer will eliminate the polymorphism, why (*fptr).func();works fine?

Kevin eyeson
  • 375
  • 4
  • 8
  • It's because you assign it by copying to `s` which is a `father`. And it is a `father` because `fptr` is a `father*`. The `child` object will be sliced and copied into the `father` s. – wohlstad Jan 20 '23 at 08:34
  • 2
    Note that in C++, types need to be resolved at compile time. Generally, when you dereference a pointer-to-base, the compiler cannot derive the type of the pointed-to object. – Daniel Langr Jan 20 '23 at 08:47

3 Answers3

4

Because fptr is a pointer to father then the deduced type of s will be father and with

auto s = *fptr;

you get a copy of the father part of the object.

But in the expression (*fptr).func() the result of (*fptr) is a reference (more specifically an rvalue reference). Polymorphism works either through pointers, or through references.

auto& s = *fptr;

or

auto&& s = *fptr;

will both make your program work.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

fptr is a pointer to father.
It's OK to use it for polymorphic calls, when the actual object it points to is a child, but the type of it is still a father*.
Therefore the expression *fptr is of type father and that is the type deduced for s.

(to be more precise: the type of *fptr is rvalue reference. But since reference is not deduced as a part of auto unless explicitly specified, the type of s is deduced to father).

The assignment:

auto s = *fptr; 

Is therefore copying into the new object s:
The actual child pointed by fptr is sliced and copied into s.

Regarding (*fptr).func():
See @Someprogrammerdude's answer.

wohlstad
  • 12,661
  • 10
  • 26
  • 39
1
auto s = *fptr; 

Expanded to

Father s = *fptr;

The object pointed by fptr will be copied into s which is just an object of type Father and holds no additional information from child. This is called object slicing.

Vahan
  • 166
  • 13