Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting around copy semantics in C++

Tags:

c++

c++11

c++14

Please consider this code:

class A
{

};

int main()
{
    std::vector<A> test;
    test.push_back(A());
}

The constructor and destructor will be called twice, also memory will be allocated twice and the object will copied, now not only is that potentially bad for performance it could also lead to run time errors, especially if there's some cleanup going on in the destructor. The way i'd usually get around this is to just create a vector of pointers instead :

std::vector<A*> test;
test.push_back(new A());

My question is two fold, is this common practice and is it good practice? Or is there a better way? If this turns out to be a dupe please let me know and i'll close the question, but I couldn't find anything on searching.

like image 846
Geoff Avatar asked Oct 29 '16 21:10

Geoff


People also ask

When should we prefer move over copy semantics?

The subtle difference is, if you create with a copy or move semantic a new object based on an existing one, that the copy semantic will copy the elements of the resource, that the move semantic will move the elements of the resource. Of course, copying is expensive, moving is cheap.

What is copy semantics?

Value (or “copy”) semantics mean assignment copies the value, not just the pointer. C++ gives you the choice: use the assignment operator to copy the value (copy/value semantics), or use a pointer-copy to copy a pointer (reference semantics).

Is STD move faster than copy?

Std::move is not faster than straight up copying.

What's the need to move semantics?

Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.


1 Answers

Use emplace_back.

std::vector<A> test;
test.emplace_back();
//test.emplace_back(constructor, parameters);

This way, A will be constructed in-place, so no copy or move will occur.

Edit: To clarify on the comments on the question - No, this will not change from push_back if you pass it a temporary. For instance,

test.emplace_back(A{});

Will, in C++11, cause a temporary A to be constructed, moved and destroyed, as if you used push_back.

like image 51
Asu Avatar answered Oct 08 '22 04:10

Asu