在分配新对象之前未删除对象
Object not deleted before new is assigned
我有点困惑,因为我确定这应该会有所不同。看看这个代码示例:
#include <iostream>
#include <string>
using namespace std;
class base
{
public:
virtual ~base() = default;
};
class derived : public base
{
private:
int a = 0;
int *b = nullptr;
std::string lol;
public:
derived(std::string s) : b(new int(6)), lol{s} { cout << "ctor " << lol << endl; }
derived(derived const& d) : lol{d.lol + " copy"} {cout << "copy " << lol << endl; }
virtual ~derived() { cout << "dtor " << lol << endl; delete b; }
virtual void superFunction() { cout << "OMG " << lol << endl; }
};
int main()
{
derived a("a");
derived b("b");
a = b;
}
关闭所有优化后的程序输出是:
ctor a
ctor b
dtor b
dtor b
我确信在这种情况下,编译器应该生成删除对象 a
并使用复制构造函数创建新对象的代码。相反,它使用隐式声明的 operator=
。
谁能解释一下为什么?或者指向 C++ 标准。
谢谢。
当你写a = b;
时,编译器会调用赋值运算符,如果代码中不存在且未标记为已删除,则会自动生成。仅当您尝试 初始化 来自另一个对象的新对象时才使用复制构造函数,如下所示:
derived a("a");
derived b = a;
此外,您的代码在 main returns 之前崩溃,因为它试图删除 b
,它指向 a
和 b
之后的相同内存 a = b;
默认分配。
如果你想在 a = b;
执行后用 derived
析构函数删除 a
,你只需要复制和交换惯用语。 What is the copy and swap idiom? has a great answer on how to do that in legacy and modern C++. Proper implementation of rule-of-four from that answer will perfectly fit the DRY principle and help you to avoid memory issues. Note the fabulous trick with passing parameter to operator=
by value, which makes compiler select the appropriate constructor (copy or move) and allows you to write only four methods instead of all five 个。
我有点困惑,因为我确定这应该会有所不同。看看这个代码示例:
#include <iostream>
#include <string>
using namespace std;
class base
{
public:
virtual ~base() = default;
};
class derived : public base
{
private:
int a = 0;
int *b = nullptr;
std::string lol;
public:
derived(std::string s) : b(new int(6)), lol{s} { cout << "ctor " << lol << endl; }
derived(derived const& d) : lol{d.lol + " copy"} {cout << "copy " << lol << endl; }
virtual ~derived() { cout << "dtor " << lol << endl; delete b; }
virtual void superFunction() { cout << "OMG " << lol << endl; }
};
int main()
{
derived a("a");
derived b("b");
a = b;
}
关闭所有优化后的程序输出是:
ctor a
ctor b
dtor b
dtor b
我确信在这种情况下,编译器应该生成删除对象 a
并使用复制构造函数创建新对象的代码。相反,它使用隐式声明的 operator=
。
谁能解释一下为什么?或者指向 C++ 标准。
谢谢。
当你写a = b;
时,编译器会调用赋值运算符,如果代码中不存在且未标记为已删除,则会自动生成。仅当您尝试 初始化 来自另一个对象的新对象时才使用复制构造函数,如下所示:
derived a("a");
derived b = a;
此外,您的代码在 main returns 之前崩溃,因为它试图删除 b
,它指向 a
和 b
之后的相同内存 a = b;
默认分配。
如果你想在 a = b;
执行后用 derived
析构函数删除 a
,你只需要复制和交换惯用语。 What is the copy and swap idiom? has a great answer on how to do that in legacy and modern C++. Proper implementation of rule-of-four from that answer will perfectly fit the DRY principle and help you to avoid memory issues. Note the fabulous trick with passing parameter to operator=
by value, which makes compiler select the appropriate constructor (copy or move) and allows you to write only four methods instead of all five 个。