What is the difference in a base hook and a member hook in Boost::Intrusive library and when is one better to use then the other?
I've read the boost documentation, but its not that explanatory.
As far as I can tell it is a matter of style and object-oriented design. Base hooks intrude upon the inheritance hierarchy, necessitating an extra public parent class and possibly forcing multiple inheritance upon the design. Using member hooks allows the programmer to treat an object as having a has-a relation with a container, rather than an is-a relation with container membership.
imho if your object is intended to be included into single container only, base hook seems more convinient. Otherwise (for multiple containers), multiple member hooks provide less ambigious solution (since multiple inheritance is avoided)
http://www.boost.org/doc/libs/1_47_0/doc/html/intrusive/recursive.html
"Member hooks are not suitable for recursive structures"
Related
It is an often repeated piece of advice that one should not inherit from classes with non-virtual destructor (if the intention is to use dynamic polymorphism). This is why inheriting from standard container classes is considered a bad idea.
On the other hand, Boost.Intrusive explicitly states that its containers are suitable for storing polymorphic objects. In the example from the link, this is achieved by deriving from boost::intrusive::list_base_hook<> which does not have a virtual destructor and only introducing one in the derived class.
Is this a valid design?
If so, why and how does it fit the general advice I mentioned above? I particular, why wouldn't the same logic justify inheriting from standard containers?
(Note that my question is not about differences between standard containers and Boost.Intrusive containers. I am interested in correct usage of Boost.Intrusive, but I mention standard containers only as an example since they often come up when similar topics are discussed.)
One should not inherit from classes with non-virtual destructor only if the use of derived classes involves ownership of objects via a pointer to a base class. There is nothing special about standard container classes. Inheriting from them is not necessary a bad idea, but the thing is that other approaches of extending their functionality should be preferred: adding a stand-alone function or aggregation.
Deriving from boost::intrusive::list_base_hook<> is a totally valid design because ownership of derived objects is never held via a pointer to list_base_hook. Note that library offers hooking through aggregation (using list_member_hook) which should be preferred to inheritance.
I'm studying for my OOP final, and came across a question that has me a bit stumped. The question is "explain why building a Stack class by publicly inheriting a List class is a poor approach. Describe a better solution."
I'm not sure if my answer is right, but is it because of "publicly inheriting..."? And that it would be better to inherit privately instead so that way no class other than Stack would know of the inheritance?
If a derived class publicly inherits from a base class, the derived class is an instance of the base class, potentially with some extra functionality or overridden functionality. In the case of a stack and a list, a stack isn't a list - it logically doesn't perform list operations like searching, concatenating, reversing, etc. - so inheriting from list would not be a good idea.
You could use private inheritance here, but that's not a particularly elegant solution. Instead, you could just implement stack by having it hold a list as a private data member. This is the reason why you often hear "favor composition (having private data members) over inheritance."
Hope this helps!
Private inheritance is also a bad idea here. The key point is really that a Stack isn't a List. While you could have a list implementation that only supports stack like operations this doesn't follow from the definition of a list.
In general you should always prefer composition over inheritance. Inheritance should, ideally, only be used to introduce runtime polymorphism. (Inheritance can sometimes be used for convenience, but you should limit this as a much as possible as it creates possibly unnecessary coupling to the base class).
Maybe it's about not using inheritance and take advantage of composition instead.
Stack has an internal list instead of Stack is a list (which is false: stack is semantically different than a list).
This is because public inheritance affects interface. If Stack publicly inherits List, it will include List interface.
Yes, private inheritance is better approach there. Personally, I prefer using aggregation in such cases.
Public inheritance
class A : public B
is used to denote that class A is some kind of class B, it extends this class. Since Stack is not a List
class Stack : public List
is wrong.
And that it would be better to inherit privately(...)?
Better but more correct IMO would be to implement a Stack by a List as a data member or pointer to implementation.
For example, you can insert in the middle of a list, but you cannot insert in the middle of a stack, but inheriting a stack from a list implies that you can. If anything, list should inherit from stack (although I wouldn't do that in practice either)
It is not always true that you should not publicly inherit from another class. You should certainly not do so if the base class exposes functionality that your inherited class should not provide. I.e., a class that inherits from another is a specialized type of the base class – which means that all of the base class’ functionality should apply to the inherited class. The inherited class should add additional functionality, or or provide a specialized/custom form of the base class’ functionality.
In the case of a list vs. a stack, the stack should NOT expose all the functionality that a list provides.
Specifically: A stack manages a collection of objects by allowing consumers to insert objects into the collection, and remove the last object inserted into the collection. (LIFO). Typical interface methods for a stack are “push” and “pop”
A list, on the other hand does not have the same limitations. It alows access to its objects in any order – often by using an index.
If you publicly derive a stack from a list, a caller that has an instance of your stack class will be able to use the base class’ public methods – which would include functionality to access any member of its collection objects, in any order. Your stack is no longer acting as a stack!!
I've just learned about what std::function really is about and what it is used for and I have a question: now that we essentially have delegates, where and when should we use Abstract Base Classes and when, instead, we should implement polymorphism via std::function objects fed to a generic class? Did ABC receive a fatal blow in C++11?
Personally my experience so far is that switching delegates is much simpler to code than creating multiple inherited classes each for particular behaviour... so I am a little confused abotu how useful Abstract Bases will be from now on.
Prefer well defined interfaces over callbacks
The problem with std::function (previously boost::function) is that most of the time you need to have a callback to a class method, and therefore need to bind this to the function object. However in the calling code, you have no way to know if this is still around. In fact, you have no idea that there even is a this because bind has molded the signature of the calling function into what the caller requires.
This can naturally cause weird crashes as the callback attempts to fire into methods for classes that no longer exist.
You can, of course use shared_from_this and bind a shared_ptr to a callback, but then your instance may never go away. The person that has a callback to you now participates in your ownership without them even knowing about it. You probably want more predictable ownership and destruction.
Another problem, even if you can get the callback to work fine, is with callbacks, the code can be too decoupled. The relationships between objects can be so difficult to ascertain that the code readability becomes decreased. Interfaces, however, provide a good compromise between an appropriate level of decoupling with a clearly specified relationship as defined be the interface's contract. You can also more clearly specify, in this relationship, issues like who owns whom, destrcution order, etc.
An additional problem with std::function is that many debuggers do not support them well. In VS2008 and boost functions, you have to step through about 7 layers to get to your function. Even if all other things being equal a callback was the best choice, the sheer annoyance and time wasted accidentally stepping over the target of std::function is reason enough to avoid it. Inheritance is a core feature of the language, and stepping into an overridden method of an interface is instantaneous.
Lastly I'll just add we don't have delegates in C++. Delegates in C# are a core part of the language, just like inheritance is in C++ and C#. We have a std library feature which IMO is one layer removed from a core language functionality. So its not going to be as tightly integrated with other core features of the language. It instead helps formalize the idea of function objects that have been a C++ idiom for a good while now.
I do not see how one can come to the conclusion that function pointers make abstract base classes obsolete.
A class, encapsulates methods and data that pertains to it.
A function pointer, is a function pointer. It has no notion of an encapsulating object, it merely knows about the parameters passed to it.
When we write classes, we are describing well-defined objects.
Function pointers are great for a good number of things, but changing the behaviour of an object isn't necessarily the target-audience (though I admit there may be times when you would want to do so, e.g. callbacks, as Doug.T mentions).
Please don't confuse the two.
This applies to several cases in my application:
I have 3 or 4 functions that belong together, one is a starting function that creates and frees the required memory structures and calls the other functions as appropriate. The other functions also call themselves repeatedly. Only the starting functions is called from outside, and only once or not at all per application-run.
Currently, I pass pointers to the memory structures from the starting function as function arguments, but the argument list is getting quite long in some cases.
Is there any argument against creating classes for all these cases and making the pointers to the memory structures members?
Definitely go for a class here. That's what objects and classes are designed for.
It seems to be a quite typical use case for classes: Just add the "memory structure" as protected member of the class and initiliaze it in the constructor.
The member functions (aka "method") than can work on the data.
If you have different, but similiar use cases, you may also make use of subclassing, so you create a base class with default implementation and create some derived class that overwrites some of the methods with an own implementation.
But note, that you could also use other members varibales to set the behaviour at runtime (e.g. a bool that is used to toggle on or off a specific behaviour).
Your question is too abstract to see what is the best solution for your case. Remember, often there are a lot of solutions - and so there is more than one good solution.
It sounds to me like these functions belong in a class - with the internal functions private or protected - likewise with the members.
Yes, relate them all within a class.
This will also give you a cleaner code which might help you minimize the functions' arguments lists.
In simple words an object can be anything you decide. Say a person. This is an object which I'll decide to define as a class if I'll write a program that needs to keep information regarding people.
There are much better explanations than this, just google/wikipedia it.
boost::intrusive_ptr requires intrusive_ptr_add_ref and intrusive_ptr_release to be defined. Why isn't a base class provided which will do this? There is an example here: http://lists.boost.org/Archives/boost/2004/06/66957.php, but the poster says "I don't necessarily think this is a good idea". Why not?
Update: I don't think the fact that this class could be misused with Multiple Inheritance is reason enough. Any class which derives from multiple base classes with their own reference count would have the same issue. Whether these refcounts are implemented via a base class or not makes no difference.
I don't think there's any issue with multithreading; boost::shared_ptr offers atomic reference counting and this class could too.
Boost provides a facility for that. It can be configured for either thread-safe or thread-unsafe refcounting:
#include <boost/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
class CMyClass
: public boost::intrusive_ref_counter<
CMyClass,
boost::thread_unsafe_counter>
...
boost::intrusive_ptr<CMyClass> myPtr;
http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ref_counter.html
It's so you can use intrusive_ptr with classes that already implement add and release.
The problem would be with Multiple Inheritance. If you inherit from 2 objects implementing this base, then you have 2 counters for your single object... and that could cause havoc.
Thus you would need to make the ptr_add and ptr_release methods virtual, so that the derived class may implement an override to properly synchronize the multiple counters at once... Some performance penalty here, especially since most of the times it would be completely unnecessary (there would be no override) because it's only useful for Multiple Inheritance after all.
And of course in Multi-Threaded environments you could have (for short periods of time) desynchronized counters (the first was incremented but the thread was interrupted before the second was) I can't think yet of any problem it may cause, but it's not a sane situation.
You also add clutter to the class, some clients may not need reference counting after all (if they create the object on the stack).
I think it's not a good idea ;)