C ++:使用友元类限制对象实例化

时间:2013-11-23 14:54:04

标签: c++ inheritance friend

我有一个类House,它包含一些类Room s作为成员变量。它本身没有任何孩子。

房间是基础类,它有几个儿童课程 - 卧室,浴室等。

我希望能够将房间的创建限制在House类中。我有以下内容:

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文件

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 */ }

程序编译并成功运行,没有受保护的构造函数,但可以随时随地创建房间。只要我将Room及其子项的构造函数切换为PROTECTED,我就会开始出现编译错误('无法访问')。如果我交换了卧室和浴室构造函数的状态,则语句(2)失败,语句(3)在.CPP文件中按预期工作。但是,保留为公共意味着它们仍然可以在我不想要的House之外创建。

我如何解决这个问题?我在创建room时依赖于多态性,因为在编译时我不知道它将是哪种类型。这会导致问题吗?

2 个答案:

答案 0 :(得分:4)

C ++中的友谊是一种利他主义的概念,而不是一种自私的概念。

一个班级可以宣布朋友。这并不意味着班级可以访问朋友的受保护和私人成员。朋友可以访问声明类的受保护和私有成员。

换句话说,朋友声明属于授予访问权限的类,而不属于要访问的类。

答案 1 :(得分:1)

您可以使用“朋友”关系:

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

然后,众议院可以访问房间的私人(和受保护的)成员。这是否真的有用是有争议的:我很少,很少使用friend,并建议在这种情况下可能没有必要:毕竟,创建一个房间有什么危害?