std::map 和 std::function 值调用析构函数 4 次但仅构造一个对象
std::map with std::function value calls destructor 4 times but only construct one object
我 运行 这个非常简单的例子 Visual Studio (2015)。
由于某种原因, Functor
class 析构函数被调用了 4 次。
我假设该实现调用了自动生成的复制构造函数几次,但我怀疑这里可能存在错误。如果我自己实现一个复制构造函数,我只会得到 3 个析构函数调用,对应于 1 个默认构造函数调用和 2 个复制构造函数调用。
#include <functional>
#include <map>
#include <iostream>
using namespace std;
class Functor
{
public:
Functor()
{
cout << "Functor::Functor()" << endl;
}
Functor& operator=(const Functor& rhs) = delete;
~Functor()
{
cout << "Functor::~Functor()" << endl;
}
void operator()()
{
cout << "Functor::operator()" << endl;
}
};
int main()
{
std::map<int, std::function<void(void)>> myMap;
myMap[1] = Functor();
return 0;
}
输出:
Functor::Functor()
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
如果我自己实现复制构造函数:
Functor(const Functor& that)
{
cout << "Functor::Functor(const Functor&)" << endl;
}
输出:
Functor::Functor();
Functor::Functor(const Functor&)
Functor::Functor(const Functor&)
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
谁能解释一下哪些对象被销毁了?这里发生了什么?
如果你实现自己的复制构造函数,移动构造函数是
被抑制,所以选择了不同的重载。
试试这个:
struct Reporter
{
Reporter() { cout << "Default constructor\n"; }
Reporter(const Reporter&) { cout << "Copy constructor\n"; }
Reporter(Reporter&&) { cout << "Move constructor\n"; }
Reporter& operator=(const Reporter&) { cout << "Assignment operator\n"; return *this; }
Reporter& operator=(Reporter&&) { cout << "Move Assignment operator\n"; return *this; }
~Reporter() { cout << "Destructor"; }
};
并且有您感兴趣的 class 从它继承。
原文中的四个地方大概是:
myMap[1]
这将创建一个默认构造的对象,该对象在被覆盖时被销毁。
Functor()
这会创建一个在完整表达式末尾被销毁的临时文件。
std::function<void(void)>
std::function
的构造函数可能按值接受它的参数,
启用移动语义
}
你的地图超出范围
我 运行 这个非常简单的例子 Visual Studio (2015)。
由于某种原因, Functor
class 析构函数被调用了 4 次。
我假设该实现调用了自动生成的复制构造函数几次,但我怀疑这里可能存在错误。如果我自己实现一个复制构造函数,我只会得到 3 个析构函数调用,对应于 1 个默认构造函数调用和 2 个复制构造函数调用。
#include <functional>
#include <map>
#include <iostream>
using namespace std;
class Functor
{
public:
Functor()
{
cout << "Functor::Functor()" << endl;
}
Functor& operator=(const Functor& rhs) = delete;
~Functor()
{
cout << "Functor::~Functor()" << endl;
}
void operator()()
{
cout << "Functor::operator()" << endl;
}
};
int main()
{
std::map<int, std::function<void(void)>> myMap;
myMap[1] = Functor();
return 0;
}
输出:
Functor::Functor()
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
如果我自己实现复制构造函数:
Functor(const Functor& that)
{
cout << "Functor::Functor(const Functor&)" << endl;
}
输出:
Functor::Functor();
Functor::Functor(const Functor&)
Functor::Functor(const Functor&)
Functor::~Functor()
Functor::~Functor()
Functor::~Functor()
谁能解释一下哪些对象被销毁了?这里发生了什么?
如果你实现自己的复制构造函数,移动构造函数是 被抑制,所以选择了不同的重载。
试试这个:
struct Reporter
{
Reporter() { cout << "Default constructor\n"; }
Reporter(const Reporter&) { cout << "Copy constructor\n"; }
Reporter(Reporter&&) { cout << "Move constructor\n"; }
Reporter& operator=(const Reporter&) { cout << "Assignment operator\n"; return *this; }
Reporter& operator=(Reporter&&) { cout << "Move Assignment operator\n"; return *this; }
~Reporter() { cout << "Destructor"; }
};
并且有您感兴趣的 class 从它继承。
原文中的四个地方大概是:
myMap[1]
这将创建一个默认构造的对象,该对象在被覆盖时被销毁。Functor()
这会创建一个在完整表达式末尾被销毁的临时文件。std::function<void(void)>
std::function
的构造函数可能按值接受它的参数, 启用移动语义}
你的地图超出范围