2
4

4 回答 4

9

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

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

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

于 2013-09-13T18:57:54.437 回答
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 次。

于 2013-09-13T18:58:34.473 回答
1

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

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 行表示向量超出范围时析构函数的输出。

于 2013-09-14T02:30:02.933 回答
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 次析构函数被调用

于 2013-09-13T19:07:07.597 回答