Should I inherit a nested class within a derived class in c++?

89 views Asked by At

Could (Edit: Should) I do something like this?

Edit:

I'll try asking about an example that may be better suited to this inheritence scheme. Note this isn't a working class, just for the concept.

template<typename T>
class Tree {
protected:
    class Node {
       Node* _parent;
       T _data
    };
};

template<typename T>
class BinaryTree: public Tree {
private:
    class BinaryNode: public Tree<T>::Node {
        Node *_left, *_right;
    };
};
2

There are 2 answers

7
Sergey Kalinichenko On BEST ANSWER

This way of constructing parallel class hierarchies is not uncommon. However, it is more common to hide the nested derived class as an implementation detail that should be encapsulated, i.e. the BiIterator in your example would be in the private: section.

However, Iterator is not a good example because of object slicing: even if BiIterator remains public, this seemingly innocent code is incorrect:

BidirectionalList biList;
// This would slice off BiIterator's functionality
Iterator iter(biList.get_iterator());
while (iter.has_next()) {
    ...
}

A better example would be if the base class member function took a reference or a pointer to an object of a nested class defined in the base, and a derived class would pass its derived nested class for it:

class Task {
public:
    class Worker {
        public virtual void work()=0;
    }
    void run(Worker& w);
};
class SpecialTask : public Task {
private:
    class SpecialWorker : public Worker {
        public virtual void work() {
            ...
        }
    };
public:
    void do_something() {
        SpecialWorker w;
        run(w); // Passes SpecialWorker to run() of base class
    }
};
5
Jonathan Mee On

There is nothing illegal about what you're doing so you could do it.

As far as should you, that's less clear cut.

But for this example I do think the answer is clear. When implementing C++ containers they decided to implement iterator separately from all their container classes. Benefiting from their wisdom wouldn't be a bad choice in this case.

EDIT:

For a container structure your contained object type should be templatized. For my proof I'd again reference C++ container design.

But here I think it's much more clear cut. If you write an excellent Tree or BinaryTree class that's templatized, you could use that over and over in all the code you write for the rest of your life. Why not take advantage of that?

(Just a word of caution you might be reinventing the wheel here. Have a look at this: http://www.cplusplus.com/reference/algorithm/make_heap/)