In C++, the T q = dynamic_cast<T>(p); construction performs a runtime cast of a pointer p to some other pointer type T that must appear in the inheritance hierarchy of the dynamic type of *p in order to succeed. That is all fine and well.
However, it is also possible to perform dynamic_cast<void*>(p), which will simply return a pointer to the "most derived object" (see 5.2.7::7 in C++11). I understand that this feature probably comes out for free in the implementation of the dynamic cast, but is it useful in practice? After all, its return type is at best void*, so what good is this?
The dynamic_cast<void*>() can indeed be used to check for identity, even if dealing with multiple inheritance.
Try this code:
#include <iostream>
class B {
public:
virtual ~B() {}
};
class D1 : public B {
};
class D2 : public B {
};
class DD : public D1, public D2 {
};
namespace {
bool eq(B* b1, B* b2) {
return b1 == b2;
}
bool eqdc(B* b1, B *b2) {
return dynamic_cast<void*>(b1) == dynamic_cast<void*>(b2);
}
};
int
main() {
DD *dd = new DD();
D1 *d1 = dynamic_cast<D1*>(dd);
D2 *d2 = dynamic_cast<D2*>(dd);
std::cout << "eq: " << eq(d1, d2) << ", eqdc: " << eqdc(d1, d2) << "\n";
return 0;
}
Output:
eq: 0, eqdc: 1
Bear in mind that C++ lets you do things the old C way.
Suppose I have some API in which I'm forced to smuggle an object pointer through the type void*, but where the callback it's eventually passed to will know its dynamic type:
struct BaseClass {
typedef void(*callback_type)(void*);
virtual callback_type get_callback(void) = 0;
virtual ~BaseClass() {}
};
struct ActualType: BaseClass {
callback_type get_callback(void) { return my_callback; }
static void my_callback(void *p) {
ActualType *self = static_cast<ActualType*>(p);
...
}
};
void register_callback(BaseClass *p) {
// service.register_listener(p->get_callback(), p); // WRONG!
service.register_listener(p->get_callback(), dynamic_cast<void*>(p));
}
The WRONG! code is wrong because it fails in the presence of multiple inheritance (and isn't guaranteed to work in the absence, either).
Of course, the API isn't very C++-style, and even the "right" code can go wrong if I inherit from ActualType. So I wouldn't claim that this is a brilliant use of dynamic_cast<void*>, but it's a use.
Casting pointers to void* has its importance since way back in C days.
Most suitable place is inside the memory manager of Operating System. It has to store all the pointer and the object of what you create. By storing it in void* they generalize it to store any object on to the memory manager data structure which could be heap/B+Tree or simple arraylist.
For simplicity take example of creating a list of generic items(List contains items of completely different classes). That would be possible only using void*.
standard says that dynamic_cast should return null for illegal type casting and standard also guarantees that any pointer should be able to type cast it to void* and back from it with only exception of function pointers.
Normal application level practical usage is very less for void* typecasting but it is used extensively in low level/embedded systems.
Normally you would want to use reinterpret_cast for low level stuff, like in 8086 it is used to offset pointer of same base to get the address but not restricted to this.
Edit:
Standard says that you can convert any pointer to void* even with dynamic_cast<> but it no where states that you can not convert the void* back to the object.
For most usage, its a one way street but there are some unavoidable usage.
It just says that dynamic_cast<> needs type information for converting it back to the requested type.
There are many API's that require you to pass void* to some object eg. java/Jni Code passes the object as void*.
Without type info you cannot do the casting.If you are confident enough that type requested is correct you can ask compiler to do the dynmaic_cast<> with a trick.
Look at this code:
class Base_Class {public : virtual void dummy() { cout<<"Base\n";} };
class Derived_Class: public Base_Class { int a; public: void dummy() { cout<<"Derived\n";} };
class MostDerivedObject : public Derived_Class {int b; public: void dummy() { cout<<"Most\n";} };
class AnotherMostDerivedObject : public Derived_Class {int c; public: void dummy() { cout<<"AnotherMost\n";} };
int main () {
try {
Base_Class * ptr_a = new Derived_Class;
Base_Class * ptr_b = new MostDerivedObject;
Derived_Class * ptr_c,*ptr_d;
ptr_c = dynamic_cast< Derived_Class *>(ptr_a);
ptr_d = dynamic_cast< Derived_Class *>(ptr_b);
void* testDerived = dynamic_cast<void*>(ptr_c);
void* testMost = dynamic_cast<void*>(ptr_d);
Base_Class* tptrDerived = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testDerived));
tptrDerived->dummy();
Base_Class* tptrMost = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testMost));
tptrMost->dummy();
//tptrMost = dynamic_cast<AnotherMostDerivedObject*>(static_cast<Base_Class*>(testMost));
//tptrMost->dummy(); //fails
} catch (exception& my_ex) {cout << "Exception: " << my_ex.what();}
system("pause");
return 0;
}
Please correct me if this is not correct in any way.
it is usefull when we put the storage back to memory pool but we only keep a pointer to the base class. This case we should figure out the original address.
Expanding on #BruceAdi's answer and inspired by this discussion, here's a polymorphic situation which may require pointer adjustment. Suppose we have this factory-type setup:
struct Base { virtual ~Base() = default; /* ... */ };
struct Derived : Base { /* ... */ };
template <typename ...Args>
Base * Factory(Args &&... args)
{
return ::new Derived(std::forward<Args>(args)...);
}
template <typename ...Args>
Base * InplaceFactory(void * location, Args &&... args)
{
return ::new (location) Derived(std::forward<Args>(args)...);
}
Now I could say:
Base * p = Factory();
But how would I clean this up manually? I need the actual memory address to call ::operator delete:
void * addr = dynamic_cast<void*>(p);
p->~Base(); // OK thanks to virtual destructor
// ::operator delete(p); // Error, wrong address!
::operator delete(addr); // OK
Or I could re-use the memory:
void * addr = dynamic_cast<void*>(p);
p->~Base();
p = InplaceFactory(addr, "some", "arguments");
delete p; // OK now
Don't do that at home
struct Base {
virtual ~Base ();
};
struct D : Base {};
Base *create () {
D *p = new D;
return p;
}
void *destroy1 (Base *b) {
void *p = dynamic_cast<void*> (b);
b->~Base ();
return p;
}
void destroy2 (void *p) {
operator delete (p);
}
int i = (destroy2 (destroy1 (create ())), i);
Warning: This will not work if D is defined as:
struct D : Base {
void* operator new (size_t);
void operator delete (void*);
};
and there is no way to make it work.
This might be one way to provide an Opaque Pointer through an ABI. Opaque Pointers -- and, more generally, Opaque Data Types -- are used to pass objects and other resources around between library code and client code in such a way that the client code can be isolated from the implementation details of the library. There are other ways to accomplish this, to be sure, and maybe some of them would be better for a particular use case.
Windows makes a lot of use of Opaque Pointers in its API. HANDLE is, I believe, generally an opaque pointer to the actual resource you have a HANDLE to, for example. HANDLEs can be Kernel Objects like files, GDI objects, and all sorts of User Objects of various kinds -- all of which must be vastly different in implementation, but all are returned as a HANDLE to the user.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
/*** LIBRARY.H ***/
namespace lib
{
typedef void* MYHANDLE;
void ShowObject(MYHANDLE h);
MYHANDLE CreateObject();
void DestroyObject(MYHANDLE);
};
/*** CLIENT CODE ***/
int main()
{
for( int i = 0; i < 25; ++i )
{
cout << "[" << setw(2) << i << "] :";
lib::MYHANDLE h = lib::CreateObject();
lib::ShowObject(h);
lib::DestroyObject(h);
cout << "\n";
}
}
/*** LIBRARY.CPP ***/
namespace impl
{
class Base { public: virtual ~Base() { cout << "[~Base]"; } };
class Foo : public Base { public: virtual ~Foo() { cout << "[~Foo]"; } };
class Bar : public Base { public: virtual ~Bar() { cout << "[~Bar]"; } };
};
lib::MYHANDLE lib::CreateObject()
{
static bool init = false;
if( !init )
{
srand((unsigned)time(0));
init = true;
}
if( rand() % 2 )
return static_cast<impl::Base*>(new impl::Foo);
else
return static_cast<impl::Base*>(new impl::Bar);
}
void lib::DestroyObject(lib::MYHANDLE h)
{
delete static_cast<impl::Base*>(h);
}
void lib::ShowObject(lib::MYHANDLE h)
{
impl::Foo* foo = dynamic_cast<impl::Foo*>(static_cast<impl::Base*>(h));
impl::Bar* bar = dynamic_cast<impl::Bar*>(static_cast<impl::Base*>(h));
if( foo )
cout << "FOO";
if( bar )
cout << "BAR";
}
Related
I'm working on some 3D rending using OpenGL and I have made a base class object, which should be used for any type of object that can be rendered.
I'm storing all my objects in a vector of Object Pointers.
Because different objects may require different treatment by some functions, it would be handy to know, if a pointer points to a for example cube or a sphere.
So is there a way in C++ to get the type of a variable when a pointer to this variable is known?
The best solution to your use case seems to be the visitor pattern.
Visitor Pattern Explanation
https://en.wikipedia.org/wiki/Visitor_pattern
The pattern allows you to implement type-specific behavior without changing the implementation of these types (except extending it once of course).
Long story short: No.
If you own a typed pointer (e.g. char *) - well, that might be a char what the pointer points, but we will never know the truth. If you own a void * pointer, then good luck, you aren't going to find anything interesting.
The types don't exist at runtime. Size is preserved (int = 4 bytes, double = 8 bytes), but no type info is usually guaranteed to be stored.
So it seems that there is no real solution to this other than using virtual functions.
Option 1, dynamic cast.
class Object {};
class Box : public Object {};
class Sphere : public Object {};
void f(Object* obj)
{
if(Sphere* sphere = dynamic_cast<Sphere*>(obj))
{
// do something with sphere
}
if(Box* box = dynamic_cast<Box*>(obj))
{
// do something with box
}
}
Option 2, roll your own form of RTTI:
#include <iostream>
#include <vector>
#include <cstdint>
#define DECLARE_TYPE(TypeId, ObjectType, Base) \
bool is(uint32_t typeId) const override { \
if(typeId == (TypeId)) return true; \
return Base::is(typeId); \
} \
constexpr static uint32_t kTypeId = (TypeId); \
const char* typeName() const override { return #ObjectType; } \
uint32_t typeId() const override { return kTypeId; }
class Object
{
public:
constexpr static uint32_t kTypeId = 0;
template<typename T>
T* as() const
{
return is(T::kTypeId) ? (T*)this : nullptr;
}
virtual bool is(uint32_t typeId) const
{
return typeId == kTypeId;
}
virtual const char* typeName() const
{
return "Object";
}
virtual uint32_t typeId() const
{
return kTypeId;
}
};
class Box : public Object
{
public:
DECLARE_TYPE(1, Box, Object);
};
class Sphere : public Object
{
public:
DECLARE_TYPE(2, Sphere, Object);
};
int main()
{
std::vector<Object*> objs;
objs.emplace_back(new Box);
objs.emplace_back(new Sphere);
objs.emplace_back(new Object);
for(auto obj : objs)
{
std::cout << obj->typeName() << std::endl;
std::cout << obj->typeId() << std::endl;
Box* b = obj->as<Box>();
std::cout << "is box? " << (b ? "Yes" : "No") << std::endl;
Sphere* s = obj->as<Sphere>();
std::cout << "is sphere? " << (s ? "Yes" : "No") << std::endl << std::endl;
}
for(auto obj : objs)
delete obj;
return 0;
}
My advice however, would be to rethink your design if possible, so that you start thinking about collections of objects, rather than single objects
class ObjectCollection
{
virtual void drawAll();
virtual void updateAll();
};
class BoxCollection : public ObjectCollection {};
class SphereCollection : public ObjectCollection {};
std::vector<ObjectCollection*> thingsInMyGame;
When you are doing things in OpenGL, you generally want to minimise the amount of state changes needed during your render loop, and if possible, leverage hardware instancing. This is significantly easier if you have already grouped your game objects by type. Retroactively trying to optimise a std::vector<Object*> for OpenGL rendering won't be very successful.
I have a struct ( can be class ) and is defined in another class as shown
struct A{
somedata_A;
somespecificimplementation_A(someclass *S1);
};
class someclass{
somedata_someclass;
A a;
};
main(){
someclass c1, *c2;
c2 = &c1;
c1.a.somespecificimplementation_A(c2);
}
How do I verify that c2 is indeed a reference for c1? Pardon me for putting up this example as it is obvious that c2 is reference for c1.
Update: A does not store a pointer to someclass
If you don't know nothing about parent, compare member' adresses
void A::somespecificimplementation_A(someclass *S1)
{
if (this == &(S1->a)) {
// parent == S1
} else {
// parent != S1
}
}
Like that:
struct A{
int somedata_A;
int somespecificimplementation_A(someclass *S1){
if ((void*) &(S1->a) == this)
{
std::cout << "S1 is a pointer to myself" << std::endl;
return 1;
}
return 0;
}
};
Assuming struct A has a pointer to c1, you can then take a pointer to c2 and compare pointer values? Similar to what you would do with assignment operator overloads?
Why go the way around and pass a pointer of your class to the nested struct which you then have to test, when you can instead give a reference to the parent by the parent during its construction?
class someclass
{
public:
struct a
{
void foo()
{
parent.doSomething();
}
private:
friend someclass;
a(someclass & parent)
: parent(parent)
{}
someclass & parent;
} a;
someclass() : a(*this) {}
private:
void doSomething()
{
}
};
Although technically unspecified, the following will work on
most modern, general purpose machines:
void A::somespecificimplementation_A( someclass* S1 )
{
char const* s = reinterpret_cast<char const*>( S1 );
char const* t = reinterpret_cast<char const*>( this );
if ( this >= s && this < s + sizeof( someclass ) ) {
// This A is a member of S1
} else {
// This A isn't
}
}
Having said that, I would stress:
This is not specified by the standard. It will work on
machines with a flat, linear addressing, but may fail (give
false positives) on a machine with e.g. segmented memory.
I'd seriously question the design if A needs to know who it
is a member of.
And if A really does need this information, it really should store
a pointer to someclass, which is passed in to its constructor, so that the dependency is manifest.
I am working on design a wrapper class to provide RAII function.
The original use case is as follows:
void* tid(NULL);
OpenFunc(&tid);
CloseFunc(&tid);
After I introduce a new wrapper class, I expect the future usage will be as follows:
void* tid(NULL);
TTTA(tid);
or
TTTB(tid);
Question:
Which implementation TTTA or TTTB is better? Or they are all bad and please introduce a better one.
One thing I have concern is that after the resource is allocated, the id will be accessed outside of class TTTA or TTTB until the id is destroyed. Based on my understanding, my design should not have side-effect for that.
Thank you
class TTTA : boost::noncopyable
{
public:
explicit TTTA(void *id)
: m_id(id)
{
OpenFunc(&m_id); // third-party allocate resource API
}
~TTTA()
{
CloseFunc(&m_id); // third-party release resource API
}
private:
void* &m_id; // have to store the value in order to release in destructor
}
class TTTB : boost::noncopyable
{
public:
explicit TTTB(void *id)
: m_id(&id)
{
OpenFunc(m_id); // third-party allocate resource API
}
~TTTB()
{
CloseFunc(m_id); // third-party release resource API
}
private:
void** m_id; // have to store the value in order to release in destructor
}
// pass-in pointers comparison
class TTTD
{
public:
TTTD(int* id) // Take as reference, do not copy to stack.
: m_id(&id)
{
*m_id = new int(40);
}
private:
int** m_id;
};
class TTTC
{
public:
TTTC(int* &id)
: m_id(id)
{
m_id = new int(30);
}
private:
int* &m_id;
};
class TTTB
{
public:
TTTB(int* id)
: m_id(id)
{
m_id = new int(20);
}
private:
int* &m_id;
};
class TTTA
{
public:
TTTA(int** id)
: m_id(id)
{
*m_id = new int(10);
}
private:
int** m_id;
};
int main()
{
//////////////////////////////////////////////////////////////////////////
int *pA(NULL);
TTTA a(&pA);
cout << *pA << endl; // 10
//////////////////////////////////////////////////////////////////////////
int *pB(NULL);
TTTB b(pB);
//cout << *pB << endl; // wrong
//////////////////////////////////////////////////////////////////////////
int *pC(NULL);
TTTC c(pC);
cout << *pC << endl; // 30
//////////////////////////////////////////////////////////////////////////
int *pD(NULL);
TTTD d(pD);
cout << *pD << endl; // wrong
}
Both break in bad ways.
TTTA stores a reference to a variable (the parameter id) that's stored on the stack.
TTTB stores a pointer to a variable that's stored on the stack.
Both times, the variable goes out of scope when the constructor returns.
EDIT: Since you want the values modifiable, the simplest fix is to take the pointer as a reference; that will make TTTC reference the actual pointer instead of the local copy made when taking the pointer as a non reference parameter;
class TTTC : boost::noncopyable
{
public:
explicit TTTA(void *&id) // Take as reference, do not copy to stack.
: m_id(id)
...
private:
void* &m_id; // have to store the value in order to release in destructor
}
The simple test that breaks your versions is to add a print method to the classes to print the pointer value and do;
int main() {
void* a = (void*)0x200;
void* b = (void*)0x300;
{
TTTA ta(a);
TTTA tb(b);
ta.print();
tb.print();
}
}
Both TTTA and TTTB print both values as 0x300 on my machine. Of course, the result is really UB; so your result may vary.
Why do you tid at all? It’s leaking information to the client and makes the usage twice as long (two lines instead of one):
class tttc {
void* id;
public:
tttc() {
OpenFunc(&id);
}
~tttc() {
CloseFunc(&id);
}
tttc(tttc const&) = delete;
tttc& operator =(tttc const&) = delete;
};
Note that this class forbids copying – your solutions break the rule of three.
If you require access to id from the outside, provide a conversion inside tttc:
void* get() const { return id; }
Or, if absolutely necessary, via an implicit conversion:
operator void*() const { return id; }
(But use that one judiciously since implicit conversions weaken the type system and may lead to hard to diagnose bugs.)
And then there’s std::unique_ptr in the standard library which, with a custom deleter, actually achieves the same and additionally implements the rule of three properly.
What about wrapping it completely? This way you do not have to worry about managing the lifecycles of two variables, but only one.
class TTTC
{
void* m_id;
public:
TTTC()
: m_id(nullptr)
{
OpenFunc(&m_id); // third-party allocate resource API
}
TTTC(TTTC const&) = delete; // or ensure copying does what you expect
void*const& tid() const { return m_id; }
~TTTC()
{
CloseFunc(&m_id); // third-party release resource API
}
};
Using it is simplicity itself:
TTTC wrapped;
DoSomethingWithTid(wrapped.tid());
Consider the following code:
class A
{
B* b; // an A object owns a B object
A() : b(NULL) { } // we don't know what b will be when constructing A
void calledVeryOften(…)
{
if (b)
delete b;
b = new B(param1, param2, param3, param4);
}
};
My goal: I need to maximize performance, which, in this case, means minimizing the amount of memory allocations.
The obvious thing to do here is to change B* b; to B b;. I see two problems with this approach:
I need to initialize b in the constructor. Since I don't know what b will be, this means I need to pass dummy values to B's constructor. Which, IMO, is ugly.
In calledVeryOften(), I'll have to do something like this: b = B(…), which is wrong for two reasons:
The destructor of b won't be called.
A temporary instance of B will be constructed, then copied into b, then the destructor of the temporary instance will be called. The copy and the destructor call could be avoided. Worse, calling the destructor could very well result in undesired behavior.
So what solutions do I have to avoid using new? Please keep in mind that:
I only have control over A. I don't have control over B, and I don't have control over the users of A.
I want to keep the code as clean and readable as possible.
I liked Klaim's answer, so I wrote this up real fast. I don't claim perfect correctness but it looks pretty good to me. (i.e., the only testing it has is the sample main below)
It's a generic lazy-initializer. The space for the object is allocated once, and the object starts at null. You can then create, over-writing previous objects, with no new memory allocations.
It implements all the necessary constructors, destructor, copy/assignment, swap, yadda-yadda. Here you go:
#include <cassert>
#include <new>
template <typename T>
class lazy_object
{
public:
// types
typedef T value_type;
typedef const T const_value_type;
typedef value_type& reference;
typedef const_value_type& const_reference;
typedef value_type* pointer;
typedef const_value_type* const_pointer;
// creation
lazy_object(void) :
mObject(0),
mBuffer(::operator new(sizeof(T)))
{
}
lazy_object(const lazy_object& pRhs) :
mObject(0),
mBuffer(::operator new(sizeof(T)))
{
if (pRhs.exists())
{
mObject = new (buffer()) T(pRhs.get());
}
}
lazy_object& operator=(lazy_object pRhs)
{
pRhs.swap(*this);
return *this;
}
~lazy_object(void)
{
destroy();
::operator delete(mBuffer);
}
// need to make multiple versions of this.
// variadic templates/Boost.PreProccesor
// would help immensely. For now, I give
// two, but it's easy to make more.
void create(void)
{
destroy();
mObject = new (buffer()) T();
}
template <typename A1>
void create(const A1 pA1)
{
destroy();
mObject = new (buffer()) T(pA1);
}
void destroy(void)
{
if (exists())
{
mObject->~T();
mObject = 0;
}
}
void swap(lazy_object& pRhs)
{
std::swap(mObject, pRhs.mObject);
std::swap(mBuffer, pRhs.mBuffer);
}
// access
reference get(void)
{
return *get_ptr();
}
const_reference get(void) const
{
return *get_ptr();
}
pointer get_ptr(void)
{
assert(exists());
return mObject;
}
const_pointer get_ptr(void) const
{
assert(exists());
return mObject;
}
void* buffer(void)
{
return mBuffer;
}
// query
const bool exists(void) const
{
return mObject != 0;
}
private:
// members
pointer mObject;
void* mBuffer;
};
// explicit swaps for generality
template <typename T>
void swap(lazy_object<T>& pLhs, lazy_object<T>& pRhs)
{
pLhs.swap(pRhs);
}
// if the above code is in a namespace, don't put this in it!
// specializations in global namespace std are allowed.
namespace std
{
template <typename T>
void swap(lazy_object<T>& pLhs, lazy_object<T>& pRhs)
{
pLhs.swap(pRhs);
}
}
// test use
#include <iostream>
int main(void)
{
// basic usage
lazy_object<int> i;
i.create();
i.get() = 5;
std::cout << i.get() << std::endl;
// asserts (not created yet)
lazy_object<double> d;
std::cout << d.get() << std::endl;
}
In your case, just create a member in your class: lazy_object<B> and you're done. No manual releases or making copy-constructors, destructors, etc. Everything is taken care of in your nice, small re-usable class. :)
EDIT
Removed the need for vector, should save a bit of space and what-not.
EDIT2
This uses aligned_storage and alignment_of to use the stack instead of heap. I used boost, but this functionality exists in both TR1 and C++0x. We lose the ability to copy, and therefore swap.
#include <boost/type_traits/aligned_storage.hpp>
#include <cassert>
#include <new>
template <typename T>
class lazy_object_stack
{
public:
// types
typedef T value_type;
typedef const T const_value_type;
typedef value_type& reference;
typedef const_value_type& const_reference;
typedef value_type* pointer;
typedef const_value_type* const_pointer;
// creation
lazy_object_stack(void) :
mObject(0)
{
}
~lazy_object_stack(void)
{
destroy();
}
// need to make multiple versions of this.
// variadic templates/Boost.PreProccesor
// would help immensely. For now, I give
// two, but it's easy to make more.
void create(void)
{
destroy();
mObject = new (buffer()) T();
}
template <typename A1>
void create(const A1 pA1)
{
destroy();
mObject = new (buffer()) T(pA1);
}
void destroy(void)
{
if (exists())
{
mObject->~T();
mObject = 0;
}
}
// access
reference get(void)
{
return *get_ptr();
}
const_reference get(void) const
{
return *get_ptr();
}
pointer get_ptr(void)
{
assert(exists());
return mObject;
}
const_pointer get_ptr(void) const
{
assert(exists());
return mObject;
}
void* buffer(void)
{
return mBuffer.address();
}
// query
const bool exists(void) const
{
return mObject != 0;
}
private:
// types
typedef boost::aligned_storage<sizeof(T),
boost::alignment_of<T>::value> storage_type;
// members
pointer mObject;
storage_type mBuffer;
// non-copyable
lazy_object_stack(const lazy_object_stack& pRhs);
lazy_object_stack& operator=(lazy_object_stack pRhs);
};
// test use
#include <iostream>
int main(void)
{
// basic usage
lazy_object_stack<int> i;
i.create();
i.get() = 5;
std::cout << i.get() << std::endl;
// asserts (not created yet)
lazy_object_stack<double> d;
std::cout << d.get() << std::endl;
}
And there we go.
Simply reserve the memory required for b (via a pool or by hand) and reuse it each time you delete/new instead of reallocating each time.
Example :
class A
{
B* b; // an A object owns a B object
bool initialized;
public:
A() : b( malloc( sizeof(B) ) ), initialized(false) { } // We reserve memory for b
~A() { if(initialized) destroy(); free(b); } // release memory only once we don't use it anymore
void calledVeryOften(…)
{
if (initialized)
destroy();
create();
}
private:
void destroy() { b->~B(); initialized = false; } // hand call to the destructor
void create( param1, param2, param3, param4 )
{
b = new (b) B( param1, param2, param3, param4 ); // in place new : only construct, don't allocate but use the memory that the provided pointer point to
initialized = true;
}
};
In some cases a Pool or ObjectPool could be a better implementation of the same idea.
The construction/destruction cost will then only be dependante on the constructor and destructor of the B class.
How about allocating the memory for B once (or for it's biggest possible variant) and using placement new?
A would store char memB[sizeof(BiggestB)]; and a B*. Sure, you'd need to manually call the destructors, but no memory would be allocated/deallocated.
void* p = memB;
B* b = new(p) SomeB();
...
b->~B(); // explicit destructor call when needed.
If B correctly implements its copy assignment operator then b = B(...) should not call any destructor on b. It is the most obvious solution to your problem.
If, however, B cannot be appropriately 'default' initialized you could do something like this. I would only recommend this approach as a last resort as it is very hard to get safe. Untested, and very probably with corner case exception bugs:
// Used to clean up raw memory of construction of B fails
struct PlacementHelper
{
PlacementHelper() : placement(NULL)
{
}
~PlacementHelper()
{
operator delete(placement);
}
void* placement;
};
void calledVeryOften(....)
{
PlacementHelper hp;
if (b == NULL)
{
hp.placement = operator new(sizeof(B));
}
else
{
hp.placement = b;
b->~B();
b = NULL; // We can't let b be non-null but point at an invalid B
}
// If construction throws, hp will clean up the raw memory
b = new (placement) B(param1, param2, param3, param4);
// Stop hp from cleaning up; b points at a valid object
hp.placement = NULL;
}
A quick test of Martin York's assertion that this is a premature optimisation, and that new/delete are optimised well beyond the ability of mere programmers to improve. Obviously the questioner will have to time his own code to see whether avoiding new/delete helps him, but it seems to me that for certain classes and uses it will make a big difference:
#include <iostream>
#include <vector>
int g_construct = 0;
int g_destruct = 0;
struct A {
std::vector<int> vec;
A (int a, int b) : vec((a*b) % 2) { ++g_construct; }
~A() {
++g_destruct;
}
};
int main() {
const int times = 10*1000*1000;
#if DYNAMIC
std::cout << "dynamic\n";
A *x = new A(1,3);
for (int i = 0; i < times; ++i) {
delete x;
x = new A(i,3);
}
#else
std::cout << "automatic\n";
char x[sizeof(A)];
A* yzz = new (x) A(1,3);
for (int i = 0; i < times; ++i) {
yzz->~A();
new (x) A(i,3);
}
#endif
std::cout << g_construct << " constructors and " << g_destruct << " destructors\n";
}
$ g++ allocperf.cpp -oallocperf -O3 -DDYNAMIC=0 -g && time ./allocperf
automatic
10000001 constructors and 10000000 destructors
real 0m7.718s
user 0m7.671s
sys 0m0.030s
$ g++ allocperf.cpp -oallocperf -O3 -DDYNAMIC=1 -g && time ./allocperf
dynamic
10000001 constructors and 10000000 destructors
real 0m15.188s
user 0m15.077s
sys 0m0.047s
This is roughly what I expected: the GMan-style (destruct/placement new) code takes twice as long, and is presumably doing twice as much allocation. If the vector member of A is replaced with an int, then the GMan-style code takes a fraction of a second. That's GCC 3.
$ g++-4 allocperf.cpp -oallocperf -O3 -DDYNAMIC=1 -g && time ./allocperf
dynamic
10000001 constructors and 10000000 destructors
real 0m5.969s
user 0m5.905s
sys 0m0.030s
$ g++-4 allocperf.cpp -oallocperf -O3 -DDYNAMIC=0 -g && time ./allocperf
automatic
10000001 constructors and 10000000 destructors
real 0m2.047s
user 0m1.983s
sys 0m0.000s
This I'm not so sure about, though: now the delete/new takes three times as long as the destruct/placement new version.
[Edit: I think I've figured it out - GCC 4 is faster on the 0-sized vectors, in effect subtracting a constant time from both versions of the code. Changing (a*b)%2 to (a*b)%2+1 restores the 2:1 time ratio, with 3.7s vs 7.5]
Note that I've not taken any special steps to correctly align the stack array, but printing the address shows it's 16-aligned.
Also, -g doesn't affect the timings. I left it in accidentally after I was looking at the objdump to check that -O3 hadn't completely removed the loop. That pointers called yzz because searching for "y" didn't go quite as well as I'd hoped. But I've just re-run without it.
Are you sure that memory allocation is the bottleneck you think it is? Is B's constructor trivially fast?
If memory allocation is the real problem, then placement new or some of the other solutions here might well help.
If the types and ranges of the param[1..4] are reasonable, and the B constructor "heavy", you might also consider using a cached set of B. This presumes you are actually allowed to have more than one at a time, that it does not front a resource for example.
Like the others have already suggested: Try placement new..
Here is a complete example:
#include <new>
#include <stdio.h>
class B
{
public:
int dummy;
B (int arg)
{
dummy = arg;
printf ("C'Tor called\n");
}
~B ()
{
printf ("D'tor called\n");
}
};
void called_often (B * arg)
{
// call D'tor without freeing memory:
arg->~B();
// call C'tor without allocating memory:
arg = new(arg) B(10);
}
int main (int argc, char **args)
{
B test(1);
called_often (&test);
}
I'd go with boost::scoped_ptr here:
class A: boost::noncopyable
{
typedef boost::scoped_ptr<B> b_ptr;
b_ptr pb_;
public:
A() : pb_() {}
void calledVeryOften( /*…*/ )
{
pb_.reset( new B( params )); // old instance deallocated
// safely use *pb_ as reference to instance of B
}
};
No need for hand-crafted destructor, A is non-copyable, as it should be in your original code, not to leak memory on copy/assignment.
I'd suggest to re-think the design though if you need to re-allocate some inner state object very often. Look into Flyweight and State patterns.
Erm, is there some reason you can't do this?
A() : b(new B()) { }
void calledVeryOften(…)
{
b->setValues(param1, param2, param3, param4);
}
(or set them individually, since you don't have access to the B class - those values do have mutator-methods, right?)
Just have a pile of previously used Bs, and re-use them.
I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.