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.
Related
If I have 8 long methods that will be shared among 4 child classes (not all of them will be using all the methods) some will be use only 2 others 4, etc.
If I create a base class and each of the 4 child classes inherit from the base class then the problem is solved but I am trying to avoid using a very long base class.
I can try to divide the base class in more classes depending on how they are used and then use multiple inheritance, this is another solution.
Is there any other pattern to solve this problem?? What would be the optimal?
From the way you have posed the question, the first thing you need to seriously consider is whether you need classes at all.
One trap that beginners often fall into is believing that everything has to be in a class. While it is true that some languages require that, it is an option, but is not necessarily required - and can even be a really bad idea - in C++.
Unless there is an actual "is-a" relationship between the classes (e.g. the base class represents a Dog and derived classes represent types of dog) it is probably better not to use inheritance at all.
[There are circumstances where a class hierarchy is appropriate, even if there isn't an "is-a" relationship - but, if your situation was like that, you almost certainly wouldn't need to ask the question you have.]
Instead, I'd simply define eight non-member functions (i.e. that are not members of a class) with appropriate arguments and return type. The arguments and return value (if any) can be used both to pass information to the function, or to pass information back.
The four classes then call the functions as needed. From your description, however, it is not even clear that you need those four classes. Possibly all that is needed is a set of functions that are implemented by calling your "8 long methods". Those "8 long methods" can be implemented locally to a source file, if you need to prevent other code from calling them.
Generally speaking, aim to make your design as simple as possible. If that is achievable without having a class hierarchy, or without defining any classes at all, then don't use classes.
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 have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.
A theoretical question. I'm reading Gof's Design Patterns, section Abstract Factory. The book mentions the possibility of implementing this pattern like a Prototype or, if the language permits it, with a Prototype which stores classes instead of objects.
I have understood this; e.g. in Java or Smalltalk, classes are also objects (in Java they are in fact instances of the class Class). Hence, we can store them inside a class and, when needed, invoke the creation of instances of these classes.
In C++, classes are not first class objects; hence, we shouldn't be able to follow this approach. However, couldn't we declare nested classes inside inside a Concrete Factory, with methods which invoke their constructors (and return their instances)? The final result would be the same of other languages such as Java or Smalltalk. Am I right?
Thank you for your attention.
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.