2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1, 2
 
 Re: наследование в C++
Сообщение06.11.2010, 20:47 
malin в сообщении #362837 писал(а):
Здравствуйте, товарищи!
...
то полями нового нового класса CRBTree будут являться указатели Parent,Left,Right на базовый класс CTRee.(А хочется, чтобы были указатели на производный класс).
Вопрос к крутым программистам: "Как быть? Неужели придется переписывать класс заново?"


Физически в производном классе унаследованные от базового указатели будут указывать на экземпляры производного.
Просто им надо подсказать. :)

Пусть:
Код:
class CBaseClass {
  public:
    CBaseClass * parent;
};

class CDerivedClass : public CBaseClass {
  public:
    int AnotherField;
};


Тогда без проблем:
Код:
    CDerivedClass dc1;
    CDerivedClass dc2;

    dc1.parent = &dc2;

А чтобы достучаться до свойств производного класса из указателя на базовый, нужно явно указать этот базовый (ибо от базовго наследоваться может несколько классов )

Код:

    CDerivedClass dc1;
    CDerivedClass dc2;

    dc1.parent = &dc2;

    dc1.AnotherField = 1;
    dc2.AnotherField = 2;

    ((CDerivedClass *) dc1.parent)->AnotherField = 3;

    std::cout << dc2.AnotherField << endl; // Будет выведено значение "3".


А чтобы не заниматься таким безобразием:

Код:
    ((CDerivedClass *) dc1.parent)->AnotherField = 3;

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

 
 
 
 Re: наследование в C++
Сообщение14.11.2010, 13:40 
Ещё можно наверное немного видоизменить подход arseniiv'а, а именно вынести рекурсивные данные в отдельную структуру, но параметризовать её типом используещего класса и добавлять эту структуру к нему как примесь (mixin). Ну как-то так (на примере чего-то больше похожего на связанный список чем на дерево):

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
struct Interface
{
    virtual void Create() {}
    virtual void Method()=0;
    // ...

    virtual ~Interface() {} // Keep it virtual.

    template <class Type>
    struct DataMixin
    {
        Type *SubObject;

        protected: DataMixin(): SubObject(0) {}
    };
};

class Derived:
    public Interface,
    protected Interface::DataMixin<Derived>
{
    public:
        virtual void Create()
        {
            SubObject=new Derived;
        }

        ~Derived()
        {
            delete SubObject;
        }

        virtual void Method()
        {
            if(SubObject)
                // Note, no type-casts!
                SubObject->Variable=1;
        }

    private: int Variable;
};

...

    Interface *Object=new Derived;
    Object->Create();

    Object->Method();

    delete Object;

 


Вот такой вот примерчик... Правда, в этом случае наследование рекурсивности не будет распространяться дальше этого второго уровня иерархии наследования. :) Незнаю, может быть это можно исправить, но можно просто запретить дальнейшее развитии иерархии вглубь (ну java'вского final в C++ нет, зато имеются похожие хаки).

Итак, мы имеем наследование и отсутствие лишних преобразований типов, что и требовалось...

Ужос. :)

Интересен совет vlad-mal'а о (пере)определении виртуальных accessor'ов, но я что-то не представляю, как это решит проблему с явными typecast'ами...

 
 
 [ Сообщений: 17 ]  На страницу Пред.  1, 2


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group