【问题标题】:Fixing object initialization so an overriden method is called修复对象初始化,以便调用覆盖的方法
【发布时间】:2019-09-09 11:37:02
【问题描述】:

我有什么(简化版):

template<typename T> class Watcher
{
 public:
    T* m_watched { nullptr };
    Watcher() = default;
    Watcher(T* watched) : m_watched(watched) { m_watched->addWatcher(this); };
    virtual void notifyChange(int = 0) /*= 0*/{std::cout << "Watcher::notifyChange()\n";};
};

template<typename T> class Watchable
{
 public:
    std::vector<Watcher<T>*> m_watchers;
    virtual void addWatcher(Watcher<T>* watcher)
    {
        m_watchers.push_back(watcher);
        watcher->notifyChange();
    }
};

class Config : public Watchable<Config>
{
};

class Property : public Watcher<Config>
{
 public:
    Property(Config* config) : Watcher<Config>(config) {};

    void notifyChange(int = 0) override { std::cout << "Property::notifyChange()\n"; }
};

所以当我创建一个基类(Watcher)的Property notifyChange() 实例时,会被调用。

我理解为什么会发生这种情况,但我不知道如何解决这个问题,但仍然有适当的现代 C++ 代码(例如,没有使 m_watched 受保护等等)。

【问题讨论】:

    标签: c++ virtual-functions


    【解决方案1】:

    你不能。

    在基础构建期间,派生的子对象还不存在。

    您可以尝试创建一个工厂函数来控制创建Propertys。然后它可以一步实例化,并在第二步中注册。根据需要将工厂函数设为friend,并将所有相关机器设为private

    【讨论】:

    • 感谢您的回复。但我选择了一种不同的方式,使用从 WatcherProperty 构造函数调用的 init() 方法。
    • @blackcat 这是一种反模式。我的建议是故意选择的。但是,这取决于你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多