C++获取静态函数内的类类型

gz5pxeao  于 2023-03-14  发布在  其他
关注(0)|答案(7)|浏览(204)

在一个静态成员函数内部我需要得到类型。

class MyClass
{
     public:
         static void myStaticFunc();
     ...
};

然后在实现中,我希望:

void MyClass::myStaticFunc()
{
     // Get MyClass as a type so I can cast using it
     (get_type_from_static_function()*)someOtherVariable;
}

这是可能的吗?通常我会在一个对象上使用typeinfo中的一些东西,但是我没有this可以使用。
我不想只使用(MyClass*),因为这是在宏内部进行的,我想让它尽可能简单,以便可以在没有类名的情况下调用它。
如果有帮助的话,我正在使用QT,但是我找不到任何宏来获取当前的类。它不一定是编程的-它可以是一个宏。
干杯!
下面是实际的宏函数:

#define RPC_FUNCTION(funcName) \
static void rpc_##funcName(void* oOwner, RpcManager::RpcParamsContainer params){ ((__class__*)oOwner)->funcName(params); }; \
void funcName(RpcManager::RpcParamsContainer params);

然后我在一个类声明中调用RPC_FUNCTION(foo)。我希望__class__是我所在的任何类声明。我很清楚我可以在funcName之后添加className,但我希望在实际使用它时尽可能简单。我的RPC管理器调用rpc_foo并传递一个指针,指向我在其中声明它的类的对象。实际上,我需要知道如何确定void* 参数的实际类。

8yparm6h

8yparm6h1#

在VisualStudio2012中,你可以使用这个技巧,但它在gcc中不起作用,至少现在是这样。

template<typename base_t>
        static auto GetFunctionBaseType(void(base_t::*)())->base_t;

        struct TBase
        {
            template<typename T> void GetBaseType();
            typedef decltype(GetFunctionBaseType(&GetBaseType<void>)) this_t;

            static void rpc_func1(void * ptr)
            {
                ((this_t*)ptr)->func1();
            }
        };
mitkmikd

mitkmikd2#

我相信你内心的要求是不可能的:C++是一种 * 静态类型化 * 语言,这意味着所有类型信息必须在编译时可用(尽管存在运行时多态性)。

T x;

那么类型T * 必须 * 在编译时已知。没有“T_from_user() x;“这样的东西,变量的实际 * 类型 * 是在运行时确定的。语言就是没有这样设计。
通常,如果你问这样的问题,这是一个指示器,你正在处理一个问题的错误的方式,虽然。典型的解决方案多态情况涉及类继承和虚函数,或其他种类的查找表,或实际上任何数量的不同的方法。您的请求预处理器宏也表明了一些是关闭的。任何编程语言都有自己的习惯用法,偏离太远通常不是个好主意。

j13ufse2

j13ufse23#

你要做的是反射,它是在.NET中实现的(我不知道,也许也是在Java中实现的),并且将在未来的C++标准中实现。

f45qwnt8

f45qwnt84#

看起来您有几个不相关的类,它们有许多共同的方法(在您的示例中可以作为funcName参数发送的方法)。
不要使用这些不相关的类,考虑一种多态方法,例如,假设你支持的函数是func1func2,那么你可以用这种方法来解决这个问题:

class BaseClass {
public:
    virtual void func1(RpcManager::RpcParamsContainer args) = 0;
    virtual void func2(RpcManager::RpcParamsContainer args) = 0;
};

class MyClass1 : public BaseClass {
public:
    virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
    virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};

class MyClass2 : public BaseClass {
public:
    virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
    virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};

通过上面的设计,你可以传递一个BaseClass*,你可以调用func1func2而不必做任何类型转换,编译器会找到正确的版本来调用。例如,在你的宏中,你可以这样做:

#define RPC_FUNCTION(funcName) static void rpc_##funcName(BaseClass* oOwner, RpcManager::RpcParamsContainer params){ oOwner->funcName(params); };

希望这能有所帮助!

tf7tbtn2

tf7tbtn25#

正在搜索函数宏?它是一个扩展到当前函数名的宏。

__FUNCTION__
clj7thdc

clj7thdc6#

我知道这是个老问题。这是个可能的解决办法。
当你定义一个类的时候,你可以使用这种习惯:

class Foo: public Bar
{
  private:
    typedef Foo this_type; // your macro will work in every class defining this
  public:
    std::string description;
  public:
    static this_type* instanciate()
    {
      return new this_type;
    }
};
imzjd6km

imzjd6km7#

不,静态方法只能看到类的静态成员。它访问示例成员(如标准变量等)是没有意义的,因为它们不存在,除非类已经被示例化。
看起来您需要类似于Singleton设计模式的东西,这允许类一次只存在一个示例。
另一种方法是拥有一个类的所有示例的静态列表,然后在类构造函数中添加指向该列表的this指针。正如我所说的,静态成员不能访问示例变量,因为它们可能根本不存在。
我想更大的问题是:为什么你需要从一个静态成员访问一个示例变量?如果你需要访问一个示例成员,你应该在当前示例的上下文中调用这个函数,否则你就很难打破OOP范式。

相关问题