【c++】动态绑定
发布时间:2022-02-25 10:27:35

C++的函数调用默认不使用动态绑定。要触发动态绑定,必须满足两个条件:

只有指定为虚函数的成员函数才能进行动态绑定

必须通过基类类型的引用或指针进行函数调用

因为每个派生类对象中都拥有基类部分,所以可以使用基类类型的指针或引用来引用派生类对象

示例

#include <iostream>
#include <string>
using namespace std;
struct base
{
    base(string str = "Base") : basename(str) {}
    virtual void print() { cout << basename << endl; }
private:
    string basename;
};
struct derived : public base
{
    derived(string str = "Derived") : derivedname(str) {}
    void print() { cout << derivedname << endl; }
private:
    string  derivedname;
};
int main(int argc, const char * argv[]) {
    base b;
    derived d;
    cout << "b.print(), d.print()" << endl;
    b.print();
    d.print();
    base *pb = &b;
    base *pd = &d;
    cout << "pb->print(), pd->print()" << endl;
    pb->print();
    pd->print();
    base &yb = b;
    base &yd = d;
    cout << "yb.print(), yd.print()" << endl;
    yb.print();
    yd.print();
    return 0;
}

结果:

 

分析

可以看出基类类型的指针或引用来引用派生类对象时,调用的是重定义的虚函数。要想覆盖虚函数机制,调用基函数的版本,可以使用强制措施。例:

代码

#include <iostream>
#include <iostream>
#include <string>
using namespace std;
struct base
{
    base(string str = "Base") : basename(str) {}
    virtual void print() { cout << basename << endl; }
    private:
        string basename;
};
struct derived : public base
{
    derived(string str = "Derived") : derivedname(str) {}
    void print() { cout << derivedname << endl; }
    private:
        string  derivedname;
};

int main()
{
    base b;
    derived d;
    cout << "b.print(), d.print()" << endl;
    b.print();
    d.base::print();

    base *pb = &b;
    base *pd = &d;
    cout << "pb->print(), pd->print()" << endl;
    pb->print();
    pd->base::print();

    base &yb = b;
    base &yd = d;
    cout << "yb.print(), yd.print()" << endl;
    yb.print();
    yd.base::print();
    return 0;
}

结果