您的位置:首页 > 编程语言 > C语言/C++

c++11---统一的初始化和初始化列表

2014-04-22 20:02 363 查看
在c++11以前,程序员,或者初学者经常会感到疑惑关于怎样去初始化一个变量或者是一个对象。   

初始化经常使用括号,或者是使用大括号,或者是复赋值操作。

因为这个原因,c++11提出了统一初始化,以为着使用这初始化列表,下面的做法都是正确的。

int value[] {1 , 2 , 3};

std::vector<int> vi {2 , 3 , 4 , 56, 7};

std::vector<std::string> cities {"Berlin" , "New York " , "london " , "cairo"};

std::complex<double> c{4.0 , 3.0};  //相当于c(4.0 , 3.0);

一个初始化列表强制使用赋值操作, 也就是以为着每个变量都是一个默认的初始化值,被初始化为0(NULL 或者是 nullptr)

如下:

int i; //这是一个未定义的行为

int i{}; //i调用默认的构造函数为i赋值为0

int *p; //这是一个未定义的行为

int *p{} ;// p被初始化为一个nullptr

然后,精确的初始化,它们减少精度,或者是一个补充值被修改,是不可能的。

例如:

int  x1(5.3); // 5

int x2 = 5.3 //5

int xi{5.0} //精确地   所以会出现error

int x4 = {5.3} // 精确地   所以会出现error

char ci{7}; 

char c9{9999}; //error  9999不合适是一个char类型

正如你所看见的,去检查是否是精确地,尽管变量或许是被认定的, 如果变量发生在编译时期。

为了支持初始化列表和用户自定义类型结合,c++11提供了类模板class templete std::initialize_list<> , 可以被用来初始化一个值或者在任何地方你想提供一组值。

void print(std::initialize_list<int> vals)

{

for(auto  p= vals.begin() ; p != vals.end() , ++p )

{

std::cout<<*p<<std::endl;

}

}

print(2 , 3, 4, 5,6 , 7);

2

3

4

5

6

7

作为程序的输出

当构造函数为一个特殊的成员或者是一个初始化列表,初始化列表是被作为首选的

class P

{

public:

p(int , int);

p(std::initialize_liat<int> );

};

P p(77,5);   //call p(int , int);

P p{77,5} ; //call p(std::initialize_liat<int> );
p r{77,5,42};  //call p(std::initialize_liat<int> );
p s = {77 , 5}; //call p(std::initialize_liat<int> );
没有构造函数的初始化列表,构造函数传递两个整形通过p,q两个形参。

因为初始化列表,explicit显示构造变成实质性的,所以现在你可以通过一个自动类型对多个值操作, 当一个初始化列表使用=语法。

class P
{
public:
p(int a , int b)
{
...
}

explicit P(int a , int b  , int c){
....
}

};

p x{(77,5); //ok
P y{77 , 5}; //ok
P z{77 , 5 , 42}; //ok
p v = {77 , 5}; //ok
p k = {77 , 5 , 42};  // 因为显式调用标记

void fp(const p&);

fp({75 , 2}); //ok
fp({75,6 , 42}) ; //error  因为显式调用标记
fp(p{47,11});  //ok
fp(p{33 , 3 , 33}); //ok

相同的方法,显式构造使用一个初始化列表是无力的内含的0 , 1 , 或者更多的初始化值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++11