c++的动态类

特色源于变化,不变的东西,不灵活的东西,一般会失去光辉,技术也是,如果一个技术容易扩展,那么它是一个好技术


今天介绍c++的动态类特性:

在介绍之前,先介绍c++11中的两个关键字,auto和any,

(1)auto

auto可以表示任何类型,是c++11中的一个关键字符号,可以使得代码简洁,不用关心具体的类型,类型在编译器编译的时候决定:


如: auto a = 5;         // int

 auto b = 5.0f;    // float

 auto c = 5.0;     // double

 std::vector name_list;

 auto iter = name_list.begin(); // 容器迭代器


 std::cout << a << b << c << endl;


         特别是容器迭代器,在没有auto之前,我们只能不厌其烦的这样定义:std::vector::iterator it = name_list.begin()


(2) any

any 出现在boost中,也是c++11的特征,与auto相比,any是一个类,有成员函数和属性,只能通过any_cast来获得内部的值,而不能像auto一样直接使用;

值得说明的是,any本身不是模板类,不像模板类一样,定义的时候需要指明实例化类型,例如:any a;(这样定义是不对的,因为any不是模板类),any只有赋值函数和构造函数是template的,所以可以像auto一样使用, any i = 5;

any的出现让C++仿佛变成了一种弱类型的动态语言。

动态语言:运行期间才做数据类型检查的语言,即编译的时候不知道每一个变量的类型

静态语言:编译期间做数据类型检查的语言,即编译的时候就知道每一个变量的类型,如C/C++、C#、JAVA
  强类型:变量一定是有类型的, 且变量/对象的类型一旦确定, 其类型不再允许更改,如C/C++/Java/C#
  弱类型: 变量的类型概念很弱或者没有类型的概念, 不同变量的类型可以更改. 如php、Ruby


下面开始介绍c++的动态类特:


我们在编写程序的时候,经常会出现需要扩展的情况,例如:
class CTest
{
public:
    CTest(){}
    ~CTest(){}


public:
    int m_a;
    int m_b;
};


如果理想的状态下,这个类不需要添加新的变量,但是大多数时候,我们的程序需要进行修改和添加新的属性。
例如我们需要给CTest类添加一个新的属性, int m_c;  以前我一直是这样添加的。 我也一直在寻找更好的方法。 上次看我同事的代码,发现他很好的实现了这种添加。 他是在QT中使用
map  m_propertys;
来保存属性。我知道有很多高手会有更好的实现方法。不过这是我最见过最好的实现方式。


这里我用boost的boost::any来实现。
#include
#include
#include
#include


using std::string;
using std::map;
using boost::any_cast;






#define   AttrMap (boost::any_cast>(propertys.property["C"]))


class CPropertys
{
public:
    CPropertys();
    ~CPropertys(){};


public:
    map  property; //这里我没有使用, m_property,
                                        //因为这样,访问者看起来会更舒服些。
};


CPropertys::CPropertys()
{


    // ! 这个可以保存字符串变量
    property["A"] =  (string)"Hello";


    // ! 保存整数变量
    property["B"] =  (int)5;




    map  a;
    a[1] = 7;
    // ! 保存map变量
    property["C"] =  (map)a;
}






int main()
{
    CPropertys propertys;


    propertys.property["B"] = 99; 


    // ! 我们也可以使用函数来实现,查询和设置,propertys中的map
    AttrMap[1] = 199;


    std::cout << boost::any_cast(propertys.property["B"]) << std::endl;
    getchar();
    return 0;
}
















#include
#include
#include
#include




using std::string;
using std::map;
using boost::any_cast;


#define AttrMap (boost::any_cast>(propertys.property["C"]))


class CPropertys
{
public:
    CPropertys();
    ~CPropertys(){};


public:


    template 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 bool SetValue(const string &stPropertyName, T &anyProperty);


public:
    map property;
};












CPropertys::CPropertys()
{


    property["A"] = (string)"Hello";;
    property["B"] = (int)5;
    map a;
    a[1] = 7;
    property["C"] = (map)a;
}






template 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 bool 
CPropertys::SetValue(const string &stPropertyName, T &anyProperty)
{
    property[stPropertyName] = anyProperty;


    return true;
}






int main()
{
    CPropertys propertys;




    //propertys.property["C"]; 


    


    //map &c = boost::any_cast>(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(propertys.property["F"])<< std::endl;




    boost::any v;
    propertys.GetValue("F", v);
    std::cout << boost::any_cast(v) << std::endl;
    value = 88888;
    propertys.SetValue("F", value);
    propertys.GetValue("F", v);
    std::cout << boost::any_cast(v) << std::endl;




    std::cout << boost::any_cast(propertys.property["B"]) << std::endl;
    getchar();
    return 0;
}



你可能感兴趣的:(c++编程技术,c++,boost,any,动态类,增加类的属性成员)