首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C++中实现寄存器/注销模式

在C++中实现寄存器/注销模式
EN

Stack Overflow用户
提问于 2009-12-10 22:06:38
回答 3查看 1K关注 0票数 0

我经常遇到这样的问题:我有一个类,它有一对Register/Unregister类方法。例如:

代码语言:javascript
复制
class Log {
public:
    void AddSink( ostream & Sink );
    void RemoveSink( ostream & Sink );
};

这适用于几种不同的情况,如观察者模式或相关内容。我担心的是,这有多安全?从我知道的previous question中,我不能安全地从该引用派生对象标识。This approach向调用者返回一个迭代器,调用者必须将其传递给注销方法,但这会暴露实现细节(迭代器类型),所以我不喜欢它。我可以返回一个整数句柄,但这需要很多额外的内部管理(最小的空闲句柄是什么?)。你是怎么做的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-15 20:50:10

除非客户端对象有两个不使用虚拟继承的ostream派生,否则您是安全的。

简而言之,这是用户的错--他们不应该以两种不同的方式多次继承一个接口类。

使用地址,然后就可以使用它了。在这些情况下,我采用指针参数而不是引用来明确表示我将存储地址。它还可以防止隐式转换,如果您决定使用常量引用,则可能会启动隐式转换。

代码语言:javascript
复制
   class Log {
   public:
       void AddSink( ostream* Sink );
       void RemoveSink( ostream* Sink );
   };

您可以创建一个RAII对象,该对象在构造函数中调用AddSink,在析构函数中调用RemoveSink,以使此模式异常安全。

票数 2
EN

Stack Overflow用户

发布于 2009-12-10 22:08:54

您可以使用智能指针管理您的对象,并在您的注册/注销函数中比较指针的相等性。

如果你只有堆栈分配的对象,而这些对象永远不会在注册和注销调用之间复制,你也可以传递一个指针而不是引用。

您还可以执行以下操作:

代码语言:javascript
复制
typedef iterator handle_t;

如果暴露了内部数据结构,那么就隐藏了这样一个事实:如果暴露了内部数据结构,就会给出内部迭代器。

票数 0
EN

Stack Overflow用户

发布于 2009-12-15 21:03:11

在你之前的问题中,Konrad Rudolph posted an answer (你没有接受,但得分最高),说如果你使用基类指针,一切都会很好,你看起来是这样做的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1881200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档