如果省略 return 操作,为什么会调用析构函数?
Why destructor is called if the return operation is elided?
我有以下模仿省略测试用例的代码
class Obj
{
public:
int x = 0;
Obj(int y) : x(y) {std::cout << "C\n"; }
~Obj() { std::cout << "D\n"; }
};
auto factory()
{
std::vector<Obj> vec {1,2,3};
std::cout<< &vec[0] << std::endl;
return vec;
}
int main()
{
auto vec = factory();
std::cout<< &vec[0] << std::endl;
for(auto& v : vec)
std::cout << v.x << std::endl;
}
输出是意外的,
C C C D D D
0x5640f1d43e80
0x5640f1d43e80
1 2 3
D D D
如果有省略活动,为什么要调用 Obj 析构函数?
我看到第一项的内存 space 是相同的(并且未调用构造函数)
所以我想没有记忆被复制。但如果是这样,为什么(再次)首先调用项目析构函数?
使用初始化列表构造:
std::vector<Obj> vec {1,2,3};
首先构建 initializer_list,包含所有 3 个 Obj 对象。只有这样 std::vector
的构造函数才会被调用,处理这三个对象。您看到的 3 个析构函数调用实际上是 initializer_list 的析构,而不是矢量对象(在这种情况下实际上被省略了)。
我有以下模仿省略测试用例的代码
class Obj
{
public:
int x = 0;
Obj(int y) : x(y) {std::cout << "C\n"; }
~Obj() { std::cout << "D\n"; }
};
auto factory()
{
std::vector<Obj> vec {1,2,3};
std::cout<< &vec[0] << std::endl;
return vec;
}
int main()
{
auto vec = factory();
std::cout<< &vec[0] << std::endl;
for(auto& v : vec)
std::cout << v.x << std::endl;
}
输出是意外的,
C C C D D D
0x5640f1d43e80
0x5640f1d43e80
1 2 3
D D D
如果有省略活动,为什么要调用 Obj 析构函数?
我看到第一项的内存 space 是相同的(并且未调用构造函数) 所以我想没有记忆被复制。但如果是这样,为什么(再次)首先调用项目析构函数?
使用初始化列表构造:
std::vector<Obj> vec {1,2,3};
首先构建 initializer_list,包含所有 3 个 Obj 对象。只有这样 std::vector
的构造函数才会被调用,处理这三个对象。您看到的 3 个析构函数调用实际上是 initializer_list 的析构,而不是矢量对象(在这种情况下实际上被省略了)。