Question

I have a class, House, which contains a selection of classes, Rooms, as member variables. It doesn't in itself have any children.

Room is a base class and it has several child classes - Bedroom, Bathroom, etc.

I want to be able to limit creation of rooms to within the House class only. I have the following:

H FILE

class house
{
public:
    house(/* constructor arguments */);
    ~house(void);
public:
    // generic member variables - length, width, floors, colour, etc.
    room  *room1;
     friend class room;
    friend class bedroom;
    friend class bathroom;
}
 class room
{
protected:                 // this compiles as PROTECTED or PUBLIC
    room(/* constructor arguments */);
public:
    virtual ~room(void);
/* generic member variables - length, width, floor, door, etc. */
}
 class bedroom : public room
{
public:                    // this compiles as PUBLIC only
    bedroom(/* constructor arguments */);
public:
    ~bedroom(void);
/* specific variables - hasBed, hasWardrobe, etc. */
}
 class bathroom : public room
{
protected:                 // this compiles as PUBLIC only
    bathroom(/* constructor arguments */);
public:
    ~bathroom(void);
/* yet more specific variables */
}

CPP FILE

house::house (/* constructor arguments */)
{
/* do stuff */

    room = new(nothrow) room(/*agrs*/)      // (1) COMPILES WITH THIS
    room = new(nothrow) bedroom(/*agrs*/)   // (2) COMPILES WITH THIS
    room = new(nothrow) bathroom(/*args*/)  // (3) DOES NOT COMPILE
}

house::~house(void) { /* clean up + delete */ }

room::room (/* constructor arguments */)
{ /* do stuff */ }
room::~room(void) { /* clean up */ }

bedroom::bedroom (/* constructor arguments */): room(/* constructor arguments */)
{ /* do stuff */ }
bedroom::~bedroom(void) { /* clean up */ }

bathroom::bathroom(/* constructor arguments */): room(/* constructor arguments */)
{ /* do stuff */ }
bathroom::~bathroom(void) { /* clean up */ }

The program compiles and runs successfully with no protected constructors, but rooms can be created willy-nilly from anywhere. As soon as I switch Room and its children's constructors to PROTECTED I start to get compilation errors ('inaccessible'). If I swap the status of the Bedroom and Bathroom constructors over then statement (2) fails and statements (3) works in the .CPP file as is expected. However, leaving either as public means they can still be created outside of House which I don't want.

How do I get around this? I rely on polymorphism when creating a room because at compile time I don't know which type it's going to be. Is this causing the problem?

Was it helpful?

Solution

Friendship in C++ is an altruistic concept, not an egoistic one.

A class can declare friends. That does not mean that the class can access protected and private members of the friend. The friend can access protected and private members of the declaring class.

In other words, friend declarations belong into the class that grants access, not into the class that wants access.

OTHER TIPS

You can use a "friend" relationship:

class Room {
  friend class House;
  // ...

Then a House will have access to the private (and protected) members of a Room. Whether this is actually useful is up for debate: I very, very rarely use friend, and suggest that in this case it may not be necessary: after all, what harm is there in creating a Room?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top