C++ 相等数量的构造函数和析构函数调用是否确保没有内存泄漏?

C++ 相等数量的构造函数和析构函数调用是否确保没有内存泄漏?,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,假设我们有一个名为memoryCounter的类,它试图捕获由MyClass引起的内存泄漏 也就是说,我们在MyClass的构造函数和析构函数以及它拥有的任何其他构造函数中放入以下行,同时假设我们不在构造函数/析构函数之外的任何其他地方修改MyClassCount: MyClass() { memoryCounter::MyClassCount++; } virtual ~MyClass() { memoryCounter::MyClassCount--; } 现在,我们能绝对

假设我们有一个名为memoryCounter的类,它试图捕获由MyClass引起的内存泄漏

也就是说,我们在MyClass的构造函数和析构函数以及它拥有的任何其他构造函数中放入以下行,同时假设我们不在构造函数/析构函数之外的任何其他地方修改MyClassCount:

MyClass()
{
    memoryCounter::MyClassCount++;
}
virtual ~MyClass()
{
    memoryCounter::MyClassCount--;
}

现在,我们能绝对确定如果memoryCounter::MyClassCount包含零,那么我们分配的所有内存都已释放,并且没有泄漏吗?或者有一种情况,当变量将包含零,但将有分配的内存,我们没有免费的,请考虑的情况下,“MyC类”是一个基础或派生类,也?< / P> < P>不,你不能。至少可以有其他构造函数以及复制构造函数。你不算他们


此外,静态变量的销毁也不能这么容易计算,因为它们在主出口后被销毁

不,你不能。至少可以有其他构造函数以及复制构造函数。你不算他们


另外,静态变量的销毁也不能这么容易统计,因为它们在主出口后被销毁

如果计数为零,那么就没有MyClass的实例。无论MyClass对象是完整对象、基类子对象还是成员子对象,它都适用。这并不一定意味着没有内存泄漏,因为MyClass本身可能会泄漏内存


需要注意的是默认生成的复制构造函数。您可以假设它拥有的任何其他构造函数都会增加您的全局计数,但是很容易错过代码中没有出现的构造函数。你可以在这里应用三个规则-你定义了一个析构函数,所以你应该定义一个复制构造函数。请注意,该规则还告诉您定义一个复制赋值运算符,在本例中不需要该运算符。

如果计数为零,则不存在MyClass的实例。无论MyClass对象是完整对象、基类子对象还是成员子对象,它都适用。这并不一定意味着没有内存泄漏,因为MyClass本身可能会泄漏内存


需要注意的是默认生成的复制构造函数。您可以假设它拥有的任何其他构造函数都会增加您的全局计数,但是很容易错过代码中没有出现的构造函数。你可以在这里应用三个规则-你定义了一个析构函数,所以你应该定义一个复制构造函数。请注意,该规则还告诉您定义一个复制赋值运算符,在本例中不需要它。

谁说只有构造函数分配内存?如果某个非构造函数成员函数静态或不分配内存,并且析构函数没有正确清理,则表明该内存已泄漏


因此,答案是否定的。您已经统计了通过标准构造函数创建的类实例。没有更多,也没有更少。

谁说只有构造函数分配内存?如果某个非构造函数成员函数静态或不分配内存,并且析构函数没有正确清理,则表明该内存已泄漏


因此,答案是否定的。您已经统计了通过标准构造函数创建的类实例。不多也不少。

您假设MyClass及其派生的任何内容都编写正确。特别是,这种泄漏不会被检测到:

class BadClass : private MyClass
{
  public:
     BadClass() { int *x = new int(5); }
}
您的计数器所做的是告诉您,每个构造都有一次破坏,这意味着没有人泄漏任何“MyClass”对象


但这与没有内存泄漏不同。

您假设MyClass及其派生的任何内容都已正确编写。特别是,这种泄漏不会被检测到:

class BadClass : private MyClass
{
  public:
     BadClass() { int *x = new int(5); }
}
您的计数器所做的是告诉您,每个构造都有一次破坏,这意味着没有人泄漏任何“MyClass”对象


但这与没有内存泄漏不同。

我假设我们准确地增加所有构造函数中的变量,并减少所有析构函数中的变量。对不起,我应该在问题中提出这个问题:=MyClass析构函数也需要是虚拟的。@SingerOfTheFall:静态实例呢?我假设我们在所有构造函数中准确地增加变量,在所有析构函数中减少变量。对不起,我应该在问题中提出这个问题:=MyClass析构函数也需要是虚拟的。@SingerOfTheFall:静态实例呢?如果您希望即使对于派生类也能这样做,请将该析构函数设置为虚拟的。不需要虚拟析构函数。如果有人担心通过指向memoryCounter的指针进行删除,您可以私下继承或保护并公开该计数。OP甚至没有建议通过继承使用memoryCounter——这不是通常的CRTP计数器
。如果您希望即使对于派生类也能这样做,请将该析构函数设置为虚拟析构函数。不需要虚拟析构函数。如果有人担心通过指向memoryCounter的指针进行删除,您可以私下继承或保护并公开该计数。OP甚至没有建议通过继承使用memoryCounter——这不是通常的CRTP计数器。