何度も繰り返し、その上に第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;