为什么在创建后立即调用此析构函数? [英] Why is this destructor being called immediately after creation?

查看:124
本文介绍了为什么在创建后立即调用此析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

class FixedByteStream {
public:
FixedByteStream() : size(0), address(NULL), existing(false) {}
FixedByteStream(int length) : existing(false) {
    size = length;
    address = new char[length];
}
FixedByteStream(int length, char* addr) : existing(true) {
    size = length;
    address = addr;
}
FixedByteStream(string* str, bool includeNull = false) : existing(true) {
    size = (*str).length();
    address = const_cast<char*>((*str).c_str());
    if (includeNull){
        ++size;
    }
}
~FixedByteStream() {
    if (existing == false) {
        delete [] address;
    }
    address = NULL;
}
int getLength() {
    return size;
}
char* getAddressAt(int index) {
    return &(address[index]);
}


char& operator[] (const int index) {
    return address[index];
}
operator char*() {
    return address;
}

private:
    bool existing;
    int size;
    char* address;
};

一个非常简单的测试就能产生问题:

And a very simple test that is able to produce the issue:

FixedByteStream received;
received = FixedByteStream(12);
received[0] = 't';

Valgrind警告写入无效,调试已说明了原因。 FixedByteStream收到; 调用不带参数的构造函数(这很愚蠢,因为它不能)。 received = FixedByteStream(12); 用整数参数调用构造函数...,然后立即对其自身调用析构函数,使对象无效。它仍然出于某些原因仍然有效,但我宁愿不要将其置于引发警告的奇怪困境中。

Valgrind warns about an invalid write, and debugging has shown why. FixedByteStream received; calls the constructor with no arguments (which is kind of stupid because it can't do anything). received = FixedByteStream(12); calls the constructor with the integer argument... and then immediately calls the destructor on itself, invalidating the object. It still works for some reason, but I'd rather it not be placed in such an odd predicament that throws warnings.

那么,为什么在那儿调用它呢?我可以某种程度地了解析构函数是否被称为 first ,以摆脱无用的临时对象(不是必需的),但是实际上我已经使用了那种声明立即分配的模式

So, why is it being called there? I could somewhat understand if the destructor were called first, to get rid of the useless temporary object (not that it needs to), but I have used that kind of declare-now-assign-later pattern practically everywhere and never had such an issue before.

推荐答案

您缺少赋值运算符。请记住三个规则(或五个)。

You are missing an assignment operator. Remember the rule of three (or five).

问题大致是这样的:

T t; // default constructed t
t = T(2); // T(2) constructor with a single argument, assignment operator= called with this == &t

您没有提供赋值运算符,因此临时变量中的指针值只是复制到t中,然后在临时变量的析构函数中删除指向的内存。

You provide no assignment operator so the pointer value in the temporary is simply copied into t and then the memory pointed to is deleted in the destructor of the temporary.

也:如果构造的对象无效,则没有默认的构造函数。

Also: Don't have a default constructor, if the object constructed is invalid.

这篇关于为什么在创建后立即调用此析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆