#include <iostream>
#include <string>
#include <vector>
/* 零初始化
build-in type:内置类型初始化,我们知道局部作用域内置类型未初始化会出现
无法预料问题
*/
// 像int、double、指针等类型没有默认的构造函数,因此不会被初始化一个有意义的值
// 任何未被初始化的局部变量都是未定义的值
void func(){
int a;
double b;
int* ptr;
}
// 因此在定义模板时,若让一个模板参数类型定义的变量初始化成一个默认值,简单的定义是无法
// 做到的,因为内置类型无法被初始化
template<typename T>
void func(){
T t; // T若是内置类型,t无法被初始化,值未定义
}
// 对于内置类型最好显示调用默认构造函数来将它们初始化为0(bool-false,ptr-nullptr)
// 值初始化-要么调用对象已有构造函数,要么用0初始化
struct MyClass;
template<typename T>
void zero_init() {
T t{}; // 在c11之前确保一个对象初始化方式是T t = T();
if (!std::is_same_v<T, MyClass>) {
std::cout<<std::boolalpha<<t<<std::endl;
}
else {
std::cout<<std::boolalpha<<t<<std::endl;
}
}
struct MyClass{
friend std::ostream& operator<<(std::ostream& os, MyClass& c) {
return os<<c.a;
}
int a;
};
void Test(){
zero_init<int>(); // 0
zero_init<bool>(); // false
zero_init<nullptr_t>(); // nullptr;
zero_init<MyClass>();
}
// 花括号初始化的情况,如果没有可用的默认构造函数,它还可以使用列表
// 初始化构造函数(initialize-list constructor)
template<typename T>
struct MyClass1{
MyClass1():t{} {
}
T t;
};
template<typename T>
struct MyClass2{
MyClass2(): t(){} // c11之前使用()初始化t
T t;
};
template<typename T>
struct MyClass3{
T t{}; // c11之后可以对非静态成员变量进行就地初始化;
};
// 注意点: 不能使用{}对默认参数进行初始化
// template<typename T>
// void func_default(T t{}) { // error
// }
// 可以使用T()进行默认参数初始化
template<typename T>
void func_default(T t = T()){ // ok
std::cout<<t<<std::endl;
}
void Test1(){
MyClass1<int> m;
std::cout<<m.t<<std::endl; // 0
MyClass1<int> m1;
std::cout<<m1.t<<std::endl;// 0
MyClass1<int> m2;
std::cout<<m2.t<<std::endl;// 0
func_default<int>(); // 0
}
int main()
{
Test();
Test1();
}
零初始化
C++中零初始化与值初始化的探讨
最新推荐文章于 2025-05-12 14:00:29 发布
这篇博客详细讨论了C++中内置类型和模板参数类型的零初始化与值初始化问题。通过示例,解释了如何使用花括号初始化以及C++11之前的初始化方式,强调了显示初始化的重要性。文章还涉及到了类模板和默认构造函数的使用,并给出了不同情况下的初始化示例。
2694

被折叠的 条评论
为什么被折叠?



