is it possible to return exemplar of object using passed type name (string) in c++?
I have some base abstract class Base and a few derivates. Example code:
class Base
{
/* ... */
};
class Der1 : public Base
{
/* ... */
};
class Der2 : public Base
{
/* ... */
};
And I need function like:
Base *objectByType(const std::string &name);
Number of derivates classes are changeable and I don't want to make something like switching of name and returning by hands new object type. Is it possible in c++ to do that automatically anyway?
p.s. usage should looks like:
dynamic_cast<Der1>(objectByType("Der1"));
I need pure c++ code (crossplatform). Using boost is permissible.
There is a nice trick which allows you to write a factory method without a sequence of if...else if....
(note that, AFAIK, it is indeed not possible to do what you want in C++ as this code is generated in the compile time. A "Factory Method" Design Pattern exists for this purpose)
First, you define a global repository for your derived classes. It can be in the form std::map<std::string, Base*>, i.e. maps a name of the derived class to an instance of that class.
For each derived class you define a default constructor which adds an object of that class to the repository under class's name. You also define a static instance of the class:
// file: der1.h
#include "repository.h"
class Der1: public Base {
public:
Der1() { repository[std::string("Der1")] = this; }
};
// file: der1.cpp
static Der1 der1Initializer;
Constructors of static variables are run even before main(), so when your main starts you already have the repository initialized with instances of all derived classes.
Your factory method (e.g. Base::getObject(const std::string&)) needs to search the repository map for the class name. It then uses the clone() method of the object it finds to get a new object of the same type. You of course need to implement clone for each subclass.
The advantage of this approach is that when you are adding a new derived class your additions are restricted only to the file(s) implementing the new class. The repository and the factory code will not change. You will still need to recompile your program, of course.
It's not possible to do this in C++.
One options is to write a factory and switch on the name passed in, but I see you don't want to do that. C++ doesn't provide any real runtime reflection support beyond dynamic_cast, so this type of problem is tough to solve.
Yes that is possible! Check this very funny class called Activator
You can create everything by Type and string and can even give a List of parameters, so the method will call the appropriate constructor with the best set of arguments.
Unless I misunderstood, the typeid keyword should be a part of what you are looking for.
It is not possible. You have to write the objectByType function yourself:
Base* objectByType(const std::string& name) {
if (name == "Der1")
return new Der1;
else if (name == "Der2")
return new Der2;
// other possible tests
throw std::invalid_argument("Unknown type name " + name);
}
C++ doesn't support reflection.
In my opinion this is the single point where Java beats C++.
(ope not to get too many down votes for this...)
You could achieve something like that by using a custom preprocessor, similar to how MOC does for Qt.
Related
i want to write a library for linear program solving. Thereby several solvers such as cplex or gurobi are used. What i already have is an interface for each of them (all containing the same functions wrapping them to solver specific code).
Now I want to have a class 'LinearProgram' which can be instantiated e.g. by LinearProgram("cplex") which then invokes the cplex solver.
My first idea was to use a super class 'solver' which is a base class of all solver interfaces containing the respective functions as virtual declarations. But then I get an abstract class which can not be instantiated.
So in LinearProgram i wanted to have a variable Solver which is instantiated depending on the string given in the constructor.
I'm sure a proper solution is quite obvious, but all I can think about in the moment is not satisfying.
Thanks for your help.
This illustrates what you describe:
class Solver {
...abstract base
};
class SolverFactory {
public:
Solver* NewSolverWithName(const std::string& pSolverName);
};
class LinearProgram {
public:
LinearProgram(const std::string& pSolverName) :
d_solver(SolverFactory::NewSolverWithName(pSolverName)) {
}
private:
some_auto_pointer<Solver> d_solver;
};
class cplex_Solver : public Solver {
...
static std::string Name();
};
Solver* SolverFactory::NewSolverWithName(const std::string& pSolverName) {
if (pSolverName == cplex_Solver::Name()) {
return new cplex_Solver();
}
...
}
This is a job for two different design patterns combined.
The first is the Envelope Letter pattern, and the second is the Strategy Pattern.
Keep on with the base class that you currently have and make a derived class that simply forwards the call to an embedded pointer to the base class. The derived class is now something you can freely pass around by value.
The base class could also contain a static member function that returns a pointer to the base class. This static member function would allow you to instantiate a derived class by using a string name to look it up. That provides a convenient way to select an algorithm at runtime.
But people who knew which derived class (which strategy) they wanted could just create one with 'new' and stuff it inside an instance of the envelope class.
You can optionally do away with the envelope class if you decide to just use a shared_ptr to the base class instead.
I have a class Manager and a class Base (with subclasses deriving from Base, say A : public Base). Inside Manager I create the right subclass of Base but then Base is oblivious to the existence of Manager. I wanted to pass into this created subclass of Base a function object bound to a member method of the Manager class for the A object to invoke. In other words during creation it would be something like this:
void Manager::createThing()
{
FunctionObject func;
if (doExtraWork)
func.bind(&Manager::someMethod, this);
Base *bla = new A(func);
}
Then inside of A, I would like to be able to detect whether we have extra work to have the Manager carry on us and do so, something like:
A::update()
{
if (func) //ideally detect if func was bound to someMethod or func is empty
func(this); //equivalent to the above instance of manager calling someMethod on this instance of A
//do regular stuff after;
}
How can I go about doing this (probably with boost function or something like that)?
If your FunctionObject type is boost::function<void()>, then you can assign to this from the result of boost::bind, something like this:
boost::function<void()> f = boost::bind(&Manager::someMethod, this);
Base *b = new A(f);
where the constructor of A has signature A(boost::function<void()>). Calling a boost::function has slightly more overhead than a virtual function call.
I don't know enough about your particular situation to know for sure, but you might end up with a better interface if you actually define an abstract base class representing the functionality of f, and have your constructor for Base and A take an object of the abstract base class instead, like this:-
struct ThingDoer
{
virtual void do() = 0;
};
class Manager : private ThingDoer
{
virtual void do()
{ ... }
void createThing()
{
Base *b = new A(this);
}
};
where the constructor of A has signature A(ThingDoer*).
If you've previously read about the 'delegate' design pattern, you know the kind of thing I mean. In this simple, abstract example, it just looks clunkier and longer than the solution using boost::function, but it does have potential advantages for real software:
It lets you give names to the 'delegate' type ThingDoer, your implementation of that type, and the function inside it. Also, if you use Doxygen or some other structured comment system, it's a lot easier to document the delegate class than a function object parameter.
It lets you choose in the Manager class and any derived classes whether to inherit from ThingDoer, or have a nested (private or protected) class that inherits ThingDoer.
If you want to add an extra function to the interface later (to make it do two different things), it's easier to do that, and you won't be tempted to simply add more and more function objects. (But it's only easier later because you've already paid the extra cost of writing your code this way.)
If you have programmers from the Java or C# communities, they'll probably be more familiar with code like this.
It may be that none of those are advantages in your situation, in which case, definitely use the boost::function / boost::bind solution. I've done the same in similar situations. I probably ought to mention too that C++11 has most or all of the function-binding functionality in std:: itself.
Last year I saw some source code (C++) where its author declares static function in base class, but leaves its definition to derived class. I remember there was constraint that only one derived class was permitted to define aforementioned static function.
I know that it is impossible to override static methods, but this trick is exactly what I need. I just can't make it work in my code :) Does anyone know about this feature?
Lets look why this would be useful. Suppose we have some base class (Shape), and its derived classes (Circle, Triangle...). Suppose Shape is part of my core architecture, and derived classes are treated as plugins. I don't want to change my core architecture in future. So we have:
class Shape
{
//other stuff here
static Shape* Factory();
}
class Circle:Shape
{
//other stuff here
static Shape* Factory();
}
Shape is sort of abstract class, and it will not implement Factory method. Method is implemented by one (and only one) of the derived classes. In implementation derived class will return new instance of itself, so it is just a factory method. This trick allowed its author to use this static method in client class in following way:
class Client
{
public Shape* shape;
public Client();
//other stuff here
}
In implementation of constructor he had something like:
Client::Client()
:shape(Shape::Factory())
{
}
This way he was able to instantiate "right" shape derivation without changing core classes in engine. When he wanted some other shape to be used in core classes he just had to define static Factory method in that derived class (and to remove the existing one in other derived class).
This way we have some sort of "static polymorphism". I can't find anything about this technique on the web. Does it even have a name? I am especially interested if something like this could be achieved in C# language? :)
Thanks in advance, and sorry for my bad English.
What it sounds like you are trying to do is a bit messy in my opinion. It feels like a combination of a Factory class, a Singleton and then trying to squish them all back into your result class hierarchy.
The simplest (not necessarily the best) solution I can think of is forget about having either Circle::Factory() or Shape::Factory() and just have a free function called get_default_shape().
class Shape
{
};
class Circle: public Shape
{
};
Shape * get_default_shape()
{
return new Circle;
}
Client::Client()
:shape(get_default_shape())
{
}
The nice bit about this is that its only the implementation of get_default_shape that needs to include Circle.h, all the definition needs is a forward declaration of the Shape class.
Hmm. I have not seen exactly what you describe. It could be that the piece of code you refer to defined the base class static function in the cpp file containing your derived class.
// definition of Circle class
.....
Shape* Shape::Factory()
{
return new Circle();
}
This is not useful in this example but it could be a useful trick if you want to hide the implementation of a class and only publish an abstract base class (to reduce compile time dependencies). It won't work if the base and derived classes are not in the same dll/exe.
Similar things can be achieved in C# by using an IOC framework, with generics, or by registring a factory delegate in your base class. I tend to prefer generics and delegates.
I'm experiencing a challenging problem, which has not been solvable - hopefully until now. I'm developing my own framework and therefore trying to offer the user flexibility with all the code complexity under the hood.
First of all I have an abstract base class which users can implement, obviously simplified:
class IStateTransit
{
public:
bool ConnectionPossible(void) = 0;
}
// A user defines their own class like so
class MyStateTransit : public IStateTransit
{
public:
bool ConnectionPossible(void){ return true; }
}
Next, I define a factory class. Users can register their own custom state transit objects and refer to them later by simply using a string identifier they have chosen:
class TransitFactory : public Singleton<TransitFactory>
{
public:
template<typename T> void RegisterStateTransit(const string& name)
{
// If the transit type is not already registered, add it.
if(transits.find(name) == transits.end())
{
transits.insert(pair<string, IStateTransit*>(name, new T()));
};
}
IStateTransit* TransitFactory::GetStateTransit(const string& type) const
{
return transits.find(type)->second;
};
private:
map<string, IStateTransit*> transits;
}
Now the problem is (probably obviously) that whenever a user requests a transit by calling GetStateTransit the system currently keeps returning the same object - a pointer to the same object that is. I want to change this.
PROBLEM: How can I return a new (clone) of the original IStateTransit object without the user having to define their own copy constructor or virtual constructor. Ideally I would somehow like the GetStateTransit method to be able to cast the IStateTransit object down to the derived type it is at runtime and return a clone of that instance. The biggest hurdle is that I do not want the user to have to implement any extra (and probably complex) methods.
4 hours of Googling and trying has led me nowhere. The one who has the answer is a hero!
The problem is that you don't have the type information to perform the clone as you only have a pointer to base class type and no knowledge as to what derived types have been implemented and are available.
I think there's a reason that 4 hours of googling haven't turned anything up. If you want IStateTransit to be cloneable you have to have an interface where the derived class implementer provides some sort of clone method implementation.
I'm sorry if this isn't what you wanted to hear.
However, implementing a clone method shouldn't be a big burden. Only the class implementor knows how a class can be copied, given a correct copy constructor, clone can be implemented for a leaf-node class like this:
Base* clone() const
{
return new MyType(*this);
}
You could even macro-alize it; although I wouldn't.
If I understand the problem correctly, you shouldn't insert new T -s into the map, but rather objects that create new T-s.
struct ICreateTransit
{
virtual ~ICreateTransit() {}
virtual IStateTransite* create() const = 0;
};
template <class T>
struct CreateTransit: public ICreateTransit
{
virtual IStateTransit* create() const { return new T(); }
};
And now insert:
transits.insert(pair<string, ICreateTransit*>(name, new CreateTransit<T>()));
And retrieve "copies" with:
return transits.find(type)->second->create(); //hopefully with error handling
It shouldn't be impossible to modify StateTransit<T> so it holds a T of which to make copies of, should the default one not do.
I think the general name for techniques like this is called "type erasure" (derived types "remember" particular types, although the base class is unaware of those).
This problem to me sounds that the abstract factory pattern might be of help. Using this pattern the libraries client can define how your framework builds its types. The client can inject his own subclass of the factory into the framework and define there what types should be build.
What you need is (additionaly)
A base class for the factory
As a client: Derive a concrete factory
A way to inject (as a client) a subtype of the factory into the framework
Call the factory metods to create new types.
Does this help you?
I have a c++ class derived from a base class in a framework.
The derived class doesn't have any data members because I need it to be freely convertible into a base class and back - the framework is responsible for loading and saving the objects and I can't change it. My derived class just has functions for accessing the data.
But there are a couple of places where I need to store some temporary local variables to speed up access to data in the base class.
mydata* MyClass::getData() {
if ( !m_mydata ) { // set to NULL in the constructor
m_mydata = some_long_and complex_operation_to_get_the_data_in_the_base()
}
return m_mydata;
}
The problem is if I just access the object by casting the base class pointer returned from the framework to MyClass* the ctor for MyClass is never called and m_mydata is junk.
Is there a way of only initializing the m_mydata pointer once?
It doesn't have members and you must maintain bit-for-bit memory layout compatibility… except it does and C++ doesn't have a concept of freely-convertible.
If the existing framework allocates the base objects, you really can't derive from it. In that case, I can think of two options:
Define your own class Cached which links to Base by reference. Make the reference public and/or duplicate Base's interface without inheritance.
Use a hash table, unordered_map< Base *, mydata > mydata_cache;. This seems most appropriate to me. Use free functions to look up cache data before delegating to the Base *.
You could initialize your private variables in a separate initialization member function, so something like this:
class MyClass {
public:
init() {
if (!m_mydata) {
m_mydata = f();
}
}
};
framework_class_t *fclass = framework.classfactory.makeclass();
MyClass *myclass = (MyClass*)fclass;
myclass->init();
char *mydata = myclass->getData();
It's hard to say if this is a good idea or not without knowing what framework you're using, or seeing your code. This is just the first thing that came to mind after reading your description.
You could create a wrapper for the factory of the framework. The wrapper would have the same interface, delegate calls to the framework but it could initialize the created base class instance before returning it. Of course, this requires you to change your code to use the wrapper everywhere, but if it is possible, after that you can be sure that the initialization happens properly.
A variation on this: use RAiI by wrapping the base class instances into a custom autopointer which could do the initialization in its constructor. Again, if you manage to change the code everywhere to use the new wrapper type instead of the derived class directly, you are safe.