C++中对象初始化方式

感谢原作者的辛勤劳作:https://blog.csdn.net/yang20141109/article/details/50374696

    当对象在创建时获得了一个特定的值,我们说这个对象被初始化。初始化不是赋值,初始化的含义是创建变量赋予其一个初始值,而赋值的含义是把当前值擦除,而以一个新值来替代

    对象初始化可以分为默认初始化直接初始化拷贝初始化以及值初始化

1,默认初始化

    如果定义变量时没有指定初值,则变量被默认初始化。

    默认值到底是什么由变量类型决定,同时定义变量的位置也会对此有影响。如果是内置类型的变量未被显示初始化,它的值由定义的位置决定,定义在任何函数体之外的变量被初始化为0。但是有一种例外,定义在函数体内部的内置类型变量将不被初始化。一个未被初始化的内置类型变量时未定义的,如果试图拷贝或以其他形式访问此变量将引发错误。 

int i1;//默认初始化,在函数体之外(初始化为0)
int f(void)
{
   int i2;//不被初始化,如果使用此对象则报错
}

   每个类各自决定了其初始化对象的方式。绝大数类支持无须显示的初始化而定义对象。默认调用该类的默认构造方法

string empty;//empty非显示的初始化为一个空串,调用的是默认构造函数

2,拷贝初始化

    使用等号(=)初始化一个变量,实际上执行的是拷贝初始化。编译器把等号右侧的初始值拷贝到新创建的对象中去,拷贝初始化通常使用拷贝构造函数来完成。  

   拷贝初始化不仅在我们使用=定义变量时会发生,在下列情况也会发生:

   1,将一个对象作为实参传递给一个非引用类型的形参。

   2,从一个返回类型为非引用类型的函数返回一个对象。

int a = 0;
int a = {0};
string str1 = "hello";

3,直接初始化

   我们不使用等号则使用的是直接初始化,实际上是要求编译器使用普通的函数来选择与我们提供的参数最匹配的构造函数。 

string str1(10,'9');//直接初始化
string str2(str1);//直接初始化
string str3 = str1;//拷贝初始化

4,值初始化

   我们只提供vector对象容纳的元素数量而去忽略元素的初始值,此时库会创建一个值初始化的元素初值,并把它赋予容器中的所有元素。这个初值由vector对象中元素的类型决定。如果vector对象的元素是内置类型,比如int,则元素初始值自动设置为0.如果元素是某种类类型,比如string,则元素由类默认初始化。

vector v1(10);//10个元素,每个元素的初始化为0
vector v2(10);//10个元素,每个元素都为空
vector v3{10};//v2有1个元素,该元素的值是10
vector v4(10, 1);//v3有10个元素,每个的值都是1
vector v5{10, 1};//v4有2个元素,值分别是10和1

使用new动态分配和初始化对象

在自由空间分配的内存是无名的,因此new无法为其分配的对象命名,而是返回一个指向该对象的指针:

int *pi = new int;//pi指向一个动态分配的,未初始化的无名对象

默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值将是未定义的,而类类型对象将使用默认构造函数进行初始化:

string *ps = new string;//初始化为空string
int *pi = new int;//pi指向一个未初始化的int

我们可以使用直接初始化方式来初始化一个动态分配的对象:

int *pi = new int(1024);//pi指向的对象的值为1024
string *ps = new string(10,'9');//*ps为"9999999999"

也可以对动态分配的对象进行值初始化,只需要在类型名后跟一对空括号即可:

string *ps1 = new string;//默认初始化为空string
string *ps2 = new string();//值初始化为空string
int *pi1 = new int;//默认初始化
int *pi2 = new int();//值初始化为0 

 

你可能感兴趣的:(C++)