C ++ Производственный класс, который самообновления

StackOverflow https://stackoverflow.com/questions/3507600

Вопрос

Так что предположим, у меня есть класс дерева в C ++

class Node{
    void addChild(Node*);
    /*obvious stuff*/
    protected:
        Node* parent;
        vector<Node*> children
}

class specialNode : public Node{
    void addChild(specialNode*);
    /*obvious stuff*/
    /*special stuff*/
}

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

Но этот специальный совет * имеет переменные элемента и функции, которые узел не имеет.

Я могу заставить специального фундамента, чтобы принять специальный совет только как дети, и в противном случае пробил время компиляции, но я все еще получаю узел * при доступе к детям / родителю, и я должен бросить его, когда я хочу использовать специальные функции, даже в специальных функциях.

Есть ли умный или просто любой лучший способ пойти об этом? Кроме буквально кастинга каждый раз?

Это было полезно?

Решение

Если вам нужно только SpecialNode объекты в вашем дереве (и просто хотите инкапсулировать все общие функциональные возможности деревьев в Node) ты можешь сделать Node так называемый «смеси в классе, как

template <class N>
class Node : public N {
public:
  void addChild(Node<N>*);
protected:
  Node<N>* parent;
  vector<Node<N>*> children;
};

class SpecialNodeBase {
  // Here comes all "special" data/methods for your "special" tree
};

typedef Node<SpecialNodeBase> SpecialNode;

После этого вы можете построить дерево SpecialNode объекты и используют все методы от SpecialNodeBase а также дополнительные функции управления деревьев Node

Другие советы

Поскольку функция Addchild в вашем классе дочернего класса не является полиморфизмом, делает его виртуальным, но функции перегрузки через базовые / члены ребенка не допускаются, поэтому мы должны изменить параметр Addchild в классе ребенка:

class Node{
    virtual void addChild(Node*);
    ...
}

class specialNode : public Node{
    virtual void addChild(Node*);
    ...
}

Теперь он должен работать.


Если вы хотите получить доступ к childeren Переменная от дочернего класса (specialNode Класс), вы должны бросить его. Например:

specialNode* var = static_cast<specialNode*>(children[i]);

Так как мы объявили Addchild как виртуальную функцию, то мы должны использовать dynamic_cast вместо static_cast Если мы не уверены, что children[i] всегда является примером specialNode класс, и, таким образом, лучше использовать dynamic_cast:

specialNode* var = dynamic_cast<specialNode*>(children[i]);
if(var != NULL)
{
    //...
}

Если я правильно понимаю, «Mix-In Class Solution не позволит вам позвонить addChild из функций, реализованных SpecialNodeBaseClass.

Вы можете сделать следующее:

template <class recursiveT>
class Base {
public:

     Base(dataType data) { populate children with data; }

     void addChild() { something base class appropriate; }

protected:
     std::vector<recursiveT> children;
};




class Derived: public Base<Derived> {
public:
     /* note: the constructor here will actually call the 
        constuctor of the base class */
     Derived(dataType data) : Base<Derived>(data) {} 
     /* other special functions go here.  */
};

Это может выглядеть немного сумасшедшим, но это чисто компилируется для меня на нескольких версиях GCC, поэтому я склонен верить, что это не совсем неправильно направляется. Теперь вы должны иметь возможность вызвать функции базы изнутри изнутри.

Вам определенно придется бросить Node * к А. specialNode * В какой-то момент, но вы можете сделать это чистое и легко управлять, делая это только в одном месте. Вы можете добавить функцию участника, скажем, getParent и переопределить его в specialNode, как это:

class Node {
  ...
  virtual Node *getParent() {
    return parent;
  }
};

class specialNode : public Node {
  ...
  specialNode *getParent() {
    return dynamic_cast<specialNode *>(parent);
  }
};

Конечно, это предполагает, что specialNodeу всегда есть другие specialNodeкак родитель / дети. Если вы смешиваете Nodeпесок specialNodeS, это, очевидно, не будет работать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top