使用shared_ptr处理可靠的命令模式
我正在尝试在库中实现一个非常干净的命令模式。
我现在有以下结构(一些部分仍在完成中):
- 用户(客户端代码)有一些对象,称其为“Manager”
Manager
拥有一个shared_ptr
shared_ptr
的集合。 Foo>
Manager
通过返回shared_ptr
提供对集合的访问- 我有一个
Command
抽象类和命令层次结构用于执行的操作Foo
- 客户端代码不应该调用
Command::execute()
,只有Manager
应该 >,Manager::execute(shared_ptr
,以便它可以处理撤消/重做)
我想遵循以下规则:
- 用户(客户端代码)有一些对象,称之为“经理”
经理
持有shared_ptr
的集合Manager
通过返回shared_ptr
提供对集合的访问- 我有一个
Command 抽象类和对
Foo
执行操作的命令层次结构 - 客户端代码不能(没有解决方法)调用
Command::execute()
, 仅有的Manager
可以,Manager::execute(shared_ptr
,这样它就可以处理undo/redo并获取非常量智能指针) - 即使用户初始化了 Command,
Manager
也必须能够允许Command
对象访问和修改shared_ptr
> objecst 与shared_ptr
我只是想找出处理发出 shared_ptr
同时允许数字 5 和 6 工作的最佳方法。
有没有任何示例/设计模式可以让我学习?与我已经拥有/正在做的事情相比,这是一个好主意吗?
I am trying to implement a very clean Command Pattern in a library.
I have the following structure right now (a few parts are still being finished up):
- users (client-code) have some Object, call it "Manager"
Manager
holds a collection ofshared_ptr<Foo>
Manager
provides access to the collection by returningshared_ptr<Foo>
- I have a
Command
abstract class and a hierarchy of commands for actions to perform onFoo
- Client code should not call
Command::execute()
, onlyManager
should,Manager::execute(shared_ptr<Command>)
, so that it can handle undo/redo
I would like to follow the following rules:
- users (client-code) have some Object, call it "Manager"
Manager
holds a collection ofshared_ptr<Foo>
Manager
provides access to the collection by returningshared_ptr<const Foo>
- I have a
Command
abstract class and a hierarchy of commands for actions to perform onFoo
- Client code cannot (without workarounds) call
Command::execute()
, onlyManager
can,Manager::execute(shared_ptr<Command>)
, so that it can handle undo/redo and get non-const smart pointers - A
Manager
must be able to allowCommand
objects to access and modifyshared_ptr<Foo>
even though the user initializesCommand
objecst withshared_ptr<const Foo>
I am just trying to figure out the best way to handle giving out shared_ptr<const Foo>
while allowing number 5 and 6 to work.
Is there any example/design pattern that does this which I could learn from? Is this a good idea compared to what I already have/am working on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这个
密钥模式
应该适合您:现在,
Command
不知道有关Manager
的任何信息,只知道所需的密钥对于执行
功能。用户将无法直接调用execute
方法,因为只有Manager
可以创建CommandExecuteKey
对象,这要归功于私有构造函数和 <代码>友谊。现在,谈谈你的第六点:
当您输入命令时,在所有
shared_ptr
中搜索正确的对象(使用保存的命令shared_ptr
作为搜索键),然后传递从内部shared_ptr
返回到命令的可变指针。I think this
passkey pattern
should be the right thing for you:Now,
Command
doesn't know anything aboutManager
, only about the key that is needed for theexecute
function. The user won't be able to call theexecute
method directly, as onlyManager
can createCommandExecuteKey
objects, thanks to a private constructor andfriend
ship.Now, for your 6th point:
When you get the command in, search all your
shared_ptr<Foo>
s for the correct object (using the savedshared_ptr
of the command as a search-key) and then pass that mutable one from your internalshared_ptr
s back to the command.因为否则对我来说没有任何意义,我将假设
命令
。在这种情况下,也许这样的方法可以工作:
我不确定使用 const 是否是这里的最佳解决方案。也许您应该将
Foo
对象包装在例如ClientFoo
对象中。管理器仅分发指向ClientFoo
的指针。然后,管理器可以(例如通过friend
)从ClientFoo
获取Foo
,并使用它来调用Command
>。Since it wouldn't make any sense to me otherwise, I'm going to assume that
Manager
class (or at least a base class), andCommand
.In that case, maybe something like this could work:
I'm not sure though if using
const
is the best solution here. Maybe you should wrap yourFoo
objects in e.g.ClientFoo
objects. The manager only hands out pointers toClientFoo
. The manager can then (e.g. viafriend
) get theFoo
from theClientFoo
, and use it to invoke theCommand
.我没有 100% 遵循你的问题,但这里是......
我唯一能想到的 #5 就是使
Command::execute
私有/受保护并使Manager< /code>
Command
的朋友
。此方法的缺点是您现在引入了从Command
到Manager
的依赖关系。对于#6,如果用户的
shared_ptr
对象源自 Manager 的shared_ptr
集合,则Manager
应该能够安全地将 const_pointer_castshared_ptr
转换回shared_ptr
。如果 Manager 尝试 const 强制转换shared_ptr
(其中指针对象是实际的常量对象),您将得到未定义的行为。我想到了 #5 的另一个解决方案:
定义一个从
Command
派生的ExecutableCommand
类。ExecutableCommand
添加了一个调用命令的方法,仅由Manager
使用。客户端只能通过Command
的指针/引用来访问ExecutableCommand
对象。当管理器想要调用Command
时,它将其向下转换为ExecutableCommand
以获得对调用接口的访问。工作示例(包括 #6 的 const_pointer_cast):
I'm not following your question 100%, but here goes...
The only thing I can think of for #5 is to make
Command::execute
private/protected and makeManager
afriend
ofCommand
. The downside of this approach is that you've now introduced a dependency fromCommand
toManager
.As for #6, if the user's
shared_ptr<const Foo>
objects were originated from Manager'sshared_ptr<Foo>
collection, thenManager
should be able to safely const_pointer_castshared_ptr<const Foo*>
back intoshared_ptr<Foo*>
. If Manager attempts to const cast ashared_ptr<const Foo*>
, where the pointee is an actual constant object, you'll get undefined behavior.I've thought of another solution for #5:
Define an
ExecutableCommand
class, derived fromCommand
.ExecutableCommand
has an added method to invoke the command, to be used only byManager
. Clients can only accessExecutableCommand
objects via pointers/references toCommand
. When a Manager wants to invoke aCommand
, it downcasts it to aExecutableCommand
to gain access to the invocation interface.Working example (including const_pointer_cast for #6):