14.1 14.7へのC ++入門第14章操作のオーバーロードと型変換と実践の概要

何度も繰り返し、その上に第14章のうち、実装定義関数を演算子オーバーロードによって実現することもできます。

演算子のオーバーロードのタイプ 勧告はで定義されている場合 戻り値の型 パラメータタイプ 注意事項
<< 非会員 ostram& ostream&、constのCLS&
>> 非会員 istream& istream&、CLS& 入力ストリームのエラーを考慮する必要がありますが、一般的に空のオブジェクトに設定されています
算術演算子 非会員 CLS constのCLS&、constのCLS& +定義し、+ =あなたは、一般的に定義さを定義する必要があります - 通常定義する必要があります - =
関係演算子 非会員 BOOL constのCLS&、constのCLS& 通常、==を定義する必要性を定義しました!=、<=、> =、<定義する必要が>定義
割り当て、化合物代入演算子 メンバー CLS& constのCLS&
添字演算子 メンバー CLS& size_tの constと非constバージョンを定義するための一般的な必要性
フロント昇順降順 メンバー CLS& -
リア昇順降順 メンバー CLS int型 int型は一つだけ、このパラメータああを使用することはできません、フロントとリアの間を区別するために使用されるパラメータ
間接参照* メンバー CLS& -
フーにアクセスするには、矢印 メンバー CLS * - アクセス矢印メンバアクセッサ例えばP->サイズなどの特定のクラス、()それ以外の場合はエラー

14.1基本概念

私たちは、事業者のほとんどを上書きすることができ、オーバーロード演算子は、簡単なコードのレベルを上げることができます。

オーバーロード演算子は、名前を演算子オーバーロードに演算子+演算子が必要です。

下記の演算子をオーバーロードされます。
ここに画像を挿入説明
私たちは、オペレータ、同じ値を返す必要が、パラメータリスト、関数本体をオーバーロードすることができるようにコールオペレータは、実際には、関数を呼び出します。しかし、オペレータは、引数の数を入力することができ、戻り値は同じではありません

bool operator+(A&,A&){
	
}
A& A::operator+=(A&){}
{
	
}

オーバーロードオペレータは実際には関数なので、外の例として、我々はこれを行うことができます+オーバーロードされますが、これは良い見ていません。

a+b;
operator+(a,b);

または構築され、後の演算子の優先順位を、オーバーロードなど。

この上のオペレータ*と結合するターゲットのオペレータメンバ関数の第一または左側である場合、オペレータは、通常の関数としてもメンバ関数としてオーバーロードすることができます。そのため、オーバーロードされた演算子クラスは、少なくとも一つのパラメータになります。

具体的な使用方法を確認するために、外部で定義されたときに正確にいつは、クラスで定義されています。

この本は、これは言っていた:
ここに画像を挿入説明
あなたはクラスで定義されている必要があり、いくつかがある見ることができ、クラス内とクラス外の数値が可能があります。
いくつかの対称演算子は、外側を定義します。

練習

14.1

オーバーロードされた演算子メンバ関数ならば、オペレータまたは最初のオペランドの左側には、*このにバインドされます。算術、関係、等==対称オペレータのために、左側(最初は)オペランドクラス型でなければなりません。

同じオペレータは、メンバ関数、動作ルールをオーバーロードし、組み込み型れていない場合。

14.2
加法
Sales_data operator+(Sales_data& data1, Sales_data& data2) {
	if (data1.isbn() == data2.isbn())
	{
		data1.combine(data2);
	}
	return data1;
}

复合赋值
inline Sales_data & Sales_data::operator+=(Sales_data & data)
{
	// TODO: 在此处插入 return 语句
	if (data.isbn()==isbn())
	{
		combine(data);
	}
	return *this;
}
14.3

ここで私は==オーバーロードさの定義は、オーバーロードされたメンバ関数内にあると思います。

A。コールシステムは、==建て
Bを。文字列を呼び出す
Cを。ベクトルコール
dは。コール文字列

14.4

A。メンバ関数は、推奨されるようにオブジェクトの周囲のオブジェクトは、それが定義されていない、操作者であってもよい
Bは。万一の
C。あなたは必要があり
日間。あなたはすべきである
電子。これは、コンテンツの背面からすべきではない
、F。&&はいけない
G、いけない
べきであり、H

14.5

私は、日付を書きました。
+ 2010年1月22日+ 2010年2月22日の定義はどのくらいのと等しい場合ので、一般的には、演算子をオーバーロードしないのですか?均一標準ないので、オーバーロード演算子、より良いADD_MONTH()、add_day()このようなインタフェースを提供するには、no。

もちろん、我々は日付を差し引いた2日を定義することができます。

具体的な実装ではありません。

入力と出力の演算子14.2

非メンバー関数として定義される過負荷オペレータ入力と出力。
通常、入力ストリームのエラー(異常)を処理するのに必要なオペレータ入力をオーバーロード、ヌルとしてオブジェクトの状態で一般的です。

練習

14.6,14.7,14.8形式は同じではなく、繰り返しています

ostream& operator<<(ostream& os,const Sales_data& data) {
	os << data.bookNo << " " << data.units_sold << " " << data.revenue;
	return os;
}
14.9
istream&  operator>>(istream& is, Sales_data & data)
{
	double price;
	is >> data.bookNo >> data.units_sold >> price;
	//is >> data.units_sold;
	if (is)
	{
		data.revenue = data.units_sold*price;
	}
	else {
		data = Sales_data();
	}
	return is;
	// TODO: 在此处插入 return 语句
}
14.10

a.得到一个正确的对象
b。因为price为double类型,而输入的是字符串,所以流的状态变为异常,所以得到一个空对象

14.11

存在,这个函数没有处理输入流错误时的情况

发生未定义了的行为,此时bookNo和units_sold都已经被赋值,但是price的值将是默认的值(如果设有默认值的话)

14.12
istream & operator>>(istream & is, My_Date & date)
{
	is >> date.year >> date.month >> date.day;
	if (!is)
	{
		date = My_Date();
	}
	return is;
	// TODO: 在此处插入 return 语句
}

14.3 算术和关系运算符

练习

14.13

可以支持==运算符

略,这些操作做一个熟悉一下就可以了

14.14

因为+=返回的是引用不用创建对象

14.15

两个日期并不好做算术运算,可以相减得到一个具体天数,但是其返回值类型并不是MyDate,这样就违背了尽量不改变运算符原本意义的初衷。

14.16

14.17
bool operator==(const My_Date & d1, const My_Date & d2)
{
	return d1.year==d2.year&&d1.month==d2.month&&d1.day==d2.day;
}

bool operator!=(const My_Date & d1, const My_Date & d2)
{
	return !(d1==d2);
}
14.18

14.19

定义了小于和大于,注意,在判断大于时,需要判断是否小于等于


bool operator<(const My_Date & d1, const My_Date & d2)
{
	bool flag = true;
	if (d1.year>d2.year)
	{
		flag = false;
	}
	else if (d1.year==d2.year&&d1.month>d2.month) {
		flag = false;
	}
	else if (d1.year == d2.year&&d1.month==d2.month&&d1.day>d2.day) {
		flag = false;
	}
	return flag;
}

bool operator>(const My_Date & d1, const My_Date & d2)
{
	return (d1!=d2)&&!(d1<d2);
}

14.4 赋值运算符

练习

14.20

14.21

+=中调用+,因为+返回一个非引用类型的对象就意味着需要构建一个临时对象。

14.22,14.23

14.24

因为My_Date中不需要管理其他的资源,没有指针类型。所以移动赋值对其作用不大。

	My_Date(const My_Date& d) :year(d.year), month(d.month), day(d.day) {};

14.25

实现复合赋值的意义不大,这里的运算对象左值右值类型都可以。
因为const的引用既可以绑定到左值上也可以绑定到右值上

My_Date & My_Date::operator=(const My_Date & d)
{
	year = d.year;
	month = d.month;
	day = d.day;
	// TODO: 在此处插入 return 语句
	return *this;
}
14.26

string & StrBlobPtr::operator[](size_t index)
{
	// TODO: 在此处插入 return 语句
	auto p =check(curr+index, "index out of range");
	return (*p)[curr+index];
}

string & StrVec::operator[](const size_t index)
{
	// TODO: 在此处插入 return 语句
	return *(elements + index);
}

string & StrVec::operator[](const size_t index) const
{
	// TODO: 在此处插入 return 语句
	return *(elements + index);
}

14.6 递增递减运算符

练习

14.27,14.28
StrBlobPtr & StrBlobPtr::operator++()
{
	check(curr, "index out of rage");
	++curr;
	return *this;
	// TODO: 在此处插入 return 语句
}

StrBlobPtr & StrBlobPtr::operator--()
{
	// TODO: 在此处插入 return 语句
	--curr;
	check(curr, "index out of rage");
	return *this;
}

StrBlobPtr  StrBlobPtr::operator++(int)
{
	auto temp = *this;
	++*this;
	return temp;
	// TODO: 在此处插入 return 语句
}

StrBlobPtr StrBlobPtr::operator--(int)
{
	auto temp = *this;
	--*this;
	return temp;
	// TODO: 在此处插入 return 语句
}

StrBlobPtr StrBlobPtr::operator+(size_t v)
{
	//检查加上一个值之后是否越界
	check(curr + v, "add size cause index out of range");
	StrBlobPtr ptr = *this;
	ptr.curr = curr + v;
	return ptr;
}

StrBlobPtr StrBlobPtr::operator-(size_t v)
{
	check(curr - v, "sub size cause index out of range");
	StrBlobPtr ptr = *this;
	ptr.curr = curr - v;
	return ptr;
}
14.29

因为递增递减需要改变对象本身,定义为const版本就不能改变自身了。

14.7 成员访问运算符

练习

14.30
string & StrBlobPtr::operator*()const
{
	// TODO: 在此处插入 return 语句
	auto ret =  check(curr, "point out of range");
	return (*ret)[curr];
}
//箭头元素运算符,必须访问一个成员
string * StrBlobPtr::operator->()const
{
	auto ret = check(curr, "point out of range");
	return &(*ret)[curr];
}

const string & ConstStrBlobPtr::operator*()const
{
	// TODO: 在此处插入 return 语句
	auto ret = check(curr, "point out of range");
	return (*ret)[curr];

}

const string * ConstStrBlobPtr::operator->()const
{
	auto ret = check(curr, "point out of range");
	return &(*ret)[curr];
}
14.31

因为StrBlobPtr内部管理资源的成员是weak_ptr一种智能指针,它指向了一个shared_ptr管理的对象,shard_ptr可以自动的管理内存,所以我们不必定义拷贝控制函数。

14.32

temp对象通过箭头访问符,访问StrBolbPtr的->访问符。strblobptr的箭头访问符,返回string类型的指针,通过该指针访问string的size()函数。

struct Temp
{
	StrBlobPtr* operator->();
	StrBlobPtr* p;
};

cout<<temp->operator->()->size()<<endl;
公開された54元の記事 ウォンの賞賛6 ビュー3294

おすすめ

転載: blog.csdn.net/zengqi12138/article/details/104537165