Understanding the use of virtual function and pointer

After understanding the section, as far as I can see, it can be broken using pointers to dynamic variables. But how did it happen? Why is there no slicing at this moment? I think, but I'm not sure. After assignment ppet = pdog; pdog points to the same ppet address. Is not it?

 //Program to illustrate use of a virtual function //to defeat the slicing problem. #include <string> #include <iostream> using namespace std; class Pet { public: virtual void print(); string name; }; class Dog : public Pet { public: virtual void print();//Keyword virtual not needed, but put //here for clarity. (It is also good style!) string breed; }; int main() { Dog vdog; Pet vpet; vdog.name = "Tiny"; vdog.breed = "Great Dane"; vpet = vdog; //vpet.breed; is illegal since class Pet has no member named breed Dog *pdog; pdog = new Dog; pdog->name = "Tiny"; pdog->breed = "Great Dane"; Pet *ppet; ppet = pdog; ppet->print(); // These two print the same output: pdog->print(); // name: Tiny breed: Great Dane //The following, which accesses member variables directly //rather than via virtual functions, would produce an error: //cout << "name: " << ppet->name << " breed: " // << ppet->breed << endl; //generates an error message: 'class Pet' has no member //named 'breed' . //See Pitfall section "Not Using Virtual Member Functions" //for more discussion on this. return 0; } void Dog::print() { cout << "name: " << name << endl; cout << "breed: " << breed << endl; } void Pet::print() { cout << "name: " << endl;//Note no breed mentioned } 

Output:

 The slicing problem: name: Tiny Note that it was print from Pet that was invoked. The slicing problem defeated: name: Tiny breed: Great Dane name: Tiny breed: Great Dane 
+5
source share
2 answers

Derived classes essentially “start” with an instance of their base classes, followed by any additional fields added by the derived class. So:

 class Base { int a, b; }; class Derived { int c, d; }; 

A Derived instance looks like this:

 [a] [b]|[c] [d] 

If you now draw it into a Base instance, this will happen:

 [a] [b]|nothing 

Pointers to objects, on the other hand, always have the same size regardless of type, so a pointer to a base can point to a derived object and not lose any information. The beginning of the Base part of the Derived object is exactly the same address as the Derived object itself.

+3
source

When you define a class , its members define its memory layout. Class data elements are stored sequentially in memory.

When deriving classes and inheritance is used, data members of the derived class are simply added after the base class.

Thus, when a slice occurs, you effectively “see” only the base classes.

Now, to the question "Why do not pointers to the base class cut objects of the derived class"?

One of the most important aspects of inheritance is not that it provides member functions for the derived class, but that it provides the relationship expressed between the derived class and the base class. A derived class can be thought of as a "type of base class."

For further reading, check the rise and fall conditions.

Upcasting converts a reference to a derived class or a pointer to a base class. In other words, increasing efficiency allows us to process a derived type as if it were its base type.

To answer your questions from the comments section, “What Override?

Getting a function with the same name and type of virtual function from the base class is called the caller.

0
source

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


All Articles