C++ Get class type inside static function

喜欢而已 提交于 2021-01-27 04:41:06

问题


Inside of a static member function I need to get the type.

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

And then in the implementation I want to have:

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

Is this even possible? Normally I would use something from typeinfo on an object but I don't have this to work with.

I do not want to just use (MyClass*) because this is going inside of a macro and I'd like to keep it as simple as possible so that it can be called without a class name.

If it helps I am using QT but I couldn't find any macros to get the current class. It doesn't necessarily need to be programmatic - it can be a macro.

Cheers!

EDIT: Here is the actual macro function:

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

I then call RPC_FUNCTION(foo) in a class declaration. I want __class__ to be whatever class declaration I am in. I'm well aware I can just add className after funcName but I want to keep this as simple as possible when actually using it. My RPC manager calls rpc_foo and passes a pointer to an object of the class I declared it in. Essentially I need to know how to determine the actual class of that void* parameter.


回答1:


I believe that what you're asking for at heart is simply not possible: C++ is a statically typed language, which means that all type information must be available at compile time (runtime polymorphism notwithstanding). That is, when you say,

T x;

then the type T must be known at compile time. There is no such thing as "T_from_user() x;", whereby the actual type of a variable is determined at runtime. The language just isn't designed that way.

Usually if you're asking such a question that's an indicator that you're going about a problem the wrong way, though. Typical solutions for polymorphic situations involve class inheritance and virtual functions, or other sorts of lookup tables, or really any number of different approaches. Your request for a preprocessor macro also indicates that something is off. Any programming language has its idioms, and veering too far from those is usually a bad idea.




回答2:


In Visual Studio 2012 you can use that trick, but it will not work in gcc, at least for now.

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



回答3:


What you want to do is called Reflection. It was implemented in .NET (I don't know, maybe in Java too) and is going to be implemented in future standards of C++.




回答4:


It seems you have a few unrelated classes that have a number of methods in common (the ones that can be sent as the funcName argument in your example).

Instead of having these unrelated classes, consider a polymorphic approach. For example, let's say the functions that you support are func1 and func2, then you can work this out in this way:

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

With the above design your can pass a BaseClass* around, and you can call func1 or func2 without having to do any casts, and the compiler will find the correct version to invoke. For example, in your macro you could do something like this:

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

I hope this helps!




回答5:


Are searching for the function macro? It's a macro that expands to the current function name.

 __FUNCTION__



回答6:


No, a static method can only see static members of the class. It doesn't make sense for it to access instance members (as in, standard variables etc) as they don't exist unless the class has been instantiated.

It seems like you want something like the Singleton design pattern. This allows for only a single instance of the class to exist at a time.

Another way would be to have a static list of all instances of a class, then in the class constructor, add the this pointer to that list. As I say though, static members cannot access instance variables, as they may not exist at all.

I suppose the greater question is this: why do you need to access an instance variable from a static member? If you require access to an instance member, you should be calling the function in the context of the current instance, otherwise you're breaking the OOP paradigm pretty hard.



来源:https://stackoverflow.com/questions/8031739/c-get-class-type-inside-static-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!