gpt4 book ai didi

c++ - 从 Vector 生成类数据成员

转载 作者:太空狗 更新时间:2023-10-29 21:09:58 26 4
gpt4 key购买 nike

请考虑这个 C++ 问题:

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

class ParseURL{
private:
int qualify; // 0 means we qualify
public:
string node;
string service;
bool primary;
bool health;
string epoch;
// methods
ParseURL(string URL);
~ParseURL();
};


ParseURL::ParseURL(string URL){
vector<string> g2 = {"node", "service", "primary", "health", "epoch"};

for (string tag : g2){
auto found = URL.find(tag);
if ( found != string::npos ){
auto cut_from = found + 1 + tag.size() ;
auto meh = URL.substr(cut_from, URL.substr(cut_from).find("&") );
// is there a way we can avoid these lines below?
if (tag.find("node",0) == 0){
this->node = meh;
} else if (tag.find("service",0) == 0 ){
this->service = meh;
} else if (tag.find("epoch",0) == 0) {
this->epoch = meh;
} else if (tag.find("health",0) == 0){
this->health = (meh == "OK");
} else if (tag.find("primary",0) == 0 ){
this->primary == (this->node == meh);
}
}
}

}

ParseURL::~ParseURL(){
cout << "Tearing Down the class\n";
}
int main(){
char req[] = "GET /register?node=hostrpi3&service=potatoservice&primary=node1&health=OK&epoch=1559345106 HTTP";
string Request = req;
Request = Request.substr(Request.find_first_of(" ") );
Request = Request.substr(0, Request.find(" HTTP"));
ParseURL *a = new ParseURL(Request);

cout.width(12);
cout << "a->node: " << a->node << endl;
cout.width(12);
cout << "a->service: " << a->service << endl;
cout.width(12);
cout << "a->epoch: " << a->epoch << endl;
cout.width(12);
cout << "a->health: " << a->health << endl;
cout.width(12);
cout << "a->primary: " << a->primary << endl;

delete(a);

return 0;
}

我需要表示一个基于 URL 查询字符串的对象,我需要的标签在 vector g2 中表示,如您所见,我从这些标签中为 ParseURL 创建了数据成员。

O/P 看起来像:

   a->node: hostrpi3
a->service: potatoservice
a->epoch: 1559345106
a->health: 1
a->primary: 0
Tearing Down the class

虽然这个版本可以,但感觉可以改进很多。尽管 Vector 中包含了所有内容,但我仍在为每个属性重复执行 tag.find。我希望一定有更好的方法。你能指出正确的方向吗?谢谢!

编辑 1

谢谢,我按照建议更新了构造函数:

ParseURL::ParseURL(string URL){
char tags[10][100] = {"node", "service", "primary", "health", "epoch"};

int i = 0;
for (auto tag : tags){
auto found = URL.find(tag);
if ( found != string::npos ){
auto cut_from = found + 1 + strlen(tag);
auto tag_info = URL.substr(cut_from, URL.substr(cut_from).find("&") );
switch (i){
case 0:
this->node = tag_info;
break;
case 1:
this->service = tag_info;
break;
case 2:
this->primary = (this->node == tag_info);
break;
case 3:
this->health = (tag_info == "OK");
break;
case 4:
this->epoch = tag_info;
break;
}
}
i++;
}
}

例如,bash 提供变量的间接引用——也就是说,一个变量可能包含另一个变量的名称:

$ cat indirect.sh 
#!/bin/bash

values="value1 value2"
value1="this is value1"
value2="this is value2"

for i in $values; do
echo "$i has value ${!i}"
done

$ ./indirect.sh
value1 has value this is value1
value2 has value this is value2

我希望像这样的案例也有类似的东西,不过,我在这里学到了宝贵的经验教训。谢谢你!

最佳答案

假设您想要保留不同的类成员(而不是一个键值存储),您可以使用一个包含字符串和成员指针的静态表:

vector<pair<string,string ParseURL::*>> keys={{"node",&ParseURL::node},…};

但这在这里行不通,因为类型不同,而且每种类型的处理也不相同。相反,对于这种几乎并行,语法上的最佳选择通常是lambda:

const auto get=[&URL](const string &tag) {
auto found = URL.find(tag);
if(found == string::npos) return "";
auto cut_from = found + 1 + tag.size() ;
return URL.substr(cut_from, URL.substr(cut_from).find("&") );
};
node=get("node");
service=get("service");
epoch=get("epoch");
health=get("health")=="OK";
primary=get("primary")==node;

这种风格的好处是可以明确初始化healthprimary。通过对私有(private)构造函数进行充分的扭曲,可以将其放入成员初始化列表中,这是更好的做法。

关于c++ - 从 Vector 生成类数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56408315/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com