C++ 继承-使用父';儿童的阅读方法

C++ 继承-使用父';儿童的阅读方法,c++,inheritance,ifstream,C++,Inheritance,Ifstream,我可以使用父级的read()函数读取名字和姓氏,然后让子级的read()只读取中间名吗?或者我必须在孩子身上读第一、第二和第二行 编辑:第一个答案似乎有效,但当我使用strtok读入child时,我得到了整行内容,而不仅仅是第三个字段。有没有办法解决这个问题,或者我只需要将前两个字段读入伪变量,然后再读入第三个字段 class Parent { protected: char first[80], last[80]; virtual istream& read(istream

我可以使用父级的
read()
函数读取名字和姓氏,然后让子级的
read()
只读取中间名吗?或者我必须在孩子身上读第一、第二和第二行

编辑:第一个答案似乎有效,但当我使用
strtok
读入child时,我得到了整行内容,而不仅仅是第三个字段。有没有办法解决这个问题,或者我只需要将前两个字段读入伪变量,然后再读入第三个字段

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
在子类的
read
函数中,您可以像这样调用父类
read
函数:

class Child : public Parent
{
    // ...

    std::istream &read(std::istream &is)
    {
        Parent::read(is);
        // Read some more
    }
};

在子类的
read
函数中,您可以像这样调用父类
read
函数:

class Child : public Parent
{
    // ...

    std::istream &read(std::istream &is)
    {
        Parent::read(is);
        // Read some more
    }
};
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); }
};
不使用
虚拟
。。。父方法将被隐藏

编辑:谢谢关注。这是错误的。请参阅下一种方法

2)或使用<代码>使用< /Cord>声明,这是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
}
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); }
};
不使用
虚拟
。。。父方法将被隐藏

编辑:谢谢关注。这是错误的。请参阅下一种方法

2)或使用<代码>使用< /Cord>声明,这是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
}

您不能从子级使用父级的read函数,因为
Parent::read()
会使用完整的输入(您只能对字符串执行一次strtok(),而不使用NULL ptr,因为它实际上会替换分隔符)。棘手的是,孩子们必须从信息流的中间获取信息

如果声明
readName()
函数,可以重用父函数,但使用
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来避免。

您不能从子级使用父级的read函数,因为
Parent::read()
使用完整的输入(您只能对字符串执行一次strtok()而不使用NULL ptr,因为它实际上替换了分隔符)。棘手的是,孩子们必须从信息流的中间获取信息

如果声明
readName()
函数,可以重用父函数,但使用
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::RestInStruts./P>来避免,我认为C++的父方法不存在任何问题。@ CPPPCODER:我在一年前做过C++编程!但我记得,这是一个家庭作业,我忘了放标签,父函数必须是虚拟的。尽管如此,istream为我提供了整个系列,而不仅仅是第三个领域。我该怎么做?@ccSadegh因为父方法是使用范围解析操作符调用的,

virtual
关键字在这里不起作用。试试看。我不想为了这个再问一个问题。为什么返回整行而不是最后一个字段?我想什么?我不认为,有父方法作为虚拟的问题。@ CPPPCODER:我做C++编程一年前!但我记得,这是一个家庭作业,我忘了放标签,父函数必须是虚拟的。尽管如此,istream为我提供了整个系列,而不仅仅是第三个领域。我该怎么做?@ccSadegh因为父方法是使用范围解析操作符调用的,
virtual
关键字在这里不起作用。试试看。我不想为了这个再问一个问题。为什么返回整行而不是最后一个字段?我错过了什么?它似乎在工作,但当我做的时候是>>温度;它似乎可以工作,但当我这样做是>>温度;库特