Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ placement new vs copy assignment

Somewhere I read that vector internally uses placement new for object construction. When I tried to implement similar container, I usually ended up with allocation like

_elements = new Type[capacity]

and then I append new objects like this

void append(const T& element) {
    // reallocation in case if capacity is equal to size
    _elements[size++] = element;
}

Is there any performance or other difference between this construction by copying and construction by placement new?

like image 351
Alexander Bily Avatar asked Dec 24 '22 20:12

Alexander Bily


1 Answers

Is there any performance or other difference between this construction by copying and construction by placement new?

Certainly. If you construct an array:

_elements = new Type[capacity]

... then the elements of the array must be initialized, up to the capacity. That means that a number of "default" Type objects will be created. On the other hand, when using placement new, you do not initialise the array, but just allocate the space, and construct objects as needed. This is both more efficient and semantically different, seeing as the initial objects are not created (remember that creating them may have side effects).

It might help your understand to think about and do some experiments with a type that does indeed have a prominent side-effect in its default constructor:

class Type
{
    public:
    Type()
    {
       cout << "Created Type." << endl;
    }
};

With the above Type, if you do new Type[3] for instance you will see three messages printed to cout. On the other hand if you create a std::vector<Type> with a capacity of 3, you should not see any messages printed to cout.

Your append method:

void append(const T& element) {
    // reallocation in case if capacity is equal to size
    _elements[size++] = element;
}

Calls the assignment operator for T. So adding an object into the container requires that:

  1. The object is first constructed using the default constructor
  2. The assignment operator is called

Contrast this with the standard library containers:

  1. The objects is constructed using the copy constructor (and via placement `new')
  2. No assignment is necessary.

One other consideration is that you cannot generally call new Type[x] if Type has no accessible default constructor. If you change the public: in the above example to private:, you will observe this. It is still possible to create an (empty) std::vector<Type> however, and you can still add objects into it so long as you add another (usable) constructor to Type.

like image 181
davmac Avatar answered Jan 15 '23 01:01

davmac