我们在编写程序的时候,经常会出现需要扩展的情况,例如:
class CTest
{
public:
CTest(){}
~CTest(){}
public:
int m_a;
int m_b;
};
如果理想的状态下,这个类不需要添加新的变量,但是大多数时候,我们的程序需要进行修改和添加新的属性。
例如我们需要给CTest类添加一个新的属性, int m_c; 以前我一直是这样添加的。 我也一直在寻找更好的方法。 上次看我同事的代码,发现他很好的实现了这种添加。 他是在QT中使用
map<QString, QVariant> m_propertys;
来保存属性。我知道有很多高手会有更好的实现方法。不过这是我最见过最好的实现方式。
这里我用boost的boost::any来实现。
#include <boost/any.hpp>
#include <iostream>
#include <string>
#include <map>
using std::string;
using std::map;
using boost::any_cast;
#define AttrMap (boost::any_cast<map<int, int>>(propertys.property["C"]))
class CPropertys
{
public:
CPropertys();
~CPropertys(){};
public:
map <string, boost::any> property; //这里我没有使用, m_property,
//因为这样,访问者看起来会更舒服些。
};
CPropertys::CPropertys()
{
// ! 这个可以保存字符串变量
property["A"] = (string)"Hello";
// ! 保存整数变量
property["B"] = (int)5;
map<int, int> a;
a[1] = 7;
// ! 保存map变量
property["C"] = (map<int, int>)a;
}
int main()
{
CPropertys propertys;
propertys.property["B"] = 99;
// ! 我们也可以使用函数来实现,查询和设置,propertys中的map
AttrMap[1] = 199;
std::cout << boost::any_cast<int>(propertys.property["B"]) << std::endl;
getchar();
return 0;
}
#include <boost/any.hpp>
#include <iostream>
#include <string>
#include <map>
using std::string;
using std::map;
using boost::any_cast;
#define AttrMap (boost::any_cast<map<int, int>>(propertys.property["C"]))
class CPropertys
{
public:
CPropertys();
~CPropertys(){};
public:
template <typename T> bool AddNewProperty(const string &stPropertyName, T &anyProperty);
bool RemoveProperty(const string &stPropertyName);
bool IsExistProperty(const string &stPropertyName);
bool GetValue(const string &stPropertyName, boost::any &value);
template <typename T> bool SetValue(const string &stPropertyName, T &anyProperty);
public:
map <string, boost::any> property;
};
CPropertys::CPropertys()
{
property["A"] = (string)"Hello";;
property["B"] = (int)5;
map<int, int> a;
a[1] = 7;
property["C"] = (map<int, int>)a;
}
template <typename T> bool
CPropertys::AddNewProperty(const string &stPropertyName, T &anyProperty)
{
if (IsExistProperty(stPropertyName))
{
return false;
}
else
{
property[stPropertyName] = anyProperty;
}
return true;
}
bool
CPropertys::RemoveProperty(const string &stPropertyName)
{
if (IsExistProperty(stPropertyName))
{
property.erase(stPropertyName);
return true;
}
return false;
}
bool
CPropertys::IsExistProperty(const string &stPropertyName)
{
return (property.find(stPropertyName) != property.end());
}
bool
CPropertys::GetValue(const string &stPropertyName, boost::any &value)
{
if (IsExistProperty(stPropertyName))
{
value = property[stPropertyName];
}
return false;
}
template <typename T> bool
CPropertys::SetValue(const string &stPropertyName, T &anyProperty)
{
property[stPropertyName] = anyProperty;
return true;
}
int main()
{
CPropertys propertys;
//propertys.property["C"];
//map<int, int> &c = boost::any_cast<map<int, int>>(propertys.property["C"]);
//c[1]
AttrMap[10] = 199;
propertys.property["B"] = 99;
std::cout << propertys.IsExistProperty("F") << std::endl;
std::cout << propertys.property.size() << std::endl;
//propertys.property["F"] = 999; //这句也是可以执行的,不过没有用AddNewProperty函数来的专业
int value = 323;
propertys.AddNewProperty("F", value);
std::cout << propertys.property.size() << std::endl;
std::cout << boost::any_cast<int>(propertys.property["F"])<< std::endl;
boost::any v;
propertys.GetValue("F", v);
std::cout << boost::any_cast<int>(v) << std::endl;
value = 88888;
propertys.SetValue("F", value);
propertys.GetValue("F", v);
std::cout << boost::any_cast<int>(v) << std::endl;
std::cout << boost::any_cast<int>(propertys.property["B"]) << std::endl;
getchar();
return 0;
}
|