C++ 构造函数和析构函数顺序

2024-04-14

我正在尝试有关基类和成员构造和销毁的代码,并且我对构造函数和析构函数的某些顺序感到困惑, 这段代码的输出是:

Base1 constructor
Member1 constructor
Member2 constructor
Derived1 constructor
Member3 constructor
Member4 constructor
Derived2 constructor
Derived2 destructor
Member4 destructor
Member3 destructor
Derived1 destructor
Member2 destructor
Member1 destructor
Base1 destructor

看前四行, 但我觉得顺序应该是

Base1 constructor
Derived1 constructor
Member1 constructor
Member2 constructor

任何人都可以给我一些解释吗?

#include "stdafx.h"
#include <fstream>
using namespace std;
ofstream out("order.out");

#define CLASS(ID) class ID { \
public: \
  ID(int) { out << #ID " constructor\n"; } \
  ~ID() { out << #ID " destructor\n"; } \
};

CLASS(Base1);
CLASS(Member1);
CLASS(Member2);
CLASS(Member3);
CLASS(Member4);

class Derived1 : public Base1 {
  Member1 m1;
  Member2 m2;
public:
  Derived1(int) : m2(1), m1(2), Base1(3) {
    out << "Derived1 constructor\n";
  }
  ~Derived1() {
    out << "Derived1 destructor\n";
  }
};

class Derived2 : public Derived1 {
  Member3 m3;
  Member4 m4;
public:
  Derived2() : m3(1), Derived1(2), m4(3) {
    out << "Derived2 constructor\n";
  }
  ~Derived2() {
    out << "Derived2 destructor\n";
  }
};

int main() {
  Derived2 d2;
} ///:~

构造函数在层次结构中向上调用:

- base class member objects
- base class constructor body
- derived class member objects
- derived class constructor body

输出是正确的。

让我们简化您的代码:

struct BaseMember
{
   BaseMember() { cout << "base member" <<endl; }
};
struct Base
{
   BaseMember b;
   Base() { cout << "base" << endl; }
};
struct DerivedMember
{
   DerivedMember() { cout << "derived member" << endl; }
};
struct Derived : public Base
{
   DerivedMember d;
   Derived() { cout << "derived" << endl; }
};

Derived d;

When d创建时,它会首先创建Base部分。在进入构造函数体之前,所有成员对象都被初始化。所以BaseMember是第一个初始化的对象。

接下来,构造函数Base已输入。

之前,构造函数Derived输入,成员对象Derived被初始化,所以DerivedMember已创建,下一步Derived构造函数被调用。

发生这种情况是因为当您进入派生类的构造函数主体时,基类和成员对象必须完全初始化。

EDIT正如 Matthieu 指出的,成员对象的初始化顺序是由它们在类定义中出现的顺序指定的,而不是它们在初始化列表中出现的顺序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 构造函数和析构函数顺序 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • 当一组凭据下的计划任务启动的进程在另一组凭据下运行另一个程序时,Windows 是否有限制

    所以我有一个简单的例子 其中我有应用程序 A 它对用户 X 本地管理员 有一些硬编码的凭据 然后它使用硬编码的绝对路径启动带有这些凭据的应用程序 B A 和 B 以及 dotnet 控制台应用程序 但是它们不与控制台交互 只是将信息写入文件
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 打破 ReadFile() 阻塞 - 命名管道 (Windows API)

    为了简化 这是一种命名管道服务器正在等待命名管道客户端写入管道的情况 使用 WriteFile 阻塞的 Windows API 是 ReadFile 服务器已创建启用阻塞的同步管道 无重叠 I O 客户端已连接 现在服务器正在等待一些数据
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • 堆栈是向上增长还是向下增长?

    我在 C 中有这段代码 int q 10 int s 5 int a 3 printf Address of a d n int a printf Address of a 1 d n int a 1 printf Address of a
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke

随机推荐

  • 如何在 Spring Hibernate 运行时设置数据库名称

    问题描述 Spring中有一个类叫做AbstractRoutingDataSource这将适合您的要求 浏览文档 您将找到一些有关如何实现具体类的帮助 您需要更改 或添加 现有代码的某些部分才能配置动态Data source 这个博客 ht
  • 在数据库中实施审查标志;最佳实践

    我需要存储一些与某些实体相关的评论标志 每个审核标志只能与单个实体属性组相关 例如表Parents has a ParentsStatus旗帜和桌子Children有一组ChildrenStatus flags 在当前的设计方案中 我有三个
  • 保留大小相等的分割视图

    我在非最大化窗口模式下启动 GVIM 并水平分割其窗口 确保窗口大小相等 当我最大化主 GVIM 窗口时 如何保留这个大小相等的分割视图 每当我最大化 GVIM 时 都会忘记窗口已被平均分割 Thanks 均衡分割的命令是 W ctrl W
  • 使自定义图像尊重tintColor属性iOS

    我必须想象这个问题已经被问过好几次了 但我的问题措辞一定不正确 我有自己在 Photoshop 中制作的自定义图像 并将其设置为按钮的图像属性 这里正常显示 背景是透明的 但它是 44x44 其中三个点是 88x88 像素的 png 文件
  • 使用 CSS 时链接不起作用

    我遇到了一个无法通过谷歌搜索解决的问题 我有一个静态 HTML
  • 一个关于二分查找的问题

    为什么人们通常使用二分搜索而不是三重搜索 将 每次分成三份 或者甚至每次分成十份 因为二分查找会产生最少数量的比较和查找 为了简单直观 请考虑每次分为 4 部分 v1 v2 v3 您现在已经完成了 3 次查找 并且必须将您正在搜索的最坏值与
  • 使用实体框架代码优先的 FSharp 记录类型

    我正在一个业务应用程序中进行概念验证 我想用 F 替换当前的 C 代码优先实体框架实现 我正在关注this http blogs msdn com b visualstudio archive 2011 04 04 f code first
  • 干净的架构,用例依赖关系

    最近 我找到了方法干净的架构 https 8thlight com blog uncle bob 2012 08 13 the clean architecture html鲍勃叔叔的帖子 但是 当我尝试将其应用到当前项目时 当一个用例需要
  • 更改 SQL Server 2012 数据库的排序规则

    更改排序规则 我需要更改特定服务器上的一个数据库的排序规则Latin1 General CI AS to SQL Latin1 General CP1 CI AI以便它与我们数据库的其余部分相匹配 问题 但是 当我尝试执行此操作时 出现以下
  • 以最小的质量损失调整大小

    我需要调整图像大小 但图像质量不会受此影响 图像将从 10x10 到 1000x1000 它会有一些严重的拥塞和一些空白时间 它必须同时放大和缩小 可能会损失一些图像质量 可以 但必须至少是 所有东西都确实带有光栅图形 请不要使用库或其他外
  • MyPy 不允许受约束的 TypeVar 是协变的?使用受约束但协变的键值类型定义通用字典

    我正在尝试定义一个自定义通用字典 其键的类型T key并且值的类型T val 我也想限制一下T key and T val 使得T key只能是类型A or B或其子类 我该如何实现这个目标 from typing import TypeV
  • 在不改变我的位置的情况下获取当前位置的经度和纬度

    我可以找到当前位置的纬度和经度 但是这些数据在更改我的当前位置之前不会显示 我想在不更改我的位置的情况下获取当前位置的经度和纬度 package com example gps import android app Activity imp
  • 如何对 HashMap 键进行排序[重复]

    这个问题在这里已经有答案了 我有一个问题 HashMap
  • Google 地图 (Android) 中的位置更新率

    我正在编写一个简单的基于 GPS 的应用程序 用于位置感知 每当启用 GPS 时 应用程序都会请求位置更新并以格式打印纬度和经度 TextView 如果 GPS 被禁用 位置提供商会回退到LocationManager NETWORK PR
  • 两个托管对象上下文可以共享一个持久存储协调器吗?

    示例 我有一个持久存储协调器 它使用一个持久存储 现在有两个托管对象上下文 并且都希望使用相同的持久存储 两者都可以简单地使用相同的持久存储协调器 还是我必须创建 NSPersistentStoreCoordinator 的两个实例 如果我
  • 如何让 PreOrder、InOrder、PostOrder 正常工作?

    如何让 PreOrder InOrder PostOrder 正常工作 这是我当前的代码和实现 请参阅 InOrder PreOrder PostOrder 我有来自 Geek4Geek 的参考 https www geeksforgeek
  • 环形缓冲区和 DMA

    我试图了解从数据包到达网卡到目标应用程序收到数据包之间发生的所有事情 假设 缓冲区足够大 可以容纳整个数据包 我知道情况并非总是如此 但我不想介绍太多技术细节 一种选择是 1 Packet reaches the NIC 2 Interru
  • 远程 PowerShell,查找最近 5 个用户登录

    我尝试在安全事件发生后以管理员身份查看企业计算机上的最后 5 个登录事件 我进行了初步调查 并试图找到一种方法来快速列出潜在的 嫌疑人 名单 我已经能够生成列出日志文件的输出 但在您通常会看到的帐户名称下 域名 用户名我只得到输出 SYST
  • 如何将 sql 查询的值存储到变量中?

    resourcesbuilt mysql query SELECT resourcesbuilt FROM user WHERE username username LIMIT 1 if resourcesbuilt lt 0 mysql
  • C++ 构造函数和析构函数顺序

    我正在尝试有关基类和成员构造和销毁的代码 并且我对构造函数和析构函数的某些顺序感到困惑 这段代码的输出是 Base1 constructor Member1 constructor Member2 constructor Derived1