Sign in to follow this  
browny

is there any other way to call the constructor

Recommended Posts

suppose i have a class X with a constructor X. Now i want to call the constructor of X , but without issuing "new". Is that somehow possible using "malloc." ?

Share this post


Link to post
Share on other sites
Quote:
Original post by browny
Now i want to call the constructor of X , but without issuing "new". Is that somehow possible using "malloc." ?



#include <cstdlib>
#include <iostream>
#include <new> //<-- must include this

struct foo {

const int bar;

foo(int i = 0): bar(i) {}

};

int main() {

foo* p = reinterpret_cast<foo*>(malloc(sizeof(foo)));

p = new(p) foo(30); //<-- placement new, does nothing but invoke constructors.

std::cout << p->bar << std::endl;

p->~foo();

free(p);

return 0;

}


Notice that if you use this method you should explicitly invoke the destructor before deallocating memory because free wont invoke it, C memory functions deal with uninitialized memory.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
p = new(p) foo(30); //<-- placement new, does nothing but invoke

Quick question: Since p is allready initialized to the malloced area, and IIRC new is never supposed to return null (instead throwing an exception) - is there anything better about your version over the plainer:
new(p) foo(30);

that I've been using?

Share this post


Link to post
Share on other sites
Every time I've had a situation like this, I added an Init() function or something similar to the class. The constructor then calls it as its primary/only operation. Then actual Initialization can be done seperately if you want to return the class to an original state or otherwise clear it.

As always though I am no expert, but it gets the job done.

Share this post


Link to post
Share on other sites
New throws an exception if it runs out of memory, or if the constructor throws.

Placement new never runs out of memory (by definition) so it will only throw if the constructor throws.

Using an "Init" function in lieu of calling placement new will not work right if the object has a vtable, because part of operator new (including placement new) is to set up the vtable for the object (as part of constructing each sub-object of the object).


#include <stdio.h>
#include <stdlib.h>
#include <new>

class Foo {
public:
virtual void foo() { printf( "%d\n", bar_ ); }
int bar_;
Foo( int b ) : bar_( b ) {}
virtual ~Foo() {}
void init( int b ) { bar_ = b; }
};

int main() {
Foo * f = (Foo *)malloc( sizeof( Foo ) );
#if defined( DONT_CRASH )
new( f ) Foo( 0 );
#endif
f->Init( 1 );
f->foo(); /* watch me crash! */
return 0;
}

Share this post


Link to post
Share on other sites
Not in lieu of calling new. I am perhaps assuming too much, but to me the OP wants to be able to re-initialize the class by calling the constructor, but without creating a new object.

So for the Init way, they would call new foo() [which calls Init] and then just call Init directly when they want to 'reset' the object.


Actually, rereading it, it does seem as though I am assuming too much. *sigh* sorry for cluttering things up.

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
is there anything better about your version over the plainer:
[code]new(p) foo(30);
that I've been using?


Haven't you seen the definition of placement new?:


inline void* operator new(std::size_t, void* __p) throw() { return __p; }


so it makes no difference at the end of the day.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this