c ++中getter和setter方法的包装器


Wrapper for getter and setter methods in c++

我有几个类有两个方法,分别代表"setter"和"getter"方法,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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。

这是我的学问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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;
};

我是这样使用的:

1
2
3
4
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<int>(10);
int v = p.Get<int>();

一切正常,但这是一个非常缓慢的方法。通过propertaccess调用setter比直接调用setter慢大约18倍。速度在这里很重要,因为我需要在动画库中使用这个机制(动画师将在不了解源对象的情况下设置属性)。

所以我的问题是:如何加速这个机制?有没有什么"行业标准"的方法?也许我应该使用经典的方法指针而不是std::function?


麦克PropertyAccess本身的模板: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
};

演示 </P >

你流的执行是只读不慢,它的unsafe。。。。。。。看到发生什么,如果你做的 </P >

1
2
3
ClassA a;
PropertyAccess p(&a, &ClassA::SetSomeProperty, &ClassA::GetSomeProperty);
p.Set<double>(10); // but property is int


你可以把安东斯莱文’s液和introduce安erase接口的对象类型。它会珍惜一生的管理更复杂的访问器(你将不得不使用的证明人/分/分和智能管理的一生,因为你不会是能复制的访问器)和成本将在运行时为虚拟方法的调用将不会内联SO I *测量值,如果它是你的quicker比原来的溶液。 </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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;
};