获取静态函数内部的类类型

C++ Get class type inside static function

本文关键字:类型 内部 静态函数 获取      更新时间:2023-10-16

在静态成员函数内部,我需要获得类型。

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中的一些东西,但是我没有这个可以使用。

我不想只使用(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*参数的实际类

在Visual Studio 2012中你可以使用这个技巧,但它在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();
            }
        };

我相信您所要求的根本是不可能的:c++是一种静态类型语言,这意味着所有类型信息必须在编译时可用(尽管运行时存在多态性)。也就是说,当你说

T x;
那么类型T 必须在编译时知道。没有"T_from_user() x;"这样的东西,因此变量的实际类型是在运行时确定的。语言不是这样设计的。 通常情况下,如果你问这样的问题,这表明你处理问题的方式是错误的。多态情况的典型解决方案包括类继承和虚函数,或其他类型的查找表,或任何不同的方法。您对预处理器宏的请求也表明有些东西出了问题。任何编程语言都有自己的习惯用法,偏离太远通常是一个坏主意。

你要做的就是反射。它是在。net中实现的(我不知道,可能在Java中也实现了),并将在未来的c++标准中实现。

似乎你有几个不相关的类,有一些共同的方法(可以在你的例子中作为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); };

我希望这对你有帮助!

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

 __FUNCTION__

我知道这是个老问题。这是一个可能的解决方案。

在定义类时可以使用这种习惯:

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;
    }
};

不能,静态方法只能看到类的静态成员。它访问实例成员(如标准变量等)是没有意义的,因为除非类已经实例化,否则它们不存在。

看起来你想要类似Singleton设计模式的东西。这允许一次只存在一个类的实例。

另一种方法是拥有一个类的所有实例的静态列表,然后在类构造函数中,将this指针添加到该列表中。正如我所说的,静态成员不能访问实例变量,因为它们可能根本不存在。

我想更大的问题是:为什么需要从静态成员访问实例变量?如果您需要访问实例成员,则应该在当前实例的上下文中调用该函数,否则将严重破坏OOP范例。