16

When I want to instantiate a class in C++ I usually go this way

Book bk = new Book();

My professor recently did this

Book &bk = *new Book();

He only told me that he would use a reference to be able to use the dot (eg bk.getTitle();) operator instead of arrow (eg bk->getTitle();). I understand this part of the code but what happens when you use the * operator in combination with new?

Thanks in advance

the full example code can be found here it is the arraystack in the main function

Donato Szilagyi
  • 4,279
  • 4
  • 36
  • 53
tim
  • 203
  • 1
  • 2
  • 7
  • 9
    So your professor showed you how to leak memory, great. – ildjarn Feb 15 '12 at 00:44
  • 2
    If your professor uses that code for anything other than as an example of something that you really really shouldn't do, then you should find a new professor. – Oliver Charlesworth Feb 15 '12 at 00:44
  • Probably your professor said, `const Book &bk = Book();`. If that is not the case, I honestly don't understand what your professor meant. – Mahesh Feb 15 '12 at 00:45
  • 1
    @Mahesh : The syntax in the question is valid, it's the semantics that are extremely misguided. – ildjarn Feb 15 '12 at 00:47
  • the full example can be found here. maybe this makes more sense then. the part is in the main function. its the arraystack. [source](http://pastebin.com/Lg2YVME5) – tim Feb 15 '12 at 00:49
  • @ildjarn I understand now. But with that syntax, can I do - `delete bk;`. Isn't a case where memory leak is inevitable? – Mahesh Feb 15 '12 at 00:49
  • 2
    @Mahesh You could do `delete &bk`, but this is still non-sense. @OP Find a new professor. – pmr Feb 15 '12 at 00:51

2 Answers2

29

This:

Book &bk = *new Book();

is pretty much equivalent to this:

Book *p = new Book();  // Pointer to new book
Book &bk = *p;  // Reference to that book

But there's one crucial difference; in the original code, you don't have a pointer which you can use to delete the dynamically-allocated object when you're done with it, so you've effectively created a memory leak.

Of course, you could do this:

delete &bk;

but that's extremely non-idiomatic C++, and very likely to cause problems later.

In summary, there's absolutely no good reason to write code like this, so don't do it. Either of the following is fine:

Book bk;
Book bk = Book();
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • thank you I think I will not use it then. The class is more about design patterns than it is about c++ so I will just ignore this programming style and do it my way. – tim Feb 15 '12 at 00:53
  • 1
    You have definitely not created a memory leak though, I think that's a huge overstatement – Seth Carnegie Feb 15 '12 at 00:56
  • @Seth : The original code does indeed have a leak... What do you mean? – ildjarn Feb 15 '12 at 00:57
  • 1
    @SethCarnegie: That's why I said "effectively". But the need to write things like insanities such as `delete &bk` leads to all sorts of semantic issues, which in turn will lead to forgetting to clean something up somewhere down the line. – Oliver Charlesworth Feb 15 '12 at 00:58
  • 1
    what issues could `delete &bk;` cause? just out of curiosity. – xyf May 12 '22 at 02:57
0

I've found a situation that let me think about that syntax. Consider a smart pointer to a Base class and that has to hold a pointer to a derived class and you would like to access some non-virtual things of the derived class after the construction. In this case something like this is legal and may not be so bad:

Derived & d = * new Derived();

d.d_method( ..whatever.. );
d.d_member = ..whatever..;
...

std::unique_ptr<Base> p( &d );

Finally I still preferred the small arrows to the weird ampersands:

Derived d = new Derived();

d->d_method( ..whatever.. );
d->d_member = ..whatever..;
...

std::unique_ptr<Base> p( d );

But I think that in this a case is just a matter of taste, especially if you access a consistent number of methods.

Other things that lead either to leaks or delete &d; are just bad, bad, bad.

DarioP
  • 5,377
  • 1
  • 33
  • 52
  • `error: Conversion from 'Derived*' to non-scalar type 'Derived' requested` – Sebi2020 Jan 28 '23 at 14:57
  • 1
    @Sebi2020 Yes, a pointer cannot be implicitly converted to its base type. I may have forgotten a `*` or something on the line that triggers the error. – DarioP Jan 29 '23 at 16:07