4

I'm pretty sure this is a question purely about aesthetics but I wanted to get all your opinions on it before I start proliferating this type of code in my codebase. Consider the following code:

//Foo.h
class Bar;
class Foo
{
 public:
 Bar& GetBar(){return *bar.get();}
 private:
 std::unique_ptr<Bar> bar;
};
//Bar.h
class Bar
{
 public:
 DoSomething(){//did something...}
};

This allows us to forward declare Bar in Foo.h and avoid having to #include Bar.h. This leads to using Foo's Bar in the following way:

Foo foo;
foo.GetBar().DoSomething();

Personally, I think this would look a lot nicer:

Foo foo;
foo.bar.DoSomething();

To achieve that, I've written:

//Foo.h
class Bar;
class Foo
{
 public:
 Foo();
 Bar& bar;
 private:
 std::unique_ptr<Bar> bar_ptr;
};
//Foo.cpp
#include "Bar.h"
Foo::Foo() : bar_ptr(new Bar()), bar(*bar_ptr) {}

This allows me to forward declare Bar and use the 'bar.' syntax.

Ugly? Not Ugly? The downside is that I have 2 member vars for only 1 object.

asked Apr 17, 2013 at 14:48
1
  • 5
    If you really have written your second example, you have a serious bug. Order of initialization of class members depends only on declaration order; the order of initializers in the constructor is irrelevant. In other words, bar(*bar_ptr) happens before bar_ptr(new Bar()). Commented Jun 6, 2017 at 15:03

2 Answers 2

15
foo.GetBar().DoSomething();

This violates the Law Of Demeter.

Generally I would avoid exposing Bar entirely:

foo::doBarSomething() { this->bar.doSomething(); }
answered Apr 17, 2013 at 15:32
2
  • +1 and in this case no longer worry about unique_ptr, and then use the simpler shared_ptr Commented Apr 17, 2013 at 15:40
  • 16
    How is shared_ptr more simple than unique_ptr? Commented Apr 17, 2013 at 19:24
3

It's usually not a good idea to use a reference as a class member.

If you use a reference, you are required to define the object that it references to in the constructor, and you can never again change the object that that reference points to again. Consequently, you'll have serious problems if you ever call bar_ptr.reset() and try to access bar.

Also, using a reference the way you are using is essentially the same as declaring Bar as a public non-pointer variable. I honestly don't see a reason for all that inconvenience just so you don't have to #include a header.

answered Apr 20, 2013 at 23:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.