is there any other way to call the constructor

Started by
9 comments, last by snk_kid 19 years, 6 months ago
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." ?
Z
Advertisement
Use placement new.
malloc has no notion of constructors. Or objects.

You're treading dangerously ugly ground here...
Quote:Original post by Oluseyi
You're treading dangerously ugly ground here...


I agree
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 thisstruct 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.
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?
It should be something like:

void* p = malloc(sizeof(Foo));
Foo* foo = new(p) Foo(34);

After the ctor is invoked, you have an actual object to refer to not, not just a chunk of memory (void*).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
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.

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;}

enum Bool { True, False, FileNotFound };
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.

This topic is closed to new replies.

Advertisement