关于C++中的友元函数

About friend function in C++

Sales_data.h

#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>

class Sales_data {
    friend std::istream &read(std::istream &in, Sales_data &data);
    friend std::ostream &print(std::ostream &out, const Sales_data &data);

public:
    Sales_data() = default;
    //Sales_data(std::string _bookNo="", unsigned _units_sold = 0, double _revenue = 0)
        //:bookNo(_bookNo), units_sold(_units_sold), revenue(_revenue) {}
    std::string isbn() { return bookNo; }
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
private:
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0;
};

Sales_data &Sales_data::combine(const Sales_data& data) {
    units_sold += data.units_sold;
    revenue += data.revenue;
    return *this;
}

std::istream &read(std::istream &in, Sales_data &data);
std::ostream &print(std::ostream &out, const Sales_data &data);

#endif

Sales_data.cpp

#include "Sales_data.h"

/*
double Sales_data::avg_price() const {
    return units_sold != 0 ? (revenue / units_sold) : 0;
}
*/

std::istream &read(std::istream &in, Sales_data &data) {
    in >> data.bookNo >> data.units_sold >> data.revenue;
    return in;
}

std::ostream &print(std::ostream &out, Sales_data &data) {
    out << data.isbn() << " " << data.units_sold << " " << data.revenue;
    return out;
}

main_func.cpp

#include "Sales_data.h"
#include <iostream>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;

void func() {
    Sales_data total;
    if(read(cin, total)) {
        Sales_data trans;
        while(read(cin, trans)) {
            if (total.isbn() == trans.isbn())
                total.combine(trans);
            else {
                print(cout, total) << endl;
                total = trans;
            }
        }
        print(cout, total) << endl;
    } else {
        cerr << "No data?!" << endl;
    }
}

int main(int argc, char** argv) {
    func();
    return 0;
}

我运行程序,但它总是告诉我有问题。我确实使用了 friend 函数,但它仍然说我使用 class 的私有成员。信息如下: Sales_data.cpp:10:23: error: invalid operands to binary expression ('basic_istream<char>' and 'unsigned int') in >> data.bookNo >> data.units_sold >> data.revenue; ~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~ /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/bits/basic_string.tcc:996:5: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against 'unsigned int' operator>>(basic_istream<_CharT, _Traits>& __in, ^ Sales_data.cpp:15:24: error: invalid operands to binary expression ('basic_ostream<char, std::char_traits<char> >' and 'const char *') out << data.isbn() << " " << data.units_sold << " " << data.revenue; ~~~~~~~~~~~~~~~~~~ ^ ~~~ /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/bits/basic_string.h:2753:5: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against 'char const[2]' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ Sales_data.cpp:15:39: error: 'units_sold' is a private member of 'Sales_data' out << data.isbn() << " " << data.units_sold << " " << data.revenue; ^ ./Sales_data.h:18:14: note: declared private here unsigned units_sold = 0; ^ Sales_data.cpp:15:65: error: 'revenue' is a private member of 'Sales_data' out << data.isbn() << " " << data.units_sold << " " << data.revenue; ^ ./Sales_data.h:19:12: note: declared private here double revenue = 0; ^ 4 errors generated.

由于 Sales_data &const Sales_data & 是不同的类型,您的 cpp 文件中的 print 函数被认为是 overload print 函数,它 不是 Sales_data class 的朋友。

添加 const 以修复此错误:

std::ostream &print(std::ostream &out, const Sales_data &data) {
... //                                 ^^^^^
}