Как полученный класс C++ может клонировать себя через указатель базы?

Вот то, что я пытаюсь сделать (этот код не работает):

class Base
{
    virtual Base *clone() { return new Base(this); }
    virtual void ID() { printf("BASE");
};

class Derived : publc Base
{
    virtual Base *clone() { return new Derived(this); }
    virtual void ID() { printf("DERIVED"); }
}

.
.
Derived d;
Base *bp = &d;
Base *bp2 = bp->clone();

bp2->ID();

То, что я хотел бы, должно видеть "ПОЛУЧЕННЫЙ", распечатал..., что я получаю, "ОСНОВА". Я - давний программист C, и справедливо опытный с C++..., но я не делаю прогресса с этим... любая справка ценилась бы.

5
задан wanlessv 28 June 2010 в 22:45
поделиться

6 ответов

После исправления всех ошибок компиляции я получил следующее:

#include <cstdio>

class Base
{
  public:
    Base() {}
    Base(const Base&) {}
    virtual Base *clone() { return new Base(*this); }
    virtual void ID() { printf("BASE"); }
};

class Derived : public Base
{
  public:
    Derived() {}
    Derived(const Derived&) {}
    virtual Base *clone() { return new Derived(*this); }
    virtual void ID() { printf("DERIVED"); }
};


int main()
{
  Derived d;
  Base *bp = &d;
  Base *bp2 = bp->clone();

  bp2->ID();
}

Что дает вам то, что вы ищете -- ДЕРИВИД.

7
ответ дан 13 December 2019 в 19:20
поделиться

Этот код пронизан синтаксическими ошибками. Возможно, наиболее важно то, что Derived не наследуется от Base. Во-вторых, помимо синтаксических ошибок (возможно, простых опечаток), Base явно нужен виртуальный деструктор. Метод clone в значительной степени требует, чтобы вы могли вызывать оператор delete для базового указателя (Base *).

class Base
{
public:
    virtual ~Base() {}
    virtual Base* clone() const { return new Base(*this); }
    virtual void ID() const { printf("BASE"); }
};

class Derived: public Base
{
public:
    // [Edit] Changed return type to Derived* instead of Base*.
    // Thanks to Matthieu for pointing this out. @see comments below.
    virtual Derived* clone() const { return new Derived(*this); }
    virtual void ID() const { printf("DERIVED"); }
};

int main()
{
    Derived d;
    Base* bp = &d;

    Base* bp2 = bp->clone();
    bp2->ID(); // outputs DERIVED as expected
    delete bp2;
}
3
ответ дан 13 December 2019 в 19:20
поделиться

С Base bp = & d;

Вы «нарезали» d , поэтому для компилятора bp действительно только типа Base , поэтому, когда вы вызываете bp-> clone () , компилятор вызывает Base :: clone (); и bp2 -> ID () печатает BASE .

Base & bp = d; будет делать то, что вы хотите.

1
ответ дан 13 December 2019 в 19:20
поделиться

Вы нарезаете класс in Base bp = & d; (это создает новую базу bp из производного-ptr.)

Попробуйте вместо этого Base * bp = & d; . (т.е. создать указатель базового типа на производный объект.)

0
ответ дан 13 December 2019 в 19:20
поделиться

Ваш пример неверен и не будет компилироваться. В частности, эта строка:

Base bp = &d;

Это также может быть основной причиной вашей проблемы (вы можете разрезать свой объект), но я не могу сказать наверняка, не увидев работающего кода.

У вас также есть проблема, когда ваши два класса не связаны (вы хотели написать class Derived: public Base ?)

0
ответ дан 13 December 2019 в 19:20
поделиться

Код выглядит нормально, за исключением глупых опечаток в синтаксисе и отсутствующих операторов.

0
ответ дан 13 December 2019 в 19:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: