C++ 获取(指向)调用对象的指针

C++ 获取(指向)调用对象的指针,c++,copy-constructor,C++,Copy Constructor,我有一个对象-一个调度程序类-。此调度程序类被赋予成员函数指针、时间和指向创建调度程序的对象的指针。 这意味着我可以做如下事情:(pObject->*h.function)(*h.param)其中pObject是指向原始对象的指针,它是一个包含函数+void pointer参数的类,因此我可以将参数传递给原始函数。 当我想初始化这个对象时,我有显式调度器(pobjo类型)构造函数(其中pObjType是模板参数) 创建应具有此报警的对象时,我键入: struct A { typedef

我有一个对象-一个调度程序类-。此调度程序类被赋予成员函数指针、时间和指向创建调度程序的对象的指针。
这意味着我可以做如下事情:
(pObject->*h.function)(*h.param)
其中pObject是指向原始对象的指针,它是一个包含
函数
+void pointer
参数
的类,因此我可以将参数传递给原始函数。
当我想初始化这个对象时,我有
显式调度器(pobjo类型)构造函数(其中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{ typedef void(A:*A_FN2)(void*); typedef调度器报警类型; A(整数x):报警(空) { 报警。设置对象(此); } 报警型报警
然而,这种报警类型对对象有很大的限制:如果我忘记添加复制构造函数(到a),类将获得未定义的行为。调度程序将继续指向原始对象,并且原始对象可能超出范围,甚至更糟的是,可能不会

是否有一种方法可以在复制报警时(默认情况下,在调度程序的复制构造函数中)获取调用对象(以及指向该对象的指针?

或者如果这是不可能的,如果我忘记为我的结构实现复制构造函数,是否可能抛出(编译)错误?-并尝试在某个地方复制此结构?

在我看来,您有机会改进您的设计,这可能会帮助您摆脱担忧

  • 通过考试通常是个坏主意 围绕成员函数指针。它 最好是让你的结构 从抽象基类继承, 制作您想要的函数 自定义抽象虚拟
  • 如果你不需要复制,那最好 在基类中不允许它。 通过使复制构造函数和运算符未定义且为私有, 或者通过继承
    boost::NonCopyable

  • 如果您想要任何类型的自动复制构造语义,那么您需要转到CRTP——没有其他模式提供指向所属对象的指针


    另一件事是,您应该真正使用boost::/std::function,它们更通用,如果您希望能够使用Lua函数,您将需要它。

    防止您询问的特定问题的最简单方法是使
    调度程序
    不可复制(例如,使用
    boost::不可复制
    )。这意味着任何包含
    调度器
    类型的值成员的客户端类都将无法复制。希望这为程序员提供一个提示,以检查文档并找出
    调度器
    的复制语义(即为每个新的
    a
    构造一个新的
    调度器
    ),但如果某人仅通过指针按住
    调度程序
    来解决此问题,则可能会出错。将指针别名与构造包含指针的
    调度程序
    实例的默认副本产生的问题完全相同

    任何时候,只要有原始指针,就必须有一个关于对象生存期的策略。您希望确保任何类
    a
    的生存期至少与
    调度程序的相应实例的生存期一样长,在我看来,有三种方法可以确保这一点:

    • 使用组合-在这种情况下不可能,因为
      A
      包含
      Scheduler
      ,所以
      Scheduler
      不能包含
      A
    • 使用继承,例如以奇怪的重复模板模式(CRTP)的形式
    • 制定强制执行
      a
      实例生存期的全局策略,例如,要求它们始终由智能指针持有,或者清除它们是某个类的责任,该类也知道清除依赖它们的
      调度程序
    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;
        }
    };
    
    #包括
    使用名称空间std;
    模板
    结构调度器{
    typedef void(T::*MemFuncPtr)(void);
    计划程序(MemFuncPtr操作):
    行动(行动)
    {
    }
    私人:
    无效doAction()
    {
    这个->*动作();
    }
    MemFuncPtr作用;
    };
    结构警报:专用计划程序{
    Alarm():计划程序(&Alarm::doStuff)
    {
    }
    void doStuff()
    {
    
    1的问题是,这些函数目前是成员函数。但稍后我想对其进行扩展,并可能为(LUA)脚本提供句柄,以便它们可以在设计级别而不是引擎级别进行自定义。2的问题是,我实际上需要复制,但因为不需要其他非默认复制构造函数(我设计的所有东西都是为了不需要它)我希望避免这种需要。我也不明白为什么复制构造函数是这里的大问题-悬空指针来自销毁,而不是复制。不?所以你需要在销毁时取消订阅。