【发布时间】:2019-10-15 11:35:31
【问题描述】:
尽管我阅读了很多关于模板的内容,但这是我第一次尝试实际使用它们。因此我的问题可能只是缺少对模板的理解。
我有一个应该独立并定期生成一些数据的类。当有新数据时,它通过回调函数调用父级并发送数据。该类应该是可移植的,因此是模板化的父类。
但是,如果我在我的数据类上使用模板,我必须将模板拖到每个函数中,而仅仅能够调用一个函数就觉得不必要的复杂。所以我在全局命名空间中创建了一个小的回调类,我想将其用作接口。
namespace wrapper
{
//Callback class
template<typename ParentClass>
class Data_Callback
{
public:
ParentClass* m_parent = nullptr;
Data_Callback<ParentClass>(ParentClass* parent)
{
m_parent = parent;
};
void DoCallback(DataClass* data)
{
if (m_parent)
m_parent->callback_func(*data);
}
};
//global object I want to use for callback
template<typename ParentClass>
std::unique_ptr<Data_Callback<ParentClass>> m_parentCallback;
template<typename ParentClass>
PatientenErkennung GetNewDataClass(ParentClass* parent)
{
m_parentCallback = std::make_unique<Data_Callback<ParentClass>>(parent);
std::shared_ptr<DataClass> obj = std::make_shared<DataClass>();
return obj;
};
}
然后我可以像这样从我的父类调用我的全局“GetNewDataClass”函数:
m_data = wrapper::GetNewDataClass(this);
但是当我想从 DataClass 调用回调时,模板会妨碍:
wrapper::m_parentCallback<I_DONT_HAVE_THIS>->DoCallback(data);
在不知道父类的情况下,我不能调用那个全局对象,可以吗?因此回调只能从 Data_Callback 类初始化,但该类不包含数据。
你如何解决这个问题?可能是继承?还是设计本身不能像这样使用? 正如我之前所说,我想避免让我的较大的 DataClass 在 DataClass 周围拖动模板,尽管这会起作用...
【问题讨论】:
-
您目前拥有的是针对每种父类类型的不同全局对象。这是你在概念上想要的,还是你想要一个所有东西都应该使用的全局回调变量?
-
如果你使用“继承”——好吧,在这种情况下,更好的术语是“多态性”,那么你就不再需要包装器了。您将为所有类型的父类设计一个公共接口,然后每个单独的类型都将从该公共基础继承。但是,如果这适合您的需求,则取决于您打算如何使用这些父母...
-
@MaxLanghof 在我的情况下它实际上是相同的,因为只有一个 DataClass 实例并且它与回调一起被初始化。不过,您是对的:它原本应该是一个全局对象。
-
@Aconcagua 我只是将包装器用作某种解决方法。我不依赖它。只有一个父类匹配一个 DataClass 对象,我只需要那个父对象用于回调函数。指向成员回调函数的指针也可以,但我认为这种方法在 C++ 中既不好也不容易。您是否有一个示例如何在我的 DataClass 中没有模板的情况下继承父指针?
-
struct Base { virtual ~Base() { }; virtual void f() = 0; }; struct Derived : Base { void f() override { } }; Base* b = new Derived(); b->f();– 由于 f 是虚拟的,因此在给定示例中,将调用可用的最派生类的变体Derived::f,即使指针的类型为Base。
标签: c++ class templates callback