2015-04-02 4 views
-1
#include <iostream> 
#include <tuple> 

class Person { 
private: 
    std::tuple<int, std::string> data; 
public: 
    enum PropertyAge { 
     Age = 0 
    }; 
    enum PropertyName { 
     Name = 1 
    }; 
    int Get(PropertyAge i) const { 
     return std::get<Age>(data); 
    } 
    std::string Get(PropertyName i) const { 
     return std::get<Name>(data); 
    } 
    void Set(PropertyAge i, int value) { 
     std::get<Age>(data) = value; 
    } 
    void Set(PropertyName i, const std::string& value) { 
     std::get<Name>(data) = value; 
    } 
}; 

int main(int argc, char* argv[]) { 
    Person p; 
    p.Set(Person::Age, 10); 
    std::cout << p.Get(Person::Age); 

    return 0; 
} 

Поскольку C++ не имеет свойства, подобного C#, я думаю, что это настраиваемое свойство отлично. Я думаю, что самое главное легко читать и отлаживать, это средство легко читать и отлаживать. У кого-то есть лучший план для реализации свойства C++? Нужно легко читать, отлаживать, а также легко получить возвращаемый тип. свойство реализовать по прокси-классу Я думаю, что нелегко получить этот тип и потерять память. В стиле кода google свойство все в нижнем регистре с подчеркиванием, которое, я думаю, я не могу отличить хорошо с нормальной функцией. Любой совет оцениваетсяC++ легко читаемая собственность

+4

Ты опоздал на день. – molbdnilo

ответ

0

Qt уже good propery system на основе мета-объектный компилятор (МОЦ)

class MyObject: public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QString prop READ prop WRITE setProp) 
    Q_PROPERTY(QString propReadOnly READ prop) 
public: 
    MyObject(QObject* p= 0) 
    : QObject(p) 
    { } 

QString prop() const 
{ return my_prop; } 


void setProp(const QString& prop) 
{ my_prop = prop; } 


private: 
    QString my_prop; 
} 

... 

MyObject self; 
QObject* obj = static_cast<QObject*>(&self); 
self.setProp("hello");       // set 
obj->setProperty("prop", "some variant value"); // also set 
obj->setProperty("propReadOnly", "some variant value"); // ERROR function return false 
obj->setProperty("nonExists", 123);    // create dynamic property (raw name is '_q_nonExists') 
qDebug() << obj->property("prop").toString()  // get "some variant value" 
     << obj->property("nonExists").toString();// get "123" 

Также Вы можете создать код отражения. Более подробная информация о рефлексии вы можете найти here

Или используя просто базовый класс с boost::any

#include <functional> 
#include <boost/any.hpp> 
#include <hash_map> 

using namespace std; 

class property_base 
{ 
public: 
    property_base() 
    {} 

    typedef std::function<void(const boost::any&)> setter; 
    typedef std::function<const boost::any&(void)> getter; 

    const boost::any& property(const string& name) 
    { 
     auto _get = hash_map[name]._getter; // check exists 
     if(_get) 
      return _get(); 

     throw logic_error("write-only prop"); 
    } 

    void setProperty(const string& name, const boost::any& value) 
    { 
     auto _set = hash_map[name]._setter; // check exists 
     if(_set) 
      return _set(value); 

     throw logic_error("read-only prop"); 
    } 

protected: 
    void addProperty(const string& name, 
        const setter& _set = nullptr, const getter& _get = nullptr) 
    { m_prop[name] = prop{_set, _get}(); } 

private: 
    struct prop 
    { 
     setter _setter; 
     getter _getter; 
    }; 

    hash_map<string, property> m_prop; 
}; 

class Person: virtual public property_base 
{ 
public: 
    Person(const string& _name) 
    : property_base(), m_name(_name), m_age(0) 
    { // may be compile-time errors here (: 
     addProperty("name", bind(&Person::name, this)); 
     addProperty("age", bind(&Person::age, this), bind(&Person::setAge, this)); 
    } 

    const boost::any& name() 
    { return m_name; } 

    const boost::any& age() 
    { return m_age; } 

    void setAge(const boost::any& _age) 
    { m_age = any_cast<int>(_age); } 

private: 
    string m_name; 
    int m_age; 
}; 

Person p("Marlyn"); 
p.setAge(52); 

property_base* obj = static_cast<property_base*>(&p); 
cout << any_cast<string>(obj->property("name")); 
+0

Подробнее о [reflection] (http://en.wikipedia.org/wiki/Reflection_ (computer_programming)) – disable13

+0

если я использую obj-> setProperty («prop1», «некоторое значение варианта»); что произойдет. Поскольку я использую тип перечисления, чтобы вы могли получить ошибку, «prop1» не является членом идентификатора «Person» или «prop1» uneclared. – bitnick

+0

@bitnick Я отредактировал свой ответ – disable13

0

Я попытался это в моем проекте, и я добавить некоторые частные перечисления, которые могут быть большими побочными эффектами поддельного частного property.There в : Трудно поддерживать перечисление. Еще одна проблема заключается в том, что вам нужно написать больше кода для чтения и записи свойства, неэффективного.

Смежные вопросы