C ++:限制派生类中的方法访问

时间:2012-04-09 14:04:48

标签: c++ inheritance

我有一个Message类的对象,可以编写并随后更新。据我所见,MessageUpdate IS-A MessageWrite:

class MessageWrite
{
  protected:
    void setVersion(int version_) {...}
    void setReceiveTime(int tmReceive_) {...}

    Message _msg;
};


class MessageUpdate:public MessageWrite
{
    //ONLY setVersionShould be accessible here, NOT setReceiveTime
};

是否有方法访问级别和继承级别的组合可以帮助实现此目的?

我知道MessageUpdate可以简单地创建基类,但是有一点:它会导致菱形模式,以防我想扩展消息类。考虑:

class MessageUpdate {...};
class MessageWrite: public MessageUpdate {...};


//Now, while extending:
class AdminMessageUpdate:public MessageUpdate {...};
class AdminMessageWrite: public AdminMessageUpdate, public MessageWrite //DIAMOND Pattern!!

我对继承理解的差距在哪里?如果没有多重继承(如后面的代码片段所示),有没有完全不同的方法来实现这种逻辑?

4 个答案:

答案 0 :(得分:2)

只需声明方法:

private:
void setReceiveTime(int tmReceive_);

在基类private中使用MessageWrite访问说明符。

我的这个答案应该是一个很好的解读:

<强> What are access specifiers? Should I inherit with private, protected or public?

答案 1 :(得分:1)

如果MessageUpdate是-MessageWrite,那么根据定义,它可以访问所有受保护和公共成员。

因此,如果您希望在MessageWrite中公开/受保护地公开您不希望在MessageUpdate中公开的成员,那么Liskov Substitution Principle,{{1} }不能是MessageUpdate

答案 2 :(得分:1)

由于MessageWrite的所有成员都是protected,您只能在setReceiveTime()内设private MessageUpdate,因此继承自MessageUpdate的类会无法访问它。但是我的设计仍然存在一些问题,例如:

你的设计如何避免钻石?它不会同样导致:

class MessageWrite {...};
class MessageUpdate: public MessageWrite {...};

//Now, while extending:
class AdminMessageWrite:public MessageWrite {...};
class AdminMessageUpdate: public AdminMessageWrite, public MessageUpdate //DIAMOND Pattern!!

为什么当你后来说不是MessageUpdate IS-A MessageWrite时(通过指定并非所有MessageWrite适用于它)?如果此代码无效:

MessageWrite& m = MessageUpdate();
m.setReceiveTime(); // Should this be valid?

然后MessageUpdate IS-NOT-A MessageWrite。如果我的代码有效,则没有理由避免访问setReceiveTime()中的MessageUpdate

通过创建基类AdminMessage然后直接从它继承以避免钻石,你可能会更好:

class MessageWrite {...};
class MessageUpdate: public MessageWrite {...};

//Now, while extending:
class AdminMessage {...};
class AdminMessageWrite: public MessageWrite, public AdminMessage {...};
class AdminMessageUpdate: public MessageUpdate, public AdminMessage {...}; // No diamond

答案 3 :(得分:0)

protected:继承的成员可以访问。

私有:继承的成员无法访问。

  protected:
    void setVersion(int version_) {...}
  private:
    void setReceiveTime(int tmReceive_) {...}