【问题标题】:C++ Operator overload calling destructorC++ 运算符重载调用析构函数
【发布时间】:2017-06-28 18:07:12
【问题描述】:

在我第一次尝试运算符重载时,我创建了一个向量类并尝试对两个向量求和。我的类包含一个数组和一个 int 向量,它们都包含相同的元素。

Addition 在std::vector 上工作得很好,但我遇到了数组的两个问题。似乎在求和操作结束时调用了析构函数,这会产生“双重释放或损坏”错误(核心转储)。另外,数组的前两个元素总是为零。

我还应该重载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.");
}

谢谢。

【问题讨论】:

  • 遵循 3/5/0 规则。

标签: c++ overloading destructor free


【解决方案1】:

the rule of three/five/zero

三态法则

如果一个类需要用户定义的析构函数、用户定义的复制构造函数或用户定义的复制赋值运算符,那么几乎可以肯定这三者都需要。

在这种情况下,您提供了析构函数和复制赋值运算符,但忘记了复制构造函数。

operator+ 中创建一个本地对象MyVector res,稍后将其复制出来然后销毁。由于您还没有实现复制构造函数,默认的复制构造函数将简单地将原始data 指针从res 复制到另一个MyVector。当res被销毁时,其data成员所指向的数组将被删除,而复制向量的data指向一个已删除的对象。

【讨论】:

  • 谢谢,之前没听说过这个规定。
猜你喜欢
  • 2013-02-06
  • 1970-01-01
  • 2012-04-01
  • 2017-03-12
  • 2011-10-11
  • 2013-10-08
  • 2016-07-11
  • 1970-01-01
  • 2011-01-27
相关资源
最近更新 更多