Типизация и наследование в C ++ - PullRequest
0 голосов
/ 31 марта 2012

У меня проблема. Есть два класса:

struct Base {
    Base* retain() {
    //retain here
        return this;
    }
};

struct Derived : Base {
};


Derived *d1 = new Derived();
Derived *d2 = d1->retain(); //error here: need to typecast to Derived*
Derived *d3 = (Derived*)d1->retain(); //OK

Есть ли способ переписать функцию retain () так, чтобы мне не нужно было вручную вводить результат? Другими словами: retain () должна возвращать объект производного типа.

Ответы [ 2 ]

4 голосов
/ 31 марта 2012
template<typename T>
struct Base
{
    T* retain()
    {
        return (T*)this;
    }
};

struct Derived : Base<Derived>
{
};


Derived *d1 = new Derived();
Derived *d2 = d1->retain();

В качестве альтернативы:

struct Base
{
    template<typename T>
    void retain(T** ptr)
    {
        *ptr = (T*)this;
    }
};

struct Derived : Base
{
};

Derived *d1 = new Derived;
Derived *d2;
d1->retain(&d2);
0 голосов
/ 31 марта 2012

Обычно, когда вы делаете то, что делаете, у базового класса будет виртуальный деструктор.Это позволяет идентифицировать тип во время выполнения.

Возможно, вы также захотите написать struct Derived : public Base, включая ключевое слово public.

Пояснение, что следует за виртуальным деструктором.

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

Однако , если базовый тип имеетхотя бы один виртуальный метод, затем компилятор добавляет один, скрытый указатель на каждый объект типа.Этот указатель указывает на таблицу, которая, помимо прочего, точно идентифицирует тип объекта, что делает возможным dynamic_cast<>() и другие полиморфные операции с указателем.

Если все это для вас ново, то здесьчто я рекомендую попробовать дальше: добавить нулевой виртуальный деструктор virtual ~Base() {} в базовый класс и затем прочитать о dynamic_cast<>().Далее, вы можете захотеть сделать базу retain() виртуальной, а затем дать Derived свою собственную, переопределив retain().

В любом случае, если вы не можете получить более точный совет, вышеприведенное должно дать вамс чего начать.Удачи.

...