簡體   English   中英

對象的C ++向量和對析構函數的過多調用?

[英]C++ vector of objects and excessive calls to destructor?

我想知道的是,代碼是否多次調用析構函數,以及是否正確以這種方式進行編碼。 看起來創建的對象在被加載到向量中之前已經超出范圍,但是對象沒有死,而是停留在向量中並在程序完成時最終再次破壞。 繼承人的輸出:

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;
}

這是對象。

#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;
}

編譯器為您生成了一個copy-ctor。 添加一個帶有一些調試輸出的代碼,您可以了解您的代碼在做什么:

object( const object& o )
{
   std::cout<<"object::copy-constructor: "<<std::endl;
   this->value = o.value;
}

發生的事情是vector正在重新分配以騰出空間。

OBJECTScapacity等於零開始。 循環構造OBJECT = object(0) ,然后復制構造該對象的副本以傳遞給push_back push _back注意沒有足夠的空間(1> 0!),因此它將vector重新分配為容量為1並將副本放入其中。然后破壞OBJECT

下次通過循環,將構造OBJECT = object(1) ,然后為push_back復制構造。 再次沒有足夠的空間,因此將OBJECTS重新分配為具有更大的容量- 並且將其中已存在的object(0)復制構造為重新分配的空間,並將原始空間銷毀 然后將復制的對象放入,然后再次破壞OBJECT

您的代碼上的這種變化應該清楚說明發生了什么。 我使代碼在每次push_back之前和之后寫出vector容量; 並且我添加了一個日志記錄復制構造函數。 我還使復制構造函數在每次調用時都增加了10的value ,因此您可以看到每個單獨object的復制方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM