placement new to defer to a different constructor

前端 未结 7 899
滥情空心
滥情空心 2021-01-04 12:28

Is this safe? I\'m not using any virtual functions in my actual implementation, but I\'m tempted to believe that even if I was, it would still be safe.

clas         


        
相关标签:
7条回答
  • 2021-01-04 12:40

    It looks like the best solution to this problem is to just create a different function to do the initialization:

    class Foo
    {
        inline void nullify()
        {
            // initialize things
        }
    
        Foo()
        {
            nullify();
        }
    
        Foo( int )
        {
            nullify();
        }
    }
    
    0 讨论(0)
  • 2021-01-04 12:44

    As others said, is a bad idea, and as a possible destructive case: what if you do

    class Foo
    {
        Foo()
        {
            // initialize things
        }
    
        Foo( int bar )
        {
             new ( this ) Foo(bar);
        }
    }
    

    welcome no the land of infinite recursion.

    0 讨论(0)
  • 2021-01-04 12:50

    You wouldn't be safe if you extended another class and that class had a destructor, for example

    class Foo
    {
        int* a;
    public:
        Foo():a(new int)
        {
    
        }
        ~Foo(){delete a;}
    }
    
    class Bar:public Foo
    {
        Bar()
        {
            // initialize things
        }
    
        Bar( int )
        {
             new ( this ) Foo();
        }
    }
    

    First Bar(int) calls Foo(), then it calls Bar() which also calls Foo(). The second time Foo() is called, it overwrites the pointer set up by the first call to Foo(), and the allocated memory is leaked.

    0 讨论(0)
  • 2021-01-04 12:53

    One worry I have is if Foo uses multiple inheritance you'll need to cast the this pointer to the most base class first. Othewise if the the this is offset (sometimes happens in multiple inheritance) it'll construct at the wrong address.

    0 讨论(0)
  • 2021-01-04 12:56

    The key problem here is that constructors are special - when you write a construct that calls a constructor (for example use new keyword to create an object) not only the constructor body is executed, instead the whole chain of objects is constructed first.

    So when you use placement-new syntax to run another constructor first C++ automagically reruns all the base class object constructors and all the member variables constructors and only then the other constructor body is invoked. Sometimes you'll be okay, but many times you will run into unexpected behavior.

    0 讨论(0)
  • 2021-01-04 12:57

    http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3

    0 讨论(0)
提交回复
热议问题