Swapping Polymorphic Objects

I have a base class A and derived class of B. What I want to be able to is to swap the objects they point to. Applying std::swap on the underlying base objects of the pointers only swaps the base object contents and not that of the derived object as well. How do I fix that to get std::swap to work properly.

#include <iostream>
#include <memory>


class A {
public:
    void setA(unsigned int value) { *a = value; }

    unsigned int getA() { return *a; }
    virtual void h(){}

protected:
    std::unique_ptr<unsigned int> a = std::make_unique<unsigned int>();
};

class B : public A {
public:
    void setB(unsigned int value) { *b = value; }

    unsigned int getB() { return *b; }

protected:
    std::unique_ptr<unsigned int> b = std::make_unique<unsigned int>();
};


int main() {

    std::unique_ptr<A> oA = std::make_unique<B>();
    oA->setA(100);

    auto a = dynamic_cast<B*>(oA.get());
    a->setB(30);


    std::unique_ptr<A> oB = std::make_unique<B>();
    oB->setA(1000);
    std::swap(*oA.get(), *oB.get());

    std::cout << dynamic_cast<B*>(oB.get())->getB() << std::endl;
    std::cout << dynamic_cast<B*>(oA.get())->getB() << std::endl;
    std::cout << dynamic_cast<B*>(oA.get())->getA() << std::endl;

    return 0;
}

Solution 1:

In the example, you have two A* variables (misleadingly) named a and b, both pointing to B objects. You want std::swap(*a, *b) to swap the full B objects. If you had a way to do it, what would you want it do if a was actually pointing to an object of type A?

You cannot swap A and B because the objects have different sizes. You would need to put 'B' object where 'A' used to be, but there is not enough room in the memory for that.

You can, of course, swap pointers themselves: std::swap(a, b) would work fine.