AlexG
AlexG

Reputation: 5919

moving smart pointers twice vs copying

Is there any significant difference in performance, memory, etc, between:

I have the following code, two pointer of objects a Base and a Derived (which is derived from Base) are allowed to be stored inside a vector of pointers of Base objects, when reading the vector I need to check whether I need to dynamic_pointer_cast the pointer so data doesn't get sliced off.

#include "Base.h"
#include "Derived.h"

class Base
{
public:
    Base() {};
    ~Base() {};
};

class Derived: public Base
{
public:
    Derived() {};
    ~Derived() {};
};

int main()
{
    std::vector<std::shared_ptr<Base>> vectorOfBaseObjects;

    std::shared_ptr<Base> base = std::make_shared<Base>();
    std::shared_ptr<Derived> derived = std::make_shared<Derived>();

    vectorOfBaseObjects.push_back(base);
    vectorOfBaseObjects.push_back(derived);

    for (auto &it : vectorOfBaseObjects) {
        // #1: Move pointer to a temporary location and move it back when done
        if (std::shared_ptr<Derived> tmp_ptr = std::move(std::dynamic_pointer_cast<Derived>(it))) {
            // Do something with the derived object
            it = std::move(tmp_ptr);
        }

        // #2: Create a new temporary pointer
        if (std::shared_ptr<Derived> tmp_ptr = std::dynamic_pointer_cast<Derived>(it)) {
            // Do something with the derived object
        }
    }
}

Both statements work just fine, the only issues I could make of might be

Upvotes: 1

Views: 423

Answers (2)

Alan Birtles
Alan Birtles

Reputation: 36409

If you're worried about the speed of creating new shared_ptrs then tmp_ptr probably doesn't even need to be a shared_ptr. Using a raw pointer would look like this:

Derived* tmp_ptr = dynamic_cast<Derived*>(it.get());

Upvotes: 1

Toby Speight
Toby Speight

Reputation: 30882

The two cases are pretty much equivalent, since std::dynamic_pointer_cast() returns a new shared pointer. it is not moved from in this expression:

std::move(std::dynamic_pointer_cast<Derived>(it))

The result of the cast is already an xvalue, so that's exactly the same as

std::dynamic_pointer_cast<Derived>(it)

The only difference is the copy of the pointer back to it. If you've not changed what it points to, then that's a wasted statement.

Upvotes: 3

Related Questions