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());
Related
My question is reasonably simple: How do I obtain a pointer to the object calling a function, without passing this?
The reason I am asking, however, is slightly more complex.
I am led to ask this because I am writing a class (named SubordnateRegistry), which contains a heterogeneous list (of lists) of function delegates --- callable objects with different signatures.
Whichever classes wish to have delegates called must register themselves, of course, with the type of data which they wish to receive, and either a pointer to the object or an already-constructed delegate. A call from inside a class Bar might look like this:
ARegistry.Subscribe <Foo> (& Bar:: BarFunction, this);
Or like this:
using namespace std:: placeholders;
auto Func = std:: bind (& Bar:: BarFunction, this, _1);
ARegistry.Subscribe <Foo> (Func);
Because std:: function is more versatile (you can bind any callable, including lambdas), I would prefer to use that over raw pointers.
My problem lies in the fact that I have to specify this all the time. If I pass an invalid pointer, or end up registering an object which is not related at all, then I will end up invoking UB at some indeterminate point in the future with no idea where it came from or where the root of the error is. Nasty!
Now, if you're wondering what happens if the caller is not an object (a free function), then the element will simply remain registered forever, as I will never automatically remove (unregister) the callable, as it never destructs.
Any ideas, or is this impossible as I was led to believe? Is preprocessor magic an option? Is there a better way?
Of course, any questions are welcome. Thanks for your time :).
You could use a #define to include this automatically, for instance.
#define REG_SUBSCRIBE(t,f) ARegistry.Subscribe <t> (f, this)
Of course that could turn ugly fast, so I don't know if I would recommend it.
If you are worried about keeping track and releasing them, then I would recommend returning an object with a destructor which unsubscribes the thing. Alternatively (or in addition) providing a method call to do that.
I gave it a shot using the curiously recurring template pattern. The idea is to encapsulate the registration of a method in a class whose destructor will automatically unregister the client object on destruction. The Client derives from this class. This way the destructor will be called automatically, and the registration class has implicit access to the clients this pointer. Such that it is not necessary to pass it explicitely.
The Visitor class
Throughout this answer I will assume the following visitor class:
// The visitor class. Clients can register methods here.
class Visitor {
public:
// Expects void(void) methods.
template <class T>
using method_t = void (T::*)();
// Register a new method of a client.
template <class T>
void subscribe(method_t<T> method, T* object);
// unsubscribe all methods of a given client.
template <class T>
void unsubscribe(T* object);
};
A registration of a method
The registration class looks like this:
// CRTP registration class.
// Will automatically subscribe and unsubscribe its base class.
template <class Derived>
class Registration {
public:
// The constructor takes a reference to the visitor,
// and a pointer to the method that should be registered.
// It will then register this particular method.
Registration(Visitor &visitor, Visitor::method_t<Derived> method)
: visitor_(visitor) {
visitor_.subscribe(method, static_cast<Derived *>(this));
}
// The destructor calls the visitors unsubscribe method unregistering
// all methods of this particular client.
virtual ~Registration() {
visitor_.unsubscribe(static_cast<Derived *>(this));
}
private:
Visitor &visitor_;
};
A client
An actual client would then look like this.
// A client using the registration class.
// Has to inherit publically, otherwise the `this` pointer cast will fail.
class Client : public Registration<Client> {
public:
Client(Visitor &visitor)
: Registration<Client>(visitor, &Client::method) {}
void method();
};
You can find an example usage here.
A few notes:
Since the registration class has non-trivial destructor, you need to consider the rule of five, and need to decide what to do about the copy-/move- constructor/assignment.
This pattern needs to be changed if you want to register multiple methods of one object. Consider this a rough sketch for how you could solve your problem. The Registration class could register methods in a publically available member function instead of the constructor. If, for some reason, you need to inherit from Registration multiple times, consider factoring out the reference to the visitor and base class chaining.
The registration could also store the method pointer, if the unsubscribe method requires that one as well.
I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.
I'm having a class with 2 pure virtual methods and another class which needs to use an object of this class. I want to allow the user of this class to specify which derivation of the abstract class should be used inside of it.
I'm struggling to figure out what the right way is.
struct abstract {
virtual int fst_func() = 0;
virtual void sec_func(int) = 0;
};
// store an instance of "abstract".
class user_of_abstract
{
private:
abstract* m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(abstract* a) : m_abstract(a) { }
// Pase any type, which needs to be derived from "abstract" and create a copy. Free memory in destructor.
template<class abstract_type>
user_of_abstract_base(abstract_type const& a) : m_abstract(new abstract_type(a)) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// use boost::shared_ptr
class user_of_abstract
{
private:
boost::shared_ptr<abstract> m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(boost::shared_ptr<abstract> a) : m_abstract(a) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// pass a pointer of an "abstract" object wherever needed.
struct user_of_abstract
{
// use the passed pointer to an "abstract" object to call fst_func.
int use_fst_func(abstract* a) {
return a->fst_func();
}
// use the passed pointer to an "abstract" object to call sec_func.
void use_sec_func(abstract* a, int x) {
a->sec_func(x);
}
};
It's important to note that parameter "x" from sec_func() needs to be a value returned by fst_func() on the same "abstract" instance.
EDIT:
Added another approach using boost::shared_ptr which should take the most advantages.
I would say that passing the abstract object into the constructor of your user is the proper approach as the methods of the user depend being called on the same abstract object. I would even go further and make the x parameter an internal state of your user as you have said it's important that this value is the one returned from a call from the first function.
Update: If you are worried about the lifetimes then you could make use of the various smart pointer options available in for example boost. Those should cover most usage scenarios.
Since you say the second function should use the output of the first. I guess first approach will decrease chance of mistakes. You can even modify it to the following:
int use_fst_func() {
return x=this->m_abstract->fst_func();
}
void use_sec_func() {
this->m_abstract->sec_func(x);
}
protected:
int x;
You're putting yourself in a sea of maintenance trouble.
In your first example...
there's really no need for the template constructor. It's speced as
// Parse any type, which needs to be derived from "abstract" and create a copy.
The user can already do that by creating the instance himself and pass it to the first constructor.
Also, with this:
// Free memory in destructor.
You explicitly say that you have no idea how this class should be used. As your first example is written, you need to decide: use an instance created from the outside or use an instance created on the inside. It's confusing to see an interface with one ctor taking a pointer and another ctor taking a reference, both essentially to the same type.
In my eyes, the only acceptable way of using an instance created from the outside that will not be memory-managed or an instance created from the inside that will be memory-managed, is when there's a default ctor that can initialize the internal pointer to a sensible value (but that doesn't seem to be the case here, since you want to copy another instance):
template <typename T>
class user_of_abstract
{
bool m_owner_;
abstract* m_abstract;
public:
user_of_abstract_base(abstract* a = NULL)
: m_owner(a == NULL)
, m_abstract(m_owner ? new T(): a)
{
}
~user_of_abstract_base()
{
if (m_owner)
{
delete m_abstract;
}
}
}
Your second example...
is superior to the first, since you don't explicitly mix memory management with memory reference. You let shared_ptr do it implicitly. Very good, that's what it's for.
However, since you have a requirement that use_sec_func must take the output of use_fst_func as input, you stay a long way from the safe shore of the sea of maintenance problems.
For instance, what happens if use_fst_func on an instance throws an exception and use_sec_func is later called on that same instance?
How do you expect that the important information "Always call A before B. And only once. And pass the A result to B." should propagate to users of the class 2 years from now?
Why can't use_sec_func just call use_fst_func?
As for your third example...
can you give 1 single scenario when you'd want to use this instead of just calling the instance functions directly?
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.
I was looking at the boost serialization library, and the intrusive way to provide support for serialization is to define a member function with signature (simplifying):
class ToBeSerialized {
public:
//Define this to support serialization
//Notice not virtual function!
template<class Archive>
void serialize(Archive & ar)
{.....}
};
Moreover, one way to support serilization of derived class trough base pointers is to use a macro of the type:
//No mention to the base class(es) from which Derived_class inherits
BOOST_CLASS_EXPORT_GUID(Derived_class, "derived_class")
where Derived_class is some class which is inheriting from a base class, say Base_class. Thanks to this macro, it is possible to serialize classes of type Derived_class through pointers to Base_class correctly.
The question is:
I am used in C++ to write abstract factories implemented through a map from std::string to (pointer to) functions which return objects of the desired type (and eveything is fine thanks to covariant types).
Hover I fail to see how I could use the above non-virtual serialize template member function to properly de-serialize (i.e. construct) an object without knowing its type (but assuming that the type information has been stored by the serializer, say in a string).
What I would like to do (keeping the same nomenclature as above) is something like the following:
XmlArchive xmlArchive; //A type or archive
xmlArchive.open("C:/ser.txt"); //Contains type information for the serialized class
Base_class* basePtr = Factory<Base_class>::create("derived_class",xmlArchive);
with the function on the righ-hand side creating an object on the heap of type Derived_class (via default constructor, this is the part I know how to solve) and calling the serialize function of xmlArchive (here I am stuck!), i.e. do something like:
Base_class* Factory<Base_class>::create("derived_class",xmlArchive)
{
Base_class* basePtr = new Base_class; //OK, doable, usual map string to pointer to function
static_cast<Derived_class*>( basePtr )->serialize( xmlArchive ); //De-serialization, how?????
return basePtr;
}
I am sure this can be done (boost serialize does it but its code is impenetrable! :P), but I fail to figure out how.
The key problem is that the serialize function is a template function. So I cannot have a pointer to a generic templated function.
As the point in writing the templated serialize function is to make the code generic (i.e. not having to re-write the serialize function for different Archivers), it does not make sense then to have to register all the derived classes for all possible archive types, like:
MY_CLASS_REGISTER(Derived_class, XmlArchive);
MY_CLASS_REGISTER(Derived_class, TxtArchive);
...
In fact in my code I relies on overloading to get the correct behaviour:
void serialize( XmlArchive& archive, Derived_class& derived );
void serialize( TxtArchive& archive, Derived_class& derived );
...
The key point to keep in mind is that the archive type is always known, i.e. I am never using runtime polymorphism for the archive class...(again I am using overloading on the archive type).
Any suggestion to help me out?
Thank you very much in advance!
Cheers
All you need is to store some sort of identifier before storing the information from the derived type. Then upon reading you use that identifier, which you've read first, to direct you to a factory that can then interpret the next block of information correctly and generate your derived type. This is probably what boost::serialization does at a very basic level. Maybe something like so:
ar >> type;
Base_class* basePtr = Factory<Base_class>::create(type,xmlArchive);
Then you have a map of objects that look something like so:
struct reader_base { virtual void load(xmlArchive, base_ptr) = 0; }
template < typename T >
struct reader : reader_base
{
virtual void load(xmlArchive, base_ptr)
{
static_cast<T*>(base_ptr)->serialize(xmlArchive);
}
};
If your archive type is always known, why bother parameterizing your serialize function on it? There's an argument to be made for code reuse, yes, but if your Archive class ever changes its definition or gets replaced, you will likely need to refactor some of your serialization code anyway.
If you stick with:
class ToBeSerialized : public Base_class {
public:
void serialize(Archive & ar)
{.....}
};
You can then take a pointer to your serialize function, and bind it to your factory.
You will also need to bind separate create functions for each class, so that it can instantiate the right type when it's asked for it. Something like:
template <typename T> Base_class* Factory::create(Archive& xmlArchive) {
T* derivedPtr = new T;
derivedPtr->serialize( xmlArchive );
return derivedPtr;
}
The factory will then need a generic create method that calls out to the correct static parameterized create<T>:
Base_class* Factory::create(const char* typeString, Archive& xmlArchive) {
// Pseudocode.
return m_map.find(typeString)->callCreate(xmlArchive);
}