静态联编和动态联编

静态联编:在编译时确定函数的调用,根据指针或引用的类型来决定调用哪个类的函数,而不是根据指针或引用的实际对象来调用哪个类的函数

动态联编:在运行时确定函数的调用,根据指针或引用的实际指向来决定调用哪个类的函数,而不是根据指针或引用的类型来决定调用哪个类的函数

1.要进行动态联编,要在父类同名函数前面必须加上virtual,子类加不加无所谓,因为父类的虚函数特性会被子类继承

2.虚函数virtual的本质,是增加了一个虚函数指针,这个指针指向底层的虚函数表,虚函数表记录着你函数调用的地址,那么调用这个函数的时候,他会顺着表

找到实际执行的函数

3.为什么要存在virtual, void showData(const Parent *p){ p->show() } 这样通用范围更广,父类对象进入,使用的是父类的show函数,子类对象进入使用的是

子类的show函数。using namespace stdclass Parent

{
public:

    Parent()
    {
        cout<<"Parent()"<<endl;
        this->privata_data =0;
    }
    Parent(int k)
    {
        this->privata_data =k;
    }

    virtual void show() //加上virtual就是动态联编了
    {
        cout<<"Parent:show"<<this->privata_data<<endl;
    }
    void setPrivatadata(int a)
    {
        this->privata_data = a;
    }

int privata_data;
};

class Sub:public Parent
{
public:
    Sub()
    {
        cout<<"Sub()"<<endl;
        this->name = " ";
    }

    Sub(const string &name,int k=0):Parent(k)
    {
        cout<<"Sub(const string &name,int k=0):Parent(k"<<endl;
        this->name = name;
    }
    void show()
    {
        cout<<"Sub:show"<<this->name<<endl;
    }

    ~Sub()
    {
        cout<<"~Sub()"<<endl;
    }

private:
    string name;
};
void showData(Parent *p)
{
    p->show();
}
int main(int argc, char *argv[])
{
#if 1
    Parent *p = new Sub;//父类指针指向子类对象
    p->show();//静态联编,结果是调用父类的show函数  //动态联编,结果是调用子类的show函数
    delete p;
#endif
#if 1
    Sub s;
    Parent &pref =s;         //父类引用子类对象
    pref.show();   //静态联编,结果为调用父类的show函数  //动态联编,结果是调用子类的show函数
#endif
#if 1   //父类指针和子类指针都能调用,能够自动找到实际地址
    Parent *pa = new Parent;
    Sub    *sa = new Sub;
    showData(pa);
    showData(sa);
#endif
#if 0
    Sub *s = new Parent;    子类不能指向父类(儿子不能打老子)
    Parent p; Sub &s1 = p;
#endif
}
原文地址:https://www.cnblogs.com/xiaozoui11cl/p/12766489.html