关于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) {
... // ^^^^^
}
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) {
... // ^^^^^
}