代码之家  ›  专栏  ›  技术社区  ›  Nick

用ifstream构建一个阶级诗人,然后用相同的ifstream构建其成员阶级诗歌

  •  -1
  • Nick  · 技术社区  · 7 年前

    想象一个名为“诗人”的班级,其中名为“FirstName”,名为“LastName”,名为“Verse”的班级是“诗人”的成员。可以用ifstream构造诗人,然后用ifstream初始化名字和姓氏,然后用相同的ifstream构造成员诗吗?我的意思是,在初始化一些成员之后,如何将ifstream从一个类正确地传递到它的成员类?谢谢

    2 回复  |  直到 7 年前
        1
  •  0
  •   user4581301    7 年前

    步骤1:添加运算符>&燃气轮机;到诗句

    这是一件微不足道的事 >> 基于 What are the basic rules and idioms for operator overloading?

    因为我不知道在一个 Verse ,我坚持一行的字面定义。

    friend std::istream& operator>>(std::istream& in, Verse & obj)
    {
        std::getline(in, obj.line);
        return in;
    }
    

    这可以让您从任何流中读取,而不仅仅是 fstream ,转换为 韵文 . 在有意义的地方,从抽象的最高级别开始工作,以获得更通用的解决方案。

    步骤2:使用 韵文 >> 在构造函数中。

    我正在讨论这是否是构造函数中的一件好事。构造函数和其他函数一样,应该完成一项工作。构造函数的任务是初始化对象。从文件读入通常可能会超出一个作业规则。另一个原因是,构造函数只有(或应该有)两种方法:初始化对象或抛出异常,异常代价高昂。IO有很大的出错空间,因此您可能会发现自己抛出异常的频率比您希望的要高。

    Poet(std::istream & in)
    {
        in >> FirstName >> LastName >> Verse;
        if (!in)
        {
            throw std::runtime_error("Aaaaaaaarrrggghhhh!");
        }
    }
    

    再次注意,我已将输入流从文件流扩展到所有 istream s来推广函数。

    如果读取失败,也不例外。你得到一个物体,或者你没有。

    最后一句话(巴林编辑)面对像“约翰·冯·歌德”这样的诗人名字,这种解决方案非常失败,因为它只接受一个词的名字。

        2
  •  0
  •   Nick    7 年前

    我找到了另一种方法。诗人h:

    private:
    std::string FirstName;
    std::string LastName;
    int BirthYear;
    bool IsAlive;
    int DeathYear;
    Verse FirstVerse;
    

    类POETER重载了POETER中的构造函数。cpp:

    Poet::Poet(std::ifstream & in):DeathYear(0)
    {
        std::getline(in, FirstName);
        std::getline(in, LastName);
        in >> BirthYear;
        in >> IsAlive;
        setDeathYearIfNotAlive(in);
    
        //in >> FirstVerse;
    
        FirstVerse.~Verse();
        new(&FirstVerse) Verse(in);
    }
    

    请注意,“in”没有重载的友元运算符>>,这是基本的 std::ifstream in