简体   繁体   中英

Why does an empty vector call the value type's default constructor?

Using g++, I observe that creating a vector of size zero calls the vector's parameterized object type's constructor once. It then is deleted. Why does this happen?

#include <iostream>
#include <vector>
using namespace std;

class s
{
    public:
    s() { cout << endl << "default s constructor" << endl; }
    ~s() { cout << endl << "default s destructor" << endl; }

};

int main()
{
    vector<s> v(0);
}

Output:

default s constructor

default s destructor

Because you're explicitly passing an initial size, which calls a constructor that has another parameter whose default value is s() . Just leave out the (0) (ie std::vector<s> v; ) and it won't happen.

For completeness, the Standard 23.2.4-2 defines the constructor you're calling as:

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

Aside (relevant to C++03 but not C++11)

Another interesting behavioural aspect of this constructor also raises its head on SO periodically: when the initial number of elements requested is > 0, it copy-constructs those elements from the prototypal parameter to the constructor:

  • people often put a default constructor that leaves member variables uninitialised, hoping to make vector(n) almost as fast as the underlying free store allocation, BUT
  • the copy-constructor is still called n times to copy the "garbage" content of the prototypal object into each of the requested elements

This has an obvious performance cost, but can also crash the application if the garbage content includes eg pointers that the copy-constructor can only assume are valid. Similarly, it's extremely dangerous to even push_back such an uninitialised garbage object - it lacks proper value semantic encapsulation and may be copied as the vector resizes, algorithmic operations like std::sort() are performed on the vector etc..

The actual constructor you are calling is (from cplusplus.com):

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

So even though you only specify the size, a new T object is created for second parameter, and will therefore also be destroyed at the conclusion of the constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM