首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提高我班的操作者重载能力?

如何提高我班的操作者重载能力?
EN

Stack Overflow用户
提问于 2022-04-18 15:30:23
回答 2查看 115关注 0票数 2

我已经开始学习C++了。我的老师布置了一个作业。我完成了它(一些抛光工作还剩下),一切似乎都正常,但仍然存在冗余。我的主要问题是超载。如何提高我班的过载能力。与其编写所有四个函数(两个用于fstream,两个用于iostream),还可以只编写两个函数吗?还有其他改进代码的建议吗?

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <string>
#include "../../my_func.hpp"
#define usi unsigned short int

using namespace std;

class book
{
    public:
    usi book_id = 0, price = 0, no_of_pages = 0, year_of_publishing = 0;
    string author_name = "NONE", publisher = "NONE";
    book(usi b_id = 0, usi b_price = 0, usi b_no_of_pages = 0, usi b_year_of_publishing = 0,
         const string& b_author_name = "NONE", const string& b_publisher = "NONE")
    {
        book_id = b_id;
        price = b_price;
        no_of_pages = b_no_of_pages;
        year_of_publishing = b_year_of_publishing;
        author_name = b_author_name;
        publisher = b_publisher;
    }
    friend fstream& operator >> (fstream& is, book& obj);
    friend fstream& operator << (fstream& os, const book& obj);
    friend istream& operator >> (istream &is, book& obj);
    friend ostream& operator << (ostream &os, const book& obj);
};

fstream& operator >> (fstream &is, book& obj)
{
    char ch;
    is >> obj.book_id >> obj.price 
       >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n'); //To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

fstream& operator << (fstream &os, const book& obj)
{
    os.operator<<(obj.book_id) << '\n' //calling operator function cuz it works 
               << obj.price << '\n'
               << obj.no_of_pages << '\n'
               << obj.year_of_publishing << '\n';
    os << obj.author_name << '\n'
       << obj.publisher << '\n';
    return os;
}

istream& operator >> (istream &is, book& obj)
{
    is >> obj.book_id >> obj.price 
       >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n'); //To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

ostream& operator << (ostream &os, const book& obj)
{
    os << obj.book_id << '\n'
       << obj.price << '\n'
       << obj.no_of_pages << '\n'
       << obj.year_of_publishing << '\n'
       << obj.author_name << '\n'
       << obj.publisher << '\n';
    return os;
}
int main()
{
    string path = ".\\C++_Experiment\\Exp-7\\Files\\Source.txt";
    book b1(12, 3000, 100, 2003, "Lol", "Pew"), b2, b3;
    fstream fio;
    fio.open(path, ios::out | ios::app | ios::in);
    if(fio) fio << b1;
    else cout <<  "error"; 
    fio.seekg(0, ios::beg);
    if(fio) fio >> b2 >> b3;
    cout << b2 << b3;
    fio.close();
    cout << "DONE";
    return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-18 15:36:49

这里只需要两个过载。ifstreamofstream分别从istreamostream继承,所以如果您有

代码语言:javascript
复制
friend istream& operator >> (istream &is, book& obj);
friend ostream& operator << (ostream &os, const book& obj);

然后,它们将与coutcin以及任何fstreamstringstream对象一起工作,因为它们也继承了istreamostream

票数 5
EN

Stack Overflow用户

发布于 2022-04-18 16:47:12

除了仅针对std::istreamstd::ostream的重载之外,还有其他一些建议

  • 不要using namespace std;。更喜欢在STL类型和算法前面加上std::
  • 喜欢using而不是typedef,在本例中更喜欢#define。您可以将usi别名限制在book范围内。
  • book转换为一个结构:如果类book中的所有内容都是公共的。这样,您不需要操作符重载就可以成为book的朋友,因为他们可以直接访问book实例中的成员。
  • 更喜欢使用成员初始化列表,即在参数列表之后初始化成员变量。您还可以在声明点提供默认的成员初始化值;但是,在这种情况下,一个{}将对usi类型进行零初始化。在本例中,我不会对构造函数使用默认参数值。
  • 请考虑,如果提供自定义构造函数,则默认构造函数、复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符将被删除,因此不可用。

[演示]

代码语言:javascript
复制
#include <iostream>
#include <string>

struct book {
    using usi = unsigned short int;

    usi book_id{};
    usi price{};
    usi no_of_pages{};
    usi year_of_publishing{};
    std::string author_name{"NONE"};
    std::string publisher{"NONE"};

    book() = default;
    book(const book& other) = default;
    book& operator=(const book& other) = default;
    book(book&& other) noexcept = default;
    book& operator=(book& other) noexcept = default;
    ~book() = default;

    book(usi b_id,
         usi b_price,
         usi b_no_of_pages,
         usi b_year_of_publishing,
         const std::string& b_author_name,
         const std::string& b_publisher)
        : book_id{b_id}
        , price{b_price}
        , no_of_pages{b_no_of_pages}
        , year_of_publishing{b_year_of_publishing}
        , author_name{b_author_name}
        , publisher{b_publisher}
    {}
};

std::istream& operator>>(std::istream& is, book& obj) {
    is >> obj.book_id >> obj.price >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n');  // To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

std::ostream& operator<<(std::ostream& os, const book& obj) {
    return os 
        << "["
        << obj.book_id << ", "
        << obj.price << ", "
        << obj.no_of_pages << ", "
        << obj.year_of_publishing << ", "
        << obj.author_name << ", "
        << obj.publisher << "]";
}

int main() {
    book b1{ 12, 3000, 100, 2003, "Lol", "Pew" };
    std::cout << "b1: " << b1 << "\n";

    book b2{};
    std::cin >> b2;
    std::cout << "b2: " << b2;
}
  • book成为聚合。如果您忘记将std::string成员初始化为"NONE" (您总是可以在operator<<处检查空字符串,如果需要的话可以输出"NONE ),您可以删除很多代码。您可以去掉自定义构造函数,以及所有其他默认构造函数和赋值运算符。

[演示]

代码语言:javascript
复制
#include <iostream>
#include <string>

struct book {
    using usi = unsigned short int;

    usi book_id{};
    usi price{};
    usi no_of_pages{};
    usi year_of_publishing{};
    std::string author_name{};
    std::string publisher{};
};

std::istream& operator>>(std::istream& is, book& obj) {
    is >> obj.book_id >> obj.price >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n');  // To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

std::ostream& operator<<(std::ostream& os, const book& obj) {
    return os 
        << "["
        << obj.book_id << ", "
        << obj.price << ", "
        << obj.no_of_pages << ", "
        << obj.year_of_publishing << ", "
        << (obj.author_name.empty() ? "NONE" : obj.author_name) << ", "
        << (obj.publisher.empty() ? "NONE" : obj.publisher) << "]";
}

int main() {
    book b1{ 12, 3000, 100, 2003, "Lol", "" };
    std::cout << "b1: " << b1 << "\n";

    book b2{};
    std::cin >> b2;
    std::cout << "b2: " << b2;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71913815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档