Create object based on class name provided in text file? - c++

I'm wondering, is it possible in C++ to use a text value read in from a file to create an object of a class of that name eg.
contents of file: "MyClass"
code: read file
code: instantiate "MyClass" object.
I'd like to avoid a whole series of hardcoded if/then/elses if possible.
Sorry I'm not sure how to describe this problem in more technical terms!

As long as you don't mind some restrictions, this is fairly easy to do. The easiest way to do the job restricts you to classes that descend from one common base class. In this case, you can do something like this:
// warning: I've done this before, but none of this code is tested. The idea
// of the code works, but this probably has at least a few typos and such.
struct functor_base {
virtual bool operator()() = 0;
};
You'll then obviously need some concrete classes derived from that base:
struct eval_x : functor_base {
virtual bool operator()() { std::cout << "eval_x"; }
};
struct eval_y : functor_base {
virtual bool operator()() { std::cout << "eval_y"; }
};
Then we need some way to create an object of each type:
functor_base *create_eval_x() { return new eval_x; }
functor_base *create_eval_y() { return new eval_y; }
Finally, we need a map from the names to the factory functions:
// the second template parameter is:
// pointer to function returning `functor_base *` and taking no parameters.
std::map<std::string, functor_base *(*)()> name_mapper;
name_mapper["eval_x"] = create_eval_x;
name_mapper["eval_y"] = create_eval_y;
That (finally!) gives us enough so we can map from a name to a function object:
char *name = "eval_x";
// the map holds pointers to functions, so we need to invoke what it returns
// to get a pointer to a functor:
functor_base *b = name_mapper.find(name)();
// now we can execute the functor:
(*b)();
// since the object was created dynamically, we need to delete it when we're done:
delete b;
There are, of course, many variations on the general theme. For example, instead of factory functions that create objects dynamically, you can create an instance of each object statically, and just put the address of the static object in the map.

you can use abstract factory to do this. Limitations are the classes need to implement a base class and you need to register the factory class with the abstract factory.
class AbstractFactory;
class Factory;
class Object;
// base marker class for all the classes that need this instantiation strategy
class Object{}
class Factory
{
public:
//override this in concrete factories
virtual Object* create() = 0;
};
// helper macro to declare an inner class that's a default factory
#define DECL_DEFAULT_FACTORY(ObjectClass) class Factory : public Factory \
{\
public:\
Factory(){}\
virtual ~Factory(){}\
Object* create(){ return new ObjectClass(); } \
}
// this can be made a singleton
class AbstractFactory
{
public:
void registerClass(const String& clsName, Factory* factory){ //put this in a std::map }
void deregisterClass(const String& className){ //remove factory from map and delete the ptr }
Object* create(const String& className)
{
Factory* factory = factories[className];
if(factory){ return factory->create(); }
else{ return 0; }
}
};
so it shall be used like:
class SampleClass : public Object
{
//impl goes here
DECL_DEFAULT_FACTORY(SampleClass);
}
and somewhere else you need to do
abstractFactoryInstance->registerClass("SampleClass",new SampleClass::Factory());
then your AbstractFactory is ready to do
SampleClass* obj = (SampleClass*)(abstractFactoryInstance->create("SampleClass"));
you can further refine the scheme by declaring template classes for Factory

Most C++ frameworks (e.g., MFC, Boost) support some kind of object serialization, though it doesn't generally take the form of a human-readable text file. In C++, all of the class types whose instances are recorded in a file have to be present (i.e., compiled and linked into) a program in order for that program to either write or read (and create objects from) such a file.

With Compiled languages like C++, you won't be able to do so.
Such things are only possible with interpreted languages, such as PHP.

What you need is boost serializarion. This will allow you to persist your objects in a file. You can find an example here.

Related

What is the purpose of having such complicated C++ class design?

I came across an open source C++ code and I got curious, why do people design the classes this way?
So first things first, here is the Abstract class:
class BaseMapServer
{
public:
virtual ~BaseMapServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name) = 0;
virtual void LoadMapFromFile(const std::string &map_name) = 0;
virtual void PublishMap() = 0;
virtual void SetMap() = 0;
virtual void ConnectROS() = 0;
};
Nothing special here and having an abstract class can have several well understood reasons. So from this point, I thought maybe author wanted to share common features among other classes. So here is the next class, which is a seperate class but actually holds a pointer of type abstract class mentioned above (actual cpp file, other two classes are header files) :
class MapFactory
{
BaseMapServer *CreateMap(
const std::string &map_type,
rclcpp::Node::SharedPtr node, const std::string &file_name)
{
if (map_type == "occupancy") return new OccGridServer(node, file_name);
else
{
RCLCPP_ERROR(node->get_logger(), "map_factory.cpp 15: Cannot load map %s of type %s", file_name.c_str(), map_type.c_str());
throw std::runtime_error("Map type not supported")
}
}
};
And now the interesting thing comes, here is the child class of the abstract class:
class OccGridServer : public BaseMapServer
{
public:
explicit OccGridServer(rclcpp::Node::SharedPtr node) : node_(node) {}
OccGridServer(rclcpp::Node::SharedPtr node, std::string file_name);
OccGridServer(){}
~OccGridServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name);
virtual void LoadMapFromFile(const std::string &map_name);
virtual void PublishMap();
virtual void SetMap();
virtual void ConnectROS();
protected:
enum MapMode { TRINARY, SCALE, RAW };
// Info got from the YAML file
double origin_[3];
int negate_;
double occ_th_;
double free_th_;
double res_;
MapMode mode_ = TRINARY;
std::string frame_id_ = "map";
std::string map_name_;
// In order to do ROS2 stuff like creating a service we need a node:
rclcpp::Node::SharedPtr node_;
// A service to provide the occupancy grid map and the message with response:
rclcpp::Service<nav_msgs::srv::GetMap>::SharedPtr occ_service_;
nav_msgs::msg::OccupancyGrid map_msg_;
// Publish map periodically for the ROS1 via bridge:
rclcpp::TimerBase::SharedPtr timer_;
};
So what is the purpose of the MapFactory class?
To be more specific - what is the advantage of creating a class which holds a pointer of type Abstract class BaseMapServer which is a constructor (I believe) and this weird constructor creates a memory for the new object called OccGridServer and returns it? I got so confused by only writing this. I really want to become a better C++ coder and I am desperate to know the secret behind these code designs.
The MapFactory class is used to create the correct subclass instance of BaseMapServer based on the parameters passed to it.
In this particular case there is only one child class instance, but perhaps there are plans to add more. Then when more are added the factory method can look something like this:
BaseMapServer *CreateMap(
const std::string &map_type,
rclcpp::Node::SharedPtr node, const std::string &file_name)
{
if (map_type == "occupancy") return new OccGridServer(node, file_name);
// create Type2Server
else if (map_type == "type2") return new Type2Server(node, file_name);
// create Type3Server
else if (map_type == "type3") return new Type3Server(node, file_name);
else
{
RCLCPP_ERROR(node->get_logger(),
"map_factory.cpp 15: Cannot load map %s of type %s",
file_name.c_str(), map_type.c_str());
throw std::runtime_error("Map type not supported")
}
}
This has the advantage that the caller doesn't need to know the exact subclass being used, and in fact the underlying subclass could potentially change or even be replaced under the hood without the calling code needing to be modified. The factory method internalizes this logic for you.
Its a Factory pattern. See https://en.wikipedia.org/wiki/Factory_method_pattern. It looks like the current code only supports one implementation (OccGridServer), but more could be added at a future date. Conversely, if there's only ever likely to be one concrete implementation, then it's overdesign.
This is example of the factory design pattern. The use case is this: there are several types of very similar classes that will be used in code. In this case, OccGridServer is the only one actually shown, but a generic explanation might reference hypothetical Dog, Cat, Otter, etc. classes. Because of their similarity, some polymorphism is desired: if they all inherit from a base class Animal they can share virtual class methods like ::genus, ::species, etc., and the derived classes can be pointed to or referred to with base class pointers/references. In your case, OccGridServer inherits from BaseMapServer; presumably there are other derived classes as well, and pointers/references.
If you know which derived class is needed at compile time, you would normally just call its constructor. The point of the factory design pattern is to simplify selection of a derived class when the particular derived class is not known until runtime. Imagine that a user picks their favorite animal by selecting a button or typing in a name. This generally means that somewhere there's a big if/else block that maps from some type of I/O disambiguator (string, enum, etc.) to a particular derived class type, calling its constructor. It's useful to encapsulate this in a factory pattern, which can act like a named constructor that takes this disambiguator as a "constructor" parameter and finds the correct derived class to construct.
Typically, by the way, CreateMap would be a static method of BaseMapServer. I don't see why a separate class for the factory function is needed in this case.

C++ fast dynamic type/subtype check

As the title suggests, I am looking for a fast way of runtime typechecking. To illustrate my problem, imagine you have a class hierarchy like the following:
Base
/ \
A D
/ \ / \
C B F E
\ /
G
My program holds all instances of any class in a single list as Base_ptr because all these classes share common tasks. Now at some point some derived classes will need to know about the existence of an instance of another class. So far so good, I know about dynamic_cast and the typeid()-operator, but both have some mayor drawbacks:
dynamic_cast consumes a lot of processing time if the types are incompatible (e.g. try to cast instances of E to C)
typeid() does not work in "isTypeOrSubtype"-cases, e.g. you need all instances of D or derived from D (so Es, Fs and Gs as well)
The ideal solution would be some kind of "isTypeOrSubtype"-test and only casting, if this test returns successfully. I got an own approach with some macro definitions and precalculated classname hashes, but it is very ugly and hardly maintainable. So I am looking for a cleaner and faster way of dynamic type and subtype checking that can check far more than 20million times per second.
I wrote an answer to my own question as this is a different approach to avoid RTTI but no real answer to a fast way of dynamic type/subtype check.
This still isn't a clean solution, but the best I could think of until now.
If every class in this hierarchy has the following characteristics, I can skip most of the RTTI.
every class should have a private member: static SecureVector<[class]*> s_Instances; where SecureVector<T> is a thread-safe vector.
at the end of every constructor, s_Instances.push_back(this); should be called, to keep track of a newly created instance of that class
at the beginning of the destructor, s_Instances.erase(this); should be called, to remove this instances reference
every class should have a public function: static const SecureVector<[class]*>& Instances() { return s_Instances; } to get an unmodifiable vector containing all instances of this or any derived class
What this does is, every time a constructor is called, the instance adds itself to its own list of instances. When derived classes call their super constructor, the super class adds itself to its respective list of instances.
E.g. if I randomly create 100 instances in the above hierarchy, there would allways be 100 entries in my Base class Instances() vector.
In code this would look like this:
class Base
{
static SecureVector<Base*> s_Instances; // 1. condition
public:
Base()
{
s_Instances.push_back(this); // 2. condition
}
~Base()
{
s_Instances.erase(this); // 3. condition
}
static const SecureVector<Base*>& Instances() { return s_Instances; } // 4. condition
};
This is still just as a workaround as the four conditions have to be added manually (or by macro or something like it).
Some time ago I used something like this:
// the actual type is irrelevant, const char*, int, ...
// but const char* is great for debugging, when it contains the actual class name
typedef const char* TypeId;
class Base {
// actually the type id is not the value, but its memory location !
// the value is irrelevant (but its a good idea to set it to the class name)
static TypeId s_myTypeId;
public:
static TypeId* getClassType() { return &s_myTypeId; }
virtual TypeId* getInstanceType() { return &s_myTypeId; }
static TypeId* getClassBaseType() { return NULL; }
virtual TypeId* getInstanceBaseType() { return NULL; }
virtual bool isType( TypeId* type ) { return type==getInstanceType(); }
virtual bool isTypeOrSubType( TypeId* type ) { return isType(type); }
};
template< class MyBase >
class TBase : public MyBase {
// actually the type id is not the value, but its memory location !
// the value is irrelevant (but its a good idea to set it to the class name)
static TypeId s_myTypeId;
public:
static TypeId* getClassType() { return &s_myTypeId; }
virtual TypeId* getInstanceType() { return &s_myTypeId; }
static TypeId* getClassBaseType() { return MyBase::getClassType(); }
virtual TypeId* getInstanceBaseType() { return MyBase::getInstanceType(); }
virtual bool isType( TypeId* type ) { return type==getInstanceType(); }
virtual bool isTypeOrSubType( TypeId* type ) { return isType(type) || MyBase::isTypeOrSubType(type); }
};
// by deriving from TBase<Base>, a new instantiation of s_myTypeId was created,
// so the class now has its very own unique type id,
// and it inherited all the type resolution magic
class A : public TBase<Base> {
};
// NOTE: class B must not derive directly from A, but from TBase<A>
// imagine a hidden class between B and A,
// actually B inherits from the TBase<A> instantiation, which in turn inherits from A
class B : public TBase<A> {
};
// you will also need to instantiate the static members
// hereby the memory location will be reserved,
// and on execution that memory location becomes the unique type id
#define IMPLEMENT_RTTI(CL) TypeId CL::s_myTypeId = STRFY(CL)
// one per class per source file:
IMPLEMENT_RTTI(Base);
IMPLEMENT_RTTI(A);
IMPLEMENT_RTTI(B);
// example usage:
A a;
B b;
b.getInstanceType()==B::getClassType(); // TRUE
b.getInstanceBaseType()==A::getClassType(); // TRUE
B::getClassBaseType()==A::getClassType(); // TRUE
b.isType( B::getClassType() ); // TRUE
b.isType( A::getClassType() ); // FALSE
b.isTypeOrSubType( B::getClassType() ); // TRUE
b.isTypeOrSubType( A::getClassType() ); // TRUE
b.isTypeOrSubType( Base::getClassType() ); // TRUE
It is safe, fast and easy to use. You just have to obey two rules:
do not inherit directly from a class X, but inherit from TBase<X>,
and add an IMPLEMENT_RTTI(Me) to source file.
There is one drawback: it does not yet support multiple inheritance. But it would be possible with a few changes.
And probably the TypeId type should be composed like typedef const char* TypeLoc and typedef TypeLoc* TypeId. Maybe just a question of taste.
If your program knows about all the sub types that will be tested against, you can use a virtual interface that returns a pointer to the sub type. As noted by downvotes and comments, this is not the most flexible approach, since it requires the base class have knowledge of all the derived classes. However, it is very fast. So there is a trade off of flexibility to performance.
class Base {
//...
virtual A * is_A () { return 0; }
virtual B * is_B () { return 0; }
//...
template <typename MAYBE_DERIVED>
MAYBE_DERIVED * isTypeOrSubtype () {
//...dispatch to template specialization to call is_X()
}
};
//...
class A : virtual public Base {
//...
A * is_A () { return this; }
};
On IDEONE, the suggested technique is 20 to 50 times faster than using dynamic cast.1 The implementation uses macros to allow a new class to be added to a single place, and the proper expansions to the base class occur in an automated way after that.
(1) - I originally clocked it closer to 100 times as fast, but this was without the isTypeOrSubtype() wrapper method that I added to simulate the desired interface.
If flexibility has a higher value than performance, then a slightly less performant solution is to use a map to associate types and corresponding pointer values (having the pointer values removes the need for a dynamic cast). The map instance is maintained in the base class, and the associations are made by the constructors of the subclasses. Whether a regular map or a unordered_map is used will depend on how many subclasses virtually inherit the base class. I would presume the numbers will be small, so a regular map should suffice.
class Base {
std::map<const char *, void *> children_;
//...
template <typename MAYBE_DERIVED>
MAYBE_DERIVED * isTypeOrSubtype () {
auto x = children_.find(typeid(MAYBE_DERIVED).name());
return ((x != children_.end())
? static_cast<MAYBE_DERIVED *>(x->second)
: 0);
}
};
//...
class A : virtual public Base {
//...
A () { children_[typeid(A).name()] = this; }
//...
};
On IDEONE, this second suggestion is 10 to 30 times faster the using dynamic cast. I don't think IDEONE compiles with optimizations, so I would expect the times to be closer to the first suggestion on a production build. The mechanism as implemented uses typeid(...).name() as the key to the map.2
(2) - This assumes that typeid(...).name() returns something similar to a string literal, and always returns the same string pointer when operating on the same type. If your system does not behave that way, you can modify the map to take a std::string as the key instead, but performance will be degraded.
dynamic_cast would work wonderfully for this!
Base *instance = //get the pointer from your collection;
A* ap = dynamic_cast<A*>(instance);
D* dp = dynamic_cast<D*>(instance);
if(ap) {
//instance is an A or a subclass of A
}
if(dp) {
//instance is a D or a subclass of D
}
This will work for more specific checks as well. So you could check for any type you want.

C++ : Pointer to "new Class()" function

I have a Parent abstract class, and derivated Foo and Bar classes. They all have a constructor taking a string name parameter. They have a string type() member function which returns "foo" and "bar" respectively.
Now I would like to build a dictionnary with keys "foo" and "bar", and values equal to pointers to functions creating a new instance of the corresponding class. This means these pointers will be of type Parent* (*) (const string &) and executing them will be equivalent to calling new Foo(name) and new Bar(name)
Can I avoid creating a static function for each class that will just call new, and get a pointer to this static function?
Thanks!
Edit : Actually, the goal behind this is implementing a plugin system in my app, the plugins adding new Derived class types. The plugin authors are generally my customers, and for this reason, I want to let them the most simple and elegant interface possible. So declaring and registering the factory functions should be as simple and as short as possible for them
Can I avoid creating a static function for each class that will just call new, and get a pointer to this static function?
Yes, you can create a generic function:
template <typename T>
ptr_type<Parent> create() {
return new T();
}
… and then take its address (but you need to get an address per derived type).
Note that I have explicitly not used T* as a return type – raw pointers should never own memory … an appropriate smart pointer should instead be used here.
What you describe is a factory method pattern.
Here's a link: http://en.wikipedia.org/wiki/Factory_method_pattern
The static function or a factory of some sort basically the thing you want.
Why do you want to avoid the static creation method?
You need to instantiate a factory function for each class you want to be able to build by this means. The following code shows you how to do so without having to recur to static members and by not writing by hand a number of different functions:
#include <iostream>
#include <map>
#include <functional>
#include <string>
#include <memory>
struct Parent{
Parent(std::string){}
};
struct Child1 : public Parent{
Child1(std::string d) : Parent(d){
std::cout << "Child1 constructor: " << d << std::endl;
}
};
struct Child2 : public Parent{
Child2(std::string d) : Parent(d){
std::cout << "Child2 constructor: " << d << std::endl;
}
};
template <typename Product, typename Return, typename Parameter>
Return factory(const Parameter& a){
return Return(new Product(a));
}
std::map<std::string, std::function<Parent*(std::string)> > mrp;
std::map<std::string, std::function<std::shared_ptr<Parent>(std::string)> > msp;
int main(){
mrp["Child1"] = &factory<Child1, Parent*, std::string>;
mrp["Child2"] = &factory<Child2, Parent*, std::string>;
Parent* a = mrp["Child1"]("one");
delete a;
std::unique_ptr<Parent> b(mrp["Child2"]("two"));
msp["Child1"] = &factory<Child1, std::shared_ptr<Parent>, std::string>;
msp["Child2"] = &factory<Child2, std::shared_ptr<Parent>, std::string>;
msp["Child1"]("one");
msp["Child2"]("two");
}
try this code here.
Also, as you can see, this method can be "configured" to use std::shared_ptr, raw pointers, ... and with different ownership semanthics, notice the line:
std::unique_ptr<Parent> b(mrp["Child2"]("two"));
However, any variation of what you briefly described in the question is, well, a variation of it! What you are trying to do is an abstract factory, which "standard" implementation relies exactly on making a factory function for each class you want to build. As I said, it doesn't need to be a static member of the class, it can well be a non-member non-friend function but this doesn't change very much (except better encapsulation, and the need for the constructor being public, or for the factory to be friend, which, somehow, breaks encapsulation).
The object factory is implemented in a very elegant way in loki. Refer to Modern C++ (Alexandrescu) for a thorough discussion of the design pattern itself as well as of the implementation given by loki.
As for your edit: registration in loki is sweet and simple as in (cited from the book):
// Implementation module for class Line
// Create an anonymous namespace
// to make the function invisible from other modules
namespace
{
Shape* CreateLine()
{
return new Line;
}
// The ID of class Line
const int LINE = 1;
// Assume TheShapeFactory is a singleton factory
// (see Chapter 6)
const bool registered =
TheShapeFactory::Instance().RegisterShape(
LINE, CreateLine);
}

How can I instantiate an object knowing only its name? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a way to instantiate objects from a string holding their class name?
In C++, I want to have my user enter the object type name to be created at run-time, and, depending on the string I get from them, the program will instantiate the correct object (in short, I'm implementing factory method pattern). However, if the program has to support a new object type, then modifying existing code is not allowed.
So is it possible to remove all the if...else if...else if... stuff from the method, and still have my program instantiate a correct object of a specific product type (out of many, which are known only at compile time)?
My searching around got me this link: Is there a way to instantiate objects from a string holding their class name? and it seems it's what I want but I can't understand the code at all.
Any help would be really appreciated.
This will only work if all the required classes are derived from some common base class, and you will generally be limited to using the base interface (though you can work around that with some additional effort). Here's one approach:
// Immutable core code:
#include <map>
#include <string>
class Base
{
typedef Base * (*crfnptr)(const std::string &);
typedef std::map<std::string, crfnptr> CreatorMap;
static CreatorMap creators;
public:
virtual ~Base() { }
Base * clone() const { return new Base(*this); }
static Base * create_from_string(std::string name)
{
CreatorMap::const_iterator it = creators.find(name);
return it == creators.end() ? NULL : it->first();
}
static void register(std::string name, crfnptr f)
{
creators[name] = f;
}
};
Now you can add new derived classes from your new code:
// your code:
#include "immutable_core.hpp"
class Foo : public Base
{
public:
Foo * clone() const { return new Foo(*this); }
static Foo * create() { return new Foo; }
};
Base::register("Foo", &Foo::create);
To create a class, you simply call Base * p = Base::create_from_string("Foo");.
You can do that implementing something like a plugin system. I've implemented this in Linux with dlopen. The program doesn't need to be modified, but you need only add new classes as dynamic libraries that will be loaded at runtime.
You can start here for more info: C++ dlopen mini HOWTO

How create an object of a Class from a string that holds the name of that class?

Let's say I have a string with my class name inside:
mystring = "CDialogChild";
I would like to create an object of the type name written in my string.
I'd like to do something like:
CDialogParent dlg = CDialogParent(mystring);
My new dlg is now created as type CDialogChild and I can use its methods:
dlg.mycdialogchild_method();
There is nothing in C++ that will provide you such feature (called Reflection).
However, if your classes are of finite number, you can do some kind of mapping with some factories :
class IClassFactory // base interface
{ public:
virtual ~IClassFactory(){}
}
template< class T >
class ClassFactory {
/* whatever necessary here*/
public:
T* create();
};
class ClassManager
{
public:
void add( std::string name, IClassFactory* factory ) { m_map[name] = factory; }
ACommonBaseClass* create( std::string class_name ) { return m_map[class_name]->create(); } // this line isn't correct but you get the idea
private:
std::map< std::string, IClassFactory* > m_map;
};
Or something similar (this is written quickly).
Alternatively you could work with a scripting language that would allow Reflection, but that would add a whole layer to your application. Scripting languages that might be of interest for embedding with c++ : ChaiScript, Falcon, Lua, Python, AngelScript, MonkeyScript, Io, ...
In general this is not possible within the language, since C++ is not a reflective language and it is statically typed.
As an alternative, you could consider hardcoding a collection of related, polymorphic types with a common base class into the program and writing a factory method that creates the desired concrete instance based on a runtime parameter.
There is a design pattern for completing your objective: Factory.
You will need to compare the class name and return the object:
class MyObject;
MyObject * creator(const std::string& object_name)
{
return (object_name == "MyObject") ? new MyObject : 0;
}
The Factory pattern differs a little in that it uses pointers to a base class and returns instances of child classes.