析构函数在 lambda 捕获说明符中声明的类实例上运行两次
Destructor running twice on class instance declared inside lambda capture specifier
运行以下代码时,析构函数似乎运行了两次。我有一个理论,这可能与添加的自动移动构造函数有关,但我不确定如何测试这一点。
#include <iostream>
#include <functional>
struct Structure {
Structure(int n) :
Value(n) {
std::cout << "constructor: " << Value << std::endl;
}
~Structure() {
std::cout << "destructor: " << Value << std::endl;
}
int Value;
};
int main() {
int Init = 4;
std::function<void()> Function = [Instance = Structure(Init)] () {
std::cout << "Value is: " << Instance.Value << std::endl;
};
Function();
Function();
return 0;
}
输出:
constructor: 4
destructor: 4
Value is: 4
Value is: 4
destructor: 4
此输出是否正确?
std::function
通过复制您提供的可调用对象来工作。这里没有复制省略,因为您的 lambda 不是std::function
而是匿名的、不相关的类型。
因此,您看到的两个析构函数是:
-
原始临时 lambda 的
Instance
成员; -
存储在
std::function
中并一直存在到main
年底的 lambda 副本的Instance
成员。
好的,我手动定义了移动和复制构造函数,当我指示编译器在下面的代码变体中删除它们时也看到了错误。一切似乎都很正常。
修订后的代码:
#include <iostream>
#include <functional>
struct Structure {
Structure(int n) :
Value(n) {
std::cout << "constructor: " << Value << std::endl;
}
Structure(const Structure& other) :
Value(other.Value) {
std::cout << "copy constructor: " << Value << std::endl;
}
Structure(Structure&& other) :
Value(other.Value) {
other.Value = -1;
std::cout << "move constructor: " << Value << std::endl;
}
~Structure() {
std::cout << "destructor: " << Value << std::endl;
}
int Value;
};
int main() {
int Init = 4;
std::function<void()> Function = [Instance = Structure(Init)] () {
std::cout << "Value is: " << Instance.Value << std::endl;
};
Function();
Function();
return 0;
}
输出:
constructor: 4
move constructor: 4
destructor: -1
Value is: 4
Value is: 4
destructor: 4
相关文章:
- 建议在运行时将带有类实例的列表从c++导入qml
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 当函数返回C++向量实例时,它正在运行
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- 使用to_string、reverse、stoi组合的C++反转编号给出运行时错误实例超出范围
- 非类型引用参数可以在运行时修改,这是否意味着模板可以在运行时实例化?
- 运行时检查实例 (Base*) 是否覆盖父函数 (Base::f())
- 根据运行时参数避免模板实例化的代码重复
- 获取派生模板实例化的运行时类型
- 如何根据运行时输入实例化 c++ 模板
- 确保只有一个函数实例在运行?
- 一次运行程序的多个实例C
- 在C 中运行时从指针访问对象实例
- JIT 编译的运行速度能否比编译时模板实例化更快?
- 析构函数在 lambda 捕获说明符中声明的类实例上运行两次
- 备份正在运行的 rocksdb 实例
- 使用运行时常量实例化的函数模板
- 最大化qt中单个实例应用程序的已运行实例
- 获取应用程序运行实例的句柄
- 如何限制c++中运行实例的数量