c++中getter和setter方法的包装器
Wrapper for getter and setter methods in c++
我有几个类有一对代表"setter"answers"getter"方法的方法,比如:
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。这将允许我将此PropertyAccess传递给其他对象,这些对象将能够在不了解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;
};
我是这样用的:
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<int>(10);
int v = p.Get<int>();
一切都很好,但这是一种非常缓慢的方法。通过PropertAccess调用setter的速度大约是直接调用setter速度的18倍。速度在这里很重要,因为我需要在动画库中使用该机制(Animator将在不了解源对象的情况下设置属性)。
所以我的问题是:如何加快这个机制?有什么"行业标准"的方法吗?也许我应该使用经典的方法指针而不是std::函数?
您可以采用Anton Slavin的解决方案,并引入一个接口来擦除对象类型。它将使访问器的生存期管理更加复杂(您将不得不使用引用/指针/智能指针来管理生存期,因为您将无法复制访问器),并且在运行时会产生成本,因为虚拟方法调用不会内联,所以我会衡量它是否比您的原始解决方案更快。
template<typename TType>
struct PropertyAccess
{
virtual void Set(const TType& value) = 0;
virtual TType Get() = 0;
};
template <typename TClass, typename TType>
class PropertyAccessT : public PropertyAccess<TType>
{
public:
using SetterPointer = void (TClass::*)(const TType&);
using GetterPointer = TType(TClass::*)();
PropertyAccessT(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;
};
将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;
};
演示
您当前的实施不仅速度慢,而且不安全。看看如果你做会发生什么
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int
相关文章:
- 有什么方法可以包装自动类型扣除的助推"tee"流的构造?
- Qt中的包装连接方法隐藏了编译器所需的信息
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- C++ sqrat 通过包装器绑定方法
- 如何在 C 中包装C++具有参数的类方法或返回另一个C++类的实例?
- 是否有类周围最薄的包装器来添加方法?
- 抽象包装带有异常的 C 错误处理的最佳方法
- 如何为其他类成员函数编写模板包装方法
- 为多线程环境包装 c++ new/delete 的安全/好方法
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 是否有一种方法可以让公共成员在班级外部无法解码,而无需访问包装器功能
- 在没有包装程序类的情况下,在ActiveX接口上调用方法
- 将C++转换为C#:如何包装C++中的类,使模板类中的方法在C#中的派生类中可用
- 为对象创建"thin"结构包装器的正确方法是什么?
- C# 使用包装类中的字符串参数调用 C++ 方法
- C++包装Objective-C的方法:如何为变量添加值
- 从Rcpp中的包装方法返回自定义对象
- C++中宏中的包装方法
- 如何在c#上为具有双间接参数的包装c++方法编写签名?
- 包装方法返回 c++ std::array<std::string, 4> in cython