Question

The following cases point out the slicing problem: During an assignment: https://stackoverflow.com/a/274634/640639

During a function call: What is object slicing?

My question is wouldnt both of these cases be solved if the assignment operator and copy constructor are declared virtual and the derived class appropriately copies the required data? If so in principle pass-by-value should still work in these cases, correct?

Was it helpful?

Solution 2

Obviously, you cannot declare copy construction to be virtual: There is no object, yet. You can disable copy construction, though.

That said, making assignment virtual still doesn't work because when slicing objects the static type of the assigned object is still just a base class. It will never become a derived class independent on what type you assign to it.

OTHER TIPS

No. The argument is passed by value, and so a new base object is created.

There is no such thing as a virtual constructor, as virtual means "depends on the dynamic type of this", and before the constructor has been run, the object does not even exist, so it cannot have a derived dynamic type.

Virtual assignment operators would also not help, as they would depend on the type of the object being assigned in to, rather than the type of the object being assigned from.

If you want to be able to copy by value but still have polymorphic behaviour, you could make a object that holds a pointer to another object, and which clones the object in its constructors and assignment operators (using something like value_ptr from Martinho Fernandes' Wheels library):

class Base {
    public:
    virtual Base* clone() const = 0;
    virtual void do_stuff() = 0;
};

class CopyablePolymorphic {
public:
    CopyablePolymorphic(Base* base) : ptr(base) {}
private:
    value_ptr<Base> ptr;
};

class Derived1 : public Base {
public:
    virtual Base* clone() const {
        return new Derived1(*this);
    }
    virtual void do_stuff() {
        //Derived1 stuff
    }
};

class Derived2 : public Base {
public:
    virtual Base* clone() const {
        return new Derived2(*this);
    }
    virtual void do_stuff() {
        //Derived2 stuff
    }
};

//etc...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top