我可以使用父的read()
函数来读取名字和姓氏,然后让孩子的read()
只读取中间名吗?或者我必须在孩子的第一,第二和中间阅读?
strtok
读到孩子时,我得到整行,而不仅仅是第三个字段。有没有办法绕过它,或者我只需要将前两个字段读入虚拟变量然后读取第三个字段?
class Parent
{
protected:
char first[80], last[80];
virtual istream& read(istream &is) {
char temp[80];
char *f, *l;
is >> temp;
f = strtok(temp, ",");
strcpy(first, f);
l = strtok(NULL, ",");
strcpy(last, l);
return is;
}
public:
friend istream& operator>> (istream &is, Parent &parent) {
return parent.read(is);
}
};
class Child: public Parent
{
char middle[80];
istream& read(istream &is) {
/*inherit first and last from parent*/
char temp[80];
char *m;
is >> temp;
m = strtok(temp, ",");
strcpy(middle, m);
}
};
in main()
Parent *object;
ifstream inf("filename.csv");
object = new Child();
inf >> *object;
George,Bush,Walker
答案 0 :(得分:4)
在子类的read
函数中,您可以像这样调用父read
函数:
class Child : public Parent
{
// ...
std::istream &read(std::istream &is)
{
Parent::read(is);
// Read some more
}
};
答案 1 :(得分:1)
你不能使用Child的Parent的read函数,因为Parent::read()
使用完整的输入(你只能在字符串上执行strtok()而不使用NULL-ptr,因为它实际上取代了分隔符)。棘手的部分是Child必须从流中间获取信息。
如果声明readName()
函数,则可以重复使用Parent的函数,但这对strtok()
不起作用。我建议使用std::istringstream
来输入行(而不是使用strtok)并传递给readName()
作为参数。使用strtok(),您可以执行prepareRead(),然后执行标记化,然后使用strtok(NULL,“,”)读取readName()函数,但这很大程度上取决于函数内的副作用。
未编译/测试/处理错误案例,因此请勿为您的作业复制/粘贴此内容:
class Parent {
protected:
std::string first, last;
std::istringstream readLine(istream& is)
{
std::string line;
std::getline(is, line);
return std::istringstream(line);
}
std::string readName(std::istringstream& iss)
{
std::string name;
std::getline(iss, name, ',');
return name;
}
virtual istream& read(istream &is)
{
std::istringstream iss = readLine(is);
first = readFirstName(iss);
last = readLastName(iss);
return is;
}
public:
friend istream& operator>> (istream &is, Parent &parent)
{
return parent.read(is);
}
};
class Child : public Parent
{
private:
std::string middle;
virtual istream& read(istream &is)
{
std::istringstream iss = readLine(is);
first = readName(iss);
middle = readName(iss)
last = readName(iss);
return is;
}
};
备注你应该避免使用strcpy,尤其是输入:你的程序会失败并且可以通过传递包含大于80个字符的名称的文件来攻击,这可以通过使用std :: string和std :: istringstream来避免
答案 2 :(得分:0)
1)不要将父方法声明为virtual
并更改以下代码:
class Child: public Parent {
char middle[80];
istream& read(istream &is) {
Parent::read(is);
char temp[80];
char *m;
is >> temp;
m = strtok(temp, ",");
strcpy(middle, m); }
};
不使用virtual
...将隐藏父方法。
编辑:感谢cppcoder关注。这是错的。看下一个方法。
2)或使用using
声明,这是C ++标准的一个例子:
struct A {
virtual void f();
};
struct B : virtual A {
virtual void f();
};
struct C : B , virtual A {
using A::f;
};
void foo() {
C c;
c.f(); // calls B::f, the final overrider
c.C::f(); // calls A::f because of the using-declaration
}