重置object object = Object(new,parameters);

时间:2012-07-20 06:49:25

标签: c++ constructor copy-constructor

我有一个简单的课程:

class Histogram {
    int m_width;
    int m_height;
    int m_sampleSize;
    int m_bufferWidth;
    int m_bufferHeight;

    uint8* m_buffer;
    int m_size;
public:
    Histogram() : m_buffer(0) { }
    Histogram(int width, int height, int sampleSize) {
        m_buffer = new unsigned char [width*height*sampleSize];
    }
    ~Histogram() {
        my_log("destructor: buffer: %p", m_buffer);
        if ( m_buffer ) { delete [] m_buffer; m_buffer = NULL; }
    }
    unsigned char* buffer() {
        return m_buffer;
    }
};

它是其他班级的成员:

class Other {
    Histogram m_histogram;

    void reset() {
        my_log("reset() called: buffer: %p", m_histogram.buffer());
        m_histogram = Histogram(512, 512, 2);
    }
}

现在,我首先使用Histogram()构造函数创建“未初始化”对象 - 它将m_buffer设置为NULL;

然后,我调用reset方法,它执行m_histogram = Histogram(512,512,3) - 新对象通过new初始化了m_buffer。

所以预期的日志消息序列是:

  • “reset()调用:buffer:0x0”
  • “析构函数:缓冲区:0x0”

但相反,我得到了:

  • “reset()调用:buffer:0x0”
  • “析构函数:缓冲区:0x072a7de”

因此正在进行一些不合理的行动。此外,当我还删除第二个对象(使用“更大”的构造函数创建,带有三个int参数)时,显示0x072a7de地址。

2 个答案:

答案 0 :(得分:2)

你必须为你的班级直方图实现copy-ctor和赋值运算符,因为

m_histogram = Histogram(512, 512, 2);

是赋值运算符调用。隐式运算符=类的按位复制成员。

你必须在析构函数中使用delete[],而不是delete,因为你分配了一个数组。

答案 1 :(得分:1)

首先,由于您指向动态分配的数组,因此需要使用运算符delete[]

delete[] m_buffer;

其次,更重要的是,由于您已动态分配内存,因此应遵循rule of three并实现复制构造函数和赋值运算符,以及修复析构函数。

现在发生的是你的(编译器合成)赋值运算符正在制作一个“浅”副本,即它正在复制指针。那么你将有多个析构函数试图删除它。您正在调用未定义的行为。

使用std::vector<uint8>作为缓冲区,你真的可以省去很多麻烦。