Note: I do not mean a pointer to an OBJECT or INSTANCE I mean a pointer to a CLASS
I put this at the top because I know if I don't people will tell me that I can do
class MyClass;
MyClass* pointerToMyClass = new MyClass(); // Ta-da! pointer to class!
This is not what I am looking for. I would like to make a pointer to a class type itself, kind of like a function pointer, but for a class.
To make it more clear what I am asking, here is some code that roughly demonstrates what I am looking for.
class MyClass; // real Class
class MyDerived : public MyClass; // derived class
class * ClassPointer = &MyClass; // pointer to my class
MyClass * instanceOfPointer = new ClassPointer(); // now makes an instance of MyClass
ClassPointer = &MyDerived; // pointer to derived class
MyClass * instance2 = new ClassPointer(); // now makes an instance of DerivedClass
So kind of like a typedef, but more dynamic.
I would also want be able to make a vector of class pointers. Currently, I am hacking in the behavior I need with a class function clone() that returns a new pointer to the base class, but I don't particularly like this approach.
Is there anything like this possible in C++?
Edit:
The current problem I am using this for is a polymorphic network protocol.
There is a base packet class:
class packet{
int id=0;
virtual packet* read(); // read packet type into id
virtual packet* clone(){ return new packet(); }
};
then multiple derived packets:
class packet1 : public packet{
int id=1
packet* read(); // do packet specific reading
packet * clone(){ return new packet1(); }
};
class packet2 : public packet{
int id=2
packet* read(); // do packet specific reading
packet * clone(){ return new packet21(); }
};
class packet3 : public packet{
int id=3
packet* read(); // do packet specific reading
packet * clone(){ return new packet3(); }
};
then to read a packet all you have to do is
packet* array[] = { new packet(), new packet1(), new packet2(), new packet3() }; // array of packets, this should be class* if possible
packet type = packet();
type.read(); // read type from network
packet* data = array[type.id].clone(); // pick derived class based on type
data->read(); // read specific packet from network
The packet*[] would be replaced with a class*[] to avoid having to use clone().
This is a simplified but workable example.
No, it's not possible this way because types have to be resolved during compilation. You "physically" compile in instruction how to create new objects. Sure, you can make it variable by simple condition based on typeinfo utilizing RTTI.
#include <typeinfo>
MyClass *createInstanceOf(const std::type_info& myType)
{
if (myType == typeid(MyClass))
return new MyClass();
if (myType == typeid(MyDerived))
return new MyDerived();
// handle invalid type
}
This way you can create different objects based on runtime variable (which is variable std::type_info).
class MyClass;//real Class
class MyDerived: public MyClass;//derived class
std::type_info myType = typeid(MyClass);//pointer to my class
MyClass * instanceOfPointer = createInstanceOf(myType);//now makes an instance of MyClass
myType = typeid(MyDerived);//pointer to derived class
MyClass * instance2 = createInstanceOf(myType);//now makes an instance of DerivedClass
Important part is that this function knows which object creation should be compiled in (all of types you want to support), decision on which path is taken is made in runtime but creation itself is known when you compile the code. Types can never be variable. Even templates are not variable, they generate instances of functions/classes per each type that it was instantiated for during compilation.
I'll add that this solution is useful only in very specific cases. Essentially if you know the type during compilation, then you should never save type_info of the type and then use it in condition to get the type back. It would be much heavier than it should be and is almost impossible to optimize.
Your example seems to be lacking something. As I understand, all you want to do is read type from outside source and then read data based on this variable type. This is quite standard way of reading any outside communication and is done more or less in a way I mentioned above. You need runtime decision mechanism which will take path proper for given type. At some point you'll have to make this decision because your code has to branch out and reach for proper handler (which seems to be packet in your example).
In this case you should not use typeid as it is only guaranteed to be unique and same for the same type in one execution of program - it can't be shared or stored for next execution. In your case you need your own type information (usually enum is most efficient). This way you can create map of your handlers. If types of packets are known and well defined, then you can make them in order from 0 and store them in regular array with constant access time. That's one of most efficient ways to do this. Essentially it would be your type.id.
Best answer was never posed as an answer, credit to Raymond Chen
No you can not take a pointer to a class (and are actually forbidden to take the pointer of a constructor http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf 12.1.12), however you can make a pointer to an abject factory by
template<typename T> T* make<T>() { return new T(); }
and take a function pointer of make<classToPointTo>
Much better than my clone function and I didnt want this wonderful answer burred in the comments for the rest of time.
Related
I am trying to assign the instance class to a pointer, how can I do that:
#include <fstream>
using namespace std;
class A
{
private:
static A *pointer;
protected:
A(){}
A GetInstance()
{
//On this point throw the error: could not convert A::pointer’ from A*’ to ‘A’
pointer& = (A)this;
return pointer;
}
};
A *A::pointer = NULL;
How can I do that?
static A *pointer;
...
...
pointer& = (A)this;
Is it possible? I am trying to create a simple repository class with an unique connection instantiated (only one time) and the class repository with the virtuals functions (Add, Save, GetById, GetAll()) inherit from this class, in this way I could create a lot of Repository classes using just only connection without open and close every time. If someone has a example, I would be glad.
Thanks in advanced.
It doesn't work as you tried because (A)this is a conversion from type A * (a pointer to an object of class A) to class A (an object of class A). The compiler cannot do such a conversion.
The type of A::pointer is A *. So is this inside the methods of class A.
All you need is:
pointer = this;
Or, if you want to make more readable, you can write:
A::pointer = this;
This way it's clear for a reader that pointer is a static property (class member) and not an instance property.
You have an error on the next line. The value returned by A::getInstance() (return pointer;) doesn't match the type declared in the method's header (an object of class A). The one that is wrong is the method's declaration. It doesn't make much sense to return an object of type A, it should return a pointer to such an object (more specifically, the only instance of the class, stored in A::pointer.
Change the method's definition like this:
A *GetInstance()
{
pointer = this;
return pointer;
}
As other readers already noticed in comments, it seems you are trying to implement the Singleton pattern (but you are only half-way through it). The best advice about Singleton is to avoid it because it is not testable. It is just a disguised global variable and global variables are, in general, a bad way to store your data.
It appeared that this problem is quite common in our job.
We we are sending an int or enum value through the network, then we receive it we would like to create/call a particular object/function.
The most simply solution would be to use the switch statement, like below:
switch (value) {
case FANCY_TYPE_VALUE: return new FancyType();
}
It works fine, but we would have plenty of these switch blocks, and when we create new value and type, we would need to change all of them. It does seem right.
Other possibility would be to use the templates. But we cannot, since the value of enum is defined in runtime.
Is there any right design pattern for that, or any right approach?
It seems like a very general and common problem in every day coding...
Try a map:
struct Base { };
struct Der1 : Base { static Base * create() { return new Der1; } };
struct Der2 : Base { static Base * create() { return new Der2; } };
struct Der3 : Base { static Base * create() { return new Der3; } };
std::map<int, Base * (*)()> creators;
creators[12] = &Der1::create;
creators[29] = &Der2::create;
creators[85] = &Der3::create;
Base * p = creators[get_id_from_network()]();
(This is of course really crude; at the very least you'd have error checking, and a per-class self-registration scheme so you can't forget to register a class.)
You can actually do this with some template trickery:
#include <map>
template <typename Enum, typename Base>
class EnumFactory {
public:
static Base* create(Enum e) {
typename std::map<Enum,EnumFactory<Enum,Base>*>::const_iterator const it = lookup().find(e);
if (it == lookup().end())
return 0;
return it->second->create();
}
protected:
static std::map<Enum,EnumFactory<Enum,Base>*>& lookup() {
static std::map<Enum,EnumFactory<Enum,Base>*> l;
return l;
}
private:
virtual Base* create() = 0;
};
template <typename Enum, typename Base, typename Der>
class EnumFactoryImpl : public EnumFactory<Enum,Base> {
public:
EnumFactoryImpl(Enum key)
: position(this->lookup().insert(std::make_pair<Enum,EnumFactory<Enum,Base>*>(key,this)).first) {
}
~EnumFactoryImpl() {
this->lookup().erase(position);
}
private:
virtual Base* create() {
return new Der();
}
typename std::map<Enum,EnumFactory<Enum,Base>*>::iterator position;
};
This allows you to create a new derived object from a given enum, by saying
// will create a new `FancyType` object if `value` evaluates to `FANCY_TYPE_VALUE` at runtime
EnumFactory<MyEnum,MyBase>::create(value)
However, you have to have some EnumFactoryImpl objects, which could be static in some function or namespace.
namespace {
EnumFactoryImpl<MyEnum,MyBase,Derived1> const fi1(ENUM_VALUE_1);
EnumFactoryImpl<MyEnum,MyBase,Derived2> const fi2(ENUM_VALUE_2);
EnumFactoryImpl<MyEnum,MyBase,Derived3> const fi3(ENUM_VALUE_3);
EnumFactoryImpl<MyEnum,MyBase,FancyType> const fi1(FANCY_TYPE_VALUE); // your example
}
These lines are the single point where your source code maps enum values to derived types. So you have everything at the same location, and no redundancy (this eliminates the problem of forgetting to change it in some places, when adding new derived types).
One option is to maintain a dictionary of creators(which has the same interface) that can create a concrete type. Now the creation code will search in the dictionary for an int value (resulting from the enum sent from the client) and call the create method, which returns the concrete object via a base-class pointer.
The dictionary can be initialized at one place with the concrete creators corresponding to each possible enum values.
The problem here is that you have to extend this dictionary initialization code when you add a new type of object. A way to avoid is as following.
Let the creator look for a singleton factory instance and register itself in the constructor with the type enums(integers) with which it can create a concret object.
Create a DLL for one/set of creators and have a global instance of the creators.
The name of the DLL can be entered in a config file which is read by the factory in the initialization. The factory loads all the DLLs in this file and this results in the creation of the static objects which registers themselves with the factory.
Now the factory has the map of all the type enums which it can create with the concrete object creators.
The same object creator look-up mechanism is implemented to create the objects.
Now, the factory doesn't need to be extended at all since step 3,4 and 5 doesn't change for new objects introduced. Step 1 can be implemented in one place.
Only thing you need to do is to add a global object for each of the new concrete type which should be there since the C++ doesn't support reflection natively.
kogut, I don't propose this as an answer, but since you ask me to expand on my comment on your original question here's a very brief summary of what the .net environment gives you...
public enum MyEnum
{
[MyAttribute(typeof(ClassNone))]
None,
[MyAttribute(typeof(ClassOne))]
One,
[MyAttribute(typeof(ClassTwo))]
Two,
[MyAttribute(typeof(ClassThree))]
Three
}
So you have your basic enum One, Two, Three etc. which works just like....er....an enum!
But you also code up a class called MyAttribute (and in fact for more information in this area, just search for Attributes). But as you can see this allows you to say, at design time, that such-and-such an enum value is associated with such-and-such a class.
This information is stored in the enum's metadata (the value of a managed environment!) and can be interrogated at runtime (using Reflection). Needless to say this is very powerful, I've used this mechanism to systematically strip out loads of maps of the kind proposed in other answers to your question.
An example of the usefulness is this...at one client I worked with, the convention was to store statuses as strings in a database on the grounds that they would be more readable to a human who needed to run a table query. But this made no sense in the applications, where statuses were pushed through as enums. Take the above approach (with a string rather than a type) and this transform happened on a single line of code as data was read and written. Plus, of course, once you've defined MyAttribute it can be tagged onto any enum you like.
My language if choice these days is c# but this would also be good in (managed) c++.
I have this problem again and again... and still have not a satisfactory answer...
Especially when I put the class into a container, later on I need to record more information on every element in the container during a specific processing, but after processing I do not need the extra information anymore....
I often found some libraries try to solve the above situation by defining a void* in their data structure to provide user-defined data structure extension. Just the same described in this Q&A.
But it produces memory / resource handling problem... and other problems that I feel this approach is error-prone.
In the modern day of object-oriented programming, I am thinking of
using inheritance & polymorphism. Use base class's pointer in the container, but then I have to add derived class's accessor into the base class. It is kind of strange...
is there any other better ways to extend a class's property while maintain container comparability in C++?
The best way to store extra data about a object without actually compromising the integrity of the object itself is to store a pair of data in the container instead.
struct User { ... };
struct ExtraData { ... };
typedef std::pair<User, ExtraData> UserAndExtraData;
Now I can create a container type in C++ which stores both pieces of information together without compromising the independence of either type.
std::vector<UserAndExtraData> vector;
I would look into the Decorator Pattern. You can decorate your objects while processing them then throw the decorated objects away. If there is a lot of shared data you can also look into the FlyWeight pattern.
"User" could be extended by template parameters. for example,
template <typename... Extra>
struct User : Extra...
{
...
};
struct ExtraData {...};
struct ExtraExtraData {...};
using ExtraUser = User<ExtraData>;
using MoreExtraUser = User<ExtraData, ExtraExtraData>;
In the modern day of object-oriented programming, I am thinking of
using inheritance & polymorphism. Use base class's pointer in the
container, but then I have to add derived class's accessor into the
base class. It is kind of stange...
you don't need to put a pointer to your derived class in your base class when using inheritance. You just need to cast to the derived class. the problem is getting your data into the derived objects when it's stored in the base objects - you can only cast them if they were created as the derived type, even if your collection holds them as the base type. (if they are created as the derived type, then just cast!)
So if you have a collection of BaseC, you can create a new class DerivedC that has a copy constructor that takes a BaseC. You can copy your BaseC object into it, perform your processing on the DerivedC objects and then copy these back into a BaseC object for storage. This uses the Flyweight pattern. Note that if you have a collection of BaseC objects, you cannot just pretend they are DerivedC classes as they will not have the storage to hold all the data members, you need to create new DerivedC objects.
Alternatively, create a new class just for processing that contains a (smart pointer) reference to your base class objects, copy the reference in, perform the processing, delete the processing objects when you're done.
If your objects are in a vector, then a simple approach is to make a parallel vector:
void doSomething(const vector<MyObject>& my_objects)
{
vector<ExtraData> extra_data;
int n_objects = extra_data.size();
extra_data.reserve(n_objects);
for (int i=0; i!=n_objects; ++i) {
extra_data.push_back(calcExtraData(my_objects[i]));
}
// now use my_objects[i] and extra_data[i] together.
// extra data goes away when the function returns.
}
You don't have to modify your original objects, and it is very efficient.
If you have some other container type, you can use a map:
void doSomething(const set<MyObject>& my_objects)
{
map<MyObject*,ExtraData> extra_data;
set<MyObject>::const_iterator i=my_objects.begin(), end=my_objects.end();
for (;i!=end;++i) {
extra_data[&*i] = calcExtraData(*i);
}
// now use extra_data[&obj] to access the extra data for obj.
// extra data goes away when the function returns.
}
this isn't as efficient as with vectors, but you still don't have to modify your original classes.
However, it becomes more difficult to maintain the parallel structures if the underlying container can change during the processing.
One simple option is to add a type parameter representing the "extra data"...
template<class ExtraDataType>
struct MyExtensibleContainer
{
...
ExtraDataType extra;
};
Perhaps if you indicate why this solution isn't sufficient, the true requirements will come through.
Example for int and void*:
struct IntOrVoid
{
};
struct IntOrVoid1 : IntOrVoid
{
int x;
};
struct IntOrVoid2 : IntOrVoid
{
void* x;
};
typedef shared_ptr<IntOrVoid> PIntOrVoid;
then use MyExtensibleContainer<PIntOrVoid>
or altenatively:
union IntOrVoid
{
int x_int;
void* x_voidp;
};
then use MyExtensibleContainer<IntOrVoid>
The problem you are describing has nothing to do with adding an "extra" data type. The problem you are describing has to do with holding a variant type that can have one of many hetrogeneous types. There are many ways to do this, it is a much more general problem.
Is there some way to allocate memory depending on the type of pointer passed?
Here is my problem: I have a 'bouncyball' and 'hero' class both inheriting from 'Actor'. To add a bouncyball, I call:
_actors.push_back(new Bouncyball());
For a hero, it would be:
_actors.push_back(new Hero());
Since _actors is a vector of Actor pointers, it works because of polymorphism. But I want to write a generic method to add new actors to my scene:
unsigned Scene::addActor(Actor * actor){
this->_actors.push_back(new [something]);
}
Because the parameter can be any derivative of Actor, I don't know what to allocate memory for... I can work around this with a case statement, but what if I derive other Actors later on?
What is wrong with this:
unsigned Scene::addActor(Actor * actor){
this->_actors.push_back(actor);
//what do you want to return? why not make return type as void?
}
Isn't it actor which you want to add to _actors?
And you can call addActor() as:
scene.addActor(new Bouncyball());
scene.addActor(new Hero());
Make sure that you declare the destructor of Actor as virtual, as most likely you would want to delete derived class objects through the pointer of base type (which is Actor).
Nawaz's solution is fine, but an alternative is a template member function:
template<typename T>
unsigned Scene::addActor()
{
_actors.push_back(new T());
}
And then in the client code:
scene.addActor<Hero>();
It's worth noting that the template member function will need to be implemented in a header or file included by a header (such as a .inl). If you implement it directly in the class body you shouldn't write Scene:: in front of addActor().
One advantage of this method is that clients are not calling new. It's generally 'bad' if code is calling new, but isn't calling delete, and in this case delete would presumably be called by the Scene class later. This also creates a pinch point if a custom allocator needs to be used for performance reasons.
Why not create a pv class Clonable:
template <typename T>
struct Clonable {
virtual smart_ptr<T> clone() const = 0;
}
for smart_ptr being std::shared_ptr, std::unique_ptr, boost::shared_ptr, etc.
The point is to refcount the pointer to avoid use of manual deletes, except when writing a custom Deleter.
Then define Actor as:
class Actor : ..., public Clonable<Actor> {
...
public:
...
virtual smart_ptr<T> clone() const { return 0; }
...
...
}
Then, for T : public Actor,
scene.addActor((T()).clone());
I've been programming in Java way too long, and finding my way back to some C++. I want to write some code that given a class (either a type_info, or its name in a string) can create an instance of that class. For simplicity, let's assume it only needs to call the default constructor. Is this even possible in C++, and if not is it coming in a future TR?
I have found a way to do this, but I'm hoping there is something more "dynamic". For the classes I expect to wish to instantiate (this is a problem in itself, as I want to leave that decision up to configuration), I have created a singleton factory with a statically-created instance that registers itself with another class. eg. for the class Foo, there is also a FooFactory that has a static FooFactory instance, so that at program startup the FooFactory constructor gets called, which registers itself with another class. Then, when I wish to create a Foo at runtime, I find the FooFactory and call it to create the Foo instance. Is there anything better for doing this in C++? I'm guessing I've just been spoiled by rich reflection in Java/C#.
For context, I'm trying to apply some of the IOC container concepts I've become so used to in the Java world to C++, and hoping I can make it as dynamic as possible, without needing to add a Factory class for every other class in my application.
You could always use templates, though I'm not sure that this is what your looking for:
template <typename T>
T
instantiate ()
{
return T ();
}
Or on a class:
template <typename T>
class MyClass
{
...
};
Welcome in C++ :)
You are correct that you will need a Factory to create those objects, however you might not need one Factory per file.
The typical way of going at it is having all instanciable classes derive from a common base class, that we will call Base, so that you'll need a single Factory which will serve a std::unique_ptr<Base> to you each time.
There are 2 ways to implement the Factory:
You can use the Prototype pattern, and register an instance of the class to create, on which a clone function will be called.
You can register a pointer to function or a functor (or std::function<Base*()> in C++0x)
Of course the difficulty is to register those entries dynamically. This is typically done at start-up during static initialization.
// OO-way
class Derived: public Base
{
public:
virtual Derived* clone() const { return new Derived(*this); }
private:
};
// start-up...
namespace { Base* derived = GetFactory().register("Derived", new Derived); }
// ...or in main
int main(int argc, char* argv[])
{
GetFactory().register("Derived", new Derived(argv[1]));
}
// Pointer to function
class Derived: public Base {};
// C++03
namespace {
Base* makeDerived() { return new Derived; }
Base* derived = GetFactory().register("Derived", makeDerived);
}
// C++0x
namespace {
Base* derived = GetFactory().register("Derived", []() { return new Derived; });
}
The main advantage of the start-up way is that you can perfectly define your Derived class in its own file, tuck the registration there, and no other file is impacted by your changes. This is great for handling dependencies.
On the other hand, if the prototype you wish to create requires some external information / parameters, then you are forced to use an initialization method, the simplest of which being to register your instance in main (or equivalent) once you have the necessary parameters.
Quick note: the pointer to function method is the most economic (in memory) and the fastest (in execution), but the syntax is weird...
Regarding the follow-up questions.
Yes it is possible to pass a type to a function, though perhaps not directly:
if the type in question is known at compile time, you can use the templates, though you'll need some time to get acquainted with the syntax
if not, then you'll need to pass some kind of ID and use the factory approach
If you need to pass something akin to object.class then it seems to me that you are approaching the double dispatch use case and it would be worth looking at the Visitor pattern.
No. There is no way to get from a type's name to the actual type; rich reflection is pretty cool, but there's almost always a better way.
no such thing as "var" or "dynamic" in C++ last time I've checked(although that was a WHILE ago). You could use a (void*) pointer and then try casting accordingly. Also, if memory serves me right, C++ does have RTTI which is not reflection but can help with identifying types at runtime.