简体   繁体   中英

c++ Project Design - private inheritance and “is a” relationship

I want to extend a class throught private inheritance.

the base class is: Graph<T>

The derived is: Tree<T>

We know that a tree is a particular graph, so i want to extend my Graph class without letting user use the PUBLIC methods of Graph class.

Making:

template <typename T> class Tree : public Graph<T>{

    .
    .
    .
}

works but i don't want to alter my tree state with Graph class methods. Users must use Tree class specific methods. I think i should use private inheritance to get what i want.

The problem is that i can't lose the "is a" relationship, because a Tree is, as a matter of fact, a graph.

What is a good design in order to make things good and semantically ordered?

Thanks

Well, you can't have it both ways. is-a relationship exactly means that users can use any Graph -defined non-virtual, non-overridden functions on a pointer (or reference) to Tree and achieve expected results.

If you can't allow users to call those functions, it means, is-a relationship is not appropriate by definition, and you should choose private inheritance instead.

Private inheritance is not such a great idea - see this post for more details.

However, I think you're approaching the problem in the wrong way. If a Tree is a Graph, then any operation one might want to do on a Graph is valid. And clients should be allowed to do it. The operations should be built in such a way that it makes sense. If you find that some operations don't, then perhaps this isn't a right use of inheritance.

Remember that in Graph Theory/Combinatorics, a tree is a graph, but in Computer Science, that relationship is tenuous. The ways in which trees and graphs are represented as data structures is quite different, which makes sharing of code a hassle.

Object orientation doesn't always work very well. A tree is a special type of a graph. But in being special it is more restricted and simpler than a general graph, and supports fewer operations. So you can write a graph base that allows any number of nodes and any topology, then restrict the topology in the tree layer. Or you can just say that tree doesn't inherit from graph at all. Or you can say that there is a abstract "graph base" which can then be instantiated with tree, general graph, directed acyclic graph, balanced tree, and so on.

I'd suggest the last is what you want. So write an abstract_graph base class with at least one virtual member function set to null.

Then you can inherit privately. It depends if the tree clients care that a tree isa graph or not. Private inheritance isn't all that common, however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM