运算符和构造函数

operators and constructor

本文关键字:构造函数 运算符      更新时间:2023-10-16

我有一个类,在那里我实现了自己的构造函数、析构函数、复制构造函数和复制分配运算符。

该类有一组核心成员,我在上面的所有内容中都有这些成员,还有一组"状态变量",我添加这些变量作为一些方法的助手。

这些状态变量从来没有在构造函数中初始化过(只是因为我没有这么做),而是在使用之前初始化过。

因此,复制构造函数和复制赋值对它们没有任何作用。他们只是复制我明确想要的成员。

  • 这会是个问题吗
  • 没有显式复制的成员(顺便说一句,这些成员中没有指针)会发生什么?
    • 它们也不会在构造函数中初始化
  • 这会导致任何"隐藏"的问题吗

干杯André

Can this be a problem?

-如果你在使用之前初始化它们,并且不要忘记发布(在指针的情况下),我看不到任何问题。

What happens to members that aren't explicitly copied (btw, no pointers in these members)? they are also not initialized in the constructor

-他们持有垃圾

Can this lead to any "hidden" problems?

-不,如果你是细心的

但我建议您在任何情况下都在构造函数中初始化它们,因为这样更容易捕捉错误,并且使对象始终处于完整状态。例如,捕获nullptr指针要比捕获垃圾指针或指向已释放对象的指针容易得多。由于在第一种情况下,程序只会崩溃(取消引用空指针是UB,但通常只是崩溃)

此外,如果可能的话,我更喜欢创建局部变量来存储中间结果。如果它不是一个单一的方法中间结果,那么如果在初始化之前在其他方法中使用这个变量,它可能会成为一个陷阱。在这种情况下,最好存储零初始化变量,这样您就可以assert,在对其进行计算之前,它处于有效状态

如果这些变量是对象状态的一部分,那么它们应该被复制。如果变量不是对象状态的一部分,那么它们就不应该是成员。如果接口中任何函数的结果取决于操作开始前变量的值,则变量是对象状态的一部分。

上面的一般规则很少有例外,特别是有一些成员变量不参与对象的状态(它们通常标记为mutable),作为同步机制或复杂操作结果的缓存。

回到您的问题,从描述中可以看出,您可能只是将这些成员用作不同成员函数之间的通信机制。接口中的一个函数设置值,然后调用其他读取/修改值的函数。如果是这种情况,请考虑将变量作为参数传递给函数。通过使用成员,可以有效地隐藏函数对这些值的依赖关系,同时向类添加依赖关系。

如果接口中的任何函数访问这些成员,情况会更糟,在这种情况下,在分配(或复制构造)后,源和目标的行为会不同,这打破了复制初始化/分配后源和目标对象等效的假设。

基本上,从实用的角度来看,如果这些成员不是对象状态的一部分,你可能会接受你目前的方法,但我真的会重新考虑这个设计。如果它们确实参与了对象的状态,则无论如何都不应避免复制它们。

从c++的角度来看,这里没有什么问题,但c++并不能保护你免受枪击。几个月后,您可能会调试一个只在发布版本中发生的错误,然后您将花几天时间找出发生这种情况的原因。为什么我的应用程序在Release中工作而在Debug中不工作,有很多问题,其中一个原因是调试堆初始化了分配的内存。