search

Home  >  Q&A  >  body text

Problem assigning base class pointer to derived class

Assign the derived class address to the base class pointer, that is, the base class pointer refers to the derived class object, which is what we usually call polymorphism

But when the reverse is true, forced type conversion is required before compilation can pass.

Download the direct code:

#include<iostream>

usingnamespacestd;

class Base
{
public:
virtual void print()
{
    cout<<"base"<<endl;
}
};

class Derived:public Base
{
public:
void print()
{
cout<<"derived"<<endl;
}
};
int main(void)
{

Base * pb=newB ase();//定义基类指针

Derived * pd=(Derived*)pb;//赋值给派生类指针

pd->print();//调用基类的print输出base

pd->Derived::print();//调用派生类的print输出derived

return 0;
}

I would like to ask why pd->print() calls the print of the base class

Then why after removing the virtual of the base class, the print of the derived class is called

曾经蜡笔没有小新曾经蜡笔没有小新2733 days ago1190

reply all(3)I'll reply

  • 滿天的星座

    滿天的星座2017-06-05 11:13:46

    Which virtual function to call is determined by the virtual function table pointed to by the object. When you use new Base(), the virtual function in the virtual function table pointed to by pb is Base. Forced conversion with (Derived*) does not change Changes, non-virtual functions are mainly based on pointer types, that is to say, pd is Derived from the beginning, so using Derived functions, the member function actually calls this pointer when calling.

    reply
    0
  • 怪我咯

    怪我咯2017-06-05 11:13:46

    The virtual specifier specifies that a non-static member function is virtual and supports dynamic binding. It may only appear in the decl-specifier-seq of the initial declaration of a non-static member function (i.e., when it is declared in the class definition).

    Virtual functions are member functions whose behavior can be overridden in derived classes.

    Using virtual means that this function can be overridden by the subclass, so that the parent class pointer pointing to the subclass does not call this function according to the category of the pointer itself, and (by checking the virtual function table V-Table) the function after being overridden by the subclass is called function.
    It’s worth mentioning

    Base * pb=new Base();//定义基类指针
    Derived * pd=(Derived*)pb;//赋值给派生类指针

    Writing like this is incorrect, at least it is unsafe. The parent class pointer pointing to the parent class object should not be assigned to the subclass pointer.

    The pd->print here points to the print of the parent class in the virtual function table, so

    pd->print();                    //调用父类的print,输出base

    The call is Base::print

    Next

    pd->Derived::print();

    This is to forcefully call the function of the subclass on the parent class object (or use the parent class object as this and forcefully call the subclass print in the virtual function table). This is generally not recommended.

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-06-05 11:13:46

    This is really the case. I just ran it and it is really difficult to understand.

    Let me talk about my thinking. I don’t know if it’s right or not. You can refer to it:

    In the first case, virtual is written. If the member function is added virtual, it means that it is dynamically bound. The address of the called function will only be found during execution. But where to find it? It seems that there is a virtual table in the memory of each object (it is also said that each class has a virtual table, which is shared by objects). Because your Derived pointer points to the memory of the Base object, the system goes to that block. Find the print function in the virtual table of the memory. The address of the print function in the virtual table of the memory is the address of the print function of the Base class, so the print function of the base class is called

    Second case: If virtual is used, dynamic binding is not involved. The address of the function is determined during compilation. How to determine the function address during compilation: it is obtained by searching in the source program symbol table. Then pd->print() in the main program. Obviously, pd is the Derived class, and pd->print() is equivalent to Derived::print. Then the compiler will look for it in the Derived class, so pd is used during compilation. ->The address of print() in print() is replaced with the address of Derived::print, so the print function of the subclass is called.

    I don’t know if you understand what I’m saying

    reply
    0
  • Cancelreply