对象的C ++向量和对析构函数的过度调用?

时间:2013-03-07 17:18:55

标签: c++ vector 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;
}

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

2 个答案:

答案 0 :(得分:3)

编译器为您生成了一个copy-ctor。添加一个带有一些调试输出,你就可以理解你的代码在做什么了:

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

答案 1 :(得分:2)

正在发生的事情是vector正在重新分配以腾出空间。

OBJECTScapacity开始,等于零。循环构造OBJECT = object(0),然后复制构造该对象的副本以传递给push_backpush _back注意到没有足够的空间(1> 0!),因此重新分配vector以使容量为1并将副本放入。然后它会破坏OBJECT

下一次循环,构造OBJECT = object(1),然后为push_back复制构造。再次没有足够的空间,因此OBJECTS被重新分配以具有更大的容量 - 并且其中已经存在的对象(0)被复制构造到重新分配的空间中,并且原始的被破坏。然后放入复制的对象,再次破坏OBJECT

您的代码的

This变体应该清楚地说明发生了什么。我已使代码在每个vector之前和之后写入push_back容量;我添加了一个日志记录副本构造函数。我每次调用时都会将copy-constructer添加到value,这样你就可以看到每个人object的复制方式。