操作符重载

注意事项:有些必须是成员函数,比如,下标操作,赋值操作,有些最好不是,比如对称的比较==

自定义操作符至少要满足基本需要:

比如在关联容器中的键类型需要<,在顺序容器也应该定义==和<,sort算法需要<,find算法需要==

BTW,很多操作最好对应出现,比如

+对应+=;

==对应!=;

>对应 >= <= <;




Q1:如果不定义,有些操作符没意义,比如赋值,取地址和逗号操作符,但是Sales_item没定义operator&,却可以取地址。

Q2:重新定义&&和||操作符将失去短路特性,短路特性是怎么来的?就是实现里加上if语句,如果false就return了?--估计是!




//类定义
//自加运算操作符定义
    Sales_item Sales_item::operator++(int){

//只是写个(int)做样子来平息operatorOverload.cpp:24:21: error: no ‘operator++(int)’ declared for postfix ‘++’

        std::cout << "test: " << i << std::endl;
        Sales_item item(*this);//还要相应加一个复制构造函数
        this->units_sold += 1;
        this->revenue += 1;//这是假定单个利润1了,多卖一个item,多一块钱利润
        return item;//返回一个原来的副本,改变对象自身
    }

//测试代码
std::cout << (item1++) << std::endl;//operatorOverload.cpp:24:21: error: no ‘operator++(int)’ declared for postfix ‘++’
std::cout << (item1++) << std::endl;//item1++怎么需要操作符operator++(int)呢,哪有int?调用这句的时候自动产生了?

//参数列表使用(int i)和(int i = 4)默认实参是没多大意义的。
打印输出测试显示i都是0;

但是也不能无参Sales_item Sales_item::operator++(){}



默认实参应该是那样写吧




IO操作符重载

IO操作符因为要给每个对象成员单独进行IO操作,所以要声明友元。

注意输入和输出的const设置不一样。


double avg_price() const{return revenue / units_sold;}

//operatorIO.cpp:21:39: error: passing ‘const Sales_item’ as ‘this’ argument of ‘double Sales_item::avg_price()’ discards qualifiers
//不加const会出错,因为传递的是const对象(this一定const?怎么规定的?)。qualifier是限定符,例如const
//反例:set(int a){this.a = a;}


如果操作符是成员函数

item << cout;//和正常用法相反

为了和常规保持一致,IO操作符必须为非成员函数

不过也可以自己搞些个性的,因为实现是自己定义的。

比如item >> cout;//不过这不叫重载了吧,最起码不是original overload,是把>>输入操作符重载成>>输出操作符

//编写输入输出操作符,歪曲原来的功能,拿来玩玩,正常情况下不允许,不易用~!
#include"head.h"

class Sales_item{
public:
    Sales_item(const std::string &book):
              isbn(book), units_sold(1), revenue(3.0) { }
 //   Sales_item(std::istream &is) { is >> *this; }//副作用1:原来的>>被占用,不能cin利用这种方法初始化对象了,不过可以把另一边也反过来
    Sales_item(const Sales_item& item): isbn(item.isbn), units_sold(item.units_sold), revenue(item.revenue) {}

	friend std::ostream&
	operator<<(std::ostream&, const Sales_item&);
	std::ostream&
	operator>>(std::ostream&);
public:
	double avg_price() const{return revenue / units_sold;}//不加const会出错,因为传递的是const对象
	//operatorIO.cpp:21:39: error: passing ‘const Sales_item’ as ‘this’ argument of ‘double Sales_item::avg_price()’ discards qualifiers
private:
	std::string isbn;
	unsigned units_sold;
	double revenue;
	
};

std::ostream&
operator<<(std::ostream& out, const Sales_item &s){
	out << s.isbn << "\t" << s.units_sold << "\t" 
		<< s.revenue << "\t" << s.avg_price();
	return out;
}
std::ostream&
Sales_item::operator>>(std::ostream& out){
	out << isbn << "\t" << units_sold << "\t" 
		<< revenue << "\t" << avg_price();
	return out;
}
int main(){
	Sales_item item1("hello");
	std::cout << item1 << std::endl;
	item1 >> std::cout;
        std::endl >> item1 >> std::cout;//error:副作用2:必须以类对象为左操作数,前边不能加endl了,相对前一句不是完全翻转
}

14.7

//为下面的类顶一个一个输出操作符,
//赶时间啊,最后那个排队那个太复杂,不弄了,在初始化列表弄不了,应该在构造函数体内初始化它
//还有Date类,没有默认的,应该从c的time.h弄吧?
#include"head.h"

class CheckoutRecord{
public:
	CheckoutRecord(): book_id(0.0), title("hell"), date_borrowed(1988), date_due(1999),
						borrower(std::make_pair("hu", "qw")){}
	friend std::ostream&
	operator<<(std::ostream&, const CheckoutRecord&);
	typedef unsigned Date;
private:
	double book_id;
	std::string title;
	//借书还书日期
	Date date_borrowed;//Date是标准库的?
	Date date_due;//
	std::pair<std::string, std::string> borrower;//用pair存放单个借阅者的名字
	//std::vector< std::pair<std::string, std::string>* > wait_list;//vector存储(指向每个排队者)的指针
	
};

std::ostream&
operator<<(std::ostream& out, const CheckoutRecord& check){
	out << check.book_id << "\t" << check.title
		<< "\t" << check.date_borrowed << "\t" << check.date_due
		 << "\t" << check.borrower.first << "\t" << check.borrower.second
		  /*<< "\t第一个排队者" << (*check.wait_list.begin())->first
		   << "\t" << (*check.wait_list.begin())->second*/
		    << "\t" << std::endl;
	return out;
}
int main(){
	CheckoutRecord check1;
	std::cout << check1 << std::endl;
}



你可能感兴趣的:(操作符重载)