c++ - C++中模板类型中的类层次结构

标签 c++ c++11 inheritance types

我正在做一个简单的项目,其中有发布者从一个数据源中读取数据并构建事件供订阅者处理。

一个事件将有一个唯一的数据ptr,订阅者将拥有一个共享的事件ptr。

我希望有一个事件的通用接口(interface),以便订阅者可以订阅任意数据发布者。
但是发布者只能发布一种类型的数据。

#include <memory>
#include <iostream>

class Data
{

};

class ChildData : public Data
{
};

template<typename T>
class Event
{
    std::unique_ptr<T> _data;
};

void someFunc(Event<Data> event)
{
    std::cout << "hello Word" << std::endl;
}

int main()
{
    Event<ChildData> event();
    someFunc(event);
    return 0;
}


但我收到以下编译器错误
/home/rory/dev/cpp_sandbox/main.cpp: In function ‘int main()’:
/home/rory/dev/cpp_sandbox/main.cpp:27:19: error: could not convert ‘event’ from ‘Event<ChildData> (*)()’ to ‘Event<Data>’
     someFunc(event);
                   ^
CMakeFiles/example.dir/build.make:62: recipe for target 'CMakeFiles/example.dir/main.cpp.o' failed
make[2]: *** [CMakeFiles/example.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/example.dir/all' failed
make[1]: *** [CMakeFiles/example.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

这种事情在 C++ 中可能吗?

最佳答案

有问题的行是这样的:

Event<ChildData> event();

根据 most vexing parse规则,这被解释为函数声明。如果您的 Event,则可以省略括号。类具有初始化所有成员的默认构造函数。否则使用统一初始化语法:
Event<ChildData> event{};

此外,您可能必须使用 std::move通过eventsomeFunc , 自 Event不可复制,因为 std::unique_ptr数据成员。此外,您必须实现从 Event<ChildData> 的转换。至Event<Data> ,这是 someFunc 所必需的.

I want to have a common interface to an event so a subscriber can subscribe to an arbitrary Data publisher. But a publisher can publish only one type of Data.



从这个描述来看,它看起来像 Event模板是多余的。 Data 的通用接口(interface)后代可以在Data中描述类本身,因此除非需要将事件与数据分开,否则只处理数据会更容易。

为了区分不同的事件类型,您可以使用枚举。
enum class EventType
{
    A,
    B,
    C
};

class Data
{
private:
    const EventType m_type;

protected:
    explicit Data(EventType type) : m_type(type) {}

public:
    virtual ~Data() = default;

    // Prohibit copying to avoid accidental slicing
    Data(Data const&) = delete;
    Data& opreator= (Data const&) = delete;

    EventType get_type() const { return m_type; }
};

class ChildData :
    public Data
{
public:
    ChildData() : Data(EventType::A) {}
};

void receive(std::unique_ptr< Data > event)
{
    switch (event->get_type())
    {
    case EventType::A:
        {
            std::unique_ptr< ChildData > child_event{ static_cast< ChildData* >(event.release()) };
            // Process ChildData
        }
        break;

    case EventType::B:
        // ...
    case EventType::C:
        // ...
    }
}

void publish(std::unique_ptr< Data > event);

int main()
{
    std::unique_ptr< ChildData > event{ new ChildData() };
    // Fill ChildData event
    publish(std::move(event));
}

关于c++ - C++中模板类型中的类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60137988/

相关文章:

c++ - 当我用 C 编写 C++ 代码时是否可能显示错误?

c++ - 无法让 std::atomic 正确保护数据

c++ - C++ 中对模板的 const 引用范围

C#继承/多态

尽管设置了私有(private)属性,但 Typescript getter 返回 undefined

c++ - 彩虹表 : Unable to get last reduction

c++ - 在多线程应用程序中使用 OpenSSL

php - Codeigniter 和多重继承?

c++ - 如何将 16 位值数组转换为 base64?

c++0x 编译但 eclipse 编辑器错误,即使使用 -gnu++0x 发现