博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

统一的初始化语法

Posted on 2017-11-28 14:32  bw_0927  阅读(525)  评论(1)    收藏  举报

http://blog.csdn.net/gzlaiyonghao/article/details/6564162

https://www.cnblogs.com/my_life/articles/10935859.html

 

C++ 最少有 4 种不同的初始化形式,如括号内初始化,见:

  1. std::string s("hello");  
  2. int m=int(); //default initialization  

还有等号形式的:

  1. std::string s="hello";  
  2. int x=5;  


对于 POD 集合,又可以用大括号

  1. int arr[4]={0,1,2,3};  
  2. struct tm today={0};  


最后还有构造函数的成员初始化

  1. struct S {  
  2.  int x;  
  3.  S(): x(0) {} };  


这么多初始化形式,不仅菜鸟会搞得很头大,高手也吃不消。更惨的是 C++03 中居然不能初始化 POD 数组的类成员,也不能在使用 new[] 的时候初始 POD 数组,操蛋啊!

 

C++11 就用大括号一统天下

  1. class C  
  2. {  
  3.   int a;  
  4.   int b;  
  5. public:  
  6.    C(int i, int j);  
  7. };  
  8. C c {0,0};     //C++11 only. 相当于 C c(0,0);  
  9. int* a = new int[3] { 1, 2, 0 }; //C++11 only  
  10. class X {  
  11.     int a[4];  
  12. public:  
  13.     X() : a{1,2,3,4} {} //C++11, 初始化数组成员  
  14. };  


还有一大好事就是对于容器来说,终于可以摆脱 push_back() 调用了,C++11中可以直观地初始化容器了: 

  1. // C++11 container initializer  
  2. vector vs<string>={ "first""second""third"};  
  3. map singers =  
  4. {   {"Lady Gaga""+1 (212) 555-7890"},  
  5.     {"Beyonce Knowles""+1 (212) 555-0987"}
  6. };  


而类中的数据成员初始化也得到了支持:

  1. class C  
  2. {  
  3.    int a=7; //C++11 only  
  4. public:  
  5.    C();  
  6. };  

 

 

在C98标准中,只有静态常量整型(longshortenum)的类成员才可以就地初始化,C++11允许任何变量进行就地初始化,但只支持={}两种方式。例如:

class A{
    string str = "sss";     // OK
    int i {23};             // OK
    int j (23);             // Error
};




https://www.cnblogs.com/youxin/p/3735064.html



在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?
比如:
CBase *base = new CDerived();
CBase *base = new CDeviced;

括号(), 代表一个初始化的动作 

 

很多人都说,加括号调用没有参数的构造函数,不加括号调用默认构造函数或唯一的构造函数。这是有问题的。

对于自定义类类型:

  •        如果该类没有定义构造函数(由编译器合成默认构造函数)也没有虚函数,那么class c = new class;将不调用合成的默认构造函数,而class c = new class();则会调用默认构造函数。
  •        如果该类没有定义构造函数(由编译器合成默认构造函数)但有虚函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。
  •        如果该类定义了默认构造函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。

 

对于内置类型:

       int *a = new int;不会将申请到的int空间初始化,而int *a = new int();则会将申请到的int空间初始化为0。

 以下两个语句的区别是:第一个动态申请的空间里面的值是随机值,第二个进行了初始化,里面的值为0:

  1. int *p1 = new int[10];  
  2. int *p2 = new int[10]();  

结论:别使用不带括号的new。

class A{
public:
//A(){a=1;}
public:
int a;
};

A *a1=new A;
A *a2=new A();

cout<<a1->a<<endl; //输出:-842150451

cout<<a2->a<<endl; //输出0

A a3;
cout<<a3.a<<endl; //运行异常,a没有初始化。

 

如果加上一个virtual,如virtual ~A(){},

cout<<a1->a<<endl; //输出:-842150451

cout<<a2->a<<endl; //输出 -842150451

 

-------------下面是网上找的帖子,对理解上面的现象可能会有帮助-------------------

一个类满足下列其中任何一个条件:
1.包含了一个类的对象,这个对象有一个构造函数(包括编译器合成的默认构造函数)
2.如果继承自一些基类,其中某些基类有一个构造函数(包括编译器合成的默认构造函数)
3.有一个虚函数,或者继承到了虚函数
4.有虚基类

如果这个类没有默认的构造函数,编译器就会合成一个默认的构造函数,分别做以下事情
如果这个类有构造函数,编译器就会扩张所有构造函数,做以下事情
1.调用这个对象的构造函数
2.调用基类的构造函数
3.设置正确的虚函数表指针
4.设置指向虚基类对象的指针

去读下《深入理解c++对象模型》,那里面解释的很清楚