非静态数据成员的默认成员初始化器将用于构造函数中,其中相同的数据成员不存在于成员初始化器列表中
[...] 会不会造成内存泄漏...?
是的。
您的示例中使用的 默认成员初始化程序 (DMI):
class Counter {
public:
int* j = new int[5]; // default member initializer for data member 'j'
}
将仅在用于给定构造函数的数据成员(此处为j)未在该给定构造函数的成员初始化列表中初始化。
因此,如果您将复制构造函数添加到Counter 且没有成员初始化列表,则将使用数据成员j 的默认成员初始化器,因此您将拥有内存泄漏。
我们可以通过将数据成员j 的 DMI 更改为立即调用的 lambda 来研究此行为,以便我们跟踪何时使用 DMI,以及简单复制指针的虚拟复制 ctor通过不同方式复制参数(这仅适用于这个虚拟示例;请参阅关于生命周期管理以及深拷贝与浅拷贝的最后一段):
#include <iostream>
struct Counter {
int* j = []() {
std::cout << "Calling DMI for j.\n";
auto p = new int[5];
return p; }();
// Uses the DMI for member 'j'.
Counter() {}
// Uses the DMI for member 'j'.
Counter(const Counter& c) { j = c.j; } // Memory leak.
};
int main() {
Counter c1; // Calling DMI for j.
Counter c2 = c1; // Calling DMI for j.
// Delete resource common for c1 and c2.
delete c2.p; // A rogue resource from c2 construction was leaked.
}
如果您将复制构造函数的成员初始值设定项列表中的j 数据成员复制到:
#include <iostream>
class Counter {
public:
int* j = []() {
std::cout << "Calling DMI for j.\n";
auto p = new int[5];
return p; }();
// Uses the DMI for member 'j'.
Counter() {}
// Does not use the DMI for data member 'j'.
Counter(const Counter& c) : j(c.j) { }
};
int main() {
Counter c1; // Calling DMI for j.
Counter c2 = c1;
// Delete resource common for c1 and c2.
delete c2.p; // OK, no resources leaked.
}
或者简单地将数据成员 j 设置为 nullptr 作为复制 ctor 中成员初始化器列表的一部分:
#include <iostream>
class Counter {
public:
int* j = []() {
std::cout << "Calling DMI for j.\n";
auto p = new int[5];
return p; }();
// Uses the DMI for member 'j'.
Counter() {}
// Does not use the DMI for data member 'j'.
Counter(const Counter& c) : j(nullptr) { j = c.j; }
};
int main() {
Counter c1; // Calling DMI for j.
Counter c2 = c1;
// Delete resource common for c1 and c2.
delete c2.p; // OK, no resources leaked.
}
您将覆盖数据成员 j 的 DMI。
请注意,在使用原始 C 样式指针实现手动内存管理时,您需要格外小心,这是解决生命周期问题的常见方法。如果可能,请改用 std::unique_pointer 或 std::shared_pointer 等智能指针来避免生命周期问题;但是,这超出了这个问题的范围。请注意,在上面的人为示例中,复制构造函数将 浅复制 int 资源,其中复制参数的 j 数据成员指针指向(并且可能拥有)。为了实现一个真实的案例复制构造函数,您可能希望深复制此资源。