Reputation: 309
Imagine the following code
struct Vehicle { virtual void drive() = 0; };
struct Car: public Vehicle {
void drive() override { std::cout << "driving a car\r\n"; }
};
struct Cycle : public Vehicle {
void drive() override { std::cout << "driving a cycle\r\n"; }
};
Vehicle* makeVehicle(const std::string& type) {
if (type == "car") { return new Car(); }
else if (type == "cycle") { return new Cycle(); }
else { return nullptr; }
}
Do I need do implement moving-operations concerning "return new Car()"? Or are they senseless because of the use of pointers? In which cases are the default moving-operation sufficient?
Cheers!
Upvotes: 0
Views: 128
Reputation: 17704
If you have move, you have C++11, and if you have C++11, you have unique_ptr
. So you actually want to write your code like this:
std::unique_ptr<Vehicle> makeVehicle(const std::string& type {
if (type == "car") { return std::make_unique<Car>(); }
...
}
unique_ptr
indicates that the person calling makeVehicle
now owns the returned object and will automatically ensure that it gets destroyed and memory returned. unique_ptr
implements move operations automatically, that's why this code can compile (if it wasn't movable or copyable, it wouldn't be possible to return it from a function).
So basically, for polymorphic types, typically you will not need to implement moving operations. But unique_ptr
doesn't provide copying operations so you still may want to implement the oldie-but-goldie clone
function (if you really need it).
I recommend reading more about move semantics and in particular the "Rule of Zero"; it's generally better to avoid implementing copy/move by hand where possible. See: http://en.cppreference.com/w/cpp/language/rule_of_three.
Upvotes: 3