Effective C++条項26

3766 ワード

変数定義式の出現時間をできるだけ遅らせる
オブジェクトを定義するときに争わない事実があることを知っています.それはメモリを割り当てることです.カスタムオブジェクトの場合、プログラム実行中にクラスのコンストラクション関数とコンストラクション関数が呼び出されます.
例えば、雨が降ったら、傘を持っていくのは価値があるに違いない.しかし、もしあなたが傘を持っていたら、今日は雨が降っていません.あなたは自分が損をしたと感じていますか?確かに、持ち物に損をしても無駄なので、傘が邪魔になります.
このセクションの鍵は、変数を定義したり、オブジェクトが使用されていない場合は、完璧ではないコードです.コードクリップを見てみましょう.
std::string encryptPassword(const std::string& psaaword)
{
    using namespace std;
    string encrypted;
    if(password.length()<MinimumPasswordLength)
    {
        throw logic_error("Password is too short");
    }
    ……//    ,       encrypted 
    return encrypted;
}

もし,異常を投げ出すと,上の変数encryptedは使用されず,使用されていないが,一次構造と一次構造の挙動に耐えなければならない.
改善点は次のとおりです.
std::string encryptPassword(const std::string& psaaword) 
{ 
using namespace std;

    if(password.length()<MinimumPasswordLength)
    {
        throw logic_error("Password is too short");
    }
    string encrypted;
    ……//    ,       encrypted 
    return encrypted;
    }

改善されたコードは例外をスキップし、定義されたencryptedが必ず使用されることを保証します.しかし,copyコンストラクション関数を呼び出すことができればdefaultコンストラクション関数+付与演算子関数を呼び出す必要はないことが分かった.前者の方が効率的だからです.コードを改善し続けます.
    std::string encryptPassword(const std::string& psaaword)
    {
        using namespace std;
        if(password.length()<MinimumPasswordLength)
        {
            throw logic_error("Password is too short");
        }
        string encrypted(password);//  +  
        encrypt(encrpted);
        ……//    ,       encrypted 
        return encrypted;
    }

では、私たちは循環の中でどのようにこのような考えを貫徹しますか?コードを比較します.
Widget w;//      
for(int i=0;i < n;++i)
    w=……;
    ……
}

for(int i=0;i<n;++i){
    Widget w(……);//     
    ……
}

最初に1つのコンストラクション関数+1つのコンストラクション関数+nつの付与操作が呼び出された.2番目はn個の構造関数+n個の構造関数を呼び出した.この場合,付与操作の効率が高いか,構造+析構の効率が高いかを考慮する必要がある.実際、双方の差が大きくない場合は、後者を選択することが望ましい.後者のオブジェクトの役割ドメインがより小さく、メンテナンス性と理解性がより強く、より安全であるからだ.