基于模板的主题观察者模式 - 我应该使用 static_cast 还是dynamic_cast

2024-03-23

我指的是这篇文章使用模板实现主题/观察者模式 http://www.codeproject.com/KB/architecture/observer_with_templates.aspx

我做了一些修改,代码如下。

template <class T, class A>
class Observer {
public:
    Observer() {}
    virtual ~Observer() {}
    virtual void update(T& subject, A arg) = 0;
};

template <class T, class A>
class Subject
{
public:
    Subject() {}
    virtual ~Subject() {}

    // Take note that, we didn't make the following functions as virtual,
    // as we do not expect them to be overridden.
    void attach(Observer<T, A> &observer) {
        // Ensure no duplication.
        std::vector<Observer<T, A> *>::const_iterator iterator = std::find(observers.begin(), observers.end(), &observer);
        if (iterator == observers.end()) {
            observers.push_back(&observer);
        }
    }

    void dettach(Observer<T, A> &observer) {
        std::vector<Observer<T, A> *>::const_iterator iterator = std::find(observers.begin(), observers.end(), &observer);
        if (iterator != observers.end()) {
            observers.erase(iterator);
        }
    }

    void dettachAll() {
        observers.clear();
    }

    void notify(A arg)
    {
        std::vector<Observer<T, A> *>::const_iterator it;
        for (it = observers.begin(); it != observers.end(); it++) { 
            (*it)->update(*(static_cast<T *>(this)), arg);
        }
    }

private:
    std::vector<Observer<T, A> *> observers;
};

后来我意识到(*it)->update(*(static_cast<T *>(this)), arg);是有限制的。例如,

// cause compilation error in static_cast, as it cannot cast cat1 to animal.
class cat1 : public animal, public Subject<animal, int> {
public:
    virtual void speak() {
        notify(888);
    }
};

class zoo1 : public Observer<animal, int> {
public:
    zoo1() {
        c.attach(*this);
        c.speak();
    }

    virtual void update(animal& subject, int arg) {
        cout << "zoo1 received notification " << arg << endl;
    }

    cat1 c;
};

我可以通过更改来解决问题static_cast to dynamic_cast. 但是,我不确定我是否会陷入其他陷阱?我对作者初衷的猜测static_cast,是为了保证编译时的类型安全检查。


你的问题来自这样一个事实:动物应该是主题,而不仅仅是猫,

class animal : public Subject<animal,int>
{
    ...
};

class cat1 : public animal
{
    public:
    virtual void speak() 
    {
        notify(888);
    }
};

class zoo1 : public Observer<animal, int> {
public:
    zoo1() 
    {
        c.attach(*this);
        c.speak();
    }

virtual void update(animal& subject, int arg) 
    {
        cout << "zoo1 received notification " << arg << endl;
    }

cat1 c;
};

通过这样做,每个受试者都被静态地“能够”转化为动物。你的猫不是这种情况1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于模板的主题观察者模式 - 我应该使用 static_cast 还是dynamic_cast 的相关文章

  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 读取 C# 中的默认应用程序设置

    我的自定义网格控件有许多应用程序设置 在用户范围内 其中大部分是颜色设置 我有一个表单 用户可以在其中自定义这些颜色 并且我想添加一个用于恢复默认颜色设置的按钮 如何读取默认设置 例如 我有一个名为的用户设置CellBackgroundCo
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 为什么这个没有特殊字符的正则表达式会匹配更长的字符串?

    我正在使用此方法来尝试查找匹配项 例如 Regex Match A2 TS OIL TS OIL RegexOptions IgnoreCase Success 我得到了真实的结果 我很困惑 我认为这应该返回 false 因为模式中没有特殊
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 如何通过 JsonConvert.DeserializeObject 在动态 JSON 中使用 null 条件运算符

    我正在使用 Newtonsoft 反序列化已知的 JSON 对象并从中检索一些值 如果存在 关键在于对象结构可能会不断变化 因此我使用动态来遍历结构并检索值 由于对象结构不断变化 我使用 null 条件运算符来遍历 JSON 代码看起来像这
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐