zoukankan      html  css  js  c++  java
  • 直接初始化与复制初始化

    这是C++中所支持的两种初始化方式。 
    复制初始化使用=符号,而直接初始化将初始化式放在圆括号中。 
    (1)对于一般的内建类型,这两种初始化基本上没有区别。 
    int a(5);//直接初始化 
    int a=5;//复制初始化 
    int a=int (5);//直接初始化 
    (2)当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定构造函数创建一个临时对象,然后使用复制构造函数将那个临时对象复制到正在创建的对象。 
    string null_book = "9-999-99999-9 ";//copy-initialization 
    string dots(10, '. ');//direct-initialization 
    string empty_copy = string();//先direct,然后copy-initialization 
    string empty_direct;//direct-initialization 
    对于类类型对象,只有指定单个实参或显式创建一个临时对象用于复制时,才使用复制初始化。 
    创建dots时,调用参数为一个数量和一个字符的string构造函数并直接初始化dots的成员。创建null_book时,编译器首先调用接受一个C风格字符串形参的string构造函数,创建一个临时对象,然后,编译器使用string复制构造函数将null_book初始化为那个临时对象的副本。 
    empty_copy和empty_direct的初始化都调用默认构造函数。对前者初始化时,默认构造函数创建一个临时对象,然后复制构造函数用该对象初始化empty_copy。对后者初始化时,直接运行empty_direct的默认构造函数。 

    支持初始化的复制形式主要是为了与C的用法兼容。当情况许可时,可以允许编译器跳过复制构造函数直接创建对象,但编译器没有义务这样做。
    通常直接初始化和复制初始化仅在低级别优化上存在差异。然而,对于不支持复制的类型,或者使用非explicit构造函数的时候,它们有本质区别:
    ifstream file1("filename");//ok:direct initialization 
    ifstream file2 = "filename";//error:copy constructor is private

    //This initialization is okay only if the sales_item(const string&) constructor is not explicit 
    Sales_item item = string("9-999-99999-9"); 
    ... 
    item的初始化是否正确,取决于正在使用哪个版本的Sales_item类。某些版本将参数为一个string的构造函数定义为explicit。如果构造函数是显示的,则初始化失败;如果构造函数不是显示的,则初始化成功。 

    对于复制初始化,最显示的调用手段就是使用“=”符号(这个时候应该成为复制初始化符号)。那么还有许多地方是隐式的调用。如参数传递时,函数返回时,初始化容器时! 
    1)对于参数传递:我们知道除非是引用参数,否则就是一个使用上层对象复制初始化函数参数的过程。 
    2)对于函数返回值:我们知道除非是引用返回,否则在return的那个语句就是使用函数内的对象,复制初始化一个上层对象(通常是临时的,然后马上有被用于)
    3)在某些容器初始化的过程中如: 
    vect<string> svec(5); 
    这里的过程就是,先使用string默认构造出一个实例对象,然后使用这个对象,复制初始化其它的元素。这个过程是容器的实现细节,其实从外面看,可以理解为直接初始化。 
    4)数组初始化,有时候使用这样的语法: 
    Sales_item primer_eds[]={ string("1231231"), 
    string("3123123") 

    可知这个过程,就是一个先调用直接初始化生成string,然后继续隐式调用直接初始化生成Sales_item。最后使用复制初始化,给那个数组的各个元素初始化。
    这儿是对复制构造函数和复制初始化的介绍:http://www.cnblogs.com/xkfz007/archive/2012/03/01/2376376.html
    下面是一个测试构造函数的类:

    #include <iostream>
    using namespace std;
    class A{
    friend ostream& operator<<(ostream& os,const A& rhs);
        public:
            A(int a=10):m_a(a){
                id=count++;
                cout<<"A(int a):id="<<id<<endl;
            }
            A(const A& rhs):m_a(rhs.m_a){
                id=count++;
                cout<<"A(const A&rhs):id="<<id<<endl;
            }
            A& operator=(const A& rhs){
                if(this !=&rhs){
                    id=count++;
                    m_a=rhs.m_a;
                }
                return *this;
            }
            ~A(){
                cout<<"~A:id="<<id<<endl;
            }
        private:
            int m_a;
            int id;
            static int count;
    };
    int A::count=0;
    ostream& operator<<(ostream& os,const A& rhs){
        os<<"<A:m_a="<<rhs.m_a<<",id="<<rhs.id<<">";
        return os;
    }
    int main1(){
        A a1;
        cout<<a1<<endl;
        A a2=a1;
        cout<<a2<<endl;
        A a3;
        cout<<a3<<endl;
        a3=a2;
        cout<<a3<<endl;
        A a4(a3);
        cout<<a4<<endl;
    return 0;
    }
    int main(){
        A a1,a2(5),a3(200);
        A b=A(8000);
        cout<<b<<endl;
        A arr[]={a1,a2,a3}; 
        int i(5),j=5;
        int k=int();
        cout<<i<<j<<k<<endl;
    }
  • 相关阅读:
    【CF 359B】Permutation
    如何更新 DevC++ 的编译器
    【LG 2801】教主的魔法
    矩阵浅谈
    NOI 系列赛常见技术问题整理
    Treap 浅谈
    DP 优化浅谈
    友链
    【CF 708C】Centroids
    我跳过的坑
  • 原文地址:https://www.cnblogs.com/xkfz007/p/2562813.html
Copyright © 2011-2022 走看看