5. 临时对象 (temporary object)#
说明#
要正确而全面分析临时对象过于复杂了, 它非常容易被优化 (一个被优化的示例).
故此处针对考试进行了简化, 仅涉及两种情况 (不考虑任何优化 (返回值优化, 未使用值优化等)!).
未被延长的临时对象#
对于临时对象, 它在 整个表达式 (完整表达式, full expression, 简单来说就是分号结束时) 结束时被销毁. 如果整个表达式中有多个临时对象, 那么按临时对象构造的相反顺序被销毁.
1Noisy make_noisy(Info info) {
2 return Noisy(info);
3}
4
5int main() {
6 Noisy c1{Info{.ctor = "0", .dtor = "1"}};
7 make_noisy(Info{.ctor = "2", .dtor = "3"}), make_noisy(Info{.ctor = "4", .dtor = "5"});
8 Noisy c2{Info{.ctor = "6", .dtor = "7"}};
9}
10// 0: c1 构造
11// 2: 临时对象构造
12// 4: 临时对象构造
13// 5: 临时对象析构
14// 3: 临时对象析构
15// 6: c2 构造
16// 7: c2 析构
17// 1: c1 析构
被延长的临时对象#
通过 const&
可以延长临时对象的生命期, 则它的生命期在 const&
的生命期结束时结束.
1Noisy make_noisy(Info info) {
2 return Noisy(info);
3}
4
5int main() {
6 Noisy c1{Info{.ctor = "0", .dtor = "1"}};
7 Noisy const& c2 = make_noisy(Info{.ctor = "2", .dtor = "3"});
8 { static Noisy const& c3 = make_noisy(Info{.ctor = "4", .dtor = "5"}); }
9}
10// 0: c1 构造
11// 2: c2 构造
12// 4: c3 构造
13// 3: c2 析构
14// 1: c1 析构
15// 5: c3 析构
题目#
题 1#
1int main() {
2 make_noisy(Info{.ctor = "m", .dtor = "i"});
3
4 Derived_noisy c1{
5 Info{.ctor = "c", .copy_ctor = "o", .copy_assign = "u", .dtor = "s"},
6 Derived_info{
7 .ctor = "r", .copy_ctor = "h", .copy_assign = "a", .dtor = "d"}};
8
9 static_cast<Noisy*>(&c1);
10 static_cast<Noisy>(c1);
11
12 Noisy{Info{.ctor = "e", .dtor = "c"}}; // 这是临时对象
13 // 所以平时写代码时不要漏写名字, 除非这就是想要的
14
15 static_cast<Noisy&>(c1);
16
17 make_noisy(Info{.ctor = "o", .dtor = "n"});
18}
点击查看提示
12 个字符. 一种时间单位.
大多数情况下, static_cast<new_type>(expression)
相当于以 new_type temp(expression);
初始化了一个虚拟变量 temp
, 见于 类型转换 (type conversion).
点击查看答案
[在线代码 ns6vKq73E], 答案: microseconds
.
题 2#
1int main() {
2 Noisy c1{
3 Info{.ctor = "v", .copy_ctor = "d", .copy_assign = "u", .dtor = ">"}};
4 Noisy c2{Info{.ctor = "e", .dtor = "l"}};
5 {
6 {
7 Noisy c1{
8 Info{.ctor = "c", .copy_ctor = "b", .copy_assign = "a", .dtor = "o"}};
9 Noisy{Info{.ctor = "t", .dtor = "o"}};
10 { Noisy c2{Info{.ctor = "r", .dtor = "<"}}; }
11 Noisy{c1};
12 }
13 }
14}
点击查看提示
12 个字符. std::vector<T>
的特化版本, 但不是 STL 容器, 证明了代理对象和 STL 容器不可兼得的失败产物, 且在 C++23 之前不该用于 STL 算法.
点击查看答案
[在线代码 esqofxnjs], 答案: vector<bool>
.
注意考试中如果想用 STL 算法, 则不能用 vector<bool>
, 可以用 deque<bool>
等其他 STL 容器代替.