为什么在行mystring = "Hello, there!";
之后调用析构函数
它不像是超出了范围。我肯定错过了一些C ++的怪癖!
我知道该行调用默认的复制构造函数,是复制构造函数返回后总是调用的析构函数吗?
正如旁注,我正在使用C ++ 03,还没有使用C ++ 11。
编辑:另请注意,我知道以下程序导致的双重删除。我在这里做实验。只是想提醒你注意。
class MyString
{
private:
char* mystring;
int m_length;
public:
MyString(const char* str="")
{
assert(str);
m_length = strlen(str) + 1;
mystring = new char[m_length];
for (int i = 0; i < m_length; ++i)
mystring[i] = str[i];
mystring[m_length-1] = '\0';
}
~MyString()
{
delete[] mystring;
}
};
int main()
{
MyString mystring("");
mystring = "Hello, there!";
cout << "Destructor not yet called ";
}
答案 0 :(得分:6)
由于您的类没有赋值操作符,因此将字符串文字mystring = "Hello, there!";
转换为3部分操作。
首先,它必须从字符串文字构造一个临时对象。
然后它使用临时的并使用它与默认副本(前C ++ 11)/ move(如果没有删除,则发布C ++ 11)编译器为类生成的赋值运算符。
然后它必须销毁它创建的临时对象。这就是为什么你会在该表达式的末尾看到对析构函数的调用。
请注意,因为临时对象在
之后被销毁mystring = "Hello, there!";
指针mystring
保持现在已删除,您无法再访问它。当它被破坏时也会导致双重删除,这是一种不确定的行为,会导致并发症。