2013-10-04 39 views
1

我一直在使用我寫的類(這裏是一個減少版本的工作),它提供了一個方法來加載和保存字符串的任何變量,並且可以添加到類中,只要該類中包含此對象它被稱爲_settings_loader。每個變量都通過#define ADD_PARAMETER(x)_settings_loader.AddParameter(#x,x);宏。有沒有更好的方法來做這個C++,從任何類型的文件保存和加載變量?

如果有人能夠提出一種更簡單的擴展方法,而不是針對每種類型使用每種個案,我是否會喜歡它?我知道C++是類型定義的,但有我以前做過的事情(我不想在添加每個變量時使用模板)。

頁眉

#pragma once 
#include <boost/any.hpp> 
#include <map> 
#include <string> 
#include <iostream> 
#include <vector> 

#define ADD_PARAMETER(x) _settings_loader.AddParameter(#x, x); 

class SettingsLoader 
{ 
public: 
    SettingsLoader(); 
    template <class T> void AddParameter(std::string name, T & parameter); 
    void SetParameter(std::string name, std::string value); 
    std::string GetParameterValue(std::string name); 
    void PrintOutParameters(); 
    std::vector<std::pair<std::string, std::string> > GetAllParametersAsStrings(); 
protected: 
    std::map<std::string, boost::any> _parameters; 
    bool _debug; 
}; 


template <class T> void SettingsLoader::AddParameter(std::string name, T & parameter) 
{ 
    _parameters.insert(std::make_pair(name, boost::any(&parameter))); 

    if (_debug) 
    { 
    std::cout << "Added parameter " << name << std::endl; 
    } 
} 

CPP

#include "settingsloader.h" 
#include <boost/lexical_cast.hpp> 

SettingsLoader::SettingsLoader(): 
    _parameters(), 
    _debug(false) 
{ 
} 


void SettingsLoader::SetParameter(std::string name, std::string value) 
{ 
    try 
    { 
    std::map<std::string, boost::any>::iterator itterator = _parameters.find(name); 
    if (itterator != _parameters.end()) 
    { 
     boost::any boost_any = itterator->second; 

     if (boost::any_cast<double*>(boost_any)) 
     { 
     double * value_to_set = boost::any_cast<double*>(boost_any); 
     *value_to_set = boost::lexical_cast<double>(value); 
     } 
     else if (boost::any_cast<int*>(boost_any)) 
     { 
     int * value_to_set = boost::any_cast<int*>(boost_any); 
     *value_to_set = boost::lexical_cast<int>(value); 
     } 
     else if (boost::any_cast<long*>(boost_any)) 
     { 
     long * value_to_set = boost::any_cast<long*>(boost_any); 
     *value_to_set = boost::lexical_cast<long>(value); 
     } 
    } 
    else 
    { 
     if (_debug) 
     { 
     std::cout << "Parameter " << name << " could not be set" << std::endl; 
     } 
    } 
    } 
    catch(...) 
    { 

    } 
} 

std::string SettingsLoader::GetParameterValue(std::string name) 
{ 
    try 
    { 
    std::map<std::string, boost::any>::iterator itterator = _parameters.find(name); 
    if (itterator != _parameters.end()) 
    { 
     boost::any boost_any = itterator->second; 

     if (boost::any_cast<double*>(boost_any)) 
     { 
     double * value_to_get = boost::any_cast<double*>(boost_any); 
     return boost::lexical_cast<std::string>(*value_to_get); 
     } 

     if (boost::any_cast<int*>(boost_any)) 
     { 
     int * value_to_get = boost::any_cast<int*>(boost_any); 
     return boost::lexical_cast<std::string>(*value_to_get); 
     } 

     if (boost::any_cast<long*>(boost_any)) 
     { 
     long * value_to_get = boost::any_cast<long*>(boost_any); 
     return boost::lexical_cast<std::string>(*value_to_get); 
     } 
    } 
    } 
    catch(...) 
    { 

    } 
    return ""; 
} 

std::vector<std::pair<std::string, std::string> > SettingsLoader::GetAllParametersAsStrings() 
{ 
    std::vector<std::pair<std::string, std::string>> output_vector; 
    for (auto pair : _parameters) 
    { 
    output_vector.push_back(std::make_pair(pair.first, GetParameterValue(pair.first))); 
    } 

    return output_vector; 
} 


void SettingsLoader::PrintOutParameters() 
{ 
    std::cout << "+=======================+" << std::endl 
      << "|Printing out parameters|" << std::endl 
      << "+=======================+" << std::endl; 

    std::vector<std::pair<std::string, std::string>> names_and_values = GetAllParametersAsStrings(); 
    for (std::pair<std::string, std::string> pair : names_and_values) 
    { 
    std::cout << pair.first << " = " << pair.second << std::endl; 
    } 
} 
+0

你可能想要看的一件事是Qt實現的「無類型」對象,[QVariant](https://qt.gitorious.org/qt/qt/source/b12a8d47ba8a803cae88718249b8d3f7d4a85948:src/corelib/kernel/qvariant的.cpp)。請注意,他們也必須爲每種類型的案例編寫不同的代碼,就像你正在做的一樣。沒有更好的方式我知道。 – CmdrMoozy

回答

0

根據項目的範圍,你應該考慮的,而不是解決與C++語言工具的問題開始使用代碼生成器。有幾個很好的項目,在那裏,解決比你描述單向更多的問題:

例如:谷歌協議緩衝區,阿帕奇節儉和許多其他

0

這就是所謂的序列化或數據編組。在您的類中添加序列化和反序列化方法是很常見的。例如,Python使用pickle來將數據對象序列化爲二進制格式 - 正是你在做的。

一些更好的序列化格式(恕我直言):

  • (谷歌)ProtocolBuffers - 二進制,你想要做什麼,可用於C++,具有IDL
  • JSON - 廣泛使用/執行,交叉語言
  • BJSON - 二進制JSON格式(見MongoDB的,等等)
  • MessagePack - 另一個二進制JSON格式,可能比BJSON
  • UBJSON更好 - 這可能是最好的二進制JSON備考牛逼
  • xupl - 這也似乎是一個偉大的格式
  • XDR - 比該JSON格式有點老,但非常好
  • 味酸 - 這是特定於Python,但其他語言有泡菜庫

Ruby通過.to_s(toString)增加對象以啓用打印。遵循相同的模式,向您的類添加方法.serialize和.deserialize方法到您的類會給你很多你想要的。而使用JSON或IDL會給你更接近你尋求的多態反序列化的東西。請記住,JSON宣佈成員名稱,而IDL的服務則與此相同。

相關問題