所以也许这是一个愚蠢的问题,我在想这个,但我有以下情况。我正在制作一个“类Shell”,它可以运行抽象的“类Action”对象。它是唯一应该创建或使用这些对象的类。操作对象需要访问Shell以对其执行特定操作,但我试图避免为此添加公共接口(不应该允许其他人这样做)。
我最初有一个简单的(不那么优雅)
class Shell
{
public:
bool checkThing();
// etc...
private:
bool _thing;
};
class Action
{
public:
virtual void execute( Shell &s )=0;
};
class ChangeAction : public Action
{
public:
void execute( Shell &s )
{
// requires friendship or public mutator!
s._thing = true;
}
};
所以我考虑了一个嵌套类Action,但是我想把它变成私有的(为什么让其他人做除Shell之外的具体动作,对吧?)
class Shell
{
public:
bool checkThing();
// etc...
private:
bool _thing;
class Action;
};
class Shell::Action
{
public:
virtual void execute( Shell &s )=0;
};
class ChangeAction : public Shell::Action
{
public:
void execute( Shell &s )
{
// ok now!
s._thing = true;
}
};
但是我当然不能继续从Action继承(这是有道理的,它是私有的)。所以这不起作用。
所以我的问题,我应该选择第一种方法和友情还是公共界面?我可以使用类似于第二种方法的东西来保持与Actions和Shell的关系吗? 你有更好的主意吗?
答案 0 :(得分:3)
如果唯一需要能够看到Action
的代码是Shell
,则一个选项是在头文件中转发声明Action
,但只定义.cpp文件。这样就可以让你在实现文件中声明尽可能多的Action
子类,而不让任何其他人从Action
子类化,因为没有其他人会有{{1}的完整类定义}。这也避免了对公共接口或Action
声明的任何需要 - 所有friend
类都在全局范围内声明,但由于在.cpp文件中声明而与其他文件隔离。
很棒的问题,顺便说一句!
答案 1 :(得分:0)
您可以使用这些方法的组合:基本上只需从第一个方法中获取所有类,并将它们移动到Shell类的私有部分:
class Shell {
public:
bool checkThing(); // etc...
private:
bool _thing;
class Action {
public:
virtual void execute( Shell &s )=0;
};
class ChangeAction : public Action
{
public:
void execute( Shell &s )
{
// ok now! s._thing = true;
}
};
};