0

私が疑問に思っているのは、コードがデストラクタを何度も呼び出すかどうか、そしてこの方法でコーディングするのが正しいかどうかです。作成されたオブジェクトは、ベクターにロードされる前にスコープ外に出たように見えますが、オブジェクトは死にません。代わりに、ベクター内にとどまり、プログラムが完了すると再び破壊されます。出力は次のとおりです。

object::constructor:
before push_back
object::destructor:
object::constructor:
before push_back
object::destructor:
object::destructor:
object::call(): begin
0
object::call(): end
object::call(): begin
1
object::call(): end
object::destructor:
object::destructor:

Process returned 0 (0x0)   execution time : 0.313 s
Press any key to continue.

これはmain.cppです

#include <vector>
#include <iostream>
#include "object.h"

int main()
{
    int max = 2;
    std::vector <object> OBJECTS;

    for(int index = 0; index < max; index++)
    {
            object OBJECT(index);
            std::cout<<"before push_back"<<std::endl;
            OBJECTS.push_back(OBJECT);
    }

    for(int index = 0; index < max; index++)
        OBJECTS[index].call();

    return 0;
}

これがobject.hです。

#ifndef OBJECT_H
#define OBJECT_H

#include <iostream>

class object
{
        private:

            int value;

        public:

        object(){}
        object(int value)
        {
            std::cout<<"object::constructor: "<<std::endl;
            this->value = value;
        }
        ~object()
        {
            std::cout<<"object::destructor: "<<std::endl;
        }
        void call()
        {
            std::cout<<"object::call(): begin"<<std::endl;
            std::cout<<value<<std::endl;
            std::cout<<"object::call(): end"<<std::endl;
        }
};
#endif

これは、サイトが失敗した場合に備えて、以下のChowlettの回答からのコードです。

#include <iostream>
#include <vector>

class object
{
        private:

            int value;

        public:

        object(){}
        object(int value)
        {
            std::cout<<"object::constructor: "<< value << std::endl;
            this->value = value;
        }
        object( const object& o )
        {
           std::cout<<"object::copy-constructor: " << o.value << std::endl;
           this->value = o.value + 10;
        }
        ~object()
        {
            std::cout<<"object::destructor: "<< value << std::endl;
        }
        void call()
        {
            std::cout<<"object::call(): begin"<<std::endl;
            std::cout<<value<<std::endl;
            std::cout<<"object::call(): end"<<std::endl;
        }
};

int main()
{
    int max = 3;
    std::vector <object> OBJECTS;

    for(int index = 0; index < max; index++)
    {
            object OBJECT(index);

            std::cout<<"before push_back: capacity="<< OBJECTS.capacity() << std::endl;            
            OBJECTS.push_back(OBJECT);
            std::cout<<"after push_back: capacity="<< OBJECTS.capacity() << std::endl;
    }

    for(int index = 0; index < max; index++)
        OBJECTS[index].call();

    return 0;
}
4

2 に答える 2

3

コンパイラーがコピーコンストラクターを生成しました。デバッグ出力を含むものを追加すると、コードが何をしているのかを理解できます。

object( const object& o )
{
   std::cout<<"object::copy-constructor: "<<std::endl;
   this->value = o.value;
}
于 2013-03-07T17:21:14.827 に答える
2

何が起こっているのかというと、vectorスペースを作るために再割り当てされているということです。

OBJECTScapacityゼロに等しいところから始まります。ループは、を構築OBJECT = object(0)し、次にコピーを構築します-に渡すオブジェクトのコピーを構築しますpush_backpush _back十分なスペースがない(1> 0!)のでvector、容量が1になるように再割り当てし、コピーを挿入します。その後、を破棄しOBJECTます。

次回ループを通過すると、OBJECT = object(1)が構築され、次にforがコピー構築されpush_backます。再び十分なスペースがないため、OBJECTSより大きな容量を持つように再割り当てされます-そして、すでにその中にあるobject(0)は再割り当てされたスペースにコピー構築され、元のオブジェクトは破棄されます。次に、コピーされたオブジェクトが挿入され、OBJECTが再び破棄されます。

コードのこのバリエーションにより、何が起こっているのかが明確になります。私はコードvectorにそれぞれの前後に容量を書き込ませましたpush_back; ロギングコピーコンストラクターを追加しました。また、copy-constructerはvalue、呼び出されるたびに10を追加するようにしたので、各個人objectがどのようにコピーされるかを確認できます。

于 2013-03-08T09:06:36.847 に答える