C++ 运算符重载调用析构函数
C++ Operator overload calling destructor
第一次尝试运算符重载时,我创建了一个向量 class 并尝试求和两个向量。我的 class 包含一个数组和一个 int 向量,它们都包含相同的元素。
加法在 std::vector
上运行良好,但我遇到了两个数组问题。似乎在产生 "double free or corruption" 错误(核心转储)的求和操作结束时调用了析构函数。另外,数组的前两个元素始终为零。
我是否也应该超载 delete
还是我遗漏了什么?
头文件:
#ifndef MYVECTOR_INCLUDE
#define MYVECTOR_INCLUDE
#include <iostream>
#include <stdexcept>
#include <cstring>
#include <vector>
class MyVector {
public:
MyVector(int n);
~MyVector();
void set(int idx, int value);
int get(int idx);
void print();
MyVector &operator=(const MyVector &v);
MyVector operator+(const MyVector &v);
private:
int *data;
std::vector<int> data_vector;
int size1;
int size2;
};
#endif
cpp 文件:
#include "../include/myvector.hpp"
MyVector::MyVector(int n) {
data = new int [n];
data_vector.resize(n);
size1 = n;
size2 = 1;
}
MyVector::~MyVector() {
if (data != NULL) {
delete [] data;
}
}
void MyVector::set(int idx, int value) {
data_vector[idx] = value;
data[idx] = value;
}
int MyVector::get(int idx) {
return data_vector[idx];
}
void MyVector::print() {
std::cout << "Vector data" << std::endl;
for (int i = 0; i < size1; ++i) {
std::cout << data_vector[i] << " ";
}
std::cout << std::endl;
std::cout << "Data" << std::endl;
for (int i = 0; i < size1; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
MyVector &MyVector::operator=(const MyVector &v) {
if (this == &v)
return *this;
size1 = v.size1;
size2 = v.size2;
std::copy(v.data_vector.begin(), v.data_vector.end(), data_vector.begin());
memcpy(&data, v.data, sizeof(int)*size1);
return *this;
}
MyVector MyVector::operator+(const MyVector &v) {
if ((size1 == v.size1) && (size2 == v.size2)) {
MyVector res = MyVector(size1);
for (int i = 0; i < size1; ++i) {
res.data_vector[i] = data_vector[i] + v.data_vector[i];
res.data[i] = data[i] + v.data[i];
}
return res;
}
else
throw std::length_error("Vector dimensions must agree.");
}
谢谢。
参见the rule of three/five/zero。
三州之治
If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.
在这种情况下,您提供了析构函数和复制赋值运算符,但忘记了复制构造函数。
在 operator+
中,您创建了一个本地对象 MyVector res
,稍后将其复制出来然后销毁。由于您尚未实现复制构造函数,因此默认复制构造函数将简单地将原始 data
指针从 res
复制到另一个 MyVector
。当 res
被销毁时,它的 data
成员指向的数组将被删除,而复制的向量的 data
指向已删除的对象。
第一次尝试运算符重载时,我创建了一个向量 class 并尝试求和两个向量。我的 class 包含一个数组和一个 int 向量,它们都包含相同的元素。
加法在 std::vector
上运行良好,但我遇到了两个数组问题。似乎在产生 "double free or corruption" 错误(核心转储)的求和操作结束时调用了析构函数。另外,数组的前两个元素始终为零。
我是否也应该超载 delete
还是我遗漏了什么?
头文件:
#ifndef MYVECTOR_INCLUDE
#define MYVECTOR_INCLUDE
#include <iostream>
#include <stdexcept>
#include <cstring>
#include <vector>
class MyVector {
public:
MyVector(int n);
~MyVector();
void set(int idx, int value);
int get(int idx);
void print();
MyVector &operator=(const MyVector &v);
MyVector operator+(const MyVector &v);
private:
int *data;
std::vector<int> data_vector;
int size1;
int size2;
};
#endif
cpp 文件:
#include "../include/myvector.hpp"
MyVector::MyVector(int n) {
data = new int [n];
data_vector.resize(n);
size1 = n;
size2 = 1;
}
MyVector::~MyVector() {
if (data != NULL) {
delete [] data;
}
}
void MyVector::set(int idx, int value) {
data_vector[idx] = value;
data[idx] = value;
}
int MyVector::get(int idx) {
return data_vector[idx];
}
void MyVector::print() {
std::cout << "Vector data" << std::endl;
for (int i = 0; i < size1; ++i) {
std::cout << data_vector[i] << " ";
}
std::cout << std::endl;
std::cout << "Data" << std::endl;
for (int i = 0; i < size1; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
MyVector &MyVector::operator=(const MyVector &v) {
if (this == &v)
return *this;
size1 = v.size1;
size2 = v.size2;
std::copy(v.data_vector.begin(), v.data_vector.end(), data_vector.begin());
memcpy(&data, v.data, sizeof(int)*size1);
return *this;
}
MyVector MyVector::operator+(const MyVector &v) {
if ((size1 == v.size1) && (size2 == v.size2)) {
MyVector res = MyVector(size1);
for (int i = 0; i < size1; ++i) {
res.data_vector[i] = data_vector[i] + v.data_vector[i];
res.data[i] = data[i] + v.data[i];
}
return res;
}
else
throw std::length_error("Vector dimensions must agree.");
}
谢谢。
参见the rule of three/five/zero。
三州之治
If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.
在这种情况下,您提供了析构函数和复制赋值运算符,但忘记了复制构造函数。
在 operator+
中,您创建了一个本地对象 MyVector res
,稍后将其复制出来然后销毁。由于您尚未实现复制构造函数,因此默认复制构造函数将简单地将原始 data
指针从 res
复制到另一个 MyVector
。当 res
被销毁时,它的 data
成员指向的数组将被删除,而复制的向量的 data
指向已删除的对象。