首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有更好的方法来做这个C++,从任何类型的文件中保存和加载变量?

有没有更好的方法来做这个C++,从任何类型的文件中保存和加载变量?
EN

Stack Overflow用户
提问于 2013-10-05 05:29:28
回答 2查看 192关注 0票数 1

我一直在使用我编写的一个类(这里是一个可以工作的精简版本),它提供了一个方法来加载和保存字符串中的任何变量,并且可以添加到这个类中,前提是该类中有这个对象,并且名为_settings_loader。每个变量都是通过#define ADD_PARAMETER(x) _settings_loader.AddParameter(#x,x);宏添加的。

我希望有人能建议一种更简单的方法来扩展它,而不是为每种类型使用每个单独的案例?我知道C++是类型定义的,但是我之前尝试做的事情已经完成了(我不想在添加每个变量时使用模板)。

标题

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
  }
}
EN

回答 2

Stack Overflow用户

发布于 2013-10-05 05:44:25

根据项目的范围,您应该考虑开始使用代码生成器,而不是使用c++语言工具来解决问题。有几个非常好的项目可以解决比你描述的问题多得多的问题:

例如: Google protocol buffers,Apache thrifty和其他许多

票数 0
EN

Stack Overflow用户

发布于 2013-10-05 08:38:20

这称为序列化或数据编组。向您的类添加序列化和反序列化方法也是很常见的。例如,Python将“pickle”作为一种将数据对象序列化为二进制格式的方法--这正是您正在做的事情。

一些更好的序列化格式(IMHO):

  • (谷歌) ProtocolBuffers - binary,随心所欲,可用于C++,具有IDL
  • JSON -广泛使用/实现,以及跨语言
  • BJSON-二进制json格式(请参阅MongoDB,在Python中-另一种二进制json格式,可能比BJSON
  • UBJSON更好-这可能是最好的二进制json格式

H111xupl-这似乎也是一个很好的格式<代码>H212<代码>XDR-比JSON格式稍早,但非常好<代码>H214<代码>H115 pickle -它是特定于Python的,但其他语言有泡菜库<代码>H216<代码>F217

Ruby使用.to_s (toString)增强对象以启用打印。遵循同样的模式,将方法添加到您的类中,将.serialize方法添加到您的类中,并将.deserialize方法添加到您的类中,就可以得到您想要的大部分内容。使用JSON或IDL将使您更接近您所寻求的多态反序列化。请记住,JSON宣布成员名称,而IDL的目的大致相同。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19191110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档