2012-04-09 36 views
1

我有一个Message类的对象,它可以被写入并随后被更新。据我所看到的,MessageUpdate IS-A内留言:C++:在派生类中限制方法访问

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!! 

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

+0

菱形图案是只要OK [虚拟继承] (http://en.wikipedia.org/wiki/Virtual_inheritance)。 – dasblinkenlight 2012-04-09 14:10:18

+0

有关使用虚拟基类的示例,请参阅http://stackoverflow.com/a/21607/13140以确保您的继承树中不会获得“MessageWrite”的多个副本。所以你想只有MessageWrite能够调用setReceiveTime()? – 2012-04-09 14:15:58

+0

感谢dasblinkenlight,但我更喜欢@Als的方法,因为它可以节省多重继承的运行时成本 – vid 2012-04-09 14:16:44

回答

1

由于MessageWrite所有成员都protected,你可以只让setReceiveTime()privateMessageUpdate,所以从类继承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。如果我的代码应该是有效的,那么没有理由避免访问MessageUpdate中的setReceiveTime()

而且你很可能是通过创建一个基类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 
0

保护:继承的成员可以访问。

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

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

只是声明方法:

private: 
void setReceiveTime(int tmReceive_); 

与基类MessageWriteprivate访问符。

我这个答案应该是一个良好的阅读:

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

+0

处调用setReceiveTime(),谢谢,这就是发现。我无法自动做到这一点?必须重写所有方法声明? – vid 2012-04-09 14:11:20

+0

@vid:您必须手动执行此操作。此外,类成员的访问说明符在方法声明的类定义中指定。请注意,通常,类方法在头文件中声明*,在cpp文件中定义*。 – 2012-04-09 14:13:26

1

如果MessageUpdate是-A MessageWrite,然后通过定义,它可以访问所有的protected和public成员。

所以,如果有要公开/ protectedly暴露在MessageWrite,你不希望在MessageUpdate暴露的成员,然后由Liskov Substitution PrincipleMessageUpdate不能是MessageWrite

+0

+1原则 – vid 2012-04-09 14:18:51