【为什么】我可以从构造函数中调用虚函数吗?C++之父谈

简介: 【为什么】我可以从构造函数中调用虚函数吗?C++之父谈

此文为C++之父撰写,本篇为翻译

是的,但要小心。 它可能不会做你期望的。 在构造函数中, 虚拟调用机制被禁用,因为从派生覆盖 课程还没有发生。 对象是从基础向上构建的, “派生前的基础”。

考虑到

#include<string>
  #include<iostream>
  using namespace std;
  class B {
  public:
    B(const string& ss) { cout << "B constructor\n"; f(ss); }
    virtual void f(const string&) { cout << "B::f\n";}
  };
  class D : public B {
  public:
    D(const string & ss) :B(ss) { cout << "D constructor\n";}
    void f(const string& ss) { cout << "D::f\n"; s = ss; }
  private:
    string s;
  };
  int main()
  {
    D d("Hello");
  }

image.gif

程序编译并生成

B constructor

B::f

D constructor

注意 不是 D::f。 考虑如果规则不同会发生什么 D::f() 是 从 B::B() 调用:因为构造函数 D:: D() 尚未运行, D::f() 会尝试将其参数分配给未初始化的字符串 s。 结果很可能是立即崩溃。

破坏是“在基类之前的派生类”完成的,因此虚函数 与构造函数中的行为相同:仅使用局部定义 - 不使用 调用重写函数以避免触及(现已销毁) 对象的派生类部分。

有关详细信息,请参阅 D&E 13.2.4.2 或 TC++PL3 15.4.3。

有人建议此规则是一个实现工件。 这是 不是这样。 事实上,实施不安全规则会容易得多 从构造函数中调用虚函数与从其他函数中调用虚函数完全一样。 但是,这意味着不能编写任何虚函数来依赖 关于由基类建立的不变量。 那将是一团糟。

注意:可以结合这篇文章来看https://www.cnblogs.com/wozhuyinghao/p/17148698.html

相关文章
|
C++
C++一分钟之-虚函数与抽象类
【6月更文挑战第21天】在C++中,虚函数与抽象类是多态的基础,增进类间耦合与灵活性。虚函数实现动态绑定,抽象类定义不可实例化的接口。关键点包括:记得使用`virtual`,避免滥用虚函数,确保派生类实现纯虚函数。抽象类不能直接实例化,派生类必须实现所有纯虚函数。通过实例代码学习和实践,能更好地掌握这些概念以优化代码设计。
161 2
|
9月前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
135 4
|
9月前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
180 3
|
11月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
268 5
|
11月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
590 4
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
210 30
|
12月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
103 2
|
12月前
|
C++
C++构造函数初始化类对象
C++构造函数初始化类对象
98 0
|
12月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
114 0
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数