在结束时的节目中,我得到了这样的输出。
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;
}
答案 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行代表析构函数的输出。