taz
taz

Reputation: 61

C++ overloading virtual = operator

here is the code for my question:


class ICommon
{
public:
 virtual ICommon& operator=(const ICommon & p)const=0;
};

class CSpecial : public ICommon
{
public:
 CSpecial& operator=(const CSpecial & cs)const
 {
  //custom operations
  return *this;
 }
};
CSpecial obj;

Basically: I want the interface ICommon to force it's descendants to implement = operator but don't want to have any typecasts in the implementation. The compiler says "can't instantiate an abstract class.
Any help/advice will be appreciated.

Upvotes: 4

Views: 2446

Answers (4)

utnapistim
utnapistim

Reputation: 27365

Basically: I want the interface ICommon to force it's descendants to implement = operator but don't want to have any typecasts in the implementation. The compiler says "can't instantiate an abstract class. Any help/advice will be appreciated.

Consider separating the public interface of the base class from it's (virtual) operation implementation:

class ICommon
{
public:
    ICommon& operator=(const ICommon & p)
    {
        if(this == &p)
            return *this;
        copy(p);
        return *this;
    }
protected:
    virtual void copy(const ICommon& p) = 0;
};

class CSpecial : public ICommon
{
protected:
    virtual void copy(const ICommon& p)
    {
        // TODO: copy values from p
    }
};

Upvotes: 0

Dennis Zickefoose
Dennis Zickefoose

Reputation: 10979

You can use a recursive template to achieve what you want:

template<typename T>
struct IAssignable {
  virtual T& operator =(const T&) = 0;
};

struct Impl : IAssignable<Impl> {
  virtual Impl& operator =(const Impl&) { return *this; }
};

This does not, and can not, be used to force a copy constructor to be implemented. So I'm not convinced it is that terribly useful, and you're probably better off with the clone() option others suggested. But its a useful construct in general.

Upvotes: 1

Drew Hall
Drew Hall

Reputation: 29055

To echo what Naveen said, the operator=() defined in CSpecial isn't compatible with the one defined in ICommon, and results in an overload rather than an override. While you can have covariant return types (as you've done), the arguments themselves can't be covariant.

Furthermore, you've defined the ICommon::operator=() as const, which seems counterintuitive. In the derived class, you've made it non-const (as expected), but again, this makes the function signatures further incompatible.

Naveen's clone() idea is probably your best bet. Otherwise, you can pass an ICommon const reference to your CSpecial operator=() and attempt some dynamic_cast<>() magic internally, but that smells funny.

Good luck!

Upvotes: 2

Naveen
Naveen

Reputation: 73443

That is because the signature of the function in CSpecial is different from the pure virtual function you defined in the abstract base class. You can use the virtual copy constructor to do the copying. Basically you define a pure virtual function ICommon* clone() = 0 in the base class, and implement it in each derived class. When called this function will create a copy of the object on which it is called.

Upvotes: 3

Related Questions