是否可以"copy"其模板化类派生自非模板化基库的对象?
Is it possible to "copy" an object whose templated class derives from a non-templated base?
我在C++中构建了一个小型的、范围有限的跨平台 UI 库。它使用以下类来处理 UI 回调:
// Base class for templated __Callback class to allow for passing __Callback
// objects as parameters, storing in containers, etc. (as Callback*)
class Callback
{
public:
virtual void execute() = 0;
virtual ~Callback() { }
protected:
Callback() { }
};
正如注释所描述的,这是回调的基类 - 它允许将它们作为参数传递并将它们存储在 UI 小部件中,以便可以执行正确的回调(例如,当用户单击按钮时(。
// C++ has no callbacks (in the sense of an action [method] of a
// target [object]), so we had to roll our own. This class can be used
// directly, but the NEW_CALLBACK macro is easier.
template <class __TargetType>
class __Callback : public Callback
{
public:
typedef __TargetType TargetType;
typedef void (TargetType::*ActionType)(void);
virtual void execute()
{
(this->__target->*this->__action)();
}
__Callback(TargetType* target_, ActionType action_) :
Callback(), __target(target_), __action(action_) { }
virtual ~__Callback() { }
private:
// target object for the callback
TargetType* __target;
// action (method) of the target that will be called
ActionType __action;
};
这个模板化类是回调范式的肉。它存储指向对象的指针和指向成员函数的指针,以便以后可以在目标对象上调用成员函数。
#define NEW_CALLBACK(class_, obj_, act_)
new __Callback<class_>(obj_, &class_::act_)
此宏只是使创建模板化__Callback
对象变得更加容易。
这已经工作了很长时间!带有回调的按钮可以实例化,如下所示:
MyClass* obj = new MyClass();
Button* btn = new Button("Title", NEW_CALLBACK(MyClass, obj, btnClicked));
这将创建一个按钮,稍后放置在窗口或其他容器中,单击时将调用obj->btnClicked()
。
的问题(很抱歉设置冗长,我认为我不能再削减它了(。出现了我需要复制Callback*
对象的情况。当然,由于它只是一个指向基类的指针,因此我无法确定模板派生类的类型。
如何复制任意Callback
对象,副本指向与原始对象相同的目标和操作?或者,对于这个回调问题,我应该采取一种完全不同的方法(尽管我不想改变太多(?
谢谢大家!
我不知道
您是否应该采取更好的方法,但这似乎是克隆方法的理想用途。
您只需要在__Callback模板中定义一个复制构造函数,在基类中定义一个纯虚拟克隆方法,然后在模板中实现该虚拟方法(使用您创建的复制构造函数(
例如:
class Callback
{
public:
...
virtual Callback* Clone()=0;
};
template <class __TargetType>
class __Callback : public Callback
{
public:
...
__Callback(const __Callback& other) :
__target(other.target_), __action(other.action_) { }
virtual Callback* Clone()
{
return new __Callback(this);
}
}
使用克隆作为虚拟构造函数的替代品。注意协变量返回类型,使其真正有效。例如
struct Callback {
virtual Callback* clone() const;
};
template<...>
struct Callback_impl {
virtual Callback_impl* clone() const;
};
您还应该考虑终身管理shared_ptr
。都这似乎有点脆弱。
对我来说,看起来你想要 std::function .它是多态的、类型安全的,并通过 std::mem_fn
与指向成员函数的指针一起工作。
相关文章:
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 为什么此派生对象无法访问基类的后递减方法?
- 将带有派生模板的对象传递给接受具有基本模板的对象的功能
- 放置派生C++的新基子对象
- 在 C++ 中将对象转换为派生类型
- 链表包含 c++ 中不同的派生类对象
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 如何在新的派生对象中获取基本对象的数据?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 获取我的基类以递增派生类对象整数
- 派生类中的对象
- 在没有默认构造函数的情况下创建的派生对象
- OOP 标识派生对象
- 如何创建派生对象的向量?
- 按基类对象访问派生类资源时出错
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- static_cast将此对象派生到C++中的基类
- 如何在构造函数完成后立即销毁从 QWindow 对象派生的内容
- 我可以判断std::type_info对象是否等于另一个对象或从另一个对象派生的类吗?