【为什么】我可以从构造函数中调用虚函数吗?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

相关文章
|
2月前
|
C++
9. C++虚函数与多态
9. C++虚函数与多态
33 0
|
2月前
|
设计模式 编解码 算法
【C/C++ 虚函数以及替代方案】C++ 虚函数的使用开销以及替代方案(三)
【C/C++ 虚函数以及替代方案】C++ 虚函数的使用开销以及替代方案
43 0
|
2月前
|
安全 编译器 程序员
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
115 3
|
2月前
|
算法 安全 编译器
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
29 0
|
2月前
|
算法 Java 编译器
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
28 0
|
2月前
|
存储 编译器 C++
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
|
4天前
|
编译器 C++
【C++从练气到飞升】03---构造函数和析构函数
【C++从练气到飞升】03---构造函数和析构函数
|
6天前
|
存储 编译器 对象存储
【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)
【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)
7 0
|
11天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-3
c++初阶------类和对象(六大默认构造函数的揭破)
|
11天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-2
c++初阶------类和对象(六大默认构造函数的揭破)