在静态成员函数内部,我需要获取类型。
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 *参数的实际类。
答案 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
参数发送的方法)。
不要使用这些不相关的类,而应考虑使用多态方法。例如,假设您支持的功能是func1
和func2
,那么您可以通过以下方式解决此问题:
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*
,并且可以调用func1
或func2
而无需进行任何强制转换,编译器将找到要调用的正确版本。例如,在您的宏中,您可以执行以下操作:
#define RPC_FUNCTION(funcName) static void rpc_##funcName(BaseClass* oOwner, RpcManager::RpcParamsContainer params){ oOwner->funcName(params); };
我希望这有帮助!
答案 4 :(得分:0)
正在搜索功能宏吗?它是一个扩展为当前函数名称的宏。
__FUNCTION__
答案 5 :(得分:-1)
不,静态方法只能看到类的静态成员。它访问实例成员(如标准变量等)是没有意义的,因为除非已经实例化了类,否则它们不存在。
您似乎想要Singleton设计模式。这允许一次只存在一个类的实例。
另一种方法是拥有一个类的所有实例的静态列表,然后在类构造函数中,将this
指针添加到该列表。正如我所说,静态成员无法访问实例变量,因为它们可能根本不存在。
我想更大的问题是:为什么需要从静态成员访问实例变量?如果您需要访问实例成员,则应该在当前实例的上下文中调用该函数,否则您将非常难以打破OOP范例。