C++ 构造函数、析构函数调用虚函数

C++虚函数是通过虚表实现的,虚函数的地址记录在虚表中,只对象完成构造完成后,虚函数的地址才最终确定。

构造函数中调用虚函数

基类先于派生类构造,所以构造时没法调用到派生类的虚函数,也就是说只能调用到自己这一层,也就是虚函数失去多态功能。

析构函数调用虚函数

派生类先于基类析构,所以析构时基类没法调用到派生类的虚函数,同样只能调用到自己这一层,虚函数也失去多态功能。

代码

#include <iostream>

class Base
{
public:
    Base()
    {
        std::cout << "Base Construct.  ";
        this->fun2("Base::Base");
    }

    virtual ~Base()
    {
        std::cout << "Base Destruct.  ";
        this->fun2("Base::~Base");
    }

    virtual void fun()
    {
        std::cout << "Base::fun" << std::endl;
    }

    virtual void fun2(const char* caller)
    {
        std::cout << "Base::fun2, caller: " << caller << std::endl;
    }
};

class Derive : public Base
{
public:
    Derive()
    {
        std::cout << "Derive Construct.  ";
        this->fun2("Derive::Derive");
    }

    ~Derive() override
    {
        std::cout << "Derive Destruct.  ";
        this->fun2("Derive::~Derive");
    }

    void fun2(const char* caller) override
    {
        std::cout << "Derive::fun2: caller: " << caller << std::endl;
    }

    void fun() override
    {
        std::cout << "Derive::fun" << std::endl;
    }
};

int main()
{
    Base *p = new Derive;
    delete p;
    return 0;
}

运行结果:

Base Construct.  Base::fun2, caller: Base::Base
Derive Construct.  Derive::fun2: caller: Derive::Derive
Derive Destruct.  Derive::fun2: caller: Derive::~Derive
Base Destruct.  Base::fun2, caller: Base::~Base

在构造函数函数或者析构函数中调用虚函数,通常IDE会有警告,为了消除警告可以通过域名符号调用虚函数,此时相当于直接指定函数地址,不需要通过虚表所以不会有警告

class Base
{
public:
    Base()
    {
        std::cout << "Base Construct.  ";
        Base::fun2("Base::Base"); // 虚函数
    }

    virtual ~Base()
    {
        std::cout << "Base Destruct.  ";
        Base::fun2("Base::~Base"); // 虚函数
    }

    virtual void fun()
    {
        std::cout << "Base::fun" << std::endl;
    }

    virtual void fun2(const char* caller)
    {
        std::cout << "Base::fun2, caller: " << caller << std::endl;
    }
};

类函数指针

当类函数指针指向一个虚函数时,同样会触发多态,并不会直接调用函数指针对应的函数

#include <iostream>

class Base
{
public:
    virtual void fun()
    {
        std::cout << "Base::fun" << std::endl;
    }

};

class Derive : public Base
{
public:
    void fun() override
    {
        std::cout << "Derive::fun" << std::endl;
    }
};

int main()
{
    Base *p = new Derive;


    p->fun();
    p->Base::fun();
    auto pBFun = &Base::fun;
    auto pDFun = &Derive::fun;

    (p->*pBFun)();
    ((Derive*)p->*pDFun)();

    return 0;
}

结果

Derive::fun
Base::fun
Derive::fun
Derive::fun

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值