4
#include <new>

struct House { };
struct Room
{
  House& h;
  Room(House& h) : h(h) { }
};

int main()
{
   House h1;
   House h2;

   Room r(h1);

   //r = Room(h2); // This obviously won't work.

   ///
   r.~Room();
   new(&r) Room(h2); // This does work    
}

I have used a reference member in one place in my project and I'm wondering it's safe to use this trick as a way to reinitialize the object with a different reference.

Gam
  • 1,254
  • 1
  • 9
  • 18
  • 1
    `new(r)` should be `new(&r)`. – interjay Apr 20 '16 at 14:37
  • i've never seen `new` syntax like either of those (with parens), what does it do? i've never even seen that mentioned in any c++ book i've read – johnbakers Apr 20 '16 at 14:42
  • 4
    Formally, it doesn't reinitialise the object but destroys it and then creates a new one in the old one's place. Informally, this is usually a sign that your design should be reinitialised. – molbdnilo Apr 20 '16 at 14:45
  • 2
    @johnbakers Research [placement new](http://en.cppreference.com/w/cpp/language/new). – James Adkison Apr 20 '16 at 14:45
  • related: http://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new – johnbakers Apr 20 '16 at 14:49
  • 1
    If you need to change what the member points to, why are you using a reference, which is designed against this? Why not a pointer? There are certainly many safer options. – johnbakers Apr 20 '16 at 14:50
  • I'm voting to close this question as off-topic because as of now it is an XY problem. – SergeyA Apr 20 '16 at 14:51
  • @johnbakers, stop using the word **unsafe**. There is nothing unsafe about this code, it is indeed as safe as an insurance policy. – SergeyA Apr 20 '16 at 14:53
  • I can't get this to compile. See [here](http://coliru.stacked-crooked.com/a/9f192ebfa28296f7). It does compile if we use aggregate initialization [here](http://coliru.stacked-crooked.com/a/d0235a5b03fdb466). – wally Apr 20 '16 at 14:55
  • @flatmouse, the code certainly missess constructor for `Room`, but I'd assume, this is simply an effect of code typed in the question. – SergeyA Apr 20 '16 at 14:57
  • @SergeyA, The part that doesn't compile in those examples isn't the missing constructor, but rather the use of `()` vs `{}`. Ah, but ok, if you had the constructor then it would work this way. – wally Apr 20 '16 at 14:58
  • @flatmouse, compiles perfectly OK if you add a missing constructor to `Room` and `#include `. See here: http://coliru.stacked-crooked.com/a/51cd60531a383cc5 – SergeyA Apr 20 '16 at 15:03
  • @SergeyA, default constructor with initializer for the reference member I suppose? Without that we don't really have an MCVE. We have already found two different ways to complete it. I also only learnt about the required header from johnbakers' link. All clear to you, but not so clear for the rest of us mortals... – wally Apr 20 '16 at 15:08
  • @flatmouse, certainly not the **default** constructor! – SergeyA Apr 20 '16 at 15:10
  • @SergeyA, Oops, of course. Not a default constructor. :) At least now the question is complete and clear. – wally Apr 20 '16 at 15:13
  • @molbdnilo Placement new does not necessarily mean a bad design. Many libraries (including the standard library) use placement new to create and manage memory pools, implement garbage collection, or for performance and exception safety. [This answer](http://stackoverflow.com/a/222578/4975646) has a good explanation of the uses for placement new. – callyalater Apr 20 '16 at 18:40
  • @callyalater That's what I wrote; "X is usually a sign of Y" is a very different thing from "X necessarily means Y". – molbdnilo Apr 20 '16 at 18:54

1 Answers1

0

Using placement new is a valid practice. It is safe, and your usage is semantically correct. However, I can't answer the question of applicability in your particular case without your particular case. Provided code doesn't show your case, so I am willing to consider it an XY problem until I hear more.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • I just wanted to know if it was safe to do it because I was not sure. I didn't want to start writing code that may be unsafe. – Gam Apr 20 '16 at 14:54
  • @Phantom, define *safe*. – SergeyA Apr 20 '16 at 14:55
  • @Phantom, perhaps phrase the question in terms of undefined behavior and memory leaks? – wally Apr 20 '16 at 15:03
  • http://stackoverflow.com/a/33515129/6053907 i'm guessing the following only applies if I skip the ~destructor() call? `the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a **reference type**, and` – Gam Apr 20 '16 at 15:03
  • @Phantom, as long as you call the destructor, you are ok. – SergeyA Apr 20 '16 at 15:05