您的位置:首页 > 游戏 > 手游 > 怎么才能在百度上打广告_彼亿营销_seo公司系统_彩虹云商城网站搭建

怎么才能在百度上打广告_彼亿营销_seo公司系统_彩虹云商城网站搭建

2024/12/23 15:40:02 来源:https://blog.csdn.net/cd_yourheart/article/details/144052786  浏览:    关键词:怎么才能在百度上打广告_彼亿营销_seo公司系统_彩虹云商城网站搭建
怎么才能在百度上打广告_彼亿营销_seo公司系统_彩虹云商城网站搭建

在 C++ 中,构造函数和析构函数中调用虚函数的行为是不推荐的,因为此时虚函数的 动态绑定 特性无法正常发挥作用。这是由对象的构造和析构过程中的特殊语义决定的。


原因分析

1. 构造函数中的虚函数调用
  • 在构造一个派生类对象时,构造函数是按照从基类到派生类的顺序依次调用的。
  • 当基类的构造函数运行时,派生类部分尚未构造完成,因此调用虚函数会调用 当前类中(基类中) 的版本,而不是派生类的版本。

示例代码

#include <iostream>
class Base {
public:Base() {std::cout << "Base Constructor\n";show(); // 虚函数调用}virtual ~Base() {std::cout << "Base Destructor\n";}virtual void show() const {std::cout << "Base::show()\n";}
};class Derived : public Base {
public:Derived() {std::cout << "Derived Constructor\n";}~Derived() {std::cout << "Derived Destructor\n";}void show() const override {std::cout << "Derived::show()\n";}
};int main() {Derived d;return 0;
}

输出结果

Base Constructor
Base::show()
Derived Constructor
Derived Destructor
Base Destructor

解释

  • Base 的构造函数中,调用虚函数 show()
  • 因为此时 Derived 部分尚未构造完成,虚表指针 (vptr) 指向的是 Base 的虚表,所以调用的是 Base::show()
  • 这可能与用户的预期不符,导致错误行为。

2. 析构函数中的虚函数调用
  • 在析构一个派生类对象时,析构函数是按照从派生类到基类的顺序依次调用的。
  • 当基类的析构函数运行时,派生类部分已经销毁,因此调用虚函数时只会调用 当前类中(基类中) 的版本,而不是派生类的版本。

示例代码

#include <iostream>
class Base {
public:virtual ~Base() {std::cout << "Base Destructor\n";show(); // 虚函数调用}virtual void show() const {std::cout << "Base::show()\n";}
};class Derived : public Base {
public:~Derived() {std::cout << "Derived Destructor\n";}void show() const override {std::cout << "Derived::show()\n";}
};int main() {Base* b = new Derived();delete b;return 0;
}

输出结果

Derived Destructor
Base Destructor
Base::show()

解释

  • Base 的析构函数运行时,Derived 的部分已经销毁。
  • 虚表指针 (vptr) 被重置为指向 Base 的虚表,因此调用 show() 会调用 Base::show(),而不是 Derived::show()

设计决策

  • 安全性:调用虚函数可能依赖派生类中的资源,而这些资源在构造或析构阶段可能未初始化或已销毁。
  • 一致性:保证在构造和析构函数中调用的成员函数是当前类的版本,避免不确定行为。

解决方法

  1. 避免在构造函数或析构函数中直接调用虚函数

    • 如果需要调用函数,可以调用基类中的非虚函数,或设计一种显式的初始化函数。
  2. 使用委托设计

    • 将需要动态绑定的行为推迟到对象完全构造完成之后再执行。

示例代码

#include <iostream>
#include <memory>class Base {
public:virtual ~Base() {}virtual void show() const = 0;void init() {show(); // 在对象构造完成后调用}
};class Derived : public Base {
public:void show() const override {std::cout << "Derived::show()\n";}
};int main() {std::unique_ptr<Base> obj = std::make_unique<Derived>();obj->init(); // 确保对象完全构造后调用虚函数return 0;
}

输出

Derived::show()

总结

  • 在构造函数和析构函数中调用虚函数会导致动态绑定失效。
  • 这是由于对象的构造和析构过程中,虚表指针 (vptr) 尚未设置或已重置。
  • 为避免问题,推荐推迟虚函数的调用,或使用非虚函数替代设计。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com