Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use reference member?

I just realized I couldn't even figure out one use case of reference member in C++. Say, if I define the following class:

class Book {
   public:
       Book(const Author& author) : author(author) {}
   private:
       const Author &author;
}

How could I even use it? If I pass a newed Author to it:

Book book(*(new Author()));

Doesn't it leak memory? When will the Author be released?

Let me try again. How about passing a local variable to it:

Book macBook() {
    Author author();
    return Book(author);
}

Doesn't the returned Book have a invalid(released) reference?

I can't imagine the third way to use it. So why does reference member exist? When should I use it?

EDIT: I know there is share_ptr. But should I ALWAYS prefer share_ptr to reference?

like image 365
Lai Yu-Hsuan Avatar asked Oct 19 '25 00:10

Lai Yu-Hsuan


2 Answers

You must make sure that the author's lifetime is at least as long as the book (or, at least, be very careful not to use the book's reference outside the author's lifetime). A simple way to ensure that is to put them in the same scope, with the author created first:

Author author;
Book book(author);

As you say, both the examples in the question are bad: the first leaks memory (or would, if you added a * to make it compile), and the second leaves you with a dangling reference. But there are plenty of other ways to manage object lifetimes.

like image 193
Mike Seymour Avatar answered Oct 20 '25 15:10

Mike Seymour


If your function requires a const Author& and you pass a new Author(), then your program will not compile, because new Author() is an Author*, not an Author&.

You can pass a *(new Author()), but then you will have a leak unless the destructor of the Book deletes the &author. However, it's very odd to have a reference member and in the destructor take the address of that member and delete it. Your fellow developers will hate you for that, especially since it is not clear from the function signature, that the argument must to be allocated using new.

You can pass an Author to Book(const Author& author), but you have to make sure that the Author lives at least as long as the Book. So yes, in the code

Book macBook() {
    Author author();
    return Book(author);
}

the returned book has an invalid reference.

I suspect reference members exist for the same reason that null pointers exist: because it was so easy to implement.

like image 31
Oswald Avatar answered Oct 20 '25 16:10

Oswald



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!