c++ - 从基类构造函数调用派生类的方法

标签 c++ c++11

我遇到一种情况,我希望 System 的每个派生实例通过我自己的事件系统订阅事件。基本上,这意味着将 std::function 传递给事件,该事件是另一个实例的成员字段。所以它基本上是这样的:

// System.h
class System
{
    public:
        System(std::shared_ptr<EntityManager> entityManagerPtr);
        virtual ~System();
        virtual void componentAddedEventHandler(void* source, const ComponentAddedEventArgs& args);
    protected:
        std::shared_ptr<EntityManager> m_entityManagerPtr;
};

以及使用委托(delegate)的实现:

// System.cpp
System::System(std::shared_ptr<EntityManager> entityManagerPtr) : m_entityManagerPtr(entityManagerPtr)
{
    // Subscribe to the componentAddedEvent
    m_entityManagerPtr->componentAddedEvent += [&](void* source, ComponentAddedEventArgs args) {
        this->componentAddedEventHandler(source, args);
    };
}

但显然,如果不定义System::componentAddedEventHandler(),这将无法编译。

确保从 System 派生的每个类都订阅该事件,并且它们都必须为事件处理程序定义自己的实现的最佳方法是什么?或者强制这种行为太不方便,因此应该通过其他方式来实现?

最佳答案

OP 在评论中说(强调是我的):

I was thinking I'd like to have all classes derived from System to subscribe to an event, and to be forced to implement their own handler for said event.

同一个句子中的“从 X 派生的所有类”和“被迫”都强烈要求纯虚拟成员函数。

struct System
{
     virtual void foo() = 0;
};

struct Subsystem : public System
{
     virtual void foo() override { /* forced to implement this */ }
};

如果您通过智能指针存储系统(可能在容器中),则可以为每个系统调用 foo() 并确保获得派生类的行为。

这一切都很好,但您无法从基类的构造函数中调用 foo() 。解决这个问题的一个低技术含量的解决方案是使用工厂函数来构造每个对象。

template <typename T>
unique_ptr<T> make_system()
{
    auto obj = make_unique<T>();
    obj->foo();
    return obj;
}

auto s1 = make_system<Subsystem1>();
auto s2 = make_system<Subsystem2>();

这两个对象都被强制实现foo(),并且这两个对象在使用之前都调用了foo()。这仍然是两阶段初始化,但它隐藏在函数调用后面。

关于c++ - 从基类构造函数调用派生类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17154411/

相关文章:

c++ - 从 C++ 字符串中删除不允许的字符的最优雅、最有效的方法?

c++ - 快速排序中使用的两个版本的分区的差异

c++ - 如何在非托管 C++ 中使用 Enum::GetName

c++ - 如何以非阻塞方式压缩文件

c++ - std vector 插入和删除问题

c++ - 分形编程 - 有什么方法可以优化此代码以进行实时渲染?

c++ - 使用受限函数时的尾随返回类型问题

c++ - 用一个范围(一对迭代器)初始化 std::array

C++ noexcept 规范取决于数据成员

c++ - 需要帮助使用 switch 语句创建函数和错误