c++允許在自己的類中,或是在全域性作用域中重定義運算子的含義。由於很多物件導向的語言沒有提供這種能力,因此你可能會低估這種特性在c++中的作用。c++中運算子的概念十分廣泛,甚至包含(陣列索引)、()(函式呼叫)、型別轉換以及記憶體分配和釋放例程。可以通過運算子過載來改變語言運算子對自定義類的行為。能讓自己的類具有內建型別的類似行為,甚至可以編寫看上去類似於陣列、函式或指標的類。在博主的《c++運算子過載》系列博文中會對我們常用的運算子提供過載的例項,希望大家能有所收穫。額,本篇博文就讓我們一起來**一下過載運算子中的流插入運算子和流提取運算子過載吧。
在c++中,不僅算術操作需要使用運算子,從流中讀寫資料都可以使用運算子。流操作運算子有「<>」(流提取運算子)。
由於不能向istream類和ostream類新增方法,因此應該將流插入運算子和流提取運算子過載為全域性函式。將流插入運算子的第乙個引數設定為ostream的引用(不要加const),這個運算子就能夠應用於檔案輸出流、字串輸出流、cout、cerr和clog等。與此類似,將流提取運算子的第乙個引數設定為istream的引用(不要加const),這個運算子就能夠應用於檔案輸入流、字串輸入流和cin。因為流插入和流提取都會改變流的狀態,所有operator <>)的第乙個引數是ostream(或istream)的非const引用。
operator<>)的第二個引數是對要寫入(或讀取)的物件的引用。流插入運算子不會修改寫入的物件,因此這個引用可以是const。然而流提取運算子會修改物件,因此要求這個引數是非const引用。兩個流運算子返回的都是第乙個引數傳入的流物件的引用,所以這個運算子可以巢狀。說了那麼多的概念,可能有的小夥伴已經暈了。那咱們來簡單的封裝乙個複數類,用流運算子過載完成輸入和輸出。
#pragma
once
#include //
前向宣告(由於函式模板中有用到
complex
類,所以需要前向宣告
complex
類)template
t>
class
complex;
//函式模板宣告
template
t>
complex
operator + (const
complex
&lhs,const
complex
&rhs);
template
t>
complex
operator - (const
complex
&lhs,const
complex
&rhs);
template
std::ostream&operator
<< (std::ostream &ostr,constcomplex&rhs);
template
std::istream&operator>> (std::istream &istr, complex&rhs);
template
class complex ;
//包含模板實現部分
//如果
"complex.inl"
是標頭檔案就直接包含就行
//如果
"complex.inl"
是原始檔
,則必須將其從專案中移除
#include
"complex.inl"
using
namespacestd;
template
t>
complex
::complex(t
real
/* =t()*/, t
image
/*= t()*/)
: m_real(real),m_image(image)
template
t>
complex
::~complex()
template
complexoperator+ (const complex&lhs,constcomplex&rhs)
template
complexoperator- (const complex&lhs,constcomplex&rhs)
template
ostream& operator
<< (ostream &ostr, constcomplex&rhs)
template
istream& operator>> (istream &istr, complex&rhs)
#include
"complex.h"
int main(int
argc,char**argv)
程式執行結果:
可能你覺得前面**中的前向引用宣告有點複雜,而且還和類裡的友元宣告有點重複。有沒有簡便的方法,不用寫那些複雜的前向引用宣告呢?有,像下面這樣就可以。
#pragma
once
#include
using
namespacestd;
template
t>
class
complex;
//包含模板實現部分
//如果
"complex.inl"
是標頭檔案就直接包含就行
//如果
"complex.inl"
是原始檔
,則必須將其從專案中移除
#include
"complex.inl"
注意到沒有,用「using
namespacestd;」就可以避免繁瑣的前向引用宣告啦。不過,此時可以將「complex.inl」檔案中的「using
namespacestd;」去掉了,因為「complex.
h」已經包含了哦。相信你現在已經學會了流運算子過載的編寫,不過光看是不行的哦,自己動手敲一下。博主為了方便講解,封裝的complex模板類十分簡單,你可以嘗試一下更接近於內建型別的版本哦。雖然你封裝的類其他人已經封裝過了,不過在學習階段還是得多折騰,這樣才能加深你對這部分知識的理解。
C 的運算子過載(四) 其他運算子過載和總結
概述 除了前面過載的指標,自增自減,左移運算子之外,可以發生過載的運算子還有很多,比如等號 等等 以及 等,二 符號過載總結 三,字串類封裝 class person person int age1,char name1 person operator person p person int age...
C 運算子過載 過載特殊運算子
賦值運算子用於同類物件間的相互賦值。賦值運算子只能被過載為類的非靜態成員函式,不能過載為友元函式和普通函式。對於使用者自定義的類而言,如果沒有過載賦值運算子,那麼c 編譯器會為該類提供乙個預設的過載賦值運算子成員函式。預設賦值運算子的工作方式是按位對拷,將等到右邊物件的非靜態成員拷貝給等號左邊的物件...
C 運算子過載賦值運算子
自定義類的賦值運算子過載函式的作用與內建賦值運算子的作用類似,但是要要注意的是,它與拷貝建構函式與析構函式一樣,要注意深拷貝淺拷貝的問題,在沒有深拷貝淺拷貝的情況下,如果沒有指定預設的賦值運算子過載函式,那麼系統將會自動提供乙個賦值運算子過載函式。賦值運算子過載函式的定義與其它運算子過載函式的定義是...