0

I currently have something like this. I would like to only allow the bar class to create an instance of the foo class so I have made it a friend of foo and made the constructor of fooprivate.

 foo.h   
    class foo
    {
     friend class bar;
     private:
      foo()
      {
      }
    }


bar.h
#include "foo.h"
class bar
{
  private:
  boost::shared_ptr<foo> f;
  public:
  bar()
  {
    f = boost::shared_ptr<foo>(new foo());
  } 
}

The above works perfectly fine. However since the private member of the foo class is only being used in the constructor of the bar class (for instantiating). I would like to restrict private accessibility to only the constructor of the bar class so I decided to replace

friend class bar;

with this

friend bar::bar();

This does not work as the error messages says that bar is an incomplete type (Which I believe means that it cant find bar). Any suggestions on how to fix this problem ?

MistyD
  • 16,373
  • 40
  • 138
  • 240
  • Cant you declare a method of a different class as a friend? – MistyD Dec 03 '14 at 19:13
  • Yes you can, the problem is that `bar` hasn't been declared yet so you can't refer to its default constrcutor – Jonathan Wakely Dec 03 '14 at 19:14
  • @JonathanWakely thanks for clearing that up. Yes I am familiar with why its failing i wanted to know if there was a way for me to circumvent that issue ? – MistyD Dec 03 '14 at 19:15
  • Define `bar` before `foo`. i.e. put a declaration of `foo` in `bar.h` but don't include `foo.h`, and include `bar.h` in `foo.h` – Jonathan Wakely Dec 03 '14 at 19:16

1 Answers1

1

My first suggestion would be to look at changing the design to use a factory method to create foo. Either as a static member function or as a free function.

But in the very rare cases that this is not an option the following code illustrates how it can be done.

bar.h

#include <boost/shared_ptr.hpp>

#ifndef BAR_H_
#define BAR_H_

class foo;

class bar {
private:
    boost::shared_ptr<foo> f;

public:
    bar();
};

#endif

foo.h

#include "bar.h"

#ifndef FOO_H_
#define FOO_H_

class foo {
    friend bar::bar();
private:
    foo() {}
};

#endif

bar.cpp

#include "bar.h"
#include "foo.h"

bar::bar() : f{ new foo() } 
{}
TAS
  • 2,039
  • 12
  • 17
  • Thanks for the comment. I am not sure how factory design pattern would fit in here. Over here I have a class bar which serves as the exposed class and exposes the methods of the class foo. The purpose of this is to shield the user from creating instance of foo. Could you give me an example of how a factory would do this ? I have this http://codereview.stackexchange.com/questions/56924/factory-design-pattern-implementation but I still dont see how it fits into this situation – MistyD Dec 03 '14 at 22:27