C ++ перегрузка виртуальный = оператор - PullRequest
4 голосов
/ 19 мая 2010

вот код моего вопроса:


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;

В основном: я хочу, чтобы интерфейс ICommon заставлял своих потомков реализовывать оператор =, но не хочу, чтобы в реализации были какие-либо типы типов. Компилятор говорит "не может создать экземпляр абстрактного класса.
Любая помощь / совет будут оценены.

Ответы [ 4 ]

3 голосов
/ 19 мая 2010

Это потому, что сигнатура функции в CSpecial отличается от чисто виртуальной функции, которую вы определили в абстрактном базовом классе. Вы можете использовать конструктор виртуальной копии для копирования. По сути, вы определяете чисто виртуальную функцию ICommon* clone() = 0 в базовом классе и внедряете ее в каждом производном классе. При вызове эта функция создаст копию объекта, для которого она вызывается.

2 голосов
/ 19 мая 2010

Чтобы повторить сказанное Навином, operator=(), определенный в CSpecial, не совместим с тем, который определен в ICommon, и приводит к перегрузке, а не к переопределению. Хотя у вас могут быть ковариантные типы возвращаемых данных (как и у вас), сами аргументы не могут быть ковариантными.

Кроме того, вы определили ICommon::operator=() как const, что кажется нелогичным. В производном классе вы сделали его неконстантным (как и ожидалось), но, опять же, это делает сигнатуры функций еще более несовместимыми.

Идея Навина clone(), вероятно, является лучшим выбором. В противном случае, вы можете передать константную ссылку ICommon на ваш CSpecial operator=() и попробовать немного магии dynamic_cast<>(), но это пахнет забавно.

Удачи!

1 голос
/ 19 мая 2010

Вы можете использовать рекурсивный шаблон для достижения желаемого:

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

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

Это не может и не может быть использовано для принудительной реализации конструктора копирования. Так что я не уверен, что это ужасно полезно, и вам, вероятно, лучше использовать вариант clone(), предложенный другими. Но в целом это полезная конструкция.

0 голосов
/ 19 мая 2010

В основном: я хочу интерфейс ICommon, чтобы заставить его потомков реализовать = оператор, но не хочу есть какие-либо типы в реализация. Компилятор говорит "не могу создать экземпляр абстрактного класса. Любая помощь / совет будут оценены.

Рассмотрите возможность отделения открытого интерфейса базового класса от реализации (виртуальной) операции:

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
    }
};
...