2012-08-11 7 views
1

Интересно, как скрыть поле недвижимости (не делать его закрытым или публичным, но заставить использовать сеттеры и геттеры) и предоставить ему простой сеттер и getter. Поэтому мне интересно, как создать api как:Как скрыть поле через define и предоставить только setter и getter?

private: 
    Property(int my_a); 
public: 
    Property(int my_b); 
... 
{ 
set_my_a(1); 
cout << get_my_a() << endl; 
// my_a = 13; // will cause compiler error 
... 

Как создать такую ​​вещь через препроцессор Boost?

+0

это связано с повысить? общим способом было бы сделать переменную private – Gir

+1

Зачем вам это делать? Свойства не имеют смысла, если геттеры и сеттеры не настроены. – Puppy

+0

@DeadMG: действительно, я хочу настроить Geters и Setters, но мне интересно об общем способе обертывания поля с помощью функций geter и setter. – myWallJSON

ответ

1

Вам действительно нужно использовать предварительный процессор форсирования? у вас есть решение без наддува ниже: например

// property.h  
#include <stdio.h> 

#define property(type) struct : public Property <type> 

template <typename T> 
class Property 
{ 
protected: 
    T value; 
public: 
    virtual T get() { 
    return value; 
    } 
    virtual void set(T new_value) { 
    value = new_value; 
    } 
}; 

использования:

// test.cpp 
#include "property.h" 

class Test { 
public: 
    property(int) {} a; 

    property(int) { 
    int get() { 
     return value * 10; 
    } 
    } b; 

    property(int) { 
    void set(int x) { 
     value = x * 200; 
    } 
    } c; 

    property(int) { 
    int get() { 
     return value * 3000; 
    } 
    void set(int x) { 
     value = x * 443; 
    } 
    } d; 
}; 

main() 
{ 
    Test t; 

    printf("i\ta\tb\tc\td\t\n"); 
    for (int i=0; i<10; i++) { 
    t.a.set(i); 
    t.b.set(i); 
    t.c.set(i); 
    t.d.set(i); 
    printf("%i\t%i\t%i\t%i\t%i\n", i, t.a.get(), t.b.get(), t.c.get(), t.d.get()); 
    } 
} 

Решение википедии в http://en.wikipedia.org/wiki/Property_(programming)#C.2B.2B это хорошо, но нуждается в минимальной модификации, чтобы стать полезным, потому что без защищенного заявления вы не можете писать ваши собственные геттеры и сеттеры.

#include <iostream> 

template <typename T> 
class property { 
protected: 
    T value; 
public: 
    T & operator = (const T &i) { 
    ::std::cout << i << ::std::endl; 
    return value = i; 
    } 
    operator T const &() const { 
    return value; 
    } 
}; 

struct Bar { 
    property <bool> alpha; 
    struct :public property <int> { 
    int & operator = (const int &i) { 
     ::std::cout << "new setter " << i << ::std::endl; 
     return value = i; 
    } 
    } bravo; 
}; 

main() 
{ 
    Bar b; 
    b.alpha = false; 
    b.bravo = (unsigned int) 1; 
} 

Вы можете изменить немного больше, если вы хотите:

#include <iostream> 
#define SETTER(type) public: type& operator=(const type new_value) 
#define GETTER(type) public: operator type const &() const 

template <typename T> 
class Property { 
protected: 
    T value; 
public: 
    T & operator = (const T &i) { 
    ::std::cout << i << ::std::endl; 
    return value = i; 
    } 
    template <typename T2> T2 & operator = (const T2 &i) { 
    ::std::cout << "T2: " << i << ::std::endl; 
    T2 &guard = value; 
    throw guard; // Never reached. 
    } 
    operator T const &() const { 
    return value; 
    } 
}; 

struct Bar { 
    Property <bool> alpha; 
    struct:Property <int> { 
    SETTER(int) { 
     value = new_value * 1000; 
     ::std::cout << "new method " << new_value << ::std::endl; 
     return value; 
    } 
    GETTER(int) { 
     return value/1000; 
    } 
    } bravo; 
}; 

main() 
{ 
    Bar b; 
    b.alpha = false; 
    b.bravo = (unsigned int) 1; 
    ::std::cout << b.bravo << ::std::endl; 
} 
0

Вместо того, чтобы переписать пример реализации, это ссылка на один в Википедии: http://en.wikipedia.org/wiki/Property_(programming)#C.2B.2B

В основном это заставляет свойство быть доступны через методы геттер/сеттер. Обновление, которое вам нужно, чтобы получить желаемый эффект, - это способность передавать функторы этим свойствам. Существует множество идей по их реализации; лучший подход, который я не могу посоветовать, и зависит от ваших потребностей в развитии. Лично он чувствует себя как инженер и предпочитает просто использовать Pimpl, чтобы скрыть свои личные данные, и просто предоставить геттеры/сеттеры явно.