如果我有一个类的成员如下:
class MyClass {
public:
void set_my_vector() {
for (int ind = 0; ind < 3; ++ind) {
my_vector.push_back(new MyStruct(i, i*2));
}
}
private:
struct MyStruct {
int num_a;
int num_b;
MyStruct(int i, int j) : num_a(i), num_b(j) {}
};
std::vector<MyStruct*> my_vector;
};
我需要编写五个函数的规则吗?或者std::vector会负责深度复制和删除堆上分配的元素吗?
编辑:下面的代码使用默认的复制构造函数,所以我假设在我将my_class1对象复制到my_class2对象中之后,my_class1.my_vector和my_class2.my_vecter的元素将是相同的,因为MyStruct指针是复制的,而不是数据本身。然而,输出显示它们并不相同。您可以在此处运行代码:https://onlinegdb.com/S1pK9YE4v
#include <iostream>
#include <vector>
class MyClass {
public:
void fill_my_vector(int i, int j) {
my_vector.clear();
for (int ind = 0; ind < 3; ++ind) {
my_vector.push_back(new MyStruct(i, j));
}
}
void print () {
for (int ind = 0; ind < 3; ++ind) {
std::cout << my_vector[ind]->int1 << ", " << my_vector[ind]->int2 << std::endl;
}
std::cout << std::endl;
}
private:
struct MyStruct {
MyStruct (int i, int j) :
int1(i), int2(j)
{}
int int1;
int int2;
};
std::vector<MyStruct*> my_vector;
};
int main()
{
MyClass my_class1;
my_class1.fill_my_vector(42, 43);
std::cout << "my_class1: " << std::endl;
my_class1.print();
MyClass my_class2 = my_class1;
my_class2.fill_my_vector(12, 13);
std::cout << "my_class2: " << std::endl;
my_class2.print();
std::cout << "my_class1: " << std::endl;
my_class1.print();
}
第二版:我知道智能指针。我特别感兴趣的是,如果我使用原始指针会发生什么。
您需要实现复制构造函数、复制赋值和析构函数。
此外,考虑从更改矢量声明
std::vector<MyStruct*> my_vector;
至
std::vector<std::unique_ptr<MyStruct>> my_vector;
以便它实际正确地拥有堆分配的对象。进行此更改将帮助您不编写析构函数。
不,std::vector
不负责指针存储的对象的深度复制。你几乎没有解决这个问题的可能性:
- 按值存储
MyStruct
- 存储
std::unique_ptr<MyStruct>
- 存储
std::shared_ptr<MyStruct>
注意,因为MyStruct
只包含基元类型的字段,所以不需要复制构造函数、赋值运算符和析构函数,否则必须实现它们,编译器将自动生成的默认实现就足够了。