Вот то, что я пытаюсь сделать (этот код не работает):
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++..., но я не делаю прогресса с этим... любая справка ценилась бы.
После исправления всех ошибок компиляции я получил следующее:
#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();
}
Что дает вам то, что вы ищете -- ДЕРИВИД.
Этот код пронизан синтаксическими ошибками. Возможно, наиболее важно то, что 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;
}
С Base bp = & d;
Вы «нарезали» d
, поэтому для компилятора bp
действительно только типа Base
, поэтому, когда вы вызываете bp-> clone ()
, компилятор вызывает Base :: clone ();
и bp2 -> ID ()
печатает BASE
.
Base & bp = d;
будет делать то, что вы хотите.
Вы нарезаете класс in Base bp = & d;
(это создает новую базу bp из производного-ptr.)
Попробуйте вместо этого Base * bp = & d;
. (т.е. создать указатель базового типа на производный объект.)
Ваш пример неверен и не будет компилироваться. В частности, эта строка:
Base bp = &d;
Это также может быть основной причиной вашей проблемы (вы можете разрезать свой объект), но я не могу сказать наверняка, не увидев работающего кода.
У вас также есть проблема, когда ваши два класса не связаны (вы хотели написать class Derived: public Base
?)
Код выглядит нормально, за исключением глупых опечаток в синтаксисе и отсутствующих операторов.