C++ 设计模式:可能有继承的方法私有到派生类?
Posted
技术标签:
【中文标题】C++ 设计模式:可能有继承的方法私有到派生类?【英文标题】:C++ design pattern: Possible to have inherited method private to derived class? 【发布时间】:2011-05-15 21:23:50 【问题描述】:以下设置/设计模式在 C++ 中是否可行?
Leader 类 工人阶级 有方法 M() 一个 MyWorker 类(继承 Worker)Leader类有很多Worker,需要调用Worker类的M()方法。但是,我不希望 Worker 的任何实现(即 MyWorker)能够访问方法 M()。在这种情况下,public、private 和 protected 似乎都不起作用。
这种设置可行吗?或者我应该如何设计?
谢谢
编辑:(添加示例)
假设 M() 是 GiveMoney(),Leader = Parent,Worker = Child。我只希望父母能够给孩子钱(孩子不能给自己钱)。
【问题讨论】:
您希望一个类不能访问它自己的方法,但希望该方法可以从另一个类调用?我认为这在任何语言中都是不可能的。 邮政编码,如果将 M() 定义为私有;并且通过 public 进行扩展应该会导致 MyWorker 无法访问私有方法。只要 Worker(M() 的原始所有者)是唯一调用 M() 的东西,M() 是私有的这一事实应该可以正常工作,因为通常一个实例可以对其他实例上的私有方法/成员进行操作同班。 如果M()
被定义为 private 并且 Leader
是 Worker
的朋友,那么一切都应该如你所愿 - 如果我理解正确的话。跨度>
【参考方案1】:
你可以:
-
将
M()
设为Worker
中的私有函数,并将Leader
声明为Worker
的朋友。
将M()
的逻辑移出Worker
并移入Leader
。就个人而言,这是我会采取的方法,因为无论M()
做什么,你都不希望任何其他Worker
去做。
【讨论】:
【参考方案2】:像这样:
#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()’是私有的。
【讨论】:
不想让Worker继承Leader怎么办?举个例子,假设方法是 AddFood() 并且我不希望工人能够养活自己。 那么你必须让Worker
成为Leader
的朋友,或者你必须重写Leader
,使其不必调用Worker::M
(例如,通过移动功能这需要调用 Worker
类(但这可能不适合您的特定情况)。【参考方案3】:
拥有M
私有,并将Leader
声明为Worker
的朋友。你仍然可以在Worker
的派生类中实现M
:
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】:为什么要这样做?你到底想达到什么目的?了解您的最终目标将帮助我们帮助您找到您正在寻找的答案。
如果您想完全隐藏一些实现细节,最好的办法是为工作人员的公共方面创建一个单独的基类,让您的私人工作人员按组合包含公共位。
编辑在我看来,你给自己的生活带来了不必要的困难。除非其他人可以控制童工的实施,否则为什么不直接避免从童工那里打电话给钱呢?
这样的事情可能适用于您的示例:
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,它可以为您提供所需的安全级别.. ?
【讨论】:
【参考方案5】:听起来您应该研究访问者设计模式:http://en.wikipedia.org/wiki/Visitor_pattern
这不是完全相同的方法,但我相信如果你在Leader
类上定义一个Visit(Worker)
方法,在Worker
类上定义一个Accept(Leader)
方法,然后调用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()
提供默认行为如果你愿意。
【讨论】:
以上是关于C++ 设计模式:可能有继承的方法私有到派生类?的主要内容,如果未能解决你的问题,请参考以下文章