C++Primer第五版——书店程序实现
Book.h
#include <string>
#include <iostream>
using namespace std;
class Book{
friend ostream & operator<<(ostream &c,Book &bk);
friend ostream & operator>>(ostream &c,Book &bk);
private:
string id;
double quantity,price;
public:
double getQuantity();
double getPrice();
string getId();
void setQuantity(double value);
void setPrice(double value);
void setId(string value);
Book();
/*
在类的成员函数中的二元操作符重载默认左边的操作数就是调用函数对象本身,故参数列表应该只有一个或零个参数。
当参数列表出现两个时,报错。 故+=可以写成成员函数。
而像整形数加上复数(int+complex)时则需用全局函数。
*/
Book operator+(const Book &bk2);
//Book operator<<(bk) 一般不会采取成员函数重载左移或者右移运算符,因为这个时候cout在右边 bk<<cout
};
//ostream只会存在一个对象,所以不要创建新的
ostream& operator<<(ostream& c,Book& bk);
istream& operator>>(istream& c,Book& bk);
/*
'Book Book::operator+(const Book&, const Book&)' must take either zero or one argument
expected initializer before '&' token|
'std::__cxx11::string Book::id' is private|
*/
Book.cpp
#include"Book.h"
Book::Book()
{
quantity=0;
price=0;
}
Book Book::operator+(const Book& bk2)
{
//if(bk1.id!=bk2.id) return NULL;
Book bk;
bk.id=this->id;
bk.quantity=this->quantity+bk2.quantity;
bk.price=((this->quantity*this->price)+(bk2.quantity*bk2.price))/bk.quantity;
return bk;
}
ostream& operator<<(ostream& c,Book& bk)
{
c << bk.id << " " << bk.quantity << " " << bk.price << " " << bk.quantity*bk.price << endl;
//c << bk.getId() << " " << bk.getQuantity() << " " << bk.getPrice() << " " << bk.getQuantity()*bk.getPrice() << endl;
return c;
}
istream& operator>>(istream& c,Book& bk)
{
//c >> bk.id >> bk.quantity >> bk.price;
string a;
double b,cc;
c >> a >> b >> cc;
bk.setId(a);
bk.setQuantity(b);
bk.setPrice(cc);
return c;
}
double Book::getQuantity()
{
return this->quantity;
}
double Book::getPrice()
{
return this->price;
}
string Book::getId()
{
return this->id;
}
void Book::setQuantity(double value)
{
this->quantity=value;
}
void Book::setPrice(double value)
{
this->price=value;
}
void Book::setId(string value)
{
this->id=value;
}
main.cpp
#include <iostream>
#include "Book.h"
using namespace std;
int main()
{
Book tmp,total;
if(cin>>total)
{
while(cin>>tmp)
{
if(total.getId()==tmp.getId()){
total=total+tmp;
}
else
{
cout<<total;
total=tmp;
}
}
}
else
{
cerr<<"input error"<<endl;
}
return 0;
}
/*
ambiguous overload for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Book')|
*/
出现错误1、ambiguous overload for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Book')|
这个问题出现的原因是我在修改Book.h文件中的ostream& operator<<(ostream& c,Book& bk);方法时,没有同步修改Book.cpp文件,所以出现了operator<<函数模棱两可的报错
出现错误2、 'std::__cxx11::string Book::id' is private|
在实现istream& operator>>(istream& c,Book& bk);这个函数的时候,我以为这个函数是友元函数,所以可以直接访问Book的私有成员属性,但是没想到不能访问,满头问号????
出现错误3、 expected initializer before '&' token|
这个是我在C++的Book类的大括号后面没有加分号(";"),写Java写多了。。。
出现错误4、'Book Book::operator+(const Book&, const Book&)' must take either zero or one argument
在类的成员函数中的二元操作符重载默认左边的操作数就是调用函数对象本身,故参数列表应该只有一个或零个参数。
当参数列表出现两个时,报错。 故+可以写成成员函数。
而像整形数加上复数(int+complex)时则需用全局函数。
出现错误5、C++返回NULL对象可以吗?
class Person{ public: Person(); } And in my main: int main() { Person myPer = NULL; }
这是可能的,而C++确实允许它。这一切都取决于你如何定义类Person
。例如,如果类Person
有一个构造函数,如下所示:
class Person { public: Person(char *) {} };
然后Person myPer = NULL
将编译就好:http://www.ideone.com/586Pf
对象不能为空,只有指针可以。你的代码不正确,不能编译,因为它试图从指针初始化Person
到指向Person
的指针。如果要更改您的代码
Person* perPtr = NULL;
Person myPer = *perPtr;
那么这将是试图将Person
了解除引用空指针的初始化为Person
,这是不确定的行为(最有可能崩溃)。
如果您需要使用的习惯用法,对象可能是一个NULL
状态,你可以使用Boost.Optional
:
boost::optional<Person> myPer = boost::none; if(myPer) { myPer->do_something(); }