我有两个不同的'结构''学生'& '雇员'。我想根据消息中提到的字符串选择它。
struct student {
string name;
float score;
}
struct employee {
int id;
string dep;
}
我收到消息; $ST,16,JOHN,A
或$EM,16,IT
从关键字ST
或EM
开始,我必须决定填充哪个结构。
我设法提取类似ST
或EM
的类型但是当我写的时候,
if (type == "ST")
student x;
else if (type == "EM")
employee x;
// long code goes on here to sort and populate `struct`
它说x
未定义。我知道这是错的,但我无法解决这个问题。
如何根据条件选择struct
?
答案 0 :(得分:1)
首先,看起来你的范围是错误的。因此x
可能不可见。
不知道你的代码是如何看的,但你可以定义一个基类,一个指针在条件之前,并通过条件分配内存(我不会这样做)。或者,您需要在正确的范围内工作。
struct base {
//whatever
};
struct student : public base {
};
struct employee : public base {
};
base *ptr;
if (type == "ST")
ptr = new student;
else if (type == "EM")
ptr = new employee;
答案 1 :(得分:0)
if
语句相当于
if (type == "ST") {
student x;
} else if (type == "EM") {
employee x;
}
// other code accessing x
您可以看到student x
和employee x
附近的范围。范围结束时,对象x
也超出范围。
要正确填充结构,必须处理范围
中的结构if (type == "ST") {
student x;
// populate student
} else if (type == "EM") {
employee x;
// populate employee
}
答案 2 :(得分:0)
如果你想要一些常见的事情。除了从字符串本身读取之外什么也没有。您可以创建对象,然后就地读取字符串。或者这个解决方案使用(种类)抽象工厂模式:
using namespace std;
// "Marker interface" common between the two structs.
// Virtual destructor to make this object polymorphic.
class ReadableFromString { public: virtual ~ReadableFromString() {} };
struct student: public ReadableFromString {
string name;
int score;
char grade;
};
struct employee: public ReadableFromString {
int id;
string dept;
};
// Abstract factory function that creates a ReadableFromString
// from a string.
shared_ptr<ReadableFromString> readFromString(const string &source) {
std::stringstream s(source);
std::stringbuf buf(ios_base::out);
string type;
s.get(buf, ',');
s.get(); // This is to skip the comma
type = buf.str();
if (type == "$ST") {
shared_ptr<student> studentObj = make_shared<student>();
s >> studentObj->score;
s.get(); // This is to skip the comma
buf = std::stringbuf(ios_base::out);
s.get(buf, ',');
studentObj->name = buf.str();
s.get(); // This is to skip the comma
studentObj->grade = s.get();
s.get(); // This is to skip the comma
return studentObj;
}
else if (type == "$EM") {
shared_ptr<employee> employeeObj = make_shared<employee>();
s >> employeeObj->id;
s.get(); // This is to skip the comma
buf = std::stringbuf(ios_base::out);
s.get(buf, ',');
employeeObj->dept = buf.str();
s.get(); // This is to skip the comma
return employeeObj;
}
return shared_ptr<ReadableFromString>(); // A null pointer
}
int main() {
string sources[] = { "$ST,16,JOHN,A", "$EM,16,IT"};
for(int i=0;i<2;i++) {
shared_ptr<ReadableFromString> firstOne = readFromString(sources[i]);
// Try to cast to student
if (dynamic_pointer_cast<student>(firstOne)) {
shared_ptr<student> studentObj = dynamic_pointer_cast<student>(firstOne);
cout << "Student: " << "\n";
cout << studentObj->name << "\n";
cout << studentObj->score << "\n";
cout << studentObj->grade << "\n";
} else if (dynamic_pointer_cast<employee>(firstOne)) {
// If not student, it could be an employee
shared_ptr<employee> employeeObj = dynamic_pointer_cast<employee>(firstOne);
cout << "Employee: " << "\n";
cout << employeeObj->id << "\n";
cout << employeeObj->dept << "\n";
} else {
cout << "Not student nor employee" << "\n";
}
}
return 0;
}