C ++中是否可以使用以下设置/设计模式?
Leader类有很多Worker,需要从Worker类调用方法M()。但是,我不希望任何Worker(即MyWorker)的实现能够访问方法M()。公共,私人和受保护似乎都不适用于这种情况。
这种设置可行吗?或者我应该如何设计其他东西呢?
由于
编辑:(添加示例案例)
假设M()是GiveMoney(),Leader = Parent和Worker = Child。我只希望父母能够给孩子钱(儿童不能给自己钱)。
答案 0 :(得分:1)
你可以:
M()
中设置Worker
私有函数,并声明Leader
为Worker
的朋友。M()
的逻辑移出Worker
并移至Leader
。就个人而言,这是我会采取的方法,因为无论M()
做什么,你都不希望任何其他Worker
做。答案 1 :(得分:0)
像这样:
#include <iostream>
class Leader
{
private:
virtual char M() = 0;
public:
void foo() { std::cout << M(); }
};
class Worker : public Leader
{
private:
virtual char M() { return 'm'; }
};
然后
int main()
{
Worker w;
w.foo();
}
打印m
和
class MyWorker : public Worker
{
void foo2() { std::cout << M(); }
};
导致编译错误,抱怨
'virtual char Worker :: M()'是私有的。
答案 2 :(得分:0)
你为什么要这样做?你究竟想要实现什么目标?了解您的最终目标将有助于我们帮助您找到您正在寻找的答案。
如果你想完全隐藏一些实施细节,最好的办法是为工人的公共方面制作一个单独的基础班,让你的私人工作者包括公共部分。
编辑听起来像是在为自己的生活带来不必要的困难。除非其他人控制童工的实施,否则为什么不避免打电话给童工提供资金呢?
这样的事情可能对你的例子有用:
class Parent // Leader
{
private:
Child* m_pChildren;
};
class Child : public ChildSelf
{
public:
char GiveMoney() { return 'm'; }
};
class ChildSelf
{
Run();
Jump();
ClimbTrees();
};
class MyChild : public ChildSelf
{
void RunFaster() { Run(); Run(); }
};
您的童工实施只能访问ChildSelf,为您提供您正在寻找的安全级别。?
答案 3 :(得分:0)
将M
设为私有,并声明Leader
为Worker
的朋友。您仍然可以在M
的派生类中实现Worker
:
class Leader;
class Worker
{
virtual void M() = 0;
friend class Leader;
};
class Leader
{
Worker* w;
public:
void doSomething() { w->M(); }
};
class MyWorker : public Worker
{
void M() { ... } // No problem. Even if `M` is private in the base class, it
// can still be overridden, but not accessed.
};
答案 4 :(得分:-1)
听起来你应该查看访问者设计模式:http://en.wikipedia.org/wiki/Visitor_pattern
这不是完全相同的方法,但我相信如果您在Visit(Worker)
类上定义Leader
方法,在Accept(Leader)
类上定义Worker
方法,然后调用private M()
,您可以获得所需的功能。
看到我的帖子被低估了,我认为如果我提供一些额外的信息可能会有所帮助:
class Leader;
class Worker
{
virtual void M() = 0;
public:
void Accept( const Leader & w)
{
M();
}
};
class Leader
{
public:
void Visit ( Worker & w) const
{
w.Accept(*this);
}
};
class MyWorker : public Worker
{
virtual void M()
{
std::cout << "M()" << std::endl;
}
};
int main(int argc, char **argv)
{
Leader l;
MyWorker myW;
myW.Accept(l)
return 0;
}
调用M()
的唯一方法是使用Leader
,Worker
是一个抽象类,甚至无法实例化,但你可以提供默认值如果您愿意,M()
的行为。