2

たとえば、以下のコードでは:

class HowMany {
    static int objectCount;
    public:
        HowMany() { 
            objectCount++; 
        }
        static void print(const string& msg = "") {
             if(msg.size() != 0) 
                 cout << msg << ": ";

             cout << "objectCount = " << objectCount << endl;
        }
        ~HowMany() {
            objectCount--;
            print("~HowMany()");
        }
};

int HowMany::objectCount = 0;

// Pass and return BY VALUE:
HowMany f(HowMany x) {
    x.print("x argument inside f()");
    return x;
}

int main() {
    HowMany h;
    HowMany::print("after construction of h");
    HowMany h2 = f(h);
    HowMany::print("after call to f()");
}

コンパイラがHowManyクラスのコピーコンストラクタを自動的に作成せず、f(h)の呼び出しが行われるときにビット単位のコピーが行われるのはなぜですか?

コンパイラがデフォルトのコピーコンストラクタを作成するのはどのような場合で、作成しないのはどのような場合ですか?

次のように出力されます。

hの構築後:objectCount = 1

f()内のx引数:objectCount = 1

〜HowMany():objectCount = 0

f()の呼び出し後:objectCount = 0

〜HowMany():objectCount = -1

〜HowMany():objectCount = -2

よろしくお願いします

4

2 に答える 2

9

C++98およびC++03では、コンパイラーは常にコピーコンストラクターを作成します。これは、独自の1を作成したことを明示的に指定しない限り、フィールドのメンバーごとのコピーを実行します。

これがコードで発生することです。コンパイラによって生成されたコピーコンストラクタは特定のことを何もしません-特に、インクリメントしませんobjectCount-したがって、負のオブジェクト数になります(コピーされたすべてのオブジェクトがカウンタをインクリメントしませんでした) 、しかし彼らはそれをデクリメントしました)。

期待した結果を得るには、次のように書く必要があります。

HowMany(const HowMany &) { 
        objectCount++; 
}

  1. デフォルトのコピーコンストラクターは、コピーコンストラクターのプロトタイプを作成したが、それを実装しなかったり、プライベートとしてマークしたりしても作成されません。実際、これがコピー不可能なクラスを作成する方法です。C ++ 11は、コピーコンストラクターを生成しないようにコンパイラーに指示する特別な構文もサポートしています。
于 2012-06-07T12:57:31.710 に答える
0

すべてのオブジェクトコンパイラに対してコピーコンストラクタを作成する必要があります。ここでは、すべてのオブジェクトh、x、およびh2に対して作成されたコピーコンストラクタも作成する必要があります。ただし、hの場合、オブジェクトコピーコンストラクタは必要ありません。次に、入力引数をhとして関数fを呼び出します。ここで、コピーコンストラクターが呼び出され、hのコンテンツがxオブジェクトにコピーされます。そして、次のオブジェクトh2についても同じことです(ここでも、コピーコンストラクターがxを呼び出してh2にコピーします)。この理由により、objectcountのみが増分されません。ありがとうございました。

于 2013-10-09T07:05:33.510 に答える