• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            asm, c, c++ are my all
            -- Core In Computer
            posts - 139,  comments - 123,  trackbacks - 0

            /********************************************\
            |????歡迎轉(zhuǎn)載, 但請(qǐng)保留作者姓名和原文鏈接, 祝您進(jìn)步并共勉!???? |
            \********************************************/


            C++對(duì)象模型(7) -? Member Initialization List

            作者: Jerry Cat
            時(shí)間: 2006/05/12
            鏈接:?
            http://m.shnenglu.com/jerysun0818/archive/2006/05/12/6978.html


            2.4 Member Initialization List
            =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

            When you write a constructor, you have the option of initializing class members either through the
            member initialization list or within the body of the constructor. Except in four cases, which one
            you choose is not significant.

            In this section, I first clarify when use of the initialization list is "significant" and then
            explain what actually gets done with that list internally. I then look at a number of possible,
            subtle pitfalls.

            You must use the member initialization list in the following cases in order for your program to compile:

            (1). When initializing a reference member
            (2). When initializing a const member
            (3). When invoking a base or member class constructor with a set of arguments
            ???? 低效的第四種情況
            In the fourth case, the program compiles and executes correctly. But it does so inefficiently.
            For example, given

            class Word {
            ?? String _name;
            ?? int _cnt;
            public:
            ?? // not wrong, just naive ...
            ?? Word() {
            ????? _name = 0;
            ????? _cnt = 0;
            ?? }
            };
            this implementation of the Word constructor initializes _name once, then overrides the
            initialization with an assignment, resulting in the creation and the destruction of a temporary
            String object. Was this intentional? Unlikely. Does the compiler generate a warning? I'm not aware
            of any that does. Here is the likely internal augmentation of this constructor:
            // Pseudo C++ Code
            Word::Word( /* this pointer goes here */ )
            {
            ?? _name.String::String();???????? // invoke default String constructor
            ?? String temp = String( 0 );????? // generate temporary
            ?? _name.String::operator=( temp );// memberwise copy _name
            ?? temp.String::~String();???????? // destroy temporary
            ?? _cnt = 0;
            }

            Had the code been reviewed by the project and corrected, a significantly more efficient
            implementation would have been coded:
            // preferred implementation
            Word::Word : _name( 0 )
            {
            ?? _cnt = 0;
            }
            This expands to something like this:

            // Pseudo C++ Code
            Word::Word( /* this pointer goes here */ )
            {?? // invoke String( int ) constructor
            ?? _name.String::String( 0 );
            ?? _cnt = 0;
            }
            This pitfall, by the way, is most likely to occur in template code of this form:

            template < class type >
            foo< type >::foo( type t )
            {
            ?? // may or may not be a good idea depending on the actual type of type
            ?? _t = t;
            }
            This has led some programmers to insist rather aggressively that all member initialization be done
            within the member initialization list, even the initialization of a well-behaved member such as _cnt:

            // some insist on this coding style, 順序有問(wèn)題!
            Word::Word() : _cnt( 0 ), _name( 0 )
            {}

            Actually, there is a subtlety to note here: The order in which the list entries are set down is
            determined by the declaration order of the members within the class declaration, not the order
            within the initialization list. In this case, _name is declared before _cnt in Word and so is placed first.

            This apparent anomaly between initialization order and order within the initialization list can
            lead to the following nasty pitfall:

            class X {
            ?? int i;
            ?? int j;
            public:
            ?? // oops!? do you see the problem?
            ?? X( int val ) : j( val ), i( j )
            ?? {}
            ?? ...
            };

            // preferred idiom, 解決咯
            X::X( int val ) : j( val )
            {
            ?? i = j;
            }

            Here is an interesting question: Are the entries in the initialization list entered such that the
            declaration order of the class is preserved? That is, given

            // An interesting question is asked:
            X::X( int val ) : j( val )
            {
            ?? i = j;
            }
            is the initialization of j inserted before or after the explicit user assignment of j to i? If
            the declaration order is preserved, this code fails badly. The code is correct, however, 這才是
            真正的原因 - because the initialization list entries are placed before explicit user code.
            所以成員初始化不是一股腦兒都放到初始化列表里才是最優(yōu)方案!

            Another common question is whether you can invoke a member function to initialize a member, such as
            // is the invocation of X::xfoo() ok?? 問(wèn)得好!
            X::X( int val ) : i( xfoo( val )), j( val )
            {}

            where xfoo() is a member function of X. The answer is yes, but…. To answer the "but" first, I
            reiterate my advice to initialize one member with another inside the constructor body, not in the
            member initialization list. You don't know the dependencies xfoo() has regarding the state of the
            X object to which it is bound. 還是那句話: 別將所有的成員初始化工作全放在構(gòu)造函數(shù)的初始化列表里 -
            By placing xfoo() within the constructor body, you can ensure there is no ambiguity about which
            members are initialized at the point of its invocation.

            The use of the member function is valid (apart from the issue of whether the members it accesses
            have been initialized). This is because the this pointer associated with the object being
            constructed is well formed and the expansion simply takes a form like the following:

            // Pseudo C++ Code: constructor augmentation
            X::X( /* this pointer, */ int val )//一般都將this指針缺省, 但它的確是存在的, 至少對(duì)編譯器而言
            {
            ?? i = this->xfoo( val );
            ?? j = val;
            }

            where xfoo() is a member function of X. The answer is yes, but…. To answer the "but" first, I
            reiterate my advice to initialize one member with another inside the constructor body, not in the
            member initialization list. You don't know the dependencies xfoo() has regarding the state of the
            X object to which it is bound. By placing xfoo() within the constructor body, you can ensure
            there is no ambiguity about which members are initialized at the point of its invocation.

            The use of the member function is valid (apart from the issue of whether the members it accesses
            have been initialized). This is because the this pointer associated with the object being
            constructed is well formed and the expansion simply takes a form like the following:
            // Pseudo C++ Code: constructor augmentation
            X::X( /* this pointer, */ int val )
            {
            ?? i = this->xfoo( val );
            ?? j = val;
            }

            In summary, the compiler iterates over and possibly reorders the initialization list to reflect
            the declaration order of the members. It inserts the code within the body of the constructor
            prior to any explicit user code. 成員初始化列表的內(nèi)容"插"在構(gòu)造函數(shù)的最前端.

            posted on 2006-05-12 00:49 Jerry Cat 閱讀(811) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理



            <2006年9月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            常用鏈接

            留言簿(7)

            隨筆檔案

            最新隨筆

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            免费无码国产欧美久久18| 无遮挡粉嫩小泬久久久久久久| 久久狠狠色狠狠色综合| 7777久久久国产精品消防器材| 久久精品国产亚洲AV香蕉| 久久SE精品一区二区| 久久精品aⅴ无码中文字字幕重口| 2020久久精品国产免费| 青青青青久久精品国产h久久精品五福影院1421 | 日韩亚洲国产综合久久久| 亚洲精品无码专区久久久| 久久久久国产精品熟女影院| 久久国产精品波多野结衣AV| 久久夜色精品国产欧美乱| 伊色综合久久之综合久久| 99热成人精品免费久久| 久久久无码精品亚洲日韩按摩| 久久久久亚洲AV成人网| 99久久精品国产麻豆| 久久精品国产99国产精品导航 | 激情伊人五月天久久综合| 国产精品免费久久久久电影网| 久久这里都是精品| 九九久久精品国产| 久久久91精品国产一区二区三区| 久久人人爽人人人人爽AV | 99久久99久久久精品齐齐| 精品伊人久久大线蕉色首页| 国产精品嫩草影院久久| 俺来也俺去啦久久综合网| 欧美一区二区三区久久综合| 久久男人AV资源网站| 久久久久国产视频电影| 国产精品gz久久久| 久久国产精品免费| 亚洲国产成人久久精品动漫| 成人综合伊人五月婷久久| 99久久99久久久精品齐齐| 97久久香蕉国产线看观看| 韩国免费A级毛片久久| 俺来也俺去啦久久综合网|