前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >构造函数调用子类的方法,写过吗?

构造函数调用子类的方法,写过吗?

作者头像
gaigai
发布于 2021-04-13 06:32:04
发布于 2021-04-13 06:32:04
1.6K00
代码可运行
举报
文章被收录于专栏:Windows开发Windows开发
运行总次数:0
代码可运行

系统学习Windows客户端开发


先看一段示例代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
using namespace std;

class Base
{
public:
    Base() 
    {
        cout << "Base constructor" << endl;
        cout << "Value is " << GetValue() << endl;
    }

    ~Base() 
    {
        cout << "Base destructor" << endl;
        cout << "Value is " << GetValue() << endl;
    }

protected:
    virtual int GetValue() { return 1; }
};

class Derive : public Base
{
public:
    Derive() : Base() 
    {
        cout << "Derive constructor" << endl;
    }

    ~Derive()
    {
        cout << "Derive destructor" << endl;
    }

protected:
    virtual int GetValue() { return 2; }
};

int main()
{        
    Derive derive;
    return 0;
}

这段示例代码,类Derive派生于Base,Base的构造函数与虚构函数均调用虚函数GetValue(),根据C++多态特性,应该是要调用Derive的GetValue()返回2,真的是这样吗?让我们看下最终的输出。

从输出的结果看,Base的构造函数与虚构函数均调用Base的GetValue()返回1,而不是Derive的GetValue()。从汇编代码进一步确认,C++编译器确实是直接调用Base的GetValue()地址,而不是通过虚函数指针__vfptr去获得GetValue()的地址。

为什么Base的构造函数与虚构函数即使调用虚函数,也是调自己的函数呢?这跟构造函数与虚构函数的调用顺序有关。子类对象构造的时候,先调父类构造函数初始化父类,再调子类构造函数初始化子类。子类对象虚构的时候,恰恰相反,先调子类对象的虚构函数,再调父类的虚构函数。输出的结果也证明了这点。

所以如果父类的构造函数与虚构函数是调用子类的函数,那就非常危险了。因为父类的构造函数执行时,子类的构造函数还没有执行,说明子类还没有初始化,而这时就调用子类的方法,很容易出错,甚至崩溃。父类的虚构函数执行的时候,子类的虚构函数已经执行完毕,说明子类的资源已经被释放,而这时继续执行子类的方法,也很容易崩溃。于是,C++规范为此作了此约束。

如果真的很想在构造函数内调用子类方法进行初始化,还是显示提供一个初始化函数,让子类对象实例化完后,显示调用初始化函数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Windows开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——11.多态
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态。
hope kc
2024/09/23
1030
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——11.多态
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承后在派生类依旧保持虚函数属性)但是该种写法不规范,大家还是少用为好。
是Nero哦
2024/03/17
6310
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
【C++】多态
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
zxctscl
2024/04/25
1110
【C++】多态
解锁C++继承的奥秘:从基础到精妙实践(上)
继承是C++面向对象编程的核心特性之一,它允许程序员创建层次化的类结构,从而实现代码的重用和扩展。在这篇文章中,我们将深入探讨C++继承的基础概念,包括基类与派生类的关系、多重继承的处理、虚函数与多态的应用,以及如何在复杂系统中有效利用继承来构建可维护且扩展性强的代码架构。通过系统的学习,你将对C++继承有更深入的理解,并能够在实际开发中灵活应用这些知识。
suye
2024/10/16
2220
C++多态
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态 举个例子:比如说买票,普通人是全价买,学生是半价,退伍军人是优先。
有礼貌的灰绅士
2023/04/06
3000
C++多态
C++程序诗篇的灵动赋形:多态
本篇将开启 C++ 三大特性中的多态篇章,多态允许你以统一的方式处理不同类型的对象,通过相同的接口来调用不同的实现方法。这意味着你可以编写通用的代码,而这些代码可以在运行时根据对象的实际类型来执行特定的操作
DARLING Zero two
2025/04/11
750
C++程序诗篇的灵动赋形:多态
C++:多态
编译时多态主要就是函数重载和函数模板,传递不同类型的参数调用不同的函数,通过参数不同达到多种形态。至于叫做编译时多态的原因,是它们实参传给形参的参数匹配是在编译时完成的。
HZzzzzLu
2024/11/26
1140
C++:多态
【C++进阶篇】像传承家族宝藏一样理解C++继承
C++是一个功能强大的面向对象编程语言,它不仅支持过程式编程,还在此基础上提供了许多用于构建复杂软件系统的面向对象特性。继承是C++中最为核心的概念之一,它允许我们通过现有的类(基类)创建新的类(派生类),从而实现代码的重用和扩展。继承是面向对象编程的三个基本特性之一(另外两个是封装和多态),在设计模式、软件架构和大型系统开发中起着至关重要的作用。
熬夜学编程的小王
2024/12/24
1540
【C++进阶篇】像传承家族宝藏一样理解C++继承
【C++】看不懂多态?这篇文章带你吃透它!
​ 该内容中的代码以及解释都是在 vs2022 下的 x86 环境中,涉及的指针都是 4 个字节,如果要在其他的平台下运行,部分代码需要改动。
利刃大大
2025/02/03
760
【C++】看不懂多态?这篇文章带你吃透它!
【C++】继承和多态
继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类/子类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
YoungMLet
2024/03/01
1930
【C++】继承和多态
【C++】多态 ⑤ ( 虚析构函数 | 虚析构函数语法 | 虚析构函数意义 | 父类指针指向子类对象情况下父类和子类使用 virtual 虚析构函数 | 代码示例 )
如果要创建一个 子类的 实例对象 , 需要 从 该子类的 最上层的 父类开始 , 沿着继承路径 , 逐个调用 构造函数 ;
韩曙亮
2023/10/30
1.7K0
【C++】多态 ⑤ ( 虚析构函数 | 虚析构函数语法 | 虚析构函数意义 | 父类指针指向子类对象情况下父类和子类使用 virtual 虚析构函数 | 代码示例 )
十、继承
C++中的继承是一种面向对象编程(OOP)的特性,它允许一个类(称为派生类或子类)继承另一个类(称为基类或父类)的属性和方法。通过继承,派生类可以重用基类的代码,同时添加新的属性和方法或修改继承来的方法。这种机制促进了代码的复用、扩展和维护。
用户11332765
2024/10/28
1170
最全面的c++中类的构造函数高级使用方法及禁忌
编译后报错:错误:constructors cannot be declared ‘virtual’,可见构造函数是不能声明为virtual的,这与虚函数的机制有关,虚函数是存放在虚表的,而虚表是在构造函数执行完成以后才建立的,构造函数声明为virtual就会陷入到是先有鸡还是先有蛋的尴尬境地,所以编译器做了限制。
cpp加油站
2021/05/17
1.9K0
【C++】三大特性之多态
多态的概念:通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会
青衫哥
2023/03/31
8100
【C++】三大特性之多态
【C++修炼之路】16.C++多态
多态的概念: 通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
每天都要进步呀
2023/03/28
5290
【C++修炼之路】16.C++多态
【C++高阶】多态(概念&&虚函数&&抽象类)
在编程的广阔领域中,多态(Polymorphism) 无疑是一个令人着迷且至关重要的概念。它不仅是面向对象编程(OOP)的三大特性之一(与封装和继承并列),也是实现代码复用、提高软件灵活性和可扩展性的关键所在。当我们谈论C++这门强大的编程语言时,多态更是一个不可或缺的话题
IsLand1314
2024/10/15
1940
【C++高阶】多态(概念&&虚函数&&抽象类)
【C++】多态(定义、虚函数、重写、隐藏)
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态。
秦jh
2024/07/03
2140
【C++】多态(定义、虚函数、重写、隐藏)
【C++】详解多态的底层原理
上一篇文章我们学习了多态的语法,想必大家都会有很多疑问,这篇文章,我们就来带大家看看多态是如何实现的,它底层的原理是怎样的…
YIN_尹
2024/01/23
7380
【C++】详解多态的底层原理
【C++】模板/继承/多态
基类对象 < -派生类对象 类型从下到上的转换(可以) 派生类对象 <- 基类对象 类型从上到下的转换(不可以) 基类指针(引用)<- 派生类对象 类型从下到上的转换(可以) 派生类指针(引用)<-基类对象 类型从上到下的转换(不可以)
洁洁
2024/09/05
1500
C++多态
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
南桥
2024/08/07
1150
C++多态
相关推荐
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——11.多态
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验