由于代码还没有整理,大量的特化和偏特化散乱在代码里,所以我就暂时不发布源码了,不过这是迟早的事情,呵呵。先来说说怎么用吧,个人觉得还是蛮有意思的。
以下是可读写属性的声明方法:
#include <rdx/property.h>

class TestProperty
{
typedef TestProperty MyType;

public:
int set_X(int value)
{
return rdxLib::put(X, value * 2); // 为X设置新的值,
}

public:
rdxLib::property_bag<MyType, int, read_write> X;

TestProperty()
: X(&MyType::X, &MyType::set_X)
{
}
};
用法是:
int main()
{
TestProperty prop;
prop.X = 12;
std::cout << prop.X << std::endl; // should be 24.
int calculate = 2 * prop.X + 6 - prop.X;
std::cout << calculate << std::endl; // should be 30.
prop.X += 22;
std::cout << prop.X << std::endl; // should be 68.

return 0;
}
这里注意到几点:
1. 对于可读写的属性,我直接把属性值就存在X当中,它既是接口又是容器,用这种方法实现了默认的get和set函数。如果没有必要,就可以根本不写get和set,使这个属性自动的退化成一个public成员。
2. 对于X的用法,可以把它完全当作一个简单的int来用,完全感觉不到它和普通int的区别。
还有一个好消息,如果在类的声明里面将int都改成一个类,比如std::string,那么在使用的时候,X就和普通的std::string一个样,代码如下:
#include <string>
#include <rdx/property.h>

class TestProperty
{
typedef TestProperty MyType;

public:
std::string & set_Name(const std::string& value)
{
return rdxLib::put(Name, value + "ab"); // Set a different value for Name.
}

public:
rdxLib::property_bag<MyType, std::string, read_write> Name;

TestProperty()
: Name(&MyType::Name, &MyType::set_Name)
{
}
};

int main()
{
TestProperty prop;
prop.Name = "Hello";
std::string str = "_test_";
std::cout << prop.Name << std::endl; // should be "Helloab"
prop.Name += str + prop.Name;
std::cout << prop.Name << std::endl; // should be "Helloab_test_Helloabab"
std::cout << prop.Name->size() << std::endl; // should be 22.

return 0;
}
请注意,我可以写prop.Name->size()这样的代码,同时也可以调用std::string中的所有const的公共成员和方法,真的就和普通std::string没区别了。原因呢,是因为property_bag从std::string派生,并且没有添加任何多余的公有成员或方法。
至于readonly和writeonly属性,就有一些不同了,因为这些属性注定不能直接存储在property_bag对象里面,property_bag就退化成纯粹的接口。此时,如果Name是一个readonly的property,那么依然可以调用std::string所有const的公共成员和方法,这个和read_write的property一样。
这种readonly和writeonly属性声明方法如下:
#include <string>
#include <rdx/property.h>

class TestProperty
{
typedef TestProperty MyType;

int x_;
std::string name_;

public:
int get_X() const
{
return x_;
}
std::string & set_Name(const std::string& value)
{
name_ = value;
return name_;
}

public:
rdxLib::property_bag<MyType, int, readonly> X
rdxLib::property_bag<MyType, std::string, writeonly> Name;

TestProperty()
: X(&MyType::X, &MyType::get_X)
, Name(&MyType::Name, &MyType::set_Name)
{
}
};
如果在代码里面尝试给X赋值或读取Name,都会得到编译期间错误。
OK,这就是这个rdxLib.property的overview了。
以下是可读写属性的声明方法:





















用法是:












这里注意到几点:
1. 对于可读写的属性,我直接把属性值就存在X当中,它既是接口又是容器,用这种方法实现了默认的get和set函数。如果没有必要,就可以根本不写get和set,使这个属性自动的退化成一个public成员。
2. 对于X的用法,可以把它完全当作一个简单的int来用,完全感觉不到它和普通int的区别。
还有一个好消息,如果在类的声明里面将int都改成一个类,比如std::string,那么在使用的时候,X就和普通的std::string一个样,代码如下:


































请注意,我可以写prop.Name->size()这样的代码,同时也可以调用std::string中的所有const的公共成员和方法,真的就和普通std::string没区别了。原因呢,是因为property_bag从std::string派生,并且没有添加任何多余的公有成员或方法。
至于readonly和writeonly属性,就有一些不同了,因为这些属性注定不能直接存储在property_bag对象里面,property_bag就退化成纯粹的接口。此时,如果Name是一个readonly的property,那么依然可以调用std::string所有const的公共成员和方法,这个和read_write的property一样。
这种readonly和writeonly属性声明方法如下:
































如果在代码里面尝试给X赋值或读取Name,都会得到编译期间错误。
OK,这就是这个rdxLib.property的overview了。