#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 ++属性吗?需要易于阅读,调试,也很容易获得返回类型。一些属性通过代理类实现我觉得不容易得到那种类型和浪费内存。在谷歌代码风格的属性是小写的下划线,我认为我不能很好地与正常功能分开。任何建议表示赞赏
答案 0 :(得分:0)
Qt基于元对象编译器(moc)
good propery systemclass 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)
我在我的项目中尝试了这个,我添加了一些可以伪造的私有财产的私有枚举。有很大的副作用:难以维护枚举。另一个问题是你需要编写更多的代码来读写属性,低效的。