精华内容
下载资源
问答
  • 初始化定义:指创建变量并给它赋初始值。 赋值定义:擦除对象的当前值并用新值代替。 int a = 4;//直接初始化, a = 5;//赋值初始化 总结:赋值初始化和直接初始化对比,直接初始化的效率很高。 ...
    初始化定义:指创建变量并给它赋初始值。
    赋值定义:擦除对象的当前值并用新值代替。
    
    int a = 4;//直接初始化,
    a = 5;//赋值初始化
    总结:赋值初始化和直接初始化对比,直接初始化的效率很高。
    

     

    展开全文
  • c++构造函数成员初始化赋值和初始化列表两种方式的区别2016年08月31日 11:26:368110人阅读 评论(0) 收藏 举报 分类:C++基础(23) 先总结下:由于类成员初始化总在构造函数执行之前1)从必要性: a....
     

    c++构造函数成员初始化中赋值和初始化列表两种方式的区别

    8110人阅读 评论(0) 收藏 举报
     分类:
    C++基础(23) 

    先总结下:

    由于类成员初始化总在构造函数执行之前

    1)从必要性:

         a. 成员是类或结构,且构造函数带参数:成员初始化时无法调用缺省(无参)构造函数

         b. 成员是常量或引用:成员无法赋值,只能被初始化

    2)从效率上:

        如果在类构造函数里赋值:在成员初始化时会调用一次其默认的构造函数,在类构造函数里又会调用一次成员的构造函数再赋值

        如果在类构造函数使用初始化列表:仅在初始化列表里调用一次成员的构造函数并赋值


    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    以下内容参考自 c++中构造函数初始化的方法以及主要区别

    ----------------------

    一、我的问题是关于初始化C++类成员的。我见过许多这样的代码: 

    1. CSomeClass::CSomeClass()   
    2. {   
    3.     x=0;   
    4.     y=1;   
    5. }   
    而在别的什么地方则写成下面的样子: 
    1. CSomeClass::CSomeClass() : x(0), y(1)   
    2. {   
    3.   
    4. }   

    我的一些程序员朋友说第二种方法比较好,但他们都不知道为什么是这样。你能告诉我这两种类成员初始化方法的区别吗? 

    回答 

    从技术上说,你的程序员朋友是对的,但是在大多数情况下,两者实际上没有区别。有两个原因使得我们选择第二种语法,它被称为成员初始化列表:一个原因是必 须的,另一个只是出于效率考虑。 

    让我们先看一下第一个原因——必要性。设想你有一个类成员,它本身是一个类或者结构,而且只有一个带一个参数的构造函数。 
    1. class CMember {   
    2. public:   
    3.   
    4. CMember(int x) { ... }   
    5.   
    6. };   

    因为Cmember有一个显式声明的构造函数,编译器不产生一个缺省构造函数(不带参数),所以没有一个整数就无法创建Cmember的一个实例。 
    1. CMember* pm = new CMember; // Error!!   
    2. CMember* pm = new CMember(2); // OK   

    如果Cmember是另一个类的成员,你怎样初始化它呢?你必须使用成员初始化列表。 
    1. class CMyClass {   
    2. CMember m_member;   
    3.   
    4. public:   
    5.   
    6. CMyClass();   
    7.   
    8. };   
    9.   
    10. //必须使用成员初始化列表   
    11. CMyClass::CMyClass() : m_member(2)   
    12. {   
    13. ...  
    14. }   

    没有其它办法将参数传递给m_member,如果成员是一个常量对象或者引用也是一样。根据C++的规则,常量对象和引用不能被赋值,它们只能被初始化。 

    第二个原因是出于效率考虑,当成员类具有一个缺省的构造函数和一个赋值操作符时。MFC的Cstring提供了一个完美的例子。假定你有一个类 CmyClass具有一个Cstring类型的成员m_str,你想把它初始化为 "yada yada. "。你有两种选择: 
    1. CMyClass::CMyClass() {   
    2. // 使用赋值操作符   
    3. // CString::operator=(LPCTSTR);   
    4. m_str = _T( "yada yada ");   
    5.   
    6. }   
    7. //使用类成员列表   
    8. // and constructor CString::CString(LPCTSTR)   
    9. CMyClass::CMyClass() : m_str(_T( "yada yada "))   
    10. {   
    11.   
    12. }   

    在 它们之间有什么不同吗?是的。编译器总是确保所有成员对象在构造函数体执行之前初始化,因此在第一个例子中编译的代码将调用CString:: Cstring来初始化m_str,这在控制到达赋值语句前完成。在第二个例子中编译器产生一个对CString:: CString(LPCTSTR)的调用并将 "yada yada "传递给这个函数。结果是在第一个例子中调用了两个Cstring函数(构造函数和赋值操作符),而在第二个例子中只调用了一个函数。在 Cstring的例子里这是无所谓的,因为缺省构造函数是内联的,Cstring只是在需要时为字符串分配内存(即,当你实际赋值时)。但是,一般而言, 重复的函数调用是浪费资源的,尤其是当构造函数和赋值操作符分配内存的时候。在一些大的类里面,你可能拥有一个构造函数和一个赋值操作符都要调用同一个负 责分配大量内存空间的Init函数。在这种情况下,你必须使用初始化列表,以避免不要的分配两次内存。在内部类型如ints或者longs或者其它没有构 造函数的类型下,在初始化列表和在构造函数体内赋值这两种方法没有性能上的差别。不管用那一种方法,都只会有一次赋值发生。有些程序员说你应该总是用初始 化列表以保持良好习惯,但我从没有发现根据需要在这两种方法之间转换有什么困难。在编程风格上,我倾向于在主体中使用赋值,因为有更多的空间用来格式化和 添加注释,你可以写出这样的语句:x=y=z=0; 

    或者memset(this,0,sizeof(this)); 

    注意第二个片断绝对是非面向对象的。 

    当我考虑初始化列表的问题时,有一个奇怪的特性我应该警告你,它是关于C++初始化类成员的,它们是按照声 明的顺序初始化的,而不是按照出现在初始化列表中的顺序。 
    1. class CMyClass {   
    2. CMyClass(int x, int y);   
    3. int m_x;   
    4. int m_y;   
    5. };   
    6.   
    7. CMyClass::CMyClass(int i) : m_y(i), m_x(m_y)   
    8. {   
    9.   
    10. }   

    你 可能以为上面的代码将会首先做m_y=I,然后做m_x=m_y,最后它们有相同的值。但是编译器先初始化m_x,然后是m_y,,因为它们是按这样的顺 序声明的。结果是m_x将有一个不可预测的值。我的例子设计来说明这一点,然而这种bug会更加自然的出现。有两种方法避免它,一个是总是按照你希望它们 被初始化的顺序声明成员,第二个是,如果你决定使用初始化列表,总是按照它们声明的顺序罗列这些成员。这将有助于消除混淆。

    二、很多的人对中构造函数寝初始化很多的困惑,对冒号后初始化不是太明白,总搞不清楚它们之间的区别,我想把我对这个问题的理解和看法和大家讨论讨 论。 

    在程序中定义变量并初始化的机制中,有两种形式,一个是我们传统的初始化的形式,即赋值运算符赋值,还有一种是括号赋值,如: 
    int a=10; 
    char b='r';\\赋值运算符赋值 
    int a(10);\ 
    char b('r');\\括号赋值 
    以上定义并初始化的形式是正确的,可以通过编译,但括号赋值只能在变量定义并初始化中,不能用在变量定义后再赋值,这是和赋值运算符赋值的不同之处,如: 
    (1) 
    int a; \\先定义一个变量 
    ...... 
    a=10; \\根据需要赋值 

    (2) 
    int b; \\先定义一个变量 
    ...... 
    b(10); \\和(1)一样根据需要赋值 
    (1)是可以用通过编译,定义一个变量a但并没有初始化,在需要变量a的时候,通过赋值运算符把10赋给a,而在(2)中,是通过括号把10赋值给b,但 编译系统认为 
    这是一个函数的调用,函数名为b,10为实际参数,所以编译错误。因此,括号赋值只用在定义变量并初始化中。



    现在我们来看构造函数中冒号初始化和函数初始化的问题,类构造函数的作用是创建一个类的对象时,调用它来构造这个类对象的数据成员,一要给出此数据成员分 配内存空间,二是要给函数数据成员初始化,构造数据成员是按数据成员在类中声明的顺序进行构造。 

    冒号初始化与函数体初始化的区别在于: 

    冒号初始化是给数据成员分配内存空间时就进行初始化,就是说分配一个数据成员只要冒号后有此数据成员的赋值表达式(此表达式必须是括号赋值表达式),那么 分配了内存空间后在进入函数体之前给数据成员赋值,就是说初始化这个数据成员此时函数体还未执行。 

    对于在函数中初始化,是在所有的数据成员被分配内存空间后才进行的。 

    这样是有好处的,有的数据成员需要在构造函数调入之后函数体执行之前就进行初始化如引用数据成员,常量数据成员和对象数据成员,看下面的一段程序: 

    1. class student   
    2. {public :   
    3. student ()   
    4. .   
    5. .   
    6. .   
    7. protected:   
    8. const int a;   
    9. int &b;  
    10. }   
    11.   
    12. student ::student (int i,int j)   
    13. {   
    14. a=i;   
    15. b=j;   
    16. }   

    在Student类中有两个数据成员,一个是常量数据成员,一个是引用数据成员,并且在构造函数中初始化了这两个数据成员,但是这并不能通过编译,因为常 量初始化时必须赋值,它的值是不能再改变的,与常量一样引用初始化也需要赋值,定义了引用后,它就和引用的目标维系在了一起,也是不能再被赋值的。所以C 
    ++":"后初始化的机制,使引用和常量数据成员变为可能的,Student类的构造函数应为: 
    student ::student(int i,int j):a(i),b(j){} 

    在下面的程序: 
    1. class teach   
    2. {   
    3. public :   
    4. teach(char *p="name",int a=0)   
    5. .   
    6. .   
    7. .   
    8. protected:   
    9. char name[30];   
    10. int age;   
    11. }   
    12. teach ::teach(char*p,int a)   
    13. {   
    14. strcopy(name ,p);   
    15. age=a;   
    16. cout>>name>>endl;   
    17. }   
    18. class student   
    19. {   
    20. public:   
    21. student (char *p="name");   
    22. .   
    23. .   
    24. .   
    25. protected;   
    26. char name[30];   
    27. teach teacher;   
    28. };   
    29. student::student(char *p)   
    30. {   
    31. strcopy(name,p);   
    32. cont>>name>>endl;   
    33. }   

    在上面的程序中通不过编译,编译系统会告诉你teacher这个类对象缺默认构造函数,因为在teach 类中没有定义默认的构造函数。那么带参数的构造函数怎么进行构造呢?通过我们前面提到的冒号赋值。那它的构造函数应该是: 
    1. student::student(char *p,char *pl,int ag):teacher(pl,ag)   
    2. {   
    3. strcopy(name,p);   
    4. cont>>name>>endl;   
    5. }   

    就是说在没有默认构造函数的时候,如果一个类对象是另一个类的数据成员,那么初始化这个数 据成员,就应该放到冒号后面。这样可以带参数。在类的定义中,如: 
    protected; 
    char name[30]; 
    teach teacher 
    类对象是不能带参数的,因为它只是声明。 
    展开全文
  • 初始化赋值

    2012-12-13 11:00:13
    初始化指创建变量并给它赋初始值,赋值就是擦除...初始化变量的形式:复制初始化和直接初始化,他们之间的差别很微妙,但是直接初始化的语法更灵活而且效率很高。 int a(11);直接初始化 int a = 11; 复制初始化

    初始化指创建变量并给它赋初始值,赋值就是擦除对象的当前值并用新值代替。例如:

    int a=3;就是初始化,

    a =1;就是赋值。

    初始化变量的形式:复制初始化和直接初始化,他们之间的差别很微妙,但是直接初始化的语法更灵活而且效率很高。

    int  a(11);直接初始化

    int  a = 11; 复制初始化

    展开全文
  • 双括号初始化理解及效率问题参考:双大括号初始化的理解使用   package com.idark; import java.util.ArrayList; /** * @description: Demo测试 * @author: iDark * @create: 2018/8/3 14:57 * @email: ...

    双括号初始化理解及效率问题参考:双大括号初始化的理解和使用

     

    package com.idark;
    
    import java.util.ArrayList;
    
    /**
     * @description: Demo测试
     * @author: iDark
     * @create: 2018/8/3 14:57
     * @email: 43352901@qq.com
     */
    public class Demo {
        public static void main(String[] args) {
    
            //Method 1
            ArrayList<String> lists1 = new ArrayList<String>();
            lists1.add("test1");
            lists1.add("test2");
    
            //Method 2 , (double brace initialization)
            ArrayList<String> lists2 = new ArrayList<String>(){{
                add("test1");
                add("test2");
            }};
        }
    }
    

     

    展开全文
  • 对于内置数据类型,构造函数初始化列表构造函数内赋值是基本一样的。 但是对于结构体类型自定义类类型,初始化列表更好。当使用初始化列表构造对象的时候,初始化一次就完成了;如果使用构造函数内赋值,要调用...
  • 区别 1: 可能只知道 一个效率高一个效率低,具体...如果成员变量类型是 内置类型(int, char ), 那么初始化和赋值的成本是相同的.这里的效率高低, 指的是自定的类型(class) class test { public: test(){ std::...
  • 对于内部数据类型(char,int,float...),构造函数初始化列表构造函数体内赋值,基本上没多大区别,效率差异也不大,但两者不能共存: class Student { public: Student(char *name, int...
  • 好的。首先把构造函数内部赋值剔除掉。因为:1....下面比较类内初始化和初始化列表。 相同点:1.从名字就可以看出,两者都是初始化。 不同点:1.如果对于同一个变量,两者同时出现,则以初始化列表为主。
  • 类中成员变量在构造函数中无论是列表初始化还是函数体赋值,其最终效果都是一样的。但是在某些具体细节和效率方面是有所差别的。 class的成员变量可以分成两类:(1)内置类型:int、char、bool等 (2)用户自定义...
  • 初始化列表效率

    2018-03-14 13:37:54
    Effective C++里有提到,看过的都知道,初始化列表效率&gt;=在函数体里赋值。但有一点要特别注意,成员变量初始化的顺序取决于声明的顺序,而不是在初始化列表中的顺序。vc不说啥,gcc会报warning。如果遇到初始...
  • 之所以推荐在变量声明时进行初始化,是因为我们定义的类型往往有多个成员变量,这样会导致有多个...当我们要将对象初始化为0或者null时,这时在变量初始化时为其赋值是没有错的,但是效率不高。原因是系统默认的初始化
  • 在c++中构造函数初始化列表直接赋值的区别: 对于内置类型:没有区别。 对于自定义类型:初始化列表的效率会更高一些。
  • 最近面试过程中,面试问了类构造初始化列表构造函数内赋值有什么区别。当时没完全回答清楚,后来google了一下,发现两者有如此大的不同,现总结如下。 构造初始化列表中,是直接调用相应的构造函数进行对象初始化...
  • list 是支持常数时间从容器任何位置插入移除元素的容器。不支持快速随机访问。它通常实现为双向链表。与 forward_list 相比,...下面我们先来学习list的创建,初始化assign,赋值操作operator=, empty,size,max_size
  • 有些情况下必须用初始化——特别是const引用数据成员只能用初始化,不能被赋值。 2.成员初始化列表的效率赋值效率高。 看第一种情况: class A { const int constVal; public: // A() { constVal = 0;} ....
  • c++初始化和重载函数笔记

    千次阅读 2013-11-26 15:52:07
    c++支持两种初始化变量的形式: 复制初始化 直接初始化 复制初始化语法用等号(=) ...在冒号花括号之间的代码称为构造函数的初始化列表。 构造函数的初始化列表为类的一个或多个数据成员指定初值; 例: S
  • 在学习了简单的输入输出功能了解了一些基本的运算符号之后我们可以试着做一个非常简单的计算器。 比如说想计算23+65 输入以下代码就可以了。 printf("23+65=%d",23+65); 如果想计算100+89,就需要把上面式子中...
  • 这两种方法的差别主要是效率的差别,放在初始化表中,只有只有一个拷贝构造函数调用,而放在构造函数内部有构造函数和赋值函数两个函数调用。 在初始化表中赋值,不仅能提高效率,而且还能和const常量的赋值统一起来...
  • 数组初始化

    2019-09-23 12:48:55
    给数组赋值的方法除了用赋值语句对数组元素逐个赋值外, 还可采用初始化赋值和动态赋值的方法。数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。...
  • 推荐在构造函数初始化列表中进行初始化,这样执行效率比较高。 class Test { public: Test(int a,int b,int c) :x(a),y(b),z(c){}//在初始化列表中初始化效率较高,若在计算段{ x=a; y=b; z=c; },调用赋值操作,...
  • 在对类成员变量初始化的时候,我们很多时候没有注意到,在类构造函数的初始化列表中初始化成员变量,在构造函数中赋值初始化成员变量的差别是很大的,不仅表现在程序的执行效率上,同时还有语法上的区别。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 505
精华内容 202
关键字:

初始化和赋值效率