我有一个对象 - 一个调度程序类 - 。该调度程序类被赋予成员函数指针,times和指向创建调度程序的对象的指针
这意味着我可以做一些事情:(pObject->*h.function)(*h.param);
其中pObject是指向原始对象的指针,ha类包含function
+ void指针parameter
所以我可以将参数传递给原始功能。
当我想初始化这个对象时,我有explicit Scheduler(pObjType o);
构造函数(其中pObjType是模板参数)。
当我创建一个应该有此警报的对象时,我输入:
struct A {
typedef void (A::*A_FN2)(void*);
typedef Scheduler<A*,A_FN2> AlarmType;
A(int _x) : alarm(NULL)
{
alarm.SetObject(this);
}
AlarmType alarm
然而,这种警报类型对对象施加了很大的限制:如果我忘记添加一个拷贝构造函数(到 A ),该类会得到未定义的行为。调度程序将继续指向原始对象,并且原始对象可能超出范围,或者更糟糕的是,可能不会。
有没有一种方法可以在我复制警报时(默认情况下,在调度程序的复制构造函数中)我可以获取调用对象(以及指向它的指针?)? 或者,如果这是不可能的,如果我忘记为我的结构实现一个拷贝构造函数,是否可能抛出(编译)错误? - 并尝试在某处复制此结构?
答案 0 :(得分:1)
在我看来,你有机会在这里改进你的设计,这可以帮助你摆脱烦恼。
boost::NonCopyable
。答案 1 :(得分:0)
如果你想要任何类型的自动复制构造语义,那么你将需要转到CRTP-没有其他模式提供指向拥有对象的指针。
另一件事是你应该使用boost :: / std :: function&lt;&gt;,它们更通用,如果你想能够使用Lua函数,你将需要它。
答案 2 :(得分:0)
阻止您提出的具体问题的最简单方法是使Scheduler
不可复制(例如使用boost::noncopyable
)。这意味着包含类型Scheduler
的值成员的任何客户端类都将无法复制。希望是这为程序员提供了一个提示,可以检查文档并找出Scheduler
的复制语义(即为每个新的Scheduler
构建一个新的A
),但这是可能的如果他们只是通过指针按住Scheduler
来解决问题,那么就会出错。对指针进行别名会产生与构造保存指针的Scheduler
实例的default-copy-construct完全相同的问题。
每当你有原始指针时,你必须有一个关于对象生命周期的策略。您希望确保任何类A
的生命周期至少与Scheduler
的相应实例一样长,并且我认为有三种方法可以确保这一点:
A
包含Scheduler
,因此Scheduler
不能包含A
A
个实例生命周期的全局政策,例如要求它们始终由智能指针保持,或者清理它们是某些类的责任,这些类也知道清理依赖它们的Scheduler
CRTP可以像这样工作:
#include <iostream>
using namespace std;
template<typename T>
struct Scheduler {
typedef void (T::* MemFuncPtr)(void);
Scheduler(MemFuncPtr action) :
action(action)
{
}
private:
void doAction()
{
this->*action();
}
MemFuncPtr action;
};
struct Alarm : private Scheduler<Alarm> {
Alarm() : Scheduler<Alarm>(&Alarm::doStuff)
{
}
void doStuff()
{
cout << "Doing stuff" << endl;
}
};
请注意,私有继承可确保Alarm
类的客户端无法将其视为原始Scheduler
。