【问题标题】:Strange Issue When Trying To Implement Callbacks To Methods In C++尝试在 C++ 中实现对方法的回调时出现的奇怪问题
【发布时间】:2014-02-04 12:48:36
【问题描述】:

我正在尝试在 C++ 中实现对方法的回调。

注意:这大致遵循http://www.codeproject.com/Articles/6136/Type-safe-Callbacks-in-C 的代码

我创建了一个 Callback 类和一个从 Callback 类派生的 CallbackGen 类。

这是我创建的用于测试的类...

class ClassWithFunction
{
public:
    void TryAndCallMe(uint32_t x)
    {
        std::cout << "I was called!";
    }
};

然后在 main()..

ClassWithFunction classWithFunction;

SlotMachine::CallbackGen<ClassWithFunction, void, uint32_t>
callBackGen(&classWithFunction, &ClassWithFunction::TryAndCallMe);

std::cout << "callbackGen.obj = " << callBackGen.obj << "\r\n"; // PRINTS 0x12345
printf("callbackGen.func = %p\r\n", callBackGen.func);  // PRINTS 0x12345

SlotMachine::Callback<void, uint32_t> callBack;

// THIS LINE CALLS THE ASSIGNMENT OPERATOR          
callBack = callBackGen;

但是,当代码进入重载的赋值运算符时,事情就变得古怪了

Callback& operator=(const Callback<returnType, fArg1Type> &callback)
{
    std::cout << "Equal operator called.\r\n";
// Check if the right-hand side Callback object has been initialised
if(&callback != NULL)
{
    std::cout << "callback was not NULL.\r\n";
    this->obj = callback.obj;
    this->func = callback.func;

    std::cout << "callback.obj = " << callback.obj << "\r\n"; // PRINTS 0
    printf("callback.func = %p\r\n", callback.func);   // PRINTS (nil)
    std::cout << "this->obj = " << this->obj << "\r\n";  // PRINTS 0
    printf("this->func = %p\r\n", this->func);    // PRINTS (nil)
}
else
    Callback();

 return *this;

}

那些// PRINTS 0// PRINTS (nil) 是我遇到问题的地方。

赋值运算符函数中的回调对象(RHS 对象)objfunc 变量为NULL!即使在输入赋值函数之前检查了“相同”的值,并返回了有效的内存地址(// PRINTS 0x12345)。

编辑:为了让事情更清楚,这是CallbackGen

    //! @brief      This can generate callbacks to member functions!
    //! @details    Note that this has one more type than the callback classes, that is, a type for the object that the callback function belongs to.
    template<class objType, class returnType, class fArg1>
    class CallbackGen : public Callback<returnType, fArg1>
    {
    public:

        // Create method pointer type (points to method of a particular class
        typedef returnType (objType::*funcT)(fArg1);

        //! @brief      To store the pointer to the member callback function
        funcT func;

        //! @brief      To store the object that the callback function belongs to
        objType* obj;

        //! @brief      Constructor
        CallbackGen(objType* obj, funcT func)
        {
            this->func = func;
            this->obj = obj;
        }
    protected:
        CallbackGen();
    };

【问题讨论】:

  • 如果您认为SlotMachine::CallbackGen 的实现有助于破译您的问题,那么您是对的。
  • 已添加,抱歉,我知道这里有很多代码,试图使其尽可能简单而不掩盖很多细节。
  • 与您的问题无关,但您不必检查引用的地址是否为 NULL。引用必须始终有效。

标签: c++ object callback member assignment-operator


【解决方案1】:

我的猜测是,没有看到 Callback 类的定义,它有自己的 objfunc 成员,因为您通过赋值运算符中的 Callback &amp; 访问它们。这些将被 CallbackGen 中声明的隐藏。换句话说,您没有访问正确的字段。

【讨论】:

  • 是的!可变阴影?奇怪,因为codeproject.com/Articles/6136/Type-safe-Callbacks-in-C 和我做的一样,而且显然没有问题。如何访问可能被基类类型隐藏的继承类变量?
  • @gbmhunter 您可以通过基类名称访问它们:Callback&lt;...&gt;::func。这在您需要调用基类成员的模板类中通常是必需的。您还可以考虑使用受保护的构造函数/访问器来设置这些字段。不过,您仍然需要通过基类名称调用访问器。
  • 好的,我想我刚刚得到了 C 中与类型无关的方法回调背后的一个关键技巧,即使用 memcpy() 函数将对象和成员方法复制到通用对象和成员方法变量,在哪里只是去this-&gt;obj = obj 不会工作,因为类型不兼容,但memcpy(&amp;this-&gt;obj, &amp;obj, sizeof(obj)) 工作!
  • 好的。谢谢,你的回答是正确的。我必须删除CallbackGen 中的objfunc 对象,让它使用从Callback 继承的对象(CallbackGen 继承自Callback)。 memcpy() 技巧是让我意识到整个事情实际上是如何运作的关键部分:-)
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 2018-10-25
  • 2021-08-16
  • 1970-01-01
相关资源
最近更新 更多