C++11運(yùn)算符重載和向量類重載實(shí)例詳解(<<,>>,+,-,*等)
1. C++運(yùn)算符重載介紹
C ++ 中預(yù)定義的運(yùn)算符的操作對(duì)象只能是基本數(shù)據(jù)類型。但實(shí)際上,對(duì)于許多用戶自定義類型(例如類),也需要類似的運(yùn)算操作。這時(shí)就必須在C ++ 中重新定義這些運(yùn)算符,賦予已有運(yùn)算符新的功能,使它能夠用于特定類型執(zhí)行特定的操作。運(yùn)算符重載的實(shí)質(zhì)是函數(shù)重載,它提供了C ++ 的可擴(kuò)展性,也是C ++ 最吸引人的特性之一。
運(yùn)算符重載時(shí)要遵循以下規(guī)則:
( 1 ) 除了類屬關(guān)系運(yùn)算符 " . " 、成員指針運(yùn)算符 " .* " 、作用域運(yùn)算符 " :: " 、sizeof運(yùn)算符和三目運(yùn)算符 " ?: " 以外,C ++ 中的所有運(yùn)算符都可以重載。
( 2 ) 重載運(yùn)算符限制在C ++ 語(yǔ)言中已有的運(yùn)算符范圍內(nèi)的允許重載的運(yùn)算符之中,不能創(chuàng)建新的運(yùn)算符。
( 3 ) 運(yùn)算符重載實(shí)質(zhì)上是函數(shù)重載,因此編譯程序?qū)\(yùn)算符重載的選擇,遵循函數(shù)重載的選擇原則。
( 4 ) 重載之后的運(yùn)算符不能改變運(yùn)算符的優(yōu)先級(jí)和結(jié)合性,也不能改變運(yùn)算符操作數(shù)的個(gè)數(shù)及語(yǔ)法結(jié)構(gòu)。
( 5 ) 運(yùn)算符重載不能改變?cè)撨\(yùn)算符用于內(nèi)部類型對(duì)象的含義。它只能和用戶自定義類型的對(duì)象一起使用,或者用于用戶自定義類型的對(duì)象和內(nèi)部類型的對(duì)象混合使用時(shí)。
( 6 ) 運(yùn)算符重載是針對(duì)新類型數(shù)據(jù)的實(shí)際需要對(duì)原有運(yùn)算符進(jìn)行的適當(dāng)?shù)母脑?,重載的功能應(yīng)當(dāng)與原有功能相類似,避免沒有目的地使用重載運(yùn)算符。
1.1 單目運(yùn)算符與雙目運(yùn)算符
( 1 ) 雙目運(yùn)算符重載為類的成員函數(shù)時(shí),函數(shù)只顯式說明一個(gè)參數(shù),該形參是運(yùn)算符的右操作數(shù)。
比如說你重載+號(hào),如果寫在類外面,那么是需要兩個(gè)參數(shù)的,而寫在類里面,只能寫一個(gè)參數(shù),因?yàn)楫?dāng)這個(gè)函數(shù)被調(diào)用的時(shí)候,會(huì)自動(dòng)的傳一個(gè)this指針進(jìn)去,就是對(duì)象本身,所以只需要一個(gè)參數(shù)
( 2 ) 前置單目運(yùn)算符重載為類的成員函數(shù)時(shí),不需要顯式說明參數(shù),即函數(shù)沒有形參。
( 3 ) 后置單目運(yùn)算符重載為類的成員函數(shù)時(shí),函數(shù)要帶有一個(gè)整型形參。
比如前置++,和后置++,帶一個(gè)整形形參只是為了區(qū)分
1.2 友元運(yùn)算符
有些運(yùn)算符是一定得聲明為友元的,比如<<,>>運(yùn)算符
因?yàn)?,+這些運(yùn)算符,是c++最基本的運(yùn)算符,而>>,<<運(yùn)算符是標(biāo)準(zhǔn)頭文件里面的一個(gè)類里面寫的,你不能把這個(gè)函數(shù)聲明為你這個(gè)自定義類的函數(shù),因?yàn)檫@是別人類里面的函數(shù),因此你只能把它聲明為友元函數(shù),聲明為友元函數(shù)之后,那么這個(gè)函數(shù)它就可以訪問你這個(gè)自定義類里面的私有成員變量
2. 實(shí)例講解
光看這些概念,想必沒有接觸過的同學(xué)頭都大了,接下來我通過一個(gè)向量類的例子,來講解一下各個(gè)運(yùn)算符重載怎么用
2.1 頭文件定義
這次我們來實(shí)例一個(gè)向量類,什么是向量類呢,就是數(shù)學(xué)里面的向量,一個(gè)括號(hào),里面兩個(gè)數(shù)字,看一下頭文件你就明白啦
class Vec2D {
private:
double x_;
double y_;
public:
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
Vec2D(double x, double y) :x_(x), y_(y) {}
Vec2D() { x_ = 0.0; y_ = 0.0; }
std::string toString();
friend Vec2D operator+(const Vec2D& v1, const Vec2D& v2);
friend Vec2D operator-(const Vec2D& v1, const Vec2D& v2);
friend double operator*(const Vec2D& v1, const Vec2D& v2);
friend Vec2D operator+(const Vec2D& v1, double num);
friend Vec2D operator*(const double num, const Vec2D& v2);
friend Vec2D operator*(const Vec2D& v2, const double num);
friend istream& operator>>(istream& stream, Vec2D& v1);
friend std::ostream& operator<<(std::ostream& stream, const Vec2D& v1);
Vec2D negative();
Vec2D operator-();
Vec2D operator++();
Vec2D operator++(int dummy);
Vec2D operator--();
Vec2D operator+=(const Vec2D& v);
Vec2D operator-=(const Vec2D& v);
double& operator[](const int& index);
double magnitude();
double direction();
int compareTo(Vec2D& v2);
operator double();
double getX()const { return x_; }
double getY() const { return y_; }
void setX(double x) { x_ = x; }
void setY(double y) { y_ = y; }
};
可以看到,其實(shí)私有成員就是 x_和y_,然后我重載了非常多的函數(shù),下面我們來看一下具體的實(shí)現(xiàn)
2.2 實(shí)現(xiàn)運(yùn)算符重載
toString函數(shù)
這個(gè)函數(shù)我就不多說啦,比較簡(jiǎn)單
std::string Vec2D::toString()
{
std::string res = "(" + std::to_string(getX()) + ", " + std::to_string(getY()) + ")";
return res;
}
negative函數(shù)
這個(gè)函數(shù)是用來將向量變成負(fù)方向
Vec2D Vec2D::negative()
{
return Vec2D(-1 * x_, -1 * y_);
}
operator-函數(shù)
第一個(gè)重載函數(shù)出現(xiàn)了,是重載的符號(hào),更加方便的實(shí)現(xiàn)了改變向量為負(fù)方向的操作
這樣我們可以通過 -a,-b的形式來調(diào)用
Vec2D Vec2D::operator-()
{
return Vec2D(-1 * x_, -1 * y_);
}
operator++函數(shù)
這個(gè)函數(shù)是前置++運(yùn)算符,返回*this就是返回當(dāng)前對(duì)象
Vec2D Vec2D::operator++()
{
x_++;
y_++;
return *this;
}
operator++函數(shù)
這個(gè)函數(shù)是后置++運(yùn)算符,所以后面加了一個(gè)類型的參數(shù),這個(gè)參數(shù)唯一的意思是與前置++作區(qū)分
我們首先創(chuàng)建了一個(gè)臨時(shí)變量,然后將本身的x,y加1,返回的卻是臨時(shí)變量,這樣就實(shí)現(xiàn)了后置++的操作
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
Vec2D Vec2D::operator++(int dummy)
{
Vec2D ret(x_, y_);
x_++;
y_++;
return ret;
}
operator--函數(shù)
減減同理,就是將x,y都減1
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
Vec2D Vec2D::operator--()
{
x_ -= 1;
y_ -= 1;
return *this;
}
operator+= ,-=函數(shù)
這兩個(gè)函數(shù)比較相似,我就放到一起講啦,這里是將調(diào)用這個(gè)函數(shù)本身的對(duì)象,與參數(shù)里面的v相加或者相減
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
Vec2D Vec2D::operator+=(const Vec2D& v)
{
x_ += v.x_;
y_ += v.y_;
return *this;
}
Vec2D Vec2D::operator-=(const Vec2D& v)
{
x_ -= v.x_;
y_ -= v.y_;
return *this;
}
operator[ ]函數(shù)
這里重載了[ ],有一個(gè)參數(shù),index,用來選擇到底是返回x還是y
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
double& Vec2D::operator[](const int& index)
{
if (index == 0) {
return x_;
}
else if (index == 1) {
return y_;
}
else {
printf("subscript error\n");
exit(0);
}
}
operator+(類外)函數(shù)
因?yàn)槭窃陬愅庵剌d,所以有兩個(gè)參數(shù),同時(shí)要注意將這個(gè)函數(shù)聲明為友元函數(shù),因?yàn)檫@樣才可以訪問私有成員變量
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
//類外重載,運(yùn)算符重載函數(shù)作為類的友元函數(shù)
Vec2D operator+(const Vec2D& v1, const Vec2D& v2) {
Vec2D ret;
ret.setX(v1.getX() + v2.getX());
ret.setY(v1.getY() + v2.getY());
return ret;
}
Vec2D operator+(const Vec2D& v1, double num) {
Vec2D ret;
ret.setX(v1.getX() + num);
ret.setY(v1.getY() + num);
return ret;
}
operator*函數(shù)
這里重載了*,用來實(shí)現(xiàn)向量之間的相乘
static string AuthorBlog = "https://www.cnblogs.com/wanghongyang";
Vec2D operator*(const double num, const Vec2D& v2) {
Vec2D ret;
ret.setX(num * v2.getX());
ret.setY(num * v2.getY());
return ret;
}
重載>> <<
這里給大家避個(gè)坑,一定要引入iostream頭文件,而不是用using
這兩個(gè)函數(shù)就是用來實(shí)現(xiàn)cout和cin
可以看到,實(shí)現(xiàn)cin 是通過 istream對(duì)象來實(shí)現(xiàn)的
實(shí)現(xiàn)cout 是通過ostream來實(shí)現(xiàn)的
記得在最后返回istream或者ostream對(duì)象
istream& operator>>(istream& stream, Vec2D& v1)
{
double x, y;
stream >> x >> y;
v1.setX(x);
v1.setY(y);
// 也可以直接
// stream >> x_ >> y_;
return stream;
}
ostream& operator<<(ostream& stream, const Vec2D& v1)
{
std::string res = "(" + std::to_string(v1.getX()) + ", " + std::to_string(v1.getY()) + ")";
stream << res;
return stream;
}
總結(jié)
到此這篇關(guān)于C++11運(yùn)算符重載和向量類重載的文章就介紹到這了,更多相關(guān)C++11運(yùn)算符重載向量類重載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++標(biāo)準(zhǔn)C函數(shù)在各平臺(tái)編譯結(jié)果都相同
今天小編就為大家分享一篇關(guān)于C++標(biāo)準(zhǔn)C函數(shù)在各平臺(tái)編譯結(jié)果都相同,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
關(guān)于在MFC中將窗口最小化到托盤實(shí)現(xiàn)原理及操作步驟
最小化的原理:首先要將窗口隱藏,然后在右下角繪制圖標(biāo);恢復(fù)的原理:將窗口顯示,再將托盤中的圖片刪除,接下來介紹實(shí)現(xiàn)方法,感興趣的朋友可以了解下啊,希望本文對(duì)你有所幫助2013-01-01
undefined reference to `SetPduPowerConsumptionCnt''錯(cuò)誤的解決方法
編譯時(shí)出現(xiàn)undefined reference to `SetPduPowerConsumptionCnt'錯(cuò)誤要如何解決呢?有沒有什么好的解決方法?下面小編就為大家解答吧,如果你也遇到了這種情況,可以過來參考下2013-07-07

