C++ 问题记录

背景

记录一些项目开发过程中遇到的问题,来加深印象和理解,一方面避免重复犯错,另一方面再次遇到可以快速定位问题。

记录

  • C++单例类构造函数内打印代码没执行(成员变量类阻塞、成员变量初始化)
  • 指针成员变量若直接在构造函数申请、析构函数释放,再涉及容器/拷贝构造,会导致资源不可用(C++默认函数、浅拷贝)
  • C++格式化输出小数点后位数

二、问题列表

2.1 C++ 构造函数和析构函数 = default; 和空{}区别

在C++中,构造函数和析构函数可以被定义为= default;或留空为{}。这两种方式虽然看似相似,但实际上它们有着重要的区别,尤其是在编译器生成的行为和代码的安全性方面。

构造函数

  1. = default;

当一个构造函数被定义为= default;,你指示编译器自动生成一个默认构造函数。这意味着编译器将会:

  • 如果类没有任何用户声明的构造函数,编译器会自动提供一个默认构造函数。
  • 默认构造函数将初始化类中的所有非静态数据成员,使用它们的默认构造函数(如果成员类型有默认构造函数的话)。
  • 如果类有用户声明的构造函数,但没有默认构造函数,= default;将显式地要求编译器生成一个。
  • 如果类的成员中有任何类型不能被默认构造,或者类中定义了删除的默认构造函数,那么使用= default;将产生编译错误。
  1. {}

当构造函数被定义为空{},你告诉编译器这是一个用户定义的构造函数,它不做任何事情。这意味着:

  • 编译器不会自动生成任何代码,构造函数体内的代码将被执行(在这种情况下,没有代码,所以实际上什么也不做)。
  • 不会调用成员的默认构造函数来初始化成员,除非显式地在初始化列表中这样做。
  • 如果类有非默认构造的成员,它们将不会被初始化,除非你在构造函数的初始化列表中显式初始化它们。
  • 这样的构造函数可以被定义多次,只要它们的参数列表不同,而= default;的构造函数只能有一个。

析构函数

  1. = default;

当析构函数被定义为= default;,你告诉编译器自动生成一个默认析构函数。这意味着:

  • 析构函数将被调用来清理类中的资源。
  • 它会调用所有非静态数据成员的析构函数,按照它们在类中声明的逆序。
  • 如果成员类型有析构函数,它们将被调用。
  1. {}

当析构函数被定义为空{},这意味着:

  • 用户定义了一个空的析构函数体,这通常意味着类没有需要特殊清理的资源。
  • 成员的析构函数仍然会被调用,因为这是C++析构函数的标准行为,即使用户定义的析构函数体是空的。

总结

使用= default;是告诉编译器“按预期行为生成代码”,而使用{}是告诉编译器“我来控制这里发生什么”。= default;提供了编译器的自动化和安全保证,而空{}则需要程序员自己负责初始化和清理工作。在现代C++编程实践中,推荐尽可能使用= default;,除非有特殊需求去显式地控制构造函数和析构函数的行为。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值