【问题标题】:Passing member function that accepts void *传递接受 void * 的成员函数
【发布时间】:2016-07-02 11:41:06
【问题描述】:

我正在编写需要将成员函数指针发送到接受 void * 作为参数的记录器方法的代码。我无法将其从 void *.我也不能使用 c++11。有没有办法让它在没有任何警告的情况下工作。例如:

logger.h

    #ifndef _LOGGER_H
    #define _LOGGER_H

    void logger( void *func );

    #endif /* _LOGGER_H */

logger.cpp

    #include <cstdio>
    #include "logger.h"

    void logger( void *func )
    {
        printf("%lx\n", (unsigned long)func);
    }

testCase.cpp

    #include "logger.h"

    class myClass
    {
        public:
            void testCase( void );
    };

    void myClass::testCase( void )
    {
        /* This works on my compiler, but gives warning */
        /* warning: converting from 'void (myClass::*)()' to 'void*' */
        /* I know this is bad and wrong. */
        logger((void *)&myClass::testCase);

        /* This compiles without warning */
        /* But doesnt work the way I need, gives ffff*/
        void (myClass::*ptr)( void ) = &myClass::testCase;
        void *m_ptr = ptr;
        logger(m_ptr);
    }

logger.h 和 logger.cpp 无法更改。

这是在运行 VxWorks,我需要在符号表中查找地址。当我尝试第二种方式时,我得到了 ffff。虽然我在使用其他编译器时得到了一个真实的地址,但它对于 VxWorks 是不同的。

你能想出另一种方法来实现它吗?

References

【问题讨论】:

  • 你可以将一个指针传递给一个包含成员函数指针的结构,或者让它指向一个包含成员函数指针的地址(它们几乎相同,一个语法糖更多)跨度>

标签: c++ pointers parameters casting member


【解决方案1】:

我不知道“双倍大小”;指针就是指针,在我的理解中,给定系统上的所有指针都是相同大小的,无论它们指向什么......

但是,查看我的 Stroustrup 编写的 The C++ Programming Language, 3rd Edition(第 101 页)的副本:

void*s 在系统较高级别的出现应该被怀疑,因为它们很可能是设计错误的指标。在用于优化的地方,void* 可以隐藏在类型安全接口后面(第 13.5 节、第 24.4.2 节)。

指向函数的指针(第 7.7 节)和指向成员的指针(第 15.5 节)不能分配给 void*s

【讨论】:

  • 您应该删除关于所有指针大小相同的第一部分;这不是真的;成员函数指针可以并且通常大于“标准”指针。你每天都能学到一些东西!
  • 你的第一句话是完全错误的,你最好删除它。
【解决方案2】:

不,你不能让它发生。标准禁止将指向成员的指针转换为void*。原因是它们与void* 不兼容——它们通常是void* 大小的两倍。

您的代码还有其他问题,例如,(unsigned long)func 正在将 void* 转换为 unsigned long,这也是未定义的。例如,在许多系统中,long 的长度是 32 位,而 void* 是 64 位。要将void* 可靠地转换为整数类型,您需要使用uintptr_t(前提是您的实现有它)。

【讨论】:

  • 原始代码将成员函数作为字符串“myClass::testCase”传递,并转换为无符号长整数。我们正在尝试摆脱旧方式并实施新服务。将成员函数指针传递给记录器。记录器代码是用 c 编写的,无法更改,因为它正在许多其他地方使用。我们想找到一种方法来传递指针。
  • @TylerGajewski,就像我说的,首先你不能。其次,想象你这样做。你打算在 C logger 中用这个指针做什么?
  • 实际的记录器有 2400 行长,所以我稍微简化了一下。但理想情况下,它不使用 printf,它使用寄存器打印到 vx 控制台,用户将使用该地址在符号表中查找。记录器还接受省略号和格式以将用于调试的字符串输出到控制台。所以输出类似于:5649b0(This is a message) 然后用户可以复制该地址并使用它在符号表中查找。代码变得非常复杂
  • @TylerGajewski,您将很难在符号表中查找指向成员的指针。不要忘记虚函数!
  • 我的负责人说,如果我们能够让它在虚拟功能问题的情况下工作,那么它仍然会比我们现有的有所改进。我在第一个示例中的实现与我们想要的完全一样。但在我工作的地方,发出警告是违法的。
猜你喜欢
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
相关资源
最近更新 更多