0

I have a base class in C++ that has some protected member variables (although, I do not think it is relevant that it is protected vs. private in this case).

I have a derived class that derives from this base class. In it, there is a public function that creates an object of the base class and returns that object. However, in that function I need to be able to set the protected member variables into a special state.

Example:

class Base
{
protected:
  int b_value;
};

class Derived : public Base
{
public:
  Base createBase()
  {
    Base b;
    b.b_value = 10;
    return b;
  }
};

I specifically only want the derived class to be able to the protected member variable. I do not want a public accessor method in the base class.

I originally tried to fix this by making the derived class's createBase() function be a friend of the Base class. Like so:

class Base
{
protected:
  int b_value;
  friend Base Derived::createBase();
};

class Derived : public Base
{
public:
  Base createBase()
  {
    Base b;
    b.b_value = 10;
    return b;
  }
};

As you can see, this will not compile since Derived has not been defined yet. If it matters, these two classes are defined in separate header files. I guess one way to describe this problem is a "chicken and egg" problem where one needs the other first.

I have a feeling this has to be a "I am not designing my classes correctly and need to rethink how I am doing this" but I cannot figure out how to get this to work.

T Lytle
  • 177
  • 2
  • 13

1 Answers1

2

You can forward declare Derived and then make it a friend in Base :

class Derived;
class Base
{
    friend class Derived;
protected:
  int b_value;
};

class Derived : public Base
{
public:
  Base createBase()
  {
    Base b;
    b.b_value = 10;
    return b;
  }
};

However this design seems seriously flawed to me as you already stated, you should probably make createBase() a static public method in your Base class and have a setter for b_value or a constructor that sets it.

Remember that right now inside createBase(), this->b_value is also available.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • Does forward declaration work here? These two classes are defined in separate header files. You would need to `#include "Derived.hpp"` in Base.hpp which will not compile. – T Lytle Sep 15 '16 at 15:39
  • @TLytle No that's the thing about forward declarations, you don't include derived in base .hpp but use a forward instead, that'll work just fine. – Hatted Rooster Sep 15 '16 at 15:48