5

私は現在 C++ を学んでおり、C++ Primer plus です。しかし、cplusplus の Web サイトをチェックして、ファイル処理については少しスキップしたいような気がしました。

Java、php、ビジュアルベーシックに由来するファイル処理の基本をよく知っています。しかし、私はかなり奇妙な行に出くわしました。

ostream os(&fb);

fb は filebuf を表します。これの構文はわかりませんが、次と同じであることがわかります。

ostream os = &fb;

しかし、変数を初期化するこの方法について実際に読んだことはありません。

だから私は疑問に思っています。私は無意味で、本当に便利な機能をずっと見逃しているのでしょうか? この初期化方法は古いだけですか?それは何か違うのですか?

前もって感謝します。

4

5 に答える 5

6

どちらの形式も初期化を実行します。最初の構文 ( を使用()) は、直接初期化構文と呼ばれます。2 番目の構文 ( を使用=) は、コピー初期化構文と呼ばれます。ほとんどの実際のケースでは同じように動作しますが、実際には 2 つの間に違いがあります。

左辺 (LHS) と右辺 (RHS) の型が (const/volatile 修飾子を無視して) 同一である状況では、どちらもまったく同じです。=言語標準は、この場合、フォームはフォームと同等であると明示的に述べてい()ます。

しかし、型が異なる (そして LHS 型がクラス型である) 場合、これら 2 つの形式は通常、異なる動作をします。

  • コピー初期化フォームは次のように機能します: RHS 値を LHS 型の一時オブジェクトに変換します (可能な手段: 標準変換、変換演算子、変換コンストラクター)。次に、LHS クラスのコピー コンストラクターを使用して、一時オブジェクトを LHS オブジェクトにコピーします。

  • 直接初期化形式は次のように機能します。LHS のすべてのコンストラクターを検討し、オーバーロード解決を使用して最も適切なものを選択するだけです。

コピー初期化構文が無条件にコピー コンストラクターを使用していることにすぐに気付くでしょう (コピーと中間の一時的なものは最適化して取り除くことができますが、概念的には存在します)。LHS クラスにアクセス可能なコピー コンストラクターがない場合、コピー初期化は無条件に不適切な形式になりますが、直接初期化は引き続き機能する可能性があります。

また、特定のコンストラクターに適用されるキーワードexplicitは、どの型の組み合わせに対してどの形式の初期化を使用できるかに影響します。

于 2009-12-26T19:23:45.227 に答える
5

コピー コンストラクターが呼び出されるタイミングと、オーバーロードされた代入演算子関数が呼び出されるタイミングを確認する小さなプログラム:

#include <iostream>

using namespace std;

class test
{
    public:
        // default constructor.
        test()
        {
            cout<<"Default Ctor called"<<endl;
        }

        // copy constructor.
        test(const test& other)
        {
            cout<<"Copy Ctor called"<<endl;
        }

        // overloaded assignment operator function.
        test& operator=(const test& other)
        {
            cout<<"Overload operator function called"<<endl;
            return *this;
        }
};

int main(void) 
{
    test obj1;  // default constructor called.

    test obj2 = obj1; // copy constructor called.

    test obj3(obj2); // again copy constructor called.

    obj1 = obj2; // overloaded assignment operator function.

    return 0;
}

出力:

Default Ctor called
Copy Ctor called
Copy Ctor called
Overload operator function called

したがって、あなたの場合、両方の場合に ostream のコピー コンストラクターが呼び出されます。

于 2009-12-26T15:15:27.270 に答える
4

おそらくあなたはこれこれを読むべきです

于 2009-12-26T15:05:57.417 に答える
1

関数呼び出しの初期化の重要な利点の 1 つは、複数の引数を取るコンストラクターでも機能することです。たとえば、fstream コンストラクターは次の 2 つのパラメーターを取ることができます。

std::fstream file("filename", ios_base::out);

C++0x の均一な初期化が広く利用できるようになるまでは、関数呼び出しの初期化が複数の引数コンストラクターを処理する唯一の方法です。

于 2009-12-27T04:22:41.360 に答える
0

私の理解では、 &var は var 変数のエイリアスであり、どちらを使用してもかまいません。

- - - - 添加 - - - - - - - - -

以下のコードは Stroustrup book からの抜粋です。このことから、両方が同じ変数のエイリアスであることは明らかです。また、以下のようにも述べています。

「引数渡しのセマンティクスは初期化のセマンティクスとして定義されているため、呼び出されると、increment の引数 aa は x の別の名前になりました。」これが、&x を x のエイリアスと呼んだ理由です。

void increment(int& aa) { aa++; }

void f() { int x = 1; increment(x); }

于 2009-12-27T04:06:12.753 に答える