为何C++数组初始化器需单独声明变量才能正常工作?
为何C++中数组引用成员初始化的两种写法结果不同?
以下C++代码编译无错误或警告,但打印foo.arr的内容时会得到垃圾值,数组成员未被正确初始化:
template<int n> class C{ public: const uint8_t (&arr)[n]; const int length = n; C(const uint8_t (&arr_arg)[n]):arr(arr_arg) {} }; int main() { C<5> foo{{1,2,3,4,5}}; for(int i =0;i<foo.length;i++){ printf("foo.arr[%d]=%2x\r\n",i,foo.arr[i]); }; }
而下面的写法中,打印foo.arr能得到正确初始化的结果:
template<int n> class C{ public: const uint8_t (&arr)[n]; const int length = n; C(const uint8_t (&arr_arg)[n]):arr(arr_arg) {} }; int main() { const uint8_t x[]{1,2,3,4,5}; C<5> foo{x}; for(int i =0;i<foo.length;i++){ printf("foo.arr[%d]=%2x\r\n",i,foo.arr[i]); }; }
核心原因:临时对象的生命周期差异
- 第一种写法里,
{{1,2,3,4,5}}会触发编译器创建一个临时的const uint8_t[5]数组。根据C++标准,这种临时对象的生命周期仅持续到构造函数调用完成的那一刻——也就是foo对象初始化完毕后,这个临时数组就会被销毁。而foo.arr是对这个临时数组的引用,后续访问foo.arr时,原内存已经被释放或覆盖,自然会读出垃圾值。 - 第二种写法里,
x是main函数作用域内的局部变量,它的生命周期和foo完全一致,都会持续到main函数执行结束。foo.arr引用的是x,打印时x仍处于有效生命周期内,所以能正确读取数组内容。
内容的提问来源于stack exchange,提问作者user4574
相关产品推荐
相关产品推荐

