我正在尝试做这样的事情,
enum Data_Property
{
NAME,
DATETIME,
TYPE,
};
struct Item_properties
{
char* Name;
char* DateTime;
int Type;
};
int main() {
std::string data = "/Name Item_Name /DATETIME [TimeStamp] /TYPE [Integer value]";
std::list <std::string> known_properties;
known_properties.push_back("/Name");
known_properties.push_back("/DATETIME");
known_properties.push_back("/TYPE");
Item_properties item_p = extract_properties(data); //I use a function to get properties
//in a structure.
//here I want to use a switch-case statement to get the property by enum value
}
我需要知道有什么方法可以让它变得简单吗?或者我如何将(/ NAME / DATETIME / TYPE)等属性键与枚举结合使用,并避免使用std :: list即known_properties?
答案 0 :(得分:3)
据我所知,C ++枚举中没有任何内容与C#enum属性相似。我可能错了。
鉴于此,我建议使用地图将data属性映射到item属性。你应该只需要构建一次这个地图。您还可以将字符串表示关联到项目和数据属性。这样可以更容易地构建项目属性对象。我认为列表不是这项任务的理想数据结构。
答案 1 :(得分:2)
首先,让我说总有另一种选择,这是我的哲学之一。
让我们来看看大图片。您正在尝试从字符串中读取项。 项是基准的容器。在面向对象的术语中, Item 希望每个数据从字符串加载自己的数据。 项不需要知道如何加载数据,因为它可以从每个数据请求。
您的基准实际上比C ++简单POD类型更复杂和更智能。 (简单的POD类型没有字段名称。)因此,您需要创建表示这些的类(或封装额外的复杂性)。相信我,从长远来看,这会更好。
以下是重构 Name
成员的简单示例:
struct Name_Field
{
std::string value; // Change your habits to prefer std:string to char *
void load_from(const std::string& text,
const std::string::size_type& starting_position = 0)
{
value.clear();
std::string::size_type position = 0;
position = text.find("/Name", starting_position);
if (position != std::string::npos) // the field name was found.
{
// Skip the next space
++position;
// Check for end of text
if (position < text.length())
{
std::string::size_t end_position;
end_position = text.find_first_not_of(" ", position);
if (end_position != std::string::npos)
{
value = text.substr(position, end_position - position);
}
}
}
};
您现在可以在项类中添加load_from
:
struct Item
{
Name_Field Name;
char * DateTime;
char * Type;
void load_from(const std::string& text)
{
std::string::size_t position = 0;
// Notice, the Name member is responsible for load its data,
// relieving Item class from knowing how to do it.
Name.load_from(text, position);
}
};
加载项目:
Item new_item;
new_item.load_from(data);
在重构时,请注意常用方法。例如,您可能希望将Name_Field
和DateTime_Field
之间的常用方法放入基础(父)类Field_Base
中。这将简化您的代码和设计,并支持可重用性。
答案 2 :(得分:1)
你看过Boost :: program_options吗?这是一些示例代码:
#include "boost\program_options\parsers.hpp"
#include "boost\program_options\variables_map.hpp"
#include <iostream>
using std::cout;
using std::endl;
namespace po = boost::program_options;
int _tmain(int argc, _TCHAR* argv[])
{
po::options_description desc("Allowed options");
string taskName;
desc.add_options()
("help", "produce help message")
("TaskName", po::value<string>(&taskName), "The project's prefix")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << endl;
return 1;
}
if (!vm.count("TaskName"))
{
cout << "Use \"DOTaskTests.exe --help\" for command line options" << endl;
return 1;
}
}