I read C ++ Super-FAQ . In the Constructors section I come across this statement:

BTW do NOT try to achieve this through placement. Foo (x, int (x) +7) within the body of foo :: foo (char). However that is bad, bad, bad. Please don’t write to me on your particular compiler; it's bad

The point is that it is absolutely impossible to do so:

class Foo{ public: Foo(char x){ new (this) Foo(x, int(x)+7); } Foo(char x, int y){ //... } }; 

Can someone explain in more detail what threatens such a trick?

UPD: I suspect that in this example, everything will be fine, and problems will begin with inheritance, dynamic resource allocation, etc.

  • Well, there should be an explanation of this emotional author. - Vlad from Moscow
  • There are some ways to get a piece of music . Just say no. - yrHeTaTeJlb
  • one
    @VladfromMoscow, it really didn't help me very much :) - yrHeTaTeJlb
  • In general, the problem with such code is that when the body of the constructor is executed, the object and its sub-objects are already constructed. Calling the constructor a second time, destructors for the created objects are not called, which leads to undefined program behavior. - Vlad from Moscow

2 answers 2

http://ideone.com/gkgi7S :

 class Base { public: Base() { ptr = new int[100]; cout << "alloc mem at " << ptr << endl; } ~Base() { delete [] ptr; cout << "free mem at " << ptr << endl; } int * ptr; }; class Derived: public Base { public: Derived(int x, int y):x(x),y(y){} Derived(int x) { new(this) Derived(x,0); } int x, y; }; int main(int argc, const char * argv[]) { Derived d(5); } 

Conclusion:

 alloc mem at 0070EA58 alloc mem at 0070FFE8 free mem at 0070FFE8 

Such an example is enough? ...

It is possible and without inheritance - the essence does not change:

 class Derived { public: Derived(int x, int y):x(x),y(y){} Derived(int x) { new(this) Derived(x,0); } int x, y; Base b; }; 

    What does the vicar of God on Earth, Stroustrup, write: link

    Example of use:

     /*1*/ char *pBuf = new char[sizeof(string)]; /*2*/ string *p = new (pBuf) string("hi"); /*3*/ string *q = new string("hi"); 

    In the first line, we allocate memory, and second, we are building an object on an already allocated area of ​​memory. An example is trivial, but you will catch the essence: we are building an object on a previously allocated area of ​​memory and we can be sure that there will not be a failure in the allocation of memory - after all, it is already allocated in the required "volume", so to speak. A real example is some critical sections for which speed is important, the absence of exceptions, etc.

    Placement operator, for example:

     const SomeoneClass& SomeoneClass::operator=( const SomeoneClass& other) { if ( this != &other ) { this->~SomeoneClass(); new (this) SomeoneClass(other); } return *this; } 

    Well, note that Stroustrup writes about the release of memory in such cases.