C ++易读属性

时间:2015-04-02 10:49:16

标签: c++ properties tuples

#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 ++属性吗?需要易于阅读,调试,也很容易获得返回类型。一些属性通过代理类实现我觉得不容易得到那种类型和浪费内存。在谷歌代码风格的属性是小写的下​​划线,我认为我不能很好地与正常功能分开。任何建议表示赞赏

2 个答案:

答案 0 :(得分:0)

Qt基于元对象编译器(moc)

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"));

答案 1 :(得分:0)

我在我的项目中尝试了这个,我添加了一些可以伪造的私有财产的私有枚举。有很大的副作用:难以维护枚举。另一个问题是你需要编写更多的代码来读写属性,低效的。