为什么在赋值后调用析构函数?
Why is the destructor called after assignment?
为什么在 mystring = "Hello, there!";
行之后调用析构函数
它还没有超出范围。我绝对缺少 C++ 的一些怪癖!
我知道那行调用了默认的复制构造函数,析构函数总是在复制构造函数之后调用吗returns?
附带说明一下,我使用的是 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] = '[=10=]';
}
~MyString()
{
delete[] mystring;
}
};
int main()
{
MyString mystring("");
mystring = "Hello, there!";
cout << "Destructor not yet called ";
}
由于您的 class 没有赋值运算符,它采用字符串文字 mystring = "Hello, there!";
变成了一个 3 部分操作。
首先它必须从字符串文字构造一个临时对象。
然后它获取那个临时值并将其与编译器的默认复制(C++11 之前)/移动(post C++11,如果没有删除的话)一起使用为 class 生成。
然后它必须销毁它创建的临时对象。这就是为什么您会在该表达式的末尾看到对析构函数的调用。
请注意,因为临时对象在
之后被销毁
mystring = "Hello, there!";
mystring
保存的指针现已删除,您无法再访问它。它还会在销毁时导致双重删除,这是未定义的行为,会导致并发症。
为什么在 mystring = "Hello, there!";
行之后调用析构函数
它还没有超出范围。我绝对缺少 C++ 的一些怪癖!
我知道那行调用了默认的复制构造函数,析构函数总是在复制构造函数之后调用吗returns?
附带说明一下,我使用的是 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] = '[=10=]';
}
~MyString()
{
delete[] mystring;
}
};
int main()
{
MyString mystring("");
mystring = "Hello, there!";
cout << "Destructor not yet called ";
}
由于您的 class 没有赋值运算符,它采用字符串文字 mystring = "Hello, there!";
变成了一个 3 部分操作。
首先它必须从字符串文字构造一个临时对象。
然后它获取那个临时值并将其与编译器的默认复制(C++11 之前)/移动(post C++11,如果没有删除的话)一起使用为 class 生成。
然后它必须销毁它创建的临时对象。这就是为什么您会在该表达式的末尾看到对析构函数的调用。
请注意,因为临时对象在
之后被销毁mystring = "Hello, there!";
mystring
保存的指针现已删除,您无法再访问它。它还会在销毁时导致双重删除,这是未定义的行为,会导致并发症。