【发布时间】:2020-12-12 11:48:25
【问题描述】:
我正在尝试在我的项目中实现一个类似于 Qt 中的属性系统的属性系统。我们刚开始提出一些想法,正处于原型设计阶段。 基本上,我从 Qt 中了解到的是,客户端应该能够通过 .h 文件中的一些宏来传递 get 函数、set 函数和属性类型。所以我试着模仿。
以下是我的示例代码:
抽象的 getter 类。这种类型的getter类是Property Class的成员
class AbstractFunc
{
public:
template < typename R >
R Invoke ()
{
return (this)->Invoke ();
}
};
获取函数模板:返回值可以是 T , T&, const T& , T* 等。
template < typename R, class T > class GetterFunction : public AbstractFunc
{
typedef R (T::*GetterFunc) ();
public:
GetterFunction (T * obj, GetterFunc func):m_Obj (obj), m_Func (func)
{
}
R Invoke ()
{
return m_Obj->*(m_Func) ();
}
public:
T * m_Obj;
GetterFunc m_Func;
};
属性类:
class Property
{
public:
Property (string name, AbstractFunc* getter):m_name (name), m_getter (getter)
{
}
template < typename R > R GetValue ()
{
return m_getter->Invoke < R > ();
}
private:
string m_name;
AbstractFunc* m_getter;
};
一些窗口类:
class Window
{
public:
};
示例窗口类
class CheckBox :public Window
{
public:
int GetChecked ()
{
return m_checked;
}
void SetChecked (int nChecked)
{
m_checked = nChecked;
}
void AddProperty (string name)
{
m_prop = new Property (name, new GetterFunction< int, Checked >(this, &Checked::GetChecked));
}
int m_checked;
Property *m_prop;
};
主要功能:
int main ()
{
CheckBox cc;
cc.AddProperty ("Hello");
cout<<"value:"<< cc.m_prop->GetValue<int>();
return 0;
}
问题: Getter 函数在属性类中被记住为 AbstractFunc。我想在 AbstractFunc* 实例上调用“Invoke”,它应该调用成员函数并返回正确的返回类型。上面的代码在 AbstractFunc::Invoke 处抛出错误。
【问题讨论】:
-
return (this)->Invoke ();这毫无意义。该函数只是调用自身。也许您想让这个函数成为纯虚拟函数。不用等你不能,它是一个模板。看起来你根本没有这样的功能。 “它应该调用成员函数并返回正确的返回类型”正确的类型是什么? -
@n.'pronouns'm。所需的接口看起来很像
std::any和std::any_cast,您可以在其中传递您期望的类型,然后从中获取值。如果您对类型有误,则无法获得值。当然可以实现。 OP 的做法完全是错误的。 -
@n.'pronouns'm。是的,我不能让它成为虚函数。return (this)->Invoke ();实际上,如果我转换为派生类,这可以调用派生类函数。好的,但这是错误的。关于“它应该调用成员函数并返回正确的返回类型”,Invoke 函数应该返回正确的类型,例如:对于函数 int GetChecked(),Invoke() 应该返回 int; int& GetChecked(), Invoke() 应该返回 int&。
-
@HTNW 是的,当然可以实现。您可以为每个变量指定
std::any的类型,并在每次使用前执行any_cast。但你为什么要它? -
"实际上,如果我转换为派生类,这可以调用派生类函数" OK 继续转换它,有什么问题?你知道派生类是什么吗?
标签: c++ templates c++17 variadic-templates pointer-to-member-functions