【问题标题】:Deleting Private Array in Copy Constructor and Assignment operator在复制构造函数和赋值运算符中删除私有数组
【发布时间】:2013-05-18 02:49:42
【问题描述】:

我正在尝试实现一个为堆分配内存的容器,但似乎我的基本构造函数和我的参数构造函数彼此不喜欢。下面,我发布了没有任何注释的代码。就目前而言,它崩溃了。

#include <iostream>
using namespace std;

class foo
{
public:
    foo() {size=1; vals = new double[1]; vals[0]=0;}
    ~foo() {delete[] vals;}

    foo(const foo& other)
    {
        size=other.getsize();
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=other[i];
    }

    foo& operator=(const foo& other)
    {
        size=other.getsize();
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=other[i];
        return *this;
    }

    foo(double* invals, long unsigned insize)
    {
        size=insize;
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=invals[i];
    }

    double operator[](long unsigned i) const {return vals[i];}

    long unsigned getsize() const {return size;}
private:
    double* vals;
    long unsigned size;
};


int main()
{
    double bar[3] = {5,2,8};
    foo B(bar, 3);

    cout<< B[0]<< " "<< B[1]<< " "<< B[2]<<endl;    //couts fine

    foo A;    //crashes here

    return 0;
}

但是,当我将 main 更改为:

int main()
{
    double bar[3] = {5,2,8};
    foo B(bar, 3);

    cout<< B[0]<< " "<< B[1]<< " "<< B[2]<<endl;    //couts fine

    foo A();    //works now

    return 0;
}

运行良好。但是我不能分配 A = B 因为它认为 foo 是一个函数或其他东西。

【问题讨论】:

  • 如果您想使用delete ,而当时什么都没有,您必须根据需要重载删除运算符,因为当时调用该构造函数时,该对象中没有任何内容并且这可能是您崩溃的问题..

标签: c++ copy-constructor assignment-operator delete-operator


【解决方案1】:

我认为你有一些非常令人信服的理由不在这里使用std::vector&lt;double&gt;...

但无论如何...在您的复制构造函数中,您不想delete[] vals

foo(const foo& other)
{
    size=other.getsize();
    vals = new double[size];
    for(long unsigned i=0; i<size; i++)
        vals[i]=other[i];
}

当复制构造函数被调用时,你的对象还没有被初始化,所以vals* 甚至没有指向任何有效的东西。因此,删除它会调用undefined behavior(并且您的程序会崩溃。)您只需要在赋值运算符中使用delete[] vals

另外,当你声明Foo 变量A 时,你不希望变量名后面有括号。直接说:

foo A;

当您将这些括号放在变量名之后时,您实际上是在使用从 C 继承的语法编写函数声明,并且A 成为函数指针类型。

【讨论】:

    猜你喜欢
    • 2020-04-18
    • 2011-07-19
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多