继承 - 在child中使用parent的read方法

时间:2012-06-05 07:51:43

标签: c++ inheritance ifstream

我可以使用父的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;

cat filename.csv

George,Bush,Walker

3 个答案:

答案 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
}