What are some practical uses for the "Curiously Recurring Template Pattern"? The "counted class" example commonly shown just isn't a convincing example to me.
Simulated dynamic binding.
Avoiding the cost of virtual function calls while retaining some of the hierarchical benefits is an enormous win for the subsystems where it can be done in the project I am currently working on.
It's also especially useful for mixins (by which I mean classes you inherit from to provide functionality) which themselves need to know what type they are operating on (and hence need to be templates).
In Effective C++, Scott Meyers provides as an example a class template NewHandlerSupport<T>. This contains a static method to override the new handler for a particular class (in the same way that std::set_new_handler does for the default operator new), and an operator new which uses the handler. In order to provide a per-type handler, the parent class needs to know what type it is acting on, so it needs to be a class template. The template parameter is the child class.
You couldn't really do this without CRTP, since you need the NewHandlerSupport template to be instantiated separately, with a separate static data member to store the current new_handler, per class that uses it.
Obviously the whole example is extremely non-thread-safe, but it illustrates the point.
Meyers suggests that CRTP might be thought of as "Do It For Me". I'd say this is generally the case for any mixin, and CRTP applies in the case where you need a mixin template rather than just a mixin class.
The CRTP gets a lot less curious if you consider that the subclass type that is passed to the superclass is only needed at time of method expansion.
So then all types are defined.
You just need the pattern to import the symbolic subclass type into the superclass, but it is just a forward declaration - as all formal template param types are by definition - as far as the superclass is concerned.
We use in a somewhat modified form, passing the subclass in a traits type structure to the superclass to make it possible for the superclass to return objects of the derived type. The application is a library for geometric calculus ( points, vectors, lines, boxes ) where all the generic functionality is implemented in the superclass, and the subclass just defines a specific type : CFltPoint inherits from TGenPoint. Also CFltPoint existed before TGenPoint, so subclassing was a natural way of refactoring this.
Generally it is used for polymorphic-like patterns where you do not need to be able to choose the derived class at runtime, only at compile time. This can save the overhead of the virtual function call at runtime.
For a real-world library use of CRTP, look at ATL and WTL (wtl.sf.net). It is used extensively there for compile-time polymorphism.
Related
I'm getting confused by these two. What I learned is that Abstract data type is a mathematical model for data type, where it specifies the objects and the methods to manipulate these objects without specifying the details about the implementation of the objects and methods. Ex: an abstract stack model defines a stack with push and pop operations to insert and delete items to and from the stack. We can implement this in many ways, by using linked lists, arrays or classes.
Now, coming to the definition of abstract class, its a parent class which has one or more methods that doesn't have definition(implementation?) and cannot be instantiated (much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures). For ex: if we have an abstract class called Mammal which includes a function called eat(), we don't know how a mammal eats because a mammal is abstract. Although we can define eat() for a cow which is a derived class of mammal. Does this mean that mammal serves as an adt and cow class is an implementation of the mammal adt?
Correct me if I'm wrong in any way. Any kind of help would be really appreciated.
Abstract data type is a mathematical model for data type...
Now, coming to the definition of abstract class...
You need to distinguish between theoretical mathematical models and a practical implementation techniques.
Models are created by people in order to reason about problems easily, in some comprehensible, generalized way.
Meanwhile, the actual code is written in order to work and get the job done.
"Abstract data type" is a model. "Abstract class" is a programming technique which some programming languages (C++, C#, Java) support on the language level.
"Abstract data type" lets you think and talk about the solution of a problem, without overloading your brain with unnecessary (at this moment) implementation details. When you need a FIFO data structure, you say just "stack", but not "a doubly-linked list with the pointer to the head node and the ability to...".
"Abstract class" lets you write the code once and then reuse it later (because that is the point of OOP - code reuse). When you see that several types have a common interface and functionality - you may create "an abstract class" and put the intersection of their functionality in inside, while still being able to rely on yet unimplemented functions, which will be implemented by some concrete type later. This way, you write the code once and when you need to change it later - it's only one place to make the change in.
Note:
Although, in C++ ISO Standard (at least in the draft) there is a note:
Note: The abstract class mechanism supports the notion of a general concept,
such as a shape, of which only more concrete variants, such as circle
and square, can actually be used.
but it is just a note. The real definition is:
A class is abstract if it has at least one pure (aka unimplemented) virtual function.
which leads to the obvious constraint:
no objects of an abstract class can be created except as subobjects of
a class derived from it
Personally, I like that C++ (unlike C# and Java) doesn't have the keyword "abstract". It only has type inheritance and virtual functions (which may remain unimplemented). This helps you focus on a practical matter: inherit where needed, override where necessary.
In a nutshell, using OOP - be pragmatic.
The term "abstract data type" is not directly related to anything in C++. So abstract class is one of the potential implementation strategies to implement abstract data types in the given language. But there are a lot more techniques to do that.
So abstract base classes allow you to define a set of derived classes and give you the guarantee that all interfaces ( declarations ) have also an implementation, if not, the compiler throws an error, because you can't get an instance of your class because of the missing method definition.
But you also can use compile time polymorphism and related techniques like CRTP to have abstract data types.
So you have to decide which features you need and what price you want to pay for it. Runtime polymorphism comes with the extra cost of vtable and vtable dispatching but with the benefit of late binding. Compile time polymorphism comes with the benefit of much better optimizable code with faster execution and less code size. Both give you errors if an interface is not implemented, at minimum at the linker stage.
But abstract data types with polymorphism, independend of runtime or compile time, is not a 1:1 relation. Making things abstract can also be given by simply defining an interface which must be somewhere fulfilled.
In a short: Abstract data types is not a directly represented in c++ while abstract base class is a c++ technique.
Is Abstract class an example of Abstract data type?
Yes, but in C++, abstract classes have become an increasingly rare example of abstract data types, because generic programming is often a superior alternative.
Ex: an abstract stack model defines a stack with push and pop
operations to insert and delete items to and from the stack. We can
implement this in many ways, by using linked lists, arrays or classes.
The C++ std::stack class template more or less works like this. It has member functions push and pop, and it's implemented in terms of the Container type parameter, which defaults to std::deque.
For an implementation with a linked list, you'd type std::stack<int, std::list<int>>. However, arrays cannot be used to implement a stack, because a stack can grow and shrink, and arrays have a fixed size.
It's very important to understand that the std::stack has absolutely nothing to do with abstract classes or runtime polymorphism. There's not a single virtual function involved.
Now, coming to the definition of abstract class, its a parent class
which has one or more methods that doesn't have
definition(implementation?) and cannot be instantiated
Yes, that's precisely the definition of an abstract class in C++.
In theory, such a stack class could look like this:
template <class T>
class Stack
{
public:
virtual ~Stack() = 0;
virtual void push(T const& value) = 0;
virtual T pop() = 0;
};
In this example, the element type is still generic, but the implementation of the container is meant to be provided by a concrete derived class. Such container designs are idiomatic in other languages, but not in C++.
much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures
Yes, you couldn't use std::stack without providing a container type parameter (but that's impossible anyway, because there's the default std::deque parameter), and you cannot instantiate a Stack<int> my_stack; either.
I would like to write down a set of classes in which there are:
a pure virtual class that wraps an object of any kind and the relate getter for it.
one or more classes for every kind of object I need, extending the virtual one and overriding the getter in order to specialize it.
A template class solution for the wrapper seems to fit the case but I have to use it in two different contexts:
the first one is not aware of wrapper implementations. In this case I should declare a Wrapper<AnyObj> var; with AnyObj standing for any class name (like ? in Java). As far as I know, you can't do this in c++.
the second one is restricted to a particular wrapper implementation. In this case I need the getter to return the wrapped object with the exact type (rather than downcasting it).
If I'm right I cannot use a template class and, moreover, the wrapper won't have a protected: T* wrappedObject member.
I don't know if I'm stuck in the Java approach, wrongly thinking from the beginning, or missing something.
Any suggestion is appreciated.
I'm quite new to c++ development and design and so I apologize in advance in my question is vague or poorly structured. I have several distinct and unrelated hierarchies in my code and I would like to use a generic factory as described and implemented by Alexandrescu to instantiate objects from these hierarchies .
The part I am having difficulty with is the initialization phase. The classes have very different initialization needs. Sometimes the data needed for initialization can be looked up from storage (DB) and in those cases I can encapsulate the initialization procedure in some Init() method of the specific class. But other times the data is known only locally an the moment of instantiation and needs to be passed to the object manually. I'm struggling to come up with a uniform way to do this. Does anyone have any inputs on approaching problems of this kind?
Thanks
You are hurtling down the Over-Engineering highway... head first.
Factories are seldom required, and no two Factories are alike (as you noticed).
It is useless to try and provide a base class for all your Factories, because this base class will have no clear semantic. What does it build ? Birds ? Cars ? They are unrelated... Objects ? This is not Java!
If you wish to use Factories (for some reason), then a Factory should produce 1 kind of objects, all deriving from a common base class. If you have several kinds of objects, then you will need several kinds of Factories.
And if you find the Factory code repetitive, use a template to hoist the common code.
If I guessed correctly, your problem is that you don't know how to pass different sets of arguments to your factory methods. If so it is, I can advise you to create one more hierarchy/ Let's call it FactoryHelper. The concrete class of this hierarchy will contain spesific data for instanciation of your concrete classes, for example FactoryHelperA for ConcreteProductA will contain a string and FactoryHelperB for ProductB will contain int. An abstact method of your factory must accept abstract base class - FactoryHelper as an argument. Concrete methods of your factory will cast this argument to concrete FactoryHelperA or FactoryHelperB and get specefic data for instanciation of specefic Product
But it's not very good design. I guess you're trying to use factory methods the wrong way.
I am relatively new to "design patterns" as they are referred to in a formal sense. I've not been a professional for very long, so I'm pretty new to this.
We've got a pure virtual interface base class. This interface class is obviously to provide the definition of what functionality its derived children are supposed to do. The current use and situation in the software dictates what type of derived child we want to use, so I recommended creating a wrapper that will communicate which type of derived child we want and return a Base pointer that points to a new derived object. This wrapper, to my understanding, is a factory.
Well, a colleague of mine created a static function in the Base class to act as the factory. This causes me trouble for two reasons. First, it seems to break the interface nature of the Base class. It feels wrong to me that the interface would itself need to have knowledge of the children derived from it.
Secondly, it causes more problems when I try to re-use the Base class across two different Qt projects. One project is where I am implementing the first (and probably only real implementation for this one class... though i want to use the same method for two other features that will have several different derived classes) derived class and the second is the actual application where my code will eventually be used. My colleague has created a derived class to act as a tester for the real application while I code my part. This means that I've got to add his headers and cpp files to my project, and that just seems wrong since I'm not even using his code for the project while I implement my part (but he will use mine when it is finished).
Am I correct in thinking that the factory really needs to be a wrapper around the Base class rather than the Base acting as the factory?
You do NOT want to use your interface class as the factory class. For one, if it is a true interface class, there is no implementation. Second, if the interface class does have some implementation defined (in addition to the pure virtual functions), making a static factory method now forces the base class to be recompiled every time you add a child class implementation.
The best way to implement the factory pattern is to have your interface class separate from your factory.
A very simple (and incomplete) example is below:
class MyInterface
{
public:
virtual void MyFunc() = 0;
};
class MyImplementation : public MyInterface
{
public:
virtual void MyFunc() {}
};
class MyFactory
{
public:
static MyInterface* CreateImplementation(...);
};
I'd have to agree with you. Probably one of the most important principles of object oriented programming is to have a single responsibility for the scope of a piece of code (whether it's a method, class or namespace). In your case, your base class serves the purpose of defining an interface. Adding a factory method to that class, violates that principle, opening the door to a world of shi... trouble.
Yes, a static factory method in the interface (base class) requires it to have knowledge of all possible instantiations. That way, you don't get any of the flexibility the Factory Method pattern is intended to bring.
The Factory should be an independent piece of code, used by client code to create instances. You have to decide somewhere in your program what concrete instance to create. Factory Method allows you to avoid having the same decision spread out through your client code. If later you want to change the implementation (or e.g. for testing), you have just one place to edit: this may be e.g. a simple global change, through conditional compilation (usually for tests), or even via a dependency injection configuration file.
Be careful about how client code communicates what kind of implementation it wants: that's not an uncommon way of reintroducing the dependencies factories are meant to hide.
It's not uncommon to see factory member functions in a class, but it makes my eyes bleed. Often their use have been mixed up with the functionality of the named constructor idiom. Moving the creation function(s) to a separate factory class will buy you more flexibility also to swap factories during testing.
When the interface is just for hiding the implementation details and there will be only one implementation of the Base interface ever, it could be ok to couple them. In that case, the factory function is just a new name for the constructor of the actual implementation.
However, that case is rare. Except when explicit designed having only one implementation ever, you are better off to assume that multiple implementations will exist at some point in time, if only for testing (as you discovered).
So usually it is better to split the Factory part into a separate class.
How do Concepts (ie those recently dropped from the C++0x standard) differ from Interfaces in languages such as Java?
Concepts are for compile-time polymorphism, That means parametric generic code. Interfaces are for run-time polymorphism.
You have to implement an interface as you implement a Concept. The difference is that you don't have to explicitly say that you are implementing a Concept. If the required interface is matched then no problems. In the case of interfaces, even if you implemented all the required functions, you have to excitability say that you are implementing it!
I will try to clarify my answer :)
Imagine that you are designing a container that accepts any type that has the size member function. We formalize the Concept and call it HasSize, of course we should define it elsewhere but this is an example no more.
template <class HasSize>
class Container
{
HasSize[10]; // just an example don't take it seriously :)
// elements MUST have size member function!
};
Then, Imagine we are creating an instance of our Container and we call it myShapes, Shape is a base class and it defines the size member function. Square and Circle are just children of it. If Shape didn't define size then an error should be produced.
Container<Shape> myShapes;
if(/* some condition*/)
myShapes.add(Square());
else
myShapes.add(Circle());
I hope you see that Shape can be checked against HasSize at compile time, there is no reason to do the checking at run-time. Unlike the elements of myShapes, we could define a function that manipulates them :
void doSomething(Shape* shape)
{
if(/* shape is a Circle*/)
// cast then do something with the circle.
else if( /* shape is a Square */)
// cast then do something with the square.
}
In this function, you can't know what will be passed till run-time a Circle or a Square!
They are two tools for a similar job, though Interface-or whatever you call them- can do almost the same job of Concepts at run-time but you lose all benefits of compile-time checking and optimization!
Concepts are likes types (classes) for templates: it's for the generic programming side of the language only.
In that way, it's not meant to replace the interface classes (assuming you mean abstract classes or other C++ equivalent implementation of C# or Java Interfaces) as it's only meant to check types used in template parameters to match specific requirements.
The type check is only done at compile time like all the template code generation and whereas interface classes have an impact on runtime execution.
Concepts are implicit interfaces. In C# or Java a class must explicitly implement an interface, whereas in C++ a class is part of a concept merely as long as it meets the concept's constraints.
The reason you will see concepts in C++ and not in Java or C# is because C++ doesn't really have "interfaces". Instead, you can simulate an interface by using multiple inheritance and abstract, memberless base classes. These are somewhat of a hack and can be a headache to work with (e.g. virtual inheritance and The Diamond Problem). Interfaces play a critical role in OOP and polymorphism, and that role has not been adequately fulfilled in C++ so far. Concepts are the answer to this problem.
It's more or less a difference in the point of view. While an interface (as in C#) is specified similar to a base class, a concept can also be matched automatically (similar to duck-typing in Python). It is still unclear to which level C++ is going to support automatic concept matching, which is one of the reasons why they dropped it.
To keep it simple, as per my understanding.
Concept is a constraint on the template parameter of a Type (i.e., class or struct) or a Method
Interfaces is a contract that Type (i.e., class Or struct) has to implement.