为什么在创建向量<a>?</a>时,类A的构造函数和析构函数被调用一次

时间:2013-09-13 18:54:26

标签: c++ stl

在结束时的节目中,我得到了这样的输出。

   constructor is called
   destructor is called
   destructor is called
   destructor is called
   destructor is called
   destructor is called
   destructor is called

由于五次调用析构函数,我能够确定最后五行析构函数被称为。但我无法理解前两行。为什么构造函数只被调用一次,然后在下一行调用析构函数。

请解释一下。谢谢

class A {
    public :
    string name;
    int age;
    A(){    cout << "constructor is called" << endl;  }
    ~A() {   cout << "destructor is called"<< endl;   }
};

int main()
{
    vector<class A> vec(5);
    cout << vec.size() << endl;
    return 0;
 }

4 个答案:

答案 0 :(得分:9)

默认构造函数只构造一个对象,然后复制5次。添加:

 A(const A&) { cout << "copy-constructor is called" << endl; }

通过复制初始对象来查看创建其他对象的时间/位置。

答案 1 :(得分:3)

将您的代码更改为:

class A {
public :
  string name;
  int age;
  A(){    cout << "constructor is called" << endl;  }
  ~A() {   cout << "destructor is called"<< endl;   }
  A(const A&) { cout << "copy c'tor is called"<<endl;}
};

然后你会得到

constructor is called
copy c'tor is called
copy c'tor is called
copy c'tor is called
copy c'tor is called
copy c'tor is called
destructor is called
5
destructor is called
destructor is called
destructor is called
destructor is called
destructor is called

如您所见,您的对象创建一次,但复制了5次。

答案 2 :(得分:1)

矢量的工作原理如下:

你放入矢量的东西是东西的副本。 你从向量中得到的东西是向量中的东西的副本。

构造函数的作用是(假设你的类是A):

A array[n];        // This one will call default constructor n times
vector<A> vec(n);  // This one will call default constructor once and copy constructor n times.

默认构造函数的基本构造函数创建一个对象,而这个对象不会放入向量

你得到一个原始的,5个副本,这就是为什么有6次desctructor称为

答案 3 :(得分:1)

首先,该代码的行为取决于您的编译器和库实现的标准版本。您描述的行为是C ++ 03实现的行为,您使用的vector的构造函数是:

explicit vector(size_type n, const T& value = T(),
                    const Allocator& = Allocator());

您没有提供值或分配器,因此它们是默认的。如果您明确地创建对象,您将了解正在发生的事情:

vector<A> vec(5,A());     // A() is a temporary, destroyed at the end of the 
                          // whole expression.

也就是说,使用默认构造函数创建临时,生成构造函数调用的跟踪,并用于复制到5个位置。然后它在表达式的末尾被销毁。当向量超出范围时,内部存储的5个元素将被自行销毁。

在C ++ 11中,库已更改,现在上面的签名被分成这两个签名:

explicit vector(size_type n);
vector(size_type n, const T& value, const Allocator& = Allocator());

使用C ++ 11实现,您将调用两者的第一个版本。在这种情况下,构造函数没有参数,因此不会创建临时值。相反,新标准要求实现默认构造元素。因此,当向量超出范围时,程序的输出将是5行代表创建向量时的默认构造函数,5行代表析构函数的输出。