Właściwości w C++

No coż, w standardzie ich po prostu nie ma. Niektóre kompilatory, jak np mój ulubiony MSVC oferują je za pomocą rozszerzeń, inne nie oferują ich wcale. Wspomniany już kompilator MS wspiera je jednak znakomicie.

Składnia jest prosta

__declspec (property (get=nameOfGetFunction, put=nameOfSetFunction)) type propertyName;

np

class Renderer {
private:
     ID3D10Device* m_pDevice;
     ID3D10Device& GetDevice(){ return *m_pDevice;}
public:
     __declspec (property (get=GetDevice)) ID3D10Device& Device;
}

Szablony? Oczywiście.

template<class T>
class vec3 {
public:
    inline T get_x() const { return m_v[0]; }
    inline T get_y() const { return m_v[1]; }
    inline T get_z() const { return m_v[2]; }

    inline void set_x(T value) { m_v[0] = value; }
    inline void set_y(T value) { m_v[1] = value; }
    inline void set_z(T value) { m_v[2] = value; }

    __declspec(property(get=get_x,put=set_x)) T x ;
    __declspec(property(get=get_y,put=set_y)) T y ;
    __declspec(property(get=get_z,put=set_z)) T z ;
private:
    T m_v[3];
}

Właściwości wirtualne?


struct Shape {
     float computeArea()=0;
     __declspec(property(get=computeArea)) float Area;
}

struct Rect :  Shape {
    Rect(float w, float h): m_w(w),m_h(h) {}
    float computeArea() {
        return m_w * m_h;
    }
private:
    float m_w, m_h;
}

struct Circle : Shape {
    Circle(float r) : m_radius(r) {}
    float computArea() {
        return M_PI * m_radius * m_radius;
    }
private:
    float m_radius;
}

//...
Shape& s = *new Circle(1.0f);
float area = s.Area;

Oczywiście, świat nie jest idealny, więc i rozszerzenie kompilatora __declspec(property) nie jest, m.in
właściwości nie mogą być statyczne a i z szablonami nie zawsze wszystko działa.
Jeśli ktoś potrzebuje rozwiązań nie ograniczonych do jednego kompilatora, rozwiazanie stanowi biblioteka STLSoft Properties .

STLSoft Getting Started

MSDN property(C++)

Dodaj komentarz