精华内容
下载资源
问答
  • 初始值列表
    千次阅读
    2016-04-19 22:53:43

    在 C++编程的过程中,我们对构造函数通常有以下两种写法:
    zhangteng::zhangteng(int a,int b):age(a),score(b){}
    zhangteng::zhangteng(int a,int b)
    {
    private:
    age=a;
    score=b;
    }
    前者被称为初始值列表法,后者则是初始化与赋值分开。
    在程序的编写过程中,最好养成使用初始值列表的习惯。原因有两个:
    1.底层效率问题:前者效率优于后者
    2.一些数据成员(例如常量对象、引用、某种未提供默认构造函数的类类型)必须使用初始化列表的方法,使用赋值的方法会出现问题。
    zhangteng::zhangteng(int a,int b)
    {
    age=a;
    score=b;
    }
    private:
    const int age;
    int & score;
    上述写法是不对的。
    因为如果没有构造函数的初始值列表显示的初始化成员,则该成员将在构造函数体之前执行默认初始化。
    也即在执行age=a;score=b;之前系统已经默认对age和score执行了默认赋值。而age是定义为常int型变量,我们不能对其进行二次赋值,这是显而易见的。而score作为引用变量,也是不能进行二次赋值的。具体原因我们举个例子来说明:
    int a=6,b=9;
    int &c=a;
    c=b;
    这三条语句在语法上是没有问题的,但分析一下其结果,a和b和c的值都会变为9,而c仍然是a的引用而不是b.也就是说引用二次赋值,在语法上是没有问题的,但往往在逻辑功能上已经背离了程序设计的初衷。
    所以我们要杜绝这种做法。
    成员的初始化顺序与他们在类定义中出现的顺序一致,构造函数初始值列表的前后位置关系不会影响实际的初始化顺序。

    更多相关内容
  • C++中类初始值列表与类内初始化

    千次阅读 2020-09-22 12:18:56
    而在构造函数中可以使用初始值列表为新创建的对象的成员进行赋值。 1 初始值列表 在类的构造函数名之后紧跟着冒号,冒号后面是要初始化的成员名,之后是圆括号或者花括号括起来的初始值。这样的结构就是构造函数的...

    类的构造函数的作用是对其成员进行初始化。而在构造函数中可以使用初始值列表为新创建的对象的成员进行赋值。

    1 初始值列表

    在类的构造函数名之后紧跟着冒号,冒号后面是要初始化的成员名,之后是圆括号或者花括号括起来的初始值。这样的结构就是构造函数的初始值列表,如下所示。

    class A
    {
      public:
        A() :a(1),b(2) {};
        int a;
        int b;
    };

    其中,自定义类A具有一个包含了初始值列表的构造函数,使用该构造函数创建对象时,该对象的成员变量a的值是1,b的值是2。

    2 类内初始化

    对于“1 初始值列表”中提到的自定义类A,如果其还存在多个构造函数,

    A(int i) :a(1),b(2) {};
    A(int i, int j) :a(1),b(2) {};
    A(int i, int j, int z) :a(1),b(2) {};

    多个构造函数都包含了相同的初始值列表,代码看上去有些冗长。此时可以使用类内初始化的方法对其进行简化。

    类内初始化指的是在定义类的成员时对其赋初值,赋初值的方式有两种:使用等号赋值和使用大括号赋值。

    class A
    {
    
    public:
    .....
    
      int a = 1;
      int b{ 2 };
    };

    此时,对于之前提到的包含初始值列表的构造函数,就可以简写成如下格式

    A(){};
    A(int i) {};
    A(int i, int j){};
    A(int i, int j, int z)  {};

    之后无论使用哪一种构造方法来产生该类的对象,这个对象的a和b的值分别是1和2。需要注意的是,类内初始化是C++11的新属性

    展开全文
  • 只能通过构造函数初始值列表进行初始化: 初始化时会按照成员变量的声明顺序,而不是构造函数初始值列表中的顺序。如果你决定使用初始化列表,请按照它们声明的顺序罗列这些成员。这将有助于消除混淆。

    当一个类中有引用类型成员变量,和const成员变量时,他们是不能通过构造函数赋值初始化的。

    只能通过构造函数初始值列表进行初始化:

    class ClassX {
    public:
        int a;
        int &c;
        const int d;
    private:
        int b;
    
    public:
        ClassX(int a, int b)://注意要跟一个冒号再加列表
            c(a), d(9) {
            this -> a = a;
            this -> b = b;
            //this -> c = c;
            //this -> d = d;
        }
        int getb() {
            return this -> b;
        }
    
    };
    
    int main()
    {
        ClassX classX(1, 2);
        cout << classX.a << classX.getb() << classX.c << classX.d << endl;
        return 0;
    }


    上面的c、d分别是引用类型和常量类型的成员变量,通过c(a)、d(9)进行了初始化。

    初始化时会按照成员变量的声明顺序,而不是构造函数初始值列表中的顺序。如果你决定使用初始化列表,请按照它们声明的顺序罗列这些成员。这将有助于消除混淆。

    =======================

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

    如果内置类型的变量未被显示初始化,他的值由定义的位置决定:定义于任何函数之外的变量将初始化为0,定义在函数体内部的值将不能被初始化,其值将是未定义的。

    一些类要求每个对象都先时初始化。

    建议初始化每一个内置类型的变量。


    展开全文
  • 读取未初始化的会导致不明确的行为   在某些平台上,仅仅是读取未初始化的,就可能让你的程序终止运行。更可能的情况是读入一些“半随机”bits,污染了正在进行读取动作的那个对象,最终导致不可预知的程序...

    为什么对象使用前需要初始化

    1.读取未初始化的值会导致不明确的行为
      在某些平台上,仅仅是读取未初始化的值,就可能让你的程序终止运行。更可能的情况是读入一些“半随机”bits,污染了正在进行读取动作的那个对象,最终导致不可预知的程序行为,以及许多令人不愉快的调试过程。
      永远在使用对象之前将它初始化:对于无任何成员的内置类型,你必须手工完成此事;对于内置类型以外的任何其他东西,初始化责任落在构造函数身上,规则是:确保每一个构造函数都将对象的每一个成员初始化。
    2.构造函数的初始值有时候必不可少
    (1) 当初始化一个reference menber时;
    (2) 当初始化一个const menber时;
    (3) 当调用一个base class的constructor,而它拥有一组参数时;
    (4) 当调用一个member class的constructor,而它拥有一组参数时。

    初始化和赋值的区别

    1.底层效率
      初始化操作直接初始化成员,赋值操作则先初始化再赋值。例如:
    (1) 没有使用成员初始化列表

    class Word {
        string _name;
        int _cnt;
    public:
        //没有使用member initialization list
        Word() {
            _name = 0;
            _cnt = 0;
        }
    };

      在这里,Word constructor会先产生一个临时性额String object,然后将它初始化,之后以一个saaignment运算符将临时性object指定给_name,随后再摧毁那个临时性object。以下是constructor可能的内部扩张结果:

    //C++伪代码
    Word::Word() {
        //调用String的default constructor
        _name.String::String();
    
        //产生临时对象
        String temp = String(0);
    
        //将temp每个成员都拷贝给_name
        _name.String::operator=(temp);
    
        //析构临时对象
        temp.String::~String();
    
    
        _cnt = 0;
    }

    (2) 使用初始化列表

    //使用初始化列表
    Word::Word() : _name(0) {
        _cnt = 0;
    }

      它会被扩张成这样:

    //C++伪代码
    Word::Word() {
        //调用String(int) constructor
        _name.String::String(0);
        _cnt = 0;
    }

      这个构造函数和上一个的最终结果相同,但通常效率高很多。对于大多数类型而言,比起先调用default constructor然后再调用copy assignment操作符,值调用一次copy constructor是比较高效的。

    2.一些成员必须要求初始化
      如果成员是const或者是引用,必须将其初始化;当成员属于某种类类型而且该类设有定义默认构造函数时,也必须将这个成员初始化。

    成员初始化顺序

    1.C++成员初始化次序
      C++有着十分固定的成员初始化次序:base classes更早于其derived classes被初始化,而class的成员变量总是以其声明次序被初始化。构造函数初始值列表中初始值的前后位置关系不会影响实际的成员初始化顺序。例如:

    Word::Word() : _cnt(0), _name(0) {
    }

      编译器会一次操作initialization list,以适当顺序在constructor之内安插初始化操作,并且在任何explicit user code之前。例如,上面的Word constructor被扩充为:

    //C++伪代码
    Word::Word() {
        _name.String::String(0);
        _cnt(0);
    }

      列表中的初始化顺序是由class中的members声明顺序决定的,不是成员初始值列表的排列顺序决定的。

    2.一个成员用另一个成员来初始化
      举个例子:

    class X {
        int i;
        int j;
    public:
        X(int val) : j(val), i(j) {}
    };

      i先被初始化,因为这个初始值的效果是试图使用未定义的值j初始化i。
      测试代码如下:

    #include<iostream>
    using namespace std;
    
    class X{
    public:
        int i;
        int j;
    public:
        //有陷阱的写法
        X(int val) : j(val), i(j) {}
    }; 
    
    class Y {
    public:
        int i;
        int j;
    public:
        //修改后的写法
        Y(int val) : j(val) {
            i=j;
        }
    };
    
    int main() {
        X x(3);
        Y y(5);
    
        cout<<"x.i="<<x.i<<" x.j="<<x.j<<endl;
        cout<<"y.i="<<y.i<<" y.j="<<y.j<<endl;
    
        return 0;
    }

    这里写图片描述

      x.i的值果然不是我们所期望的3。

    总结

    • 为内置类型对象进行手动初始化,因为C++不能保证初始化它们;
    • 构造函数最好使用成员初始值列表(member initialization list),而不要在构造函数本体内使用赋值操作(assignment);
    • 最好令构造函数初始值的顺序与成员变量的顺序保持一致,如果可能的话,尽量避免使用某些成员初始化其他成员。

    参考资料

    • 《C++ Primer》7.5 构造函数再探
    • 《Effective C++》 条款4 确定对象被使用前已先被初始化
    • 《深度探索C++对象模型》 2.4 成员们的初始化队伍
    展开全文
  • 在VS2013的环境下进行编译,报错:“ error C2797: 'Window_mgr::screens': 未执行成员初始值列表内的列表初始化或非静态数据成员初始值” 在网上进行查找后,问题出在编译器上,VS2013不支持部分C++11特性。在...
  • // 如果调用的为另外一个版本的ctor(没有在初始值列表中显示构造_d,那么是否调用类内初始值) A aaa(2, 22, 3); // Data ctor: param: i: 99999 // Data ctor: param: i: 88888 // A ctor 1 param: _i:1 // Data...
  • 使用对象初始值设定项初始化对象 可以使用对象初始值设定项以声明方式初始化类型对象,而无需显式调用类型的构造函数。 下面的示例演示如何将对象初始值设定项用于命名对象。编译器通过先访问默认实例构造函数然后...
  • 主要介绍了python创建列表并给列表初始值的方法,涉及Python列表的定义与赋值技巧,需要的朋友可以参考下
  • 初始化的含义是床关键变量时赋予其一个初始值,而赋值的含义时把对象的当前值擦除,而已一个新值来替代。 列表初始化 C++定义了初始化的好几种不同形式,通常定义一个变量并初始化的方式有以下四种: int x = 0; ...
  •  这样写是有错误的,error C2758: “constRef::ci”: 必须在构造函数基/成员初始值设定项列表中初始化; constRef::ri”: 必须在构造函数基/成员初始值设定项列表中初始化; error C2166: 左值指定 const 对象; ...
  • C++构造函数之初始列表

    千次阅读 2022-03-04 10:07:39
    C++构造函数的初始列表详解
  • C++之初始列表

    千次阅读 多人点赞 2022-06-11 17:56:53
    初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。 注意: 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员...
  • 构造函数初始列表

    千次阅读 2022-03-29 21:58:10
    构造函数初始列表以一个冒号开始,接着是以逗号分隔的数据成员列表, 每个数据成员后面跟一个放在括号中的初始化式。 student(int m,int n):shengao(m),tizhong(n) { cout<<"初始化"<<endl;...
  • C++类内初始值的初始化形式

    千次阅读 2022-01-21 12:18:17
    类内初始值的初始化列表{}方式 C++11规定,可以为数据成员提供一个类内初始值。创建对象时,类内初始值用于初始化数据成员。像下面这样,cursor和height的类内初始值均为0。 class Screen { private: int cursor = ...
  • 构造函数与初始列表

    万次阅读 多人点赞 2018-08-01 18:17:33
    1)初始化:一个变量或者一个对象在产生的时候就赋予一个,属于伴随性质 2)赋值:在一个变量或者一个对象在产生之后的任意时刻赋予一个,属于任意性质 宏观代码上: 1)两者作用相同 2)对于数组和结构体来...
  • 构造函数的初始列表仅仅指定用于初始化成员的,并不指定这些初始化执行的次序。成员初始化的次序就是定义成员的次序,第一个成员首先被初始化,然后是第二个,依次类推
  • C++中的成员初始列表

    千次阅读 2018-05-09 17:23:05
    class Queue { private: //Node is a nestedstructure definition local to this c struct Node { Item item; struct Node * next;...然而,使用成员初始列表的构造函数将覆盖相应的类内初始化。
  • cpp代码-C++:初始列表:1.向数据成员传递
  • C++:初始值设定项

    千次阅读 2021-06-25 20:46:26
    C++:初始值设定项简介初始化类型零初始化默认初始化常量变量的默认初始化静态变量的默认初始化值初始化复制初始化直接初始化列表初始化聚合初始化初始化联合和结构初始化包含聚合的聚合引用初始化外部变量的初始化 ...
  • 效率低,它的本质是赋值,不是初始化,c++内部机制事实上已经为成员变量默认初始化了,然后你又在构造函数里面赋了一次。2.易错,对于const成员变量,初始化之后就不可以赋值了。 下面比较类内初始化和初始列表...
  • 展开全部python的数据是可以动态2113增长的,直接定义使用5261a=[]即可:比如:a=[0,1,2],这时a[0]=0, a[1]=1, a[[2]=2;如果4102数组想a想定义...如果想定义1000长度的a,初始值全为0,则 a = [0 for x in range(0,...
  • java中【HashMap】初始化时,尽量指定初始值大小
  • C++变量初始化形式及其默认初始值

    千次阅读 多人点赞 2022-04-18 20:33:56
    在C++中有多种变量初始化形式,本文旨在搞懂各种初始化的区别,以及在默认初始化情况下,变量的初始值情况。
  • JAVA 给List赋初始值最简单方案

    千次阅读 2021-10-06 13:42:42
    /** * swagger 放行URL */ List<String> SWAGGER_URL = Arrays.asList( "/v3/**",//此请求不放开会导致 error api-docs无法正常... "/swagger-ui**", "/swagger-ui/**",//此请求不放开没有权限请求一直失.
  • java中快速创建带初始值的List和Map实例初始化一个List和Map对象并为期加入值的写法如下:List sList = new ArrayList();sList.add("str1");sList.add("str2");Map sMap = new HashMap();sMap.put("k1", "v1");sMap....
  • 在C++项目中,使用FFmpeg中的av_err2str...error C4576: 后跟初始值设定项列表的带圆括号类型是一个非标准的显式类型转换语法 1 解决方案: 在调用该函数的文件开始加上以下代码: char av_error[AV_ERROR_MAX_S...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 792,633
精华内容 317,053
关键字:

初始值列表

友情链接: EchoSerialArduino.zip