如何拥有向量的复制构造函数?
how to have a copy constructor for vector?
我模拟了一个向量,但构造函数不起作用;当我调用 pop()
函数时,它会将垃圾值分配给向量 class.
中的旧对象
vector(vector &v) {
vec = new T[v.size()];
memcpy(vec, v,v.size());
size_arr = v.size();
}
完整代码如下:
#include <iostream>
using namespace std;
template <typename T>
class vector {
int size_arr;
T * vec = new T;
public:
vector(/*int _size*/) {
vec = new T[0];
size_arr = 0;
};
~vector() {
size_arr = 0;
delete[] vec;
};
vector(vector &v) {
vec = new T[v.size()];
memcpy(vec, v,v.size());
size_arr = v.size();
}
void push_back(T data) {
T *temp = new T[size_arr + 1];
for (int i = 0; i < size_arr; i++)
temp[i] = vec[i];
temp[size_arr] = data;
size_arr++;
delete[] vec;
vec = temp;
};
void push_front(T data){
int j;
T *temp = new T[size_arr + 1];
for ( j = size_arr; j >= 0;j--) {
temp[j + 1] = vec[j];
}
temp[0] = data;
delete[] vec;
vec = temp;
size_arr++;
};
void insert(int index, T data) {
int j;
T *temp = new T[size_arr + 1];
for (int i = 0; i < size_arr ;i++)
temp[i] = vec[i];
for (int i = 0; i < size_arr;i++) {
if (i == index) {
for ( j = size_arr; j >=i;j--) {
temp[j+1] = vec[j];
}
temp[j + 1] = data;
delete[] vec;
vec = temp;
size_arr++;
}
}
};
void pop() {
T *temp = new T[size_arr - 1];
for (int i = 0; i < size_arr-1;i++)
temp[i] = vec[i];
size_arr--;
delete[] vec;
vec = temp;
};
void Delete(int index)
{
T *temp = new T[size_arr - 1];
for (int i = 0; i < index;i++)
temp[i] = vec[i];
for (int i = 0; i < size_arr;i++) {
if (i == index) {
for (int j = i; j < size_arr-1;j++) {
temp[j] = vec[j + 1];
}
size_arr--;
delete[] vec;
vec = temp;
}
}
};
int search(T data) {
for (int i = 0; i < size_arr;i++) {
if (vec[i] == data) {
return i;
}
}
return -1;
};
int size() { return size_arr; };
};
int main() {
vector <int>test;
test.push_front(2);
test.push_front(3);
test.push_back(0);
test.push_back(-1);
test.insert(2, 2);
test.pop();
vector <int > test1;
test1 = test;// problem
test1.pop();
}
我认为问题出在您的复制操作员身上。您使用 memcpy()
这是一个 c 函数。这本身应该不是问题(除了在许多意见中不太好)。但是由于 memcpy() 是一个 c 函数,它不知道类型,并且它将其大小参数作为字节数。
你输入的元素是int
,大概是4个字节。所以当你的复制构造函数被调用时,原来有 3 个元素,你的数组中会有 12 个字节,但是 malloc 只会复制其中的 3 个。
其他人关于没有正确复制模板类型的评论是正确的,所以如果你制作一个字符串向量,你不能只是 memcpy 它们,并假设结果将是新字符串。对于这个答案,我假设您只使用基本类型作为模板参数,例如 int 或 double。
问题出在test1 = test;// problem
行,它没有调用复制构造函数,而是调用了赋值运算符。您没有声明此运算符,因此编译器将使用默认实现,它只是复制所有成员。所以,赋值后test1.vec
和test.vec
指向同一个内存位置。
当您将行(及其上面的行)更改为 vector <int > test1{test};
时,它将调用您的复制构造函数。
您还忘记了 #include <cstring>
用于 memcpy
,您不应将其用于非 POD 类型。
您必须将 memcpy
中的大小乘以 sizeof(T)
,因为 memcpy
适用于字节,而不适用于类型。您还必须使用 v.vec
而不是 v
.
这里是固定版本:https://ideone.com/JMn7ww
我模拟了一个向量,但构造函数不起作用;当我调用 pop()
函数时,它会将垃圾值分配给向量 class.
vector(vector &v) {
vec = new T[v.size()];
memcpy(vec, v,v.size());
size_arr = v.size();
}
完整代码如下:
#include <iostream>
using namespace std;
template <typename T>
class vector {
int size_arr;
T * vec = new T;
public:
vector(/*int _size*/) {
vec = new T[0];
size_arr = 0;
};
~vector() {
size_arr = 0;
delete[] vec;
};
vector(vector &v) {
vec = new T[v.size()];
memcpy(vec, v,v.size());
size_arr = v.size();
}
void push_back(T data) {
T *temp = new T[size_arr + 1];
for (int i = 0; i < size_arr; i++)
temp[i] = vec[i];
temp[size_arr] = data;
size_arr++;
delete[] vec;
vec = temp;
};
void push_front(T data){
int j;
T *temp = new T[size_arr + 1];
for ( j = size_arr; j >= 0;j--) {
temp[j + 1] = vec[j];
}
temp[0] = data;
delete[] vec;
vec = temp;
size_arr++;
};
void insert(int index, T data) {
int j;
T *temp = new T[size_arr + 1];
for (int i = 0; i < size_arr ;i++)
temp[i] = vec[i];
for (int i = 0; i < size_arr;i++) {
if (i == index) {
for ( j = size_arr; j >=i;j--) {
temp[j+1] = vec[j];
}
temp[j + 1] = data;
delete[] vec;
vec = temp;
size_arr++;
}
}
};
void pop() {
T *temp = new T[size_arr - 1];
for (int i = 0; i < size_arr-1;i++)
temp[i] = vec[i];
size_arr--;
delete[] vec;
vec = temp;
};
void Delete(int index)
{
T *temp = new T[size_arr - 1];
for (int i = 0; i < index;i++)
temp[i] = vec[i];
for (int i = 0; i < size_arr;i++) {
if (i == index) {
for (int j = i; j < size_arr-1;j++) {
temp[j] = vec[j + 1];
}
size_arr--;
delete[] vec;
vec = temp;
}
}
};
int search(T data) {
for (int i = 0; i < size_arr;i++) {
if (vec[i] == data) {
return i;
}
}
return -1;
};
int size() { return size_arr; };
};
int main() {
vector <int>test;
test.push_front(2);
test.push_front(3);
test.push_back(0);
test.push_back(-1);
test.insert(2, 2);
test.pop();
vector <int > test1;
test1 = test;// problem
test1.pop();
}
我认为问题出在您的复制操作员身上。您使用 memcpy()
这是一个 c 函数。这本身应该不是问题(除了在许多意见中不太好)。但是由于 memcpy() 是一个 c 函数,它不知道类型,并且它将其大小参数作为字节数。
你输入的元素是int
,大概是4个字节。所以当你的复制构造函数被调用时,原来有 3 个元素,你的数组中会有 12 个字节,但是 malloc 只会复制其中的 3 个。
其他人关于没有正确复制模板类型的评论是正确的,所以如果你制作一个字符串向量,你不能只是 memcpy 它们,并假设结果将是新字符串。对于这个答案,我假设您只使用基本类型作为模板参数,例如 int 或 double。
问题出在test1 = test;// problem
行,它没有调用复制构造函数,而是调用了赋值运算符。您没有声明此运算符,因此编译器将使用默认实现,它只是复制所有成员。所以,赋值后test1.vec
和test.vec
指向同一个内存位置。
当您将行(及其上面的行)更改为 vector <int > test1{test};
时,它将调用您的复制构造函数。
您还忘记了 #include <cstring>
用于 memcpy
,您不应将其用于非 POD 类型。
您必须将 memcpy
中的大小乘以 sizeof(T)
,因为 memcpy
适用于字节,而不适用于类型。您还必须使用 v.vec
而不是 v
.
这里是固定版本:https://ideone.com/JMn7ww