About implementation of abstract/concrete graphs in C++ - c++

I am writing a program that works with graphs. I am dealing with two types of graphs : "abstract graphs", which consist in abstract vertices with edges, and "planar graphs", in which the vertices have coordinates x,y in the plane (actually I am working with a complex affix z but it does not matter).
I have elected to write an (abstract) Vertex class and a derived class Planar_Vertex as follows in my Vertex.h file - this is not precisely my code, I made it slightly simpler and "translated" it from French ;)
class Vertex
{
public:
Vertex();
int get_label();
void set_label(int label);
void add_neighbor(int label);
bool is_neighbor(int label);
// etc
protected:
int _label;
std::vector<int> _list_neighbors;
};
class Planar_Vertex : public Vertex
{
complex<double> _affix;
public:
Planar_Vertex();
Planar_Vertex(Vertex& V, complex<double> affix);
complex<double> get_affix();
void set_affix(complex<double> affix);
};
Here's my main question. I would like my Planar_Vertex(Vertex& V, complex affix) constructor to have the following effects : 1. Output a Planar_Vertex whose label and list of neighbors are the same as V, and whose affix is given. So far, easy. 2. I would like V to be precisely the abstract Vertex underlying this new object. In other words, if in my main.cpp file I wrote, say,
Vertex V1;
...
Planar_Vertex V2(V1,z)
then I would like that a use of set_label() on V2 will also affect V1 (for example). The way I see it is, in this constructor, I would like to say something like: make the address of V (in memory) the same as that of the Planar_Vertex constructed (and free the memory previously allocated to V). Apparently it is not possible to change the location of a variable in memory though, so I don't know what to do. I am relatively new to C++ and I'm getting lost reading about placement new, std::move, rvalues etc. Does anybody see how to do what I want?
[Edit : To summarize, I want to be able to build an object of the derived class on top of an object of the base class that has already been built.]
Okay, now since I told you guys that much about my implementation of graphs, I thought I'd tell you the rest so you can give me your opinion about it, I hope you don't mind. Obviously you don't have to read the following, if you know the answer to my first question that'd be cool already. So as I told you we're dealing with "abstract graphs", which will consist in abstract vertices, and planar graphs, which consist in planar vertices.
Here's what my Graph.h file looks like:
class Graph
{
public:
Graph();
virtual ~Graph();
virtual std::vector<Vertex*> get_list_vertices();
void add_edge(int label1, int label2);
virtual void add_vertex(Vertex&);
// etc
};
class Abstract_Graph : public Graph
{
std::vector<Vertex*> _list_vertices;
public:
Abstract_Graph();
~Abstract_Graph();
std::vector<Vertex*> get_list_vertices();
void add_vertex(Vertex& V);
// etc
};
class Planar_Graph : public Graph
{
std::vector<Planar_Vertex*> _list_planar_vertices;
public:
Planar_Graph();
~Planar_Graph();
std::vector<Vertex*> get_list_vertices();
std::vector<Planar_Vertex*> get_list_planar_vertices();
void add_vertex(Planar_Vertex& V);
// etc
};
My idea is that the base class Graph will never be instanciated, but I will be able to implement "abstract graph operations" as functions of this base class and they will work on both Abstract_Graph and Planar_Graph objects. This is made possible thanks to the purely virtual function get_list_vertices. Is this a reasonable way to do things? What would you have done?
Thank you very much for for answers in advance.

You can keep a reference (or a pointer) to a Vertex object in your Planar_Vertex class to do what you want if I understood you.
Cut down demo:
#include <iostream>
struct Vertex {
int value;
};
struct Planar_Vertex: public Vertex {
Vertex& vr;
Planar_Vertex(Vertex& v): vr(v) {}
};
int main()
{
Vertex v;
v.value = 1;
std::cout << v.value << std::endl;
Planar_Vertex p = Planar_Vertex(v);
p.vr.value = 2;
std::cout << v.value << std::endl;
}
If you use a reference, it must be initialized in the constructor initialization list. If you use a pointer, you have more flexibility in how you initialize it, but have to worry about null pointers everywhere.
In both cases, you're responsible for making sure that the Vertex outlives the Planar_Vertex.
(Another option is to have a plain Vertex (not a reference or pointer) as a member of Planar_Vertex – you initialize it via Planar_Vertex's constructor, and use it wherever you need. This takes care of the lifetime requirements, but might not be possible in your code.)
For your second part, I don't see anything fundamentally wrong, but it's hard to have an opinion just with what you posted. Inheritance is one way to do this, another would be to use templates. Which one is more appropriate depends on the exact requirements (and your familiarity with both these concepts).

Related

Downcast from a container of Base* to Derived* without explicit conversion

I am writing a scientific code which needs to create 3-dimensional cells, defined by a set of faces, which are defined by a set of vertices.
These 3 classes (Cell, Face, Vertex) are derived respectively from some generic geometry classes (Polyhedron, Polygon, Point) which implement some geometric routines like Polygon::CalculateArea().
The Face class adds to the Polygon class with additional data and functions required for the science, like Face::Interpolate(). I don't want to make these member functions virtual in the base class (Polygon).
Now, the problem. I initialize a Cell with a vector of pointers to Face, which is handled by the base class Polyhedron constructor, which upcasts the Face* to Polygon*:
Polyhedron::Polyhedron( std::initializer_list<Polygon*> polygons );
Later, I want to access the Face* stored in a Cell so that I can call Face::Interpolate(), but it has been stored as a Polygon* and thus has no member function Polygon::Interpolate(). I can downcast it manually back to a Face* which works, but is not very clean. The user of the code has to do something like:
Face * temp_face = (Face*)cell->GetFaces()[0]; // Could use static_cast
temp_face->Interpolate();
which is not obvious.
I want the interface to be transparent, so that this just works:
cell->GetFaces()[0]->Interpolate();
I can think of two or three ways to achieve this. I'm looking for a better solution or feedback of which of these is recommended:
In Cell::GetFaces() which currently just inherits from Polyhedron::GetPolygons() I could create a wrapper that copies the std::vector<Polygon*> to a new vector std::vector<Face*>. This seems sloppy to me, not easy to maintain, inefficient and prone to errors.
Instead of storing std::vector<Polygon*> I could store std::vector<std::shared_ptr<Polygon>>. From what I understand, these smart pointers retain type-awareness so that they can call the right destructor, but they might just store a reference to the destructor depending on implementation. I don't want to use shared_ptr for performance purposes -- I know they're good and friendly, but I'm creating millions of these Polygons and its easy to destroy them in the right place. I can't use unique_ptr easily because of the copy-constructor used in std::initializer_list constructors.
Template the whole Polyhedron class, replacing every instance of Polygon* with F* and checking that F is a base of Polygon:
template<typename F = Polygon>
typename std::enable_if<std::is_base_of<Polygon, F>::value, void>::type
class Polyhedron
and then inheriting from a parent with a given typename:
class Cell : public Polyhedron<Face>
This seems like the best method to me, since it has the least boilerplate and nothing exposed to the user; but it still feels messy, especially in the "real" case where there might be multiple types that would all have to be specified:
class Cell: public Polyhedron<Face,Vertex,type3,type4,type5,...>
Is there a a better way? Perhaps a means of retaining type in the original vector (or some other container)?
If not, which of the above methods is the best practice and why?
Edit:
Here's an abstracted view of the problem. The problem occurs when trying to run sumOfSomethingSpecific(). In my actual problem, that function is inside a derived class Derived_B, which is designed to work with Derived_A, but for the sake of the problem, it makes no difference.
class Base_A
{
public:
Base_A();
~Base_A();
// I don't want virtual doSomethingSpecific() here.
};
class Derived_A
{
public:
using Base_A::Base_A;
double doSomethingSpecific();
};
// I could template this whole class
// template <typename T>
// where T replaces Base_A
class B
{
public:
// This can be initialized with:
// std::vector<Derived_A*>
// which is what I want to do, but we lose info about doSomethingSpecific()
// even if I write a separate constructor its still stored as
// std::vector<Base_A*>
B(std::vector<Base_A*> v) : v(v) {};
~B();
double sumOfSomethingSpecific()
{
double sum = 0;
for(auto&& A : v) {
// Can't do this, A is a pointer of type Base_A*, but this is the abstraction that I want to achieve
sum += A->doSomethingSpecific();
// Could do this, but its ugly and error-prone
Derived_A* tempA = (Derived_A*)A;
sum += tempA->doSomethingSpecific();
}
return sum;
}
protected:
std::vector<Base_A*> v;
};
First most of issues you're facing here are not about programming, are about design.
... class with additional data and functions required for the science, like Face::Interpolate(). I don't want to make these member functions virtual in the base class (Polygon). ...
Well, don't do that, but then you have to realize that you're adding complexity to the code you need to implement such design desicion.
However, if every polygon can be "interpolated" then you should have a virtual function (or better yet a pure virtual function) in your Polygon class.
Said that, with the code as it is, in order to add transparency to the API you declare you get_* functions as:
void GetFaces(std::vector<Face *> &faces);
that way is clear for the user that he/she has to provide a reference to a vector of faces to get the result. Lets see how this change your code:
// Face * temp_face = (Face*)cell->GetFaces()[0]; // Could use static_cast
std::vector<Face *> temp_faces;
cell->GetFaces(temp_faces);
//temp_face->Interpolate();
temp_faces[0]->Interpolate();
This way the down-cast is performed implicitly.
About your question: Is there a a better way? Yes, redesign your classes.
About your example:
I will ask you to think a moment about this:
struct Base {};
struct Derived_A: Base { double doSomethingSpecific(); };
struct Derived_B: Base { double doSomethingSpecific(); };
int main()
{
std::vector<Base*> base_v = {/*suppose initialization here*/};
base_v[0]->doSomethingSpecific(); // Which function must be called here?
// Derived_A::doSomethingSpecific or
// Derived_B::doSomethingSpecific.
}
At some point you will have to tell wich type you want call the function on.
The level of abstraction you want, does not exists in C++. The compiler needs to know the type of an object in order to perform (compile) a call to one of its member functions.
Another approach you can try (I still recommend to redesign):
If you have the need of manipulating several distinct types in a uniform manner. Perhaps you want to take a look at Boot.Variant library.
I struggled with a similar problem in one of my projects. The solution I used was to give ownership of the actual objects to the most-derived class, give the base class a copy of the objects, and use a virtual function to keep the copy up-to-date as objects are added/removed:
class Polyhedron {
protected:
bool _polygons_valid = false;
std::vector<Polygon*> _polygons;
virtual void RebuildPolygons() = 0;
public:
std::vector<Polygon*>& GetPolygons()
{
if (!_polygons_valid) {
RebuildPolygons();
_polygons_valid = true;
}
return _polygons;
}
/*Call 'GetPolygons()' whenever you need access to the list of polygons in base class*/
};
class Cell: public Polyhedron {
private:
std::vector<Face*> _faces; //Remember to set _polygons_valid = false when modifying the _faces vector.
public:
Cell(std::initializer_list<Face*> faces):
_faces(faces) {}
//Reimplement RebuildPolygons()
void RebuildPolygons() override
{
_polygons.clear();
for (Face* face : _faces)
_polygons.push_back(face);
}
};
This design has the benefits of clear ownership (most-derived class is owner), and that copying and upcasting the vector of object pointers is done only when needed. The downside is that you have two copies of essentially the same thing; a vector of pointers to objects. The design is very flexible too, since any class derived from Polyhedron only has to implement the RebuildPolygons() function, using a vector of any type derived from Polygon.

C++ class design: Covariance

The Problem
I want to implement a number of algorithms that work on a graph and return scores for node-pairs indicating whether those nodes are similar. The algorithms should work on a single node-pair and on all possible node-pairs. In the latter case a collection/matrix should be returned.
My Approach
The algorithms derive from
class SimilarityAlgorithm {
public:
Base(const Graph& G);
virtual double run(node u, node v) = 0; // indices for nodes in the graph
virtual ScoreCollection& runAll() = 0;
}
Now the algorithms differ in memory usage. Some algorithms might be symmetric and the scores for (u, v) and (v, u) are identical. This requires different ScoreCollection-types that should be returned. An example would be a sparse-matrix and a triangular matrix that both derive from ScoreCollection.
This would boil down to covariant return types:
class SpecificAlgorithm : SimilarityAlgorithm {
public:
double run(node u, node v);
// The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
SymmetricScoreCollection& runAll();
}
Question
Is this design approach a good idea for this problem?
Should the fact that the collections are all implemented as matrices be exposed?
Your design seems appropriate for the problem you describe.
Problem:
However, there is a problem with your SpecificAlgorithm : runAll() doesn't return the same type as the virtual function of the base class. So it won't be called (or more probably, your code won't compile because of a missing virtual function).
Solution:
Use also a polymorphic approach for the ScoreCollection, by making SymmetricScoreCollection a derived class of ScoreCollection :
class SymetricScoreCollection: public ScoreCollection {
//define the member functions to access the values virtual
...
};
class SpecificAlgorithm : public SimilarityAlgorithm {
public:
double run(node u, node v);
// The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
ScoreCollection& runAll();
};
In fact it's an application of the factory method pattern, with the following roles:
SimilarityAlgorithm is the factory,
SpecificAlgorithm is the concrete factory
ScoreCollection is the product
SymetricScoreCollection is the concrete product
Additional remark:
Returning a reference to ScoreCollection from runAll() brings in some risks. Suppose sa is a specific algorithm.
In the following statement :
ScoreCollection sc = sa.runAll();
sa.runAll() returns a reference to a SymetricScoreCollection, but it would copy the referred object to sc, making it a ScoreCollection. Slicing occurs, and polymorphism will fail to work.
The following statement would however succeed:
ScoreCollection& rsc = sa.runAll();
because rsc is a reference and it would still refer to the original SymetricScoreCollection object returned by sa.runAll(), and everything would work as designed.
You see that it's very easy to have unnoticed mistakes when returning references. I'd suggest to return a pointer instead of a reference.

Comparing types between derived classes

I am making the engine for a game and I can't seem to solve the following problem.
So, I have a base component class from which all the different components are derived. A GameObject is basically a container for different components. The components are stored in a vector containing pointers to the base component class. Now I need the GameObject class to have a getComponent member function template that will return the component with the requested type from the vector.
To be more clear:
class Component
{
/..../
};
class RigidBody : Component
{
/..../
};
class Animation : Component
{
/..../
};
class GameObject
{
public:
template <class T>
T* getComponent();
void addComponent(Component*);
private:
std::vector<Component*> m_components;
};
/...../
GameObject test;
test.AddComponent(new RigidBody());
test.AddComponent(new Animation());
Animation * animation = test.getComponent<Animation>();
Or something among those lines.
For simplicity's sake say that the vector is guaranteed to have the component that we are looking for and that there are no components of the same type.
Since the pointers in the vector are of the base component type, how can I check if they originally were of the requested type? Thanks in advance!
Assuming that Component has at least one virtual function (otherwise what's the point of inheriting from it, right?) you should be able to do what you need using Runtime Type Information (RTTI) and dynamic_cast, like this:
template <class T> T* getFirstComponent() {
for (int i = 0 ; i != m_components.size() ; i++) {
T *candidate = dynamic_cast<T*>(m_components[i]);
if (candidate) {
return candidate;
}
}
return nullptr;
}
Recall that dynamic_cast<T*> would return a non-null value only when the cast has been successful. The code above goes through all pointers, and picks the first one for which dynamic_cast<T*> succeeds.
Important note: While this should do the trick at making your program do what you want, consider changing your design: rather than pulling out objects by type, give them virtual functions that would let you use them all in a uniform way. It is pointless to put objects of different classes into one container, only to pull them apart at some later time. RTTI should be used as the last resort, not as a mainstream tool, because it makes your program harder to understand.
Another valid approach would be to store the individual components separately, not in a single vector, and get the vector only when you need to treat the objects uniformly.
Less important note: if nullptr does not compile on your system, replace with return 0.
There are occasions where a system would want to group derived types from a base class vector, for example, the optimisation of multithreading.
One system I cooked up uses polymorphism to create a user defined type to avoid typeid or derived_class, here is some pseudo code...
class BaseType {
public:
virtual int getType() = 0;
}
class ThisType : public BaseType {
public:
int getType() {return 1;};
}
class TypeMaster {
private:
std::vector<ThisType*> myObjects;
public:
void add(ThisType* bc){ myObjects.push_back(bc); };
}
std::map<int,TypeMaster*> masters;
std::vector<BaseType*> objects;
for(int i=0;i<objects.size();i++){
masters.find(objects[i].getType())->second.add(objects[i]);
}
You would have to do a bit of work to make a system but the rudements are there to convey the idea. This code processes an arbitary vector of base objects and appends them to the vector of its type master.
My example has a collection of execution pools with multiple instances of the type master meaning the type master cannot be polymorphed because in that scenario the object would not be able to move around execution pools.
Note the lack of use of typeid or derived class. For me, implementations using native types keeps it simple without importing bloating libraries or any unnecessary execution fuss. You could perform speed trials but I have always found simple native type implementations to be quite succinct.

How to implement the factory method pattern in C++ correctly

There's this one thing in C++ which has been making me feel uncomfortable for quite a long time, because I honestly don't know how to do it, even though it sounds simple:
How do I implement Factory Method in C++ correctly?
Goal: to make it possible to allow the client to instantiate some object using factory methods instead of the object's constructors, without unacceptable consequences and a performance hit.
By "Factory method pattern", I mean both static factory methods inside an object or methods defined in another class, or global functions. Just generally "the concept of redirecting the normal way of instantiation of class X to anywhere else than the constructor".
Let me skim through some possible answers which I have thought of.
0) Don't make factories, make constructors.
This sounds nice (and indeed often the best solution), but is not a general remedy. First of all, there are cases when object construction is a task complex enough to justify its extraction to another class. But even putting that fact aside, even for simple objects using just constructors often won't do.
The simplest example I know is a 2-D Vector class. So simple, yet tricky. I want to be able to construct it both from both Cartesian and polar coordinates. Obviously, I cannot do:
struct Vec2 {
Vec2(float x, float y);
Vec2(float angle, float magnitude); // not a valid overload!
// ...
};
My natural way of thinking is then:
struct Vec2 {
static Vec2 fromLinear(float x, float y);
static Vec2 fromPolar(float angle, float magnitude);
// ...
};
Which, instead of constructors, leads me to usage of static factory methods... which essentially means that I'm implementing the factory pattern, in some way ("the class becomes its own factory"). This looks nice (and would suit this particular case), but fails in some cases, which I'm going to describe in point 2. Do read on.
another case: trying to overload by two opaque typedefs of some API (such as GUIDs of unrelated domains, or a GUID and a bitfield), types semantically totally different (so - in theory - valid overloads) but which actually turn out to be the same thing - like unsigned ints or void pointers.
1) The Java Way
Java has it simple, as we only have dynamic-allocated objects. Making a factory is as trivial as:
class FooFactory {
public Foo createFooInSomeWay() {
// can be a static method as well,
// if we don't need the factory to provide its own object semantics
// and just serve as a group of methods
return new Foo(some, args);
}
}
In C++, this translates to:
class FooFactory {
public:
Foo* createFooInSomeWay() {
return new Foo(some, args);
}
};
Cool? Often, indeed. But then- this forces the user to only use dynamic allocation. Static allocation is what makes C++ complex, but is also what often makes it powerful. Also, I believe that there exist some targets (keyword: embedded) which don't allow for dynamic allocation. And that doesn't imply that the users of those platforms like to write clean OOP.
Anyway, philosophy aside: In the general case, I don't want to force the users of the factory to be restrained to dynamic allocation.
2) Return-by-value
OK, so we know that 1) is cool when we want dynamic allocation. Why won't we add static allocation on top of that?
class FooFactory {
public:
Foo* createFooInSomeWay() {
return new Foo(some, args);
}
Foo createFooInSomeWay() {
return Foo(some, args);
}
};
What? We can't overload by the return type? Oh, of course we can't. So let's change the method names to reflect that. And yes, I've written the invalid code example above just to stress how much I dislike the need to change the method name, for example because we cannot implement a language-agnostic factory design properly now, since we have to change names - and every user of this code will need to remember that difference of the implementation from the specification.
class FooFactory {
public:
Foo* createDynamicFooInSomeWay() {
return new Foo(some, args);
}
Foo createFooObjectInSomeWay() {
return Foo(some, args);
}
};
OK... there we have it. It's ugly, as we need to change the method name. It's imperfect, since we need to write the same code twice. But once done, it works. Right?
Well, usually. But sometimes it does not. When creating Foo, we actually depend on the compiler to do the return value optimisation for us, because the C++ standard is benevolent enough for the compiler vendors not to specify when will the object created in-place and when will it be copied when returning a temporary object by value in C++. So if Foo is expensive to copy, this approach is risky.
And what if Foo is not copiable at all? Well, doh. (Note that in C++17 with guaranteed copy elision, not-being-copiable is no problem anymore for the code above)
Conclusion: Making a factory by returning an object is indeed a solution for some cases (such as the 2-D vector previously mentioned), but still not a general replacement for constructors.
3) Two-phase construction
Another thing that someone would probably come up with is separating the issue of object allocation and its initialisation. This usually results in code like this:
class Foo {
public:
Foo() {
// empty or almost empty
}
// ...
};
class FooFactory {
public:
void createFooInSomeWay(Foo& foo, some, args);
};
void clientCode() {
Foo staticFoo;
auto_ptr<Foo> dynamicFoo = new Foo();
FooFactory factory;
factory.createFooInSomeWay(&staticFoo);
factory.createFooInSomeWay(&dynamicFoo.get());
// ...
}
One may think it works like a charm. The only price we pay for in our code...
Since I've written all of this and left this as the last, I must dislike it too. :) Why?
First of all... I sincerely dislike the concept of two-phase construction and I feel guilty when I use it. If I design my objects with the assertion that "if it exists, it is in valid state", I feel that my code is safer and less error-prone. I like it that way.
Having to drop that convention AND changing the design of my object just for the purpose of making factory of it is.. well, unwieldy.
I know that the above won't convince many people, so let's me give some more solid arguments. Using two-phase construction, you cannot:
initialise const or reference member variables,
pass arguments to base class constructors and member object constructors.
And probably there could be some more drawbacks which I can't think of right now, and I don't even feel particularly obliged to since the above bullet points convince me already.
So: not even close to a good general solution for implementing a factory.
Conclusions:
We want to have a way of object instantiation which would:
allow for uniform instantiation regardless of allocation,
give different, meaningful names to construction methods (thus not relying on by-argument overloading),
not introduce a significant performance hit and, preferably, a significant code bloat hit, especially at client side,
be general, as in: possible to be introduced for any class.
I believe I have proven that the ways I have mentioned don't fulfil those requirements.
Any hints? Please provide me with a solution, I don't want to think that this language won't allow me to properly implement such a trivial concept.
First of all, there are cases when
object construction is a task complex
enough to justify its extraction to
another class.
I believe this point is incorrect. The complexity doesn't really matter. The relevance is what does. If an object can be constructed in one step (not like in the builder pattern), the constructor is the right place to do it. If you really need another class to perform the job, then it should be a helper class that is used from the constructor anyway.
Vec2(float x, float y);
Vec2(float angle, float magnitude); // not a valid overload!
There is an easy workaround for this:
struct Cartesian {
inline Cartesian(float x, float y): x(x), y(y) {}
float x, y;
};
struct Polar {
inline Polar(float angle, float magnitude): angle(angle), magnitude(magnitude) {}
float angle, magnitude;
};
Vec2(const Cartesian &cartesian);
Vec2(const Polar &polar);
The only disadvantage is that it looks a bit verbose:
Vec2 v2(Vec2::Cartesian(3.0f, 4.0f));
But the good thing is that you can immediately see what coordinate type you're using, and at the same time you don't have to worry about copying. If you want copying, and it's expensive (as proven by profiling, of course), you may wish to use something like Qt's shared classes to avoid copying overhead.
As for the allocation type, the main reason to use the factory pattern is usually polymorphism. Constructors can't be virtual, and even if they could, it wouldn't make much sense. When using static or stack allocation, you can't create objects in a polymorphic way because the compiler needs to know the exact size. So it works only with pointers and references. And returning a reference from a factory doesn't work too, because while an object technically can be deleted by reference, it could be rather confusing and bug-prone, see Is the practice of returning a C++ reference variable, evil? for example. So pointers are the only thing that's left, and that includes smart pointers too. In other words, factories are most useful when used with dynamic allocation, so you can do things like this:
class Abstract {
public:
virtual void do() = 0;
};
class Factory {
public:
Abstract *create();
};
Factory f;
Abstract *a = f.create();
a->do();
In other cases, factories just help to solve minor problems like those with overloads you have mentioned. It would be nice if it was possible to use them in a uniform way, but it doesn't hurt much that it is probably impossible.
Simple Factory Example:
// Factory returns object and ownership
// Caller responsible for deletion.
#include <memory>
class FactoryReleaseOwnership{
public:
std::unique_ptr<Foo> createFooInSomeWay(){
return std::unique_ptr<Foo>(new Foo(some, args));
}
};
// Factory retains object ownership
// Thus returning a reference.
#include <boost/ptr_container/ptr_vector.hpp>
class FactoryRetainOwnership{
boost::ptr_vector<Foo> myFoo;
public:
Foo& createFooInSomeWay(){
// Must take care that factory last longer than all references.
// Could make myFoo static so it last as long as the application.
myFoo.push_back(new Foo(some, args));
return myFoo.back();
}
};
Have you thought about not using a factory at all, and instead making nice use of the type system? I can think of two different approaches which do this sort of thing:
Option 1:
struct linear {
linear(float x, float y) : x_(x), y_(y){}
float x_;
float y_;
};
struct polar {
polar(float angle, float magnitude) : angle_(angle), magnitude_(magnitude) {}
float angle_;
float magnitude_;
};
struct Vec2 {
explicit Vec2(const linear &l) { /* ... */ }
explicit Vec2(const polar &p) { /* ... */ }
};
Which lets you write things like:
Vec2 v(linear(1.0, 2.0));
Option 2:
you can use "tags" like the STL does with iterators and such. For example:
struct linear_coord_tag linear_coord {}; // declare type and a global
struct polar_coord_tag polar_coord {};
struct Vec2 {
Vec2(float x, float y, const linear_coord_tag &) { /* ... */ }
Vec2(float angle, float magnitude, const polar_coord_tag &) { /* ... */ }
};
This second approach lets you write code which looks like this:
Vec2 v(1.0, 2.0, linear_coord);
which is also nice and expressive while allowing you to have unique prototypes for each constructor.
You can read a very good solution in: http://www.codeproject.com/Articles/363338/Factory-Pattern-in-Cplusplus
The best solution is on the "comments and discussions", see the "No need for static Create methods".
From this idea, I've done a factory. Note that I'm using Qt, but you can change QMap and QString for std equivalents.
#ifndef FACTORY_H
#define FACTORY_H
#include <QMap>
#include <QString>
template <typename T>
class Factory
{
public:
template <typename TDerived>
void registerType(QString name)
{
static_assert(std::is_base_of<T, TDerived>::value, "Factory::registerType doesn't accept this type because doesn't derive from base class");
_createFuncs[name] = &createFunc<TDerived>;
}
T* create(QString name) {
typename QMap<QString,PCreateFunc>::const_iterator it = _createFuncs.find(name);
if (it != _createFuncs.end()) {
return it.value()();
}
return nullptr;
}
private:
template <typename TDerived>
static T* createFunc()
{
return new TDerived();
}
typedef T* (*PCreateFunc)();
QMap<QString,PCreateFunc> _createFuncs;
};
#endif // FACTORY_H
Sample usage:
Factory<BaseClass> f;
f.registerType<Descendant1>("Descendant1");
f.registerType<Descendant2>("Descendant2");
Descendant1* d1 = static_cast<Descendant1*>(f.create("Descendant1"));
Descendant2* d2 = static_cast<Descendant2*>(f.create("Descendant2"));
BaseClass *b1 = f.create("Descendant1");
BaseClass *b2 = f.create("Descendant2");
I mostly agree with the accepted answer, but there is a C++11 option that has not been covered in existing answers:
Return factory method results by value, and
Provide a cheap move constructor.
Example:
struct sandwich {
// Factory methods.
static sandwich ham();
static sandwich spam();
// Move constructor.
sandwich(sandwich &&);
// etc.
};
Then you can construct objects on the stack:
sandwich mine{sandwich::ham()};
As subobjects of other things:
auto lunch = std::make_pair(sandwich::spam(), apple{});
Or dynamically allocated:
auto ptr = std::make_shared<sandwich>(sandwich::ham());
When might I use this?
If, on a public constructor, it is not possible to give meaningful initialisers for all class members without some preliminary calculation, then I might convert that constructor to a static method. The static method performs the preliminary calculations, then returns a value result via a private constructor which just does a member-wise initialisation.
I say 'might' because it depends on which approach gives the clearest code without being unnecessarily inefficient.
Loki has both a Factory Method and an Abstract Factory. Both are documented (extensively) in Modern C++ Design, by Andei Alexandrescu. The factory method is probably closer to what you seem to be after, though it's still a bit different (at least if memory serves, it requires you to register a type before the factory can create objects of that type).
I don't try to answer all of my questions, as I believe it is too broad. Just a couple of notes:
there are cases when object construction is a task complex enough to justify its extraction to another class.
That class is in fact a Builder, rather than a Factory.
In the general case, I don't want to force the users of the factory to be restrained to dynamic allocation.
Then you could have your factory encapsulate it in a smart pointer. I believe this way you can have your cake and eat it too.
This also eliminates the issues related to return-by-value.
Conclusion: Making a factory by returning an object is indeed a solution for some cases (such as the 2-D vector previously mentioned), but still not a general replacement for constructors.
Indeed. All design patterns have their (language specific) constraints and drawbacks. It is recommended to use them only when they help you solve your problem, not for their own sake.
If you are after the "perfect" factory implementation, well, good luck.
This is my c++11 style solution. parameter 'base' is for base class of all sub-classes. creators, are std::function objects to create sub-class instances, might be a binding to your sub-class' static member function 'create(some args)'. This maybe not perfect but works for me. And it is kinda 'general' solution.
template <class base, class... params> class factory {
public:
factory() {}
factory(const factory &) = delete;
factory &operator=(const factory &) = delete;
auto create(const std::string name, params... args) {
auto key = your_hash_func(name.c_str(), name.size());
return std::move(create(key, args...));
}
auto create(key_t key, params... args) {
std::unique_ptr<base> obj{creators_[key](args...)};
return obj;
}
void register_creator(const std::string name,
std::function<base *(params...)> &&creator) {
auto key = your_hash_func(name.c_str(), name.size());
creators_[key] = std::move(creator);
}
protected:
std::unordered_map<key_t, std::function<base *(params...)>> creators_;
};
An example on usage.
class base {
public:
base(int val) : val_(val) {}
virtual ~base() { std::cout << "base destroyed\n"; }
protected:
int val_ = 0;
};
class foo : public base {
public:
foo(int val) : base(val) { std::cout << "foo " << val << " \n"; }
static foo *create(int val) { return new foo(val); }
virtual ~foo() { std::cout << "foo destroyed\n"; }
};
class bar : public base {
public:
bar(int val) : base(val) { std::cout << "bar " << val << "\n"; }
static bar *create(int val) { return new bar(val); }
virtual ~bar() { std::cout << "bar destroyed\n"; }
};
int main() {
common::factory<base, int> factory;
auto foo_creator = std::bind(&foo::create, std::placeholders::_1);
auto bar_creator = std::bind(&bar::create, std::placeholders::_1);
factory.register_creator("foo", foo_creator);
factory.register_creator("bar", bar_creator);
{
auto foo_obj = std::move(factory.create("foo", 80));
foo_obj.reset();
}
{
auto bar_obj = std::move(factory.create("bar", 90));
bar_obj.reset();
}
}
Factory Pattern
class Point
{
public:
static Point Cartesian(double x, double y);
private:
};
And if you compiler does not support Return Value Optimization, ditch it, it probably does not contain much optimization at all...
extern std::pair<std::string_view, Base*(*)()> const factories[2];
decltype(factories) factories{
{"blah", []() -> Base*{return new Blah;}},
{"foo", []() -> Base*{return new Foo;}}
};
I know this question has been answered 3 years ago, but this may be what your were looking for.
Google has released a couple of weeks ago a library allowing easy and flexible dynamic object allocations. Here it is: http://google-opensource.blogspot.fr/2014/01/introducing-infact-library.html

Best Practice For List of Polymorphic Objects in C++

What is a common practice for the storage of a list of base class pointers each of which can describe a polymorphic derived class?
To elaborate and in the interest of a simple example lets assume that I have a set of classes with the following goals:
An abstract base class whose purpose is to enforce a common functionality on its derived classes.
A set of derived classes which: can perform a common functionality, are inherently copyable (this is important), and are serializable.
Now alongside this required functionality I want to address the following key points:
I want the use of this system to be safe; I don't want a user to have undefined errors when he/she erroneously casts a base class pointer to the wrong derived type.
Additionally I want as much as possible the work for copying/serializing this list to be taken care of automatically. The reason for this is, as a new derived type is added I don't want to have to search through many source files and make sure everything will be compatible.
The following code demonstrates a simple case of this, and my proposed (again I am looking for a common well thought out method of doing this, mine may not be so good) solution.
class Shape {
public:
virtual void draw() const = 0;
virtual void serialize();
protected:
int shapeType;
};
class Square : public Shape
{
public:
void draw const; // draw code here.
void serialize(); // serialization here.
private:
// square member variables.
};
class Circle : public Shape
{
public:
void draw const; // draw code here.
void serialize(); // serialization here.
private:
// circle member variables.
};
// The proposed solution: rather than store list<shape*>, store a generic shape type which
// takes care of copying, saving, loading and throws errors when erroneous casting is done.
class GenericShape
{
public:
GenericShape( const Square& shape );
GenericShape( const Circle& shape );
~GenericShape();
operator const Square& (); // Throw error here if a circle tries to get a square!
operator const Circle& (); // Throw error here if a square tries to get a circle!
private:
Shape* copyShape( const Shape* otherShape );
Shape* m_pShape; // The internally stored pointer to a base type.
};
The above code is certainly missing some items, firstly the base class would have a single constructor requiring the type, the derived classes would internally call this during their construction. Additionally in the GenericShape class, copy/assignment constructor/operator would be present.
Sorry for the long post, trying to explain my intents fully. On that note, and to re-iterate: above is my solution, but this likely has some serious flaws and I would be happy to hear about them, and the other solutions out there!
Thank you
What is the problem of a std::list< shape* > (or a std::list< boost::shared_ptr > thereof)?
That would be the idiomatic way of implementing a list of shapes with polymorphic behavior.
I want the use of this system to be safe; I don't want a user to have undefined errors when he/she erroneously casts a base class pointer to the wrong derived type.
Users should not downcast, but rather use the polymorphism and the base (shape) operations provided. Consider why they would be interested in downcasting, if you find a reason to do so, go back to drawing board and redesign so that your base provides all needed operations.
Then if the user wants to downcast, they should use dynamic_cast, and they will get the same behavior you are trying to provide in your wrapper (either a null pointer if downcasting pointers or a std::bad_cast exception for reference downcasting).
Your solution adds a level of indirection and (with the provided interface) require the user to try guessing the type of shape before use. You offer two conversion operators to each of the derived classes, but the user must call them before trying to use the methods (that are no longer polymorphic).
Additionally I want as much as possible the work for copying/serializing this list to be taken care of automatically. The reason for this is, as a new derived type is added I don't want to have to search through many source files and make sure everything will be compatible.
Without dealing with deserialization (I will come back later), your solution, as compared to storing (smart) pointers in the list, requires revisiting the adapter to add new code for each and every other class that is added to the hierarchy.
Now the deserialization problem.
The proposed solution is using a plain std::list< boost::shared_ptr >, once you have the list built, drawing and serialization can be performed right out of the box:
class shape
{
public:
virtual void draw() = 0;
virtual void serialize( std::ostream& s ) = 0;
};
typedef std::list< boost::shared_ptr<shape> > shape_list;
void drawall( shape_list const & l )
{
std::for_each( l.begin(), l.end(), boost::bind( &shape::draw, _1 ));
}
void serialize( std::ostream& s, shape_list const & l )
{
std::for_each( l.begin(), l.end(), boost::bind( &shape::serialize, _1, s ) );
}
Where I have used boost::bind to reduce code bloat instead of iterating manually. The problem is that you cannot virtualize construction as before the object has been constructed you cannot know what type it actually is. After the problem of deserializing one element of a known hierarchy is solved, deserializing the list is trivial.
Solutions to this problem are never as clean and simple as the code above.
I will assume that you have defined unique shape type values for all shapes, and that your serialization starts by printing out that id. That is, the first element of serialization is the type id.
const int CIRCLE = ...;
class circle : public shape
{
// ...
public:
static circle* deserialize( std::istream & );
};
shape* shape_deserialize( std::istream & input )
{
int type;
input >> type;
switch ( type ) {
case CIRCLE:
return circle::deserialize( input );
break;
//...
default:
// manage error: unrecognized type
};
}
You can further alleviate the need to work on the deserializer function if you convert it into an abstract factory where upon creation of a new class the class itself registers it's deserialization method.
typedef shape* (*deserialization_method)( std::istream& );
typedef std::map< int, deserialization_method > deserializer_map;
class shape_deserializator
{
public:
void register_deserializator( int shape_type, deserialization_method method );
shape* deserialize( std::istream& );
private:
deserializer_map deserializers_;
};
shape* shape_deserializator::deserialize( std::istream & input )
{
int shape_type;
input >> shape_type;
deserializer_map::const_iterator s = deserializers_.find( shape_type );
if ( s == deserializers_.end() ) {
// input error: don't know how to deserialize the class
}
return *(s->second)( input ); // call the deserializer method
}
In real life, I would have used boost::function<> instead of the function pointers, making the code cleaner and clearer, but adding yet another dependency to the example code. This solution requires that during initialization (or at least before trying to deserialize) all classes register their respective methods in the shape_deserializator object.
You could avoid lots of repetition in GenericShape by using templates (for the constructors and converters), but the key bit that's missing is having it inherit from Shape and implement its virtuals -- without it it's unusable, with it it's a pretty normal variant on envelope/implementation idioms.
You may want to use auto_ptr (or somewhat-smarter pointers) rather than a bare pointer to Shape, too;-).
I would propose boost::shared_pointer<Shape> in an STL container. Then use dynamic_cast to downcast guarantee type correctness. If you want to provide helper functions to toss exceptions instead of returning NULL, then follow Alex's suggestion and define a template helper function like:
template <typename T, typename U>
T* downcast_to(U *inPtr) {
T* outPtr = dynamic_cast<T*>(inPtr);
if (outPtr == NULL) {
throw std::bad_cast("inappropriate cast");
}
return outPtr;
}
and use it like:
void some_function(Shape *shp) {
Circle *circ = downcast_to<Circle>(shp);
// ...
}
Using a separate class like GenericShape is just too strongly coupled with every class that descends from Shape. I wonder if this would be considered a code smell or not...
I want the use of this system to be
safe; I don't want a user to have
undefined errors when he/she
erroneously casts a base class pointer
to the wrong derived type.
Why would you get undefined errors? The behavior of dynamic_cast is perfectly well-defined and catches the error if you cast a base class pointer to the wrong derived type. This really seems like reinventing the wheel.
Additionally I want as much as
possible the work for
copying/serializing this list to be
taken care of automatically. The
reason for this is, as a new derived
type is added I don't want to have to
search through many source files and
make sure everything will be
compatible.
I'm not sure what the problem is here. If all the derived classes are serializable and copyable, isn't that good enough? What more do you need?
I'm also not sure what to make of the first two requirements.
What do you mean, the ABC should "enforce a common functionality"? And what is the point in having derived classes, if their role is only to perform that same common functionality, be copyable and serializable?
Why not just make one non-abstract class serializable and copyable then?
I'm probably missing something vital here, but I don't really think you've explained what it is you're trying to achieve.