C ++在静态函数中获取类类型

时间:2011-11-07 01:05:14

标签: c++ class types static

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

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 *参数的实际类。

6 个答案:

答案 0 :(得分:1)

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

T x;

然后在编译时必须知道类型T 。没有“T_from_user() x;”这样的东西,其中变量的实际类型是在运行时确定的。语言不是那样设计的。

通常,如果您提出这样一个问题,那就是表明您正在以错误的方式解决问题。多态情况的典型解决方案涉及类继承和虚函数,或其他种类的查找表,或实际上任何数量的不同方法。您对预处理器宏的请求也表明某些内容已关闭。任何编程语言都有它的习语,而且偏离这些语言太过分通常是一个坏主意。

答案 1 :(得分:1)

在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();
            }
        };

答案 2 :(得分:0)

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

答案 3 :(得分:0)

看起来你有一些不相关的类有许多共同的方法(可以在你的例子中作为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); };

我希望这有帮助!

答案 4 :(得分:0)

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

 __FUNCTION__

答案 5 :(得分:-1)

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

您似乎想要Singleton设计模式。这允许一次只存在一个类的实例。

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

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