C++ c+中getter和setter方法的包装器+;
我有几个类有一对代表“setter”和“getter”方法的方法,比如:C++ c+中getter和setter方法的包装器+;,c++,C++,我有几个类有一对代表“setter”和“getter”方法的方法,比如: class ClassA { void SetSomeProperty(const int& value) { ... } int GetSomeProperty() { ... } void SetAnotherProperty(const Vec3& value) { ... } Vec3 GetAnotherProperty() { ... } }; class C
class ClassA
{
void SetSomeProperty(const int& value) { ... }
int GetSomeProperty() { ... }
void SetAnotherProperty(const Vec3& value) { ... }
Vec3 GetAnotherProperty() { ... }
};
class ClassB
{
void SetColor(const Vec4& value) { ... }
Vec4 GetColor() { ... }
}
我想创建一个名为PropertyAccess的类,它可以包装任何类的每一对setter和getter。这将允许我通过此属性访问其他对象,该对象将能够调用那些对ClassA或ClassB一无所知的setter和getter
这是我的建议:
class PropertyAccess
{
public:
template <typename TClass, typename TType> using SetterPointer = void (TClass::*)(const TType&);
template <typename TClass, typename TType> using GetterPointer = TType(TClass::*)();
template <typename TClass, typename TType>
PropertyAccess(
TClass* object,
SetterPointer<TClass, TType> setter,
GetterPointer<TClass, TType> getter)
{
using std::placeholders::_1;
m_setter = new Setter<TType>(std::bind(setter, object, _1));
m_getter = new Getter<TType>(std::bind(getter, object));
}
~PropertyAccess()
{
delete m_setter;
delete m_getter;
}
template <typename T>
void Set(const T& value)
{
((Setter<T>*)m_setter)->m_setter(value);
}
template <typename T>
T Get()
{
return ((Getter<T>*)m_getter)->m_getter();
}
private:
struct Base
{
virtual ~Base() {}
};
template <typename TType>
struct Setter : public Base
{
Setter(std::function < void(const TType&) > setter) { m_setter = setter; }
std::function < void(const TType&) > m_setter;
};
template <typename TType>
struct Getter : public Base
{
Getter(std::function < TType() > getter) { m_getter = getter; }
std::function < TType() > m_getter;
};
Base* m_setter;
Base* m_getter;
};
类属性访问
{
公众:
使用SetterPointer=void(TClass::*)(const TType&)的模板;
使用GetterPointer=TType(TClass::*)()的模板;
模板
财产准入(
TClass*对象,
二传,
吸气剂(吸气剂)
{
使用std::占位符::1;
m_setter=newsetter(std::bind(setter,object,_1));
m_getter=newgetter(std::bind(getter,object));
}
~PropertyAccess()
{
删除m_setter;
删除m_getter;
}
模板
无效集(常数T和值)
{
((Setter*)m_Setter)->m_Setter(值);
}
模板
不明白
{
return((Getter*)m_Getter)->m_Getter();
}
私人:
结构基
{
虚拟~Base(){}
};
模板
结构设置器:公共基
{
Setter(std::functionSetter{m_Setter=Setter;}
std::functionm_setter;
};
模板
结构Getter:公共基
{
Getter(std::functionGetter){m_Getter=Getter;}
std::functionm_getter;
};
基地*m_设置器;
Base*m_getter;
};
我是这样用的:
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<int>(10);
int v = p.Get<int>();
ClassA;
属性访问p(&a,&ClassA::SetSomeProperty,&ClassA::GetSomeProperty);
p、 组(10);
int v=p.Get();
一切正常,但这是一个非常缓慢的方法。通过PropertAccess调用setter的速度大约是直接调用setter的18倍。速度在这里很重要,因为我需要在动画库中使用该机制(动画师将在不了解源对象的情况下设置属性)
所以我的问题是:如何加速这一机制?有没有“行业标准”的方法?也许我应该使用经典方法指针而不是std::function?将
PropertyAccess
本身作为模板:
template <typename TClass, typename TType>
class PropertyAccess
{
public:
using SetterPointer = void (TClass::*)(const TType&);
using GetterPointer = TType(TClass::*)();
PropertyAccess(TClass* object, SetterPointer setter, GetterPointer getter)
: m_object(object), m_setter(setter), m_getter(getter)
{
}
void Set(const TType& value) {
(m_object->*m_setter)(value);
}
TType Get() {
return (m_object->*m_getter)();
}
private:
TClass* m_object;
SetterPointer m_setter;
GetterPointer m_getter;
};
模板
类属性访问
{
公众:
使用SetterPointer=void(TClass::*)(constttype&);
使用GetterPointer=TType(TClass::*)();
PropertyAccess(TClass*对象、SetterPointer setter、GetterPointer getter)
:m_object(object)、m_setter(setter)、m_getter(getter)
{
}
无效集(常量类型和值){
(m_对象->*m_设置器)(值);
}
TType Get(){
返回(m_object->*m_getter)();
}
私人:
TClass*m_对象;
setterpointerm m_setter;
GetterPointer m_getter;
};
您当前的实现不仅速度慢,而且不安全。看看如果你这样做会发生什么
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int
ClassA;
属性访问p(&a,&ClassA::SetSomeProperty,&ClassA::GetSomeProperty);
p、 设置(10);//但是属性是int
将属性访问
本身作为模板:
template <typename TClass, typename TType>
class PropertyAccess
{
public:
using SetterPointer = void (TClass::*)(const TType&);
using GetterPointer = TType(TClass::*)();
PropertyAccess(TClass* object, SetterPointer setter, GetterPointer getter)
: m_object(object), m_setter(setter), m_getter(getter)
{
}
void Set(const TType& value) {
(m_object->*m_setter)(value);
}
TType Get() {
return (m_object->*m_getter)();
}
private:
TClass* m_object;
SetterPointer m_setter;
GetterPointer m_getter;
};
模板
类属性访问
{
公众:
使用SetterPointer=void(TClass::*)(constttype&);
使用GetterPointer=TType(TClass::*)();
PropertyAccess(TClass*对象、SetterPointer setter、GetterPointer getter)
:m_object(object)、m_setter(setter)、m_getter(getter)
{
}
无效集(常量类型和值){
(m_对象->*m_设置器)(值);
}
TType Get(){
返回(m_object->*m_getter)();
}
私人:
TClass*m_对象;
setterpointerm m_setter;
GetterPointer m_getter;
};
您当前的实现不仅速度慢,而且不安全。看看如果你这样做会发生什么
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int
ClassA;
属性访问p(&a,&ClassA::SetSomeProperty,&ClassA::GetSomeProperty);
p、 设置(10);//但是属性是int
将属性访问
本身作为模板:
template <typename TClass, typename TType>
class PropertyAccess
{
public:
using SetterPointer = void (TClass::*)(const TType&);
using GetterPointer = TType(TClass::*)();
PropertyAccess(TClass* object, SetterPointer setter, GetterPointer getter)
: m_object(object), m_setter(setter), m_getter(getter)
{
}
void Set(const TType& value) {
(m_object->*m_setter)(value);
}
TType Get() {
return (m_object->*m_getter)();
}
private:
TClass* m_object;
SetterPointer m_setter;
GetterPointer m_getter;
};
模板
类属性访问
{
公众:
使用SetterPointer=void(TClass::*)(constttype&);
使用GetterPointer=TType(TClass::*)();
PropertyAccess(TClass*对象、SetterPointer setter、GetterPointer getter)
:m_object(object)、m_setter(setter)、m_getter(getter)
{
}
无效集(常量类型和值){
(m_对象->*m_设置器)(值);
}
TType Get(){
返回(m_object->*m_getter)();
}
私人:
TClass*m_对象;
setterpointerm m_setter;
GetterPointer m_getter;
};
您当前的实现不仅速度慢,而且不安全。看看如果你这样做会发生什么
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int
ClassA;
属性访问p(&a,&ClassA::SetSomeProperty,&ClassA::GetSomeProperty);
p、 设置(10);//但是属性是int
将属性访问
本身作为模板:
template <typename TClass, typename TType>
class PropertyAccess
{
public:
using SetterPointer = void (TClass::*)(const TType&);
using GetterPointer = TType(TClass::*)();
PropertyAccess(TClass* object, SetterPointer setter, GetterPointer getter)
: m_object(object), m_setter(setter), m_getter(getter)
{
}
void Set(const TType& value) {
(m_object->*m_setter)(value);
}
TType Get() {
return (m_object->*m_getter)();
}
private:
TClass* m_object;
SetterPointer m_setter;
GetterPointer m_getter;
};
模板
类属性访问
{
公众:
使用SetterPointer=void(TClass::*)(constttype&);
使用GetterPointer=TType(TClass::*)();
PropertyAccess(TClass*对象、SetterPointer setter、GetterPointer getter)
:m_object(object)、m_setter(setter)、m_getter(getter)
{
}
无效集(常量类型和值){
(m_对象->*m_设置器)(值);
}
TType Get(){
返回(m_object->*m_getter)();
}
私人:
TClass*m_对象;
setterpointerm m_setter;
GetterPointer m_getter;
};
您当前的实现不仅速度慢,而且不安全。看看如果你这样做会发生什么
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int
ClassA;
属性访问p(&a,&ClassA::SetSomeProperty,&ClassA::GetSomeProperty);
p、 设置(10);//但是属性是int
您可以采用Anton Slavin的解决方案,并引入一个接口来擦除对象类型。它将使访问器的生存期管理变得更加复杂(您将不得不使用引用/指针/智能指针并管理生存期,因为您将无法复制访问器),并且在运行时会产生成本,因为虚拟方法调用不会内联