欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

初識C++05:運(yùn)算符重載

運(yùn)算符重載

運(yùn)算符重載基礎(chǔ)

函數(shù)重載(Function Overloading)可以讓一個函數(shù)名有多種功能,在不同情況下進(jìn)行不同的操作。運(yùn)算符重載(Operator Overloading)也是一個道理,同一個運(yùn)算符可以有不同的功能。

柯橋ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

例子:用+號實現(xiàn)復(fù)數(shù)加法運(yùn)算;成員函數(shù)重載運(yùn)算符

#include <iostream>
using namespace std;
class complex{
public:
    complex();
    complex(double real, double imag);
public:
    //聲明運(yùn)算符重載
    complex operator+(const complex &A) const;
    void display() const;
private:
    double m_real;  //實部
    double m_imag;  //虛部
};
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
//實現(xiàn)運(yùn)算符重載
complex complex::operator+(const complex &A) const{
    return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);//返回臨時對象
}
void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();//  運(yùn)行結(jié)果: 6.7 + 9.5i
    return 0;
}

可以看出:運(yùn)算符重載是通過函數(shù)實現(xiàn)的,它本質(zhì)上是函數(shù)重載。

運(yùn)算符重載格式:

返回值類型 operator 運(yùn)算符名稱 (形參表列){
//TODO:
}

operator是關(guān)鍵字,專門用于定義重載運(yùn)算符的函數(shù)。我們可以將`operator 運(yùn)算符名稱`這一部分看做函數(shù)名,對于上面的代碼,函數(shù)名就是operator+

即是:運(yùn)算符重載除了函數(shù)名不同,其他地方和函數(shù)沒有什么區(qū)別;

當(dāng)執(zhí)行c3 = c1 + c2;語句時,編譯器檢測到+號左邊(+號具有左結(jié)合性,所以先檢測左邊)是一個 complex 對象,就會調(diào)用成員函數(shù)operator+(),也就是轉(zhuǎn)換為下面的形式:

c3 = c1.operator+(c2);

c1 是要調(diào)用函數(shù)的對象,c2 是函數(shù)的實參

全局內(nèi)重載運(yùn)算符:

運(yùn)算符重載函數(shù)不僅可以作為類的成員函數(shù),還可以作為全局函數(shù)。利用友元函數(shù)來實現(xiàn)(獲取private屬性,歸屬于全局函數(shù)的應(yīng)用)

更改上述例子:

#include <iostream>
using namespace std;
class complex{
public:
    complex();
    complex(double real, double imag);
public:
    void display() const;
    //聲明為友元函數(shù)
    friend complex operator+(const complex &A, const complex &B);
private:
    double m_real;
    double m_imag;
};
complex operator+(const complex &A, const complex &B);
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
//在全局范圍內(nèi)重載+
complex operator+(const complex &A, const complex &B){
    complex C;
    C.m_real = A.m_real + B.m_real;
    C.m_imag = A.m_imag + B.m_imag;
    return C;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}

通過運(yùn)算符重載,擴(kuò)大了C++已有運(yùn)算符的功能,使之能用于對象,更人性了hhh;

tip: 非靜態(tài)成員函數(shù)后面加const(加到非成員函數(shù)或靜態(tài)成員后面會產(chǎn)生編譯錯誤,靜態(tài)和非靜態(tài)的區(qū)別就是,查看下面鏈接),表示成員函數(shù)隱含傳入的this指針為const指針,決定了在該成員函數(shù)中,任意修改它所在的類的成員的操作都是不允許的(因為隱含了對this指針的const引用);唯一的例外是對于mutable修飾的成員。加了const的成員函數(shù)可以被非const對象和const對象調(diào)用,但不加const的成員函數(shù)只能被非const對象調(diào)用。靜態(tài)函數(shù)和非靜態(tài)函數(shù)的區(qū)別、什么是mutable

運(yùn)算符重載的規(guī)則

  • 可以重載的運(yùn)算符:+ - * / % ^ & | ~ ! = < > += -= = /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , -> -> () [] new new[] delete delete[] ,自增自減運(yùn)算符的前置和后置形式都可以重載

長度運(yùn)算符sizeof、條件運(yùn)算符: ?、成員選擇符.和域解析運(yùn)算符::不能被重載。

  • 重載不能改變運(yùn)算符的優(yōu)先級和結(jié)合性,如+-*/等運(yùn)算符的優(yōu)先級不會被改變;
  • 運(yùn)算符重載函數(shù)不能有默認(rèn)的參數(shù),否則就改變了運(yùn)算符操作數(shù)的個數(shù)(比如+號默認(rèn)參數(shù)為1,結(jié)果肯定不對),這顯然是錯誤的(有的博客說重載函數(shù)要有遵循固定數(shù)量的參數(shù),和公認(rèn)的相同)
  • 運(yùn)算符重載函數(shù)既可以作為類的成員函數(shù),也可以作為全局函數(shù)

將運(yùn)算符重載函數(shù)作為類的成員函數(shù)時,二元運(yùn)算符的參數(shù)只有一個,一元運(yùn)算符不需要參數(shù)。之所以少一個參數(shù),是因為這個參數(shù)是隱含的,是這個類對象本身;如上面的this,通過 this 指針隱式的訪問 c1 的成員變量。

將運(yùn)算符重載函數(shù)作為全局函數(shù)時,二元操作符就需要兩個參數(shù),一元操作符需要一個參數(shù),而且其中必須至少有一個參數(shù)是對象,好讓編譯器區(qū)分這是程序員自定義的運(yùn)算符,防止程序員修改用于內(nèi)置類型的運(yùn)算符的性質(zhì),比如:

int operator + (int a,int b){//顯然錯誤,會造成歧義,改變內(nèi)置類型的運(yùn)算符的性質(zhì)(別人設(shè)過的東西你別用)
    return (a-b);
}

而如果上述的a或者b是一個對象,那么就是成立的;

同時,將運(yùn)算符重載函數(shù)作為全局函數(shù)時,一般都需要在類中將該函數(shù)聲明為友元函數(shù)。原因很簡單,該函數(shù)大部分情況下都需要使用類的 private 成員。

  • 箭頭運(yùn)算符->、下標(biāo)運(yùn)算符[ ]、函數(shù)調(diào)用運(yùn)算符( )、賦值運(yùn)算符=只能以成員函數(shù)的形式重載。

重載數(shù)學(xué)運(yùn)算符例子

實際開發(fā)中重載數(shù)學(xué)運(yùn)算符號非常常見,比如c++只是定義了復(fù)數(shù)的==,我們來實現(xiàn)復(fù)數(shù)的+,-,*,例子如下:

#include <iostream>
#include <cmath>
using namespace std;
//復(fù)數(shù)類
class Complex{
public:  //構(gòu)造函數(shù)
    Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
public:  //運(yùn)算符重載
    //以全局函數(shù)的形式重載?。。。。。。。。。。?    friend Complex operator+(const Complex &c1, const Complex &c2);
    friend Complex operator-(const Complex &c1, const Complex &c2);
    friend Complex operator*(const Complex &c1, const Complex &c2);
    friend Complex operator/(const Complex &c1, const Complex &c2);
    friend bool operator==(const Complex &c1, const Complex &c2);
    friend bool operator!=(const Complex &c1, const Complex &c2);
    //以成員函數(shù)的形式重載?。。。。。。。。。。?!
    Complex & operator+=(const Complex &c);
    Complex & operator-=(const Complex &c);
    Complex & operator*=(const Complex &c);
    Complex & operator/=(const Complex &c);
public:  //成員函數(shù)
    double real() const{ return m_real; }
    double imag() const{ return m_imag; }
private:
    double m_real;  //實部
    double m_imag;  //虛部
};
//重載+運(yùn)算符
Complex operator+(const Complex &c1, const Complex &c2){
    return 
    Complex c;
    c.m_real = c1.m_real + c2.m_real;
    c.m_imag = c1.m_imag + c2.m_imag;
    return c;
}
//重載-運(yùn)算符
Complex operator-(const Complex &c1, const Complex &c2){
    Complex c;
    c.m_real = c1.m_real - c2.m_real;
    c.m_imag = c1.m_imag - c2.m_imag;
    return c;
}
//重載*運(yùn)算符  (a+bi) * (c+di) = (ac-bd) + (bc+ad)i
Complex operator*(const Complex &c1, const Complex &c2){
    Complex c;
    c.m_real = c1.m_real * c2.m_real - c1.m_imag * c2.m_imag;
    c.m_imag = c1.m_imag * c2.m_real + c1.m_real * c2.m_imag;
    return c;
}
//重載/運(yùn)算符  (a+bi) / (c+di) = [(ac+bd) / (c2+d2)] + [(bc-ad) / (c2+d2)]i
Complex operator/(const Complex &c1, const Complex &c2){
    Complex c;
    c.m_real = (c1.m_real*c2.m_real + c1.m_imag*c2.m_imag) / (pow(c2.m_real, 2) + pow(c2.m_imag, 2));
    c.m_imag = (c1.m_imag*c2.m_real - c1.m_real*c2.m_imag) / (pow(c2.m_real, 2) + pow(c2.m_imag, 2));
    return c;
}
//重載==運(yùn)算符
bool operator==(const Complex &c1, const Complex &c2){
    if( c1.m_real == c2.m_real && c1.m_imag == c2.m_imag ){
        return true;
    }else{
        return false;
    }
}
//重載!=運(yùn)算符
bool operator!=(const Complex &c1, const Complex &c2){
    if( c1.m_real != c2.m_real || c1.m_imag != c2.m_imag ){
        return true;
    }else{
        return false;
    }
}
//重載+=運(yùn)算符,開始有&符號
Complex & Complex::operator+=(const Complex &c){
    this->m_real += c.m_real;
    this->m_imag += c.m_imag;
    return *this;//this就是一個指針,*解引用,返回的是this指向的對象
}
//重載-=運(yùn)算符
Complex & Complex::operator-=(const Complex &c){
    this->m_real -= c.m_real;
    this->m_imag -= c.m_imag;
    return *this;
}
//重載*=運(yùn)算符
Complex & Complex::operator*=(const Complex &c){
    this->m_real = this->m_real * c.m_real - this->m_imag * c.m_imag;
    this->m_imag = this->m_imag * c.m_real + this->m_real * c.m_imag;
    return *this;
}
//重載/=運(yùn)算符
Complex & Complex::operator/=(const Complex &c){
    this->m_real = (this->m_real*c.m_real + this->m_imag*c.m_imag) / (pow(c.m_real, 2) + pow(c.m_imag, 2));
    this->m_imag = (this->m_imag*c.m_real - this->m_real*c.m_imag) / (pow(c.m_real, 2) + pow(c.m_imag, 2));
    return *this;
}
int main(){
    Complex c1(25, 35);
    Complex c2(10, 20);
    Complex c3(1, 2);
    Complex c4(4, 9);
    Complex c5(34, 6);
    Complex c6(80, 90);
   
    Complex c7 = c1 + c2;
    Complex c8 = c1 - c2;
    Complex c9 = c1 * c2;
    Complex c10 = c1 / c2;
    cout<<"c7 = "<<c7.real()<<" + "<<c7.imag()<<"i"<<endl;
    cout<<"c8 = "<<c8.real()<<" + "<<c8.imag()<<"i"<<endl;
    cout<<"c9 = "<<c9.real()<<" + "<<c9.imag()<<"i"<<endl;
    cout<<"c10 = "<<c10.real()<<" + "<<c10.imag()<<"i"<<endl;
   
    c3 += c1;
    c4 -= c2;
    c5 *= c2;
    c6 /= c2;
    cout<<"c3 = "<<c3.real()<<" + "<<c3.imag()<<"i"<<endl;
    cout<<"c4 = "<<c4.real()<<" + "<<c4.imag()<<"i"<<endl;
    cout<<"c5 = "<<c5.real()<<" + "<<c5.imag()<<"i"<<endl;
    cout<<"c6 = "<<c6.real()<<" + "<<c6.imag()<<"i"<<endl;
   
    if(c1 == c2){
        cout<<"c1 == c2"<<endl;
    }
    if(c1 != c2){
        cout<<"c1 != c2"<<endl;
    }
   
    return 0;
}

運(yùn)行結(jié)果:

選擇是成員函數(shù)還是全局函數(shù)運(yùn)算符重載

看例子:

Complex(double real): m_real(real), m_imag(0.0){ }  //轉(zhuǎn)換構(gòu)造函數(shù)
//重載+號運(yùn)算符,設(shè)置成全局函數(shù)運(yùn)算符重載
Complex operator+(const Complex &c1, const Complex &c2)
.....
Complex c2 = c1 + 15.6;//正確
Complex c3 = 28.23 + c1;//正確

為什么要設(shè)置成全局運(yùn)算符呢?

因為如果設(shè)置成成員函數(shù),Complex c3 = 28.23 + c1;將會是錯誤的;

原理:因為是全局函數(shù),保證了 + 運(yùn)算符的操作數(shù)能夠被對稱的處理,存在轉(zhuǎn)換構(gòu)造函數(shù),編譯器在檢測到 Complex 和 double(小數(shù)默認(rèn)為 double 類型)相加時,會先嘗試將 double 轉(zhuǎn)換為 Complex,或者反過來將 Complex 轉(zhuǎn)換為 double(只有類型相同的數(shù)據(jù)才能進(jìn)行 + 運(yùn)算),如果都轉(zhuǎn)換失敗,或者都轉(zhuǎn)換成功(產(chǎn)生了二義性),才報錯。本例中,編譯器會先通過構(gòu)造函數(shù)Complex(double real);將 double 轉(zhuǎn)換為 Complex,再調(diào)用重載過的 + 進(jìn)行計算,整個過程類似于下面的形式:

設(shè)置成成員函數(shù):根據(jù)“+ 運(yùn)算符具有左結(jié)合性”這條原則,Complex c3 = 28.23 + c1會被轉(zhuǎn)換為Complex c3 = (28.23).operator+(c1),很顯然這是錯誤的,因為 double 類型并沒有以成員函數(shù)的形式重載 +。所以成員函數(shù)不能對此處理操作數(shù);

為什么成員函數(shù)中不能用轉(zhuǎn)換構(gòu)造函數(shù)處理數(shù)據(jù)28.23為Complex(28.23),而全局函數(shù)可以?

C++ 只會對成員函數(shù)的參數(shù)進(jìn)行類型轉(zhuǎn)換,而不會對調(diào)用成員函數(shù)的對象進(jìn)行類型轉(zhuǎn)換,因為設(shè)置為成員函數(shù),28.23不是函數(shù)的參數(shù),是擁有該函數(shù)的類對象,調(diào)用的將是28.23這個double對象的重載+,明顯是沒有的該函數(shù),會報錯;而全局函數(shù),那么調(diào)用的將是operator+(28.23, c1)這個函數(shù),那么28.23,c1都是函數(shù)的參數(shù),是可以調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)的。

注意ψ(`?′)ψ????:運(yùn)算符重載的初衷是給類添加新的功能,方便類的運(yùn)算,它作為類的成員函數(shù)是理所應(yīng)當(dāng)?shù)?,是首選的!

但是因為有處理對稱的需求,每個類都重載一下運(yùn)算符,過于麻煩了,所以允許采用全局函數(shù)重載。所以我們知道:參數(shù)具有邏輯的對稱性,我們采用全局函數(shù)定義;第一個(最左的)運(yùn)算對象不出現(xiàn)類型轉(zhuǎn)換,我們運(yùn)算符重載定義為成員函數(shù);

C++ 規(guī)定,箭頭運(yùn)算符->、下標(biāo)運(yùn)算符[ ]、函數(shù)調(diào)用運(yùn)算符( )、賦值運(yùn)算符=只能以成員函數(shù)的形式重載。

重載<<和>>運(yùn)算符

標(biāo)準(zhǔn)庫本身已經(jīng)對左移運(yùn)算符<<和右移運(yùn)算符>>分別進(jìn)行了重載,使其能夠用于不同數(shù)據(jù)的輸入輸出,但是輸入輸出的對象只能是 C++ 內(nèi)置的數(shù)據(jù)類型(例如 bool、int、double 等)和標(biāo)準(zhǔn)庫所包含的類類型(例如 string、complex、ofstream、ifstream 等)

有時候我們想重載輸入輸出符號,可以輸入輸出我們自己定義的類型,看下例,一樣采用對復(fù)數(shù)的重載,基于上面的例子,加多實現(xiàn)輸入輸出:

//complex類中定義輸入輸出為友函數(shù)(只能定義為友函數(shù)),供全局可以使用,因為重載函數(shù)中用到了 complex 類的 private 成員變量,定義為成員函數(shù)依據(jù)左結(jié)合性,會非常奇怪,>>的左邊需要一個complex類對象;
friend istream & operator>>(istream & in, complex & A);
friend ostream & operator<<(ostream & out, complex & A);

//重載輸入運(yùn)算符
istream & operator>>(istream & in, complex & A){
    in >> A.m_real >> A.m_imag;//輸入,基于標(biāo)準(zhǔn)庫的類;
    return in;//返回引用更方便再次使用,可以cin>>c1>>c2 ,連續(xù)輸入兩個對象;因為(cin>>c1)又是一個cin又可以cin>>c2;
}
//重載輸出運(yùn)算符
ostream & operator<<(ostream & out, complex & A){
    out << A.m_real <<" + "<< A.m_imag <<" i ";//輸出,基于標(biāo)準(zhǔn)庫的類
    return out;//與上同理
}
//main函數(shù)中:
complex c1, c2, c3;
cin>>c1>>c2;//具體邏輯:>>(cin, c1), >>(cin, c2)
c3 = c1 + c2;
cout<<"c1 + c2 = "<<c3<<endl;

輸入函數(shù)定義為全局函數(shù),相當(dāng)于:operator>>(cin , c);

重載[](下標(biāo)運(yùn)算符)

C++ 規(guī)定,下標(biāo)運(yùn)算符[ ]必須以成員函數(shù)的形式進(jìn)行重載,重載函數(shù)在類中的聲明如下:

返回值類型 & operator[ ] (參數(shù));

或者:

const 返回值類型 & operator[ ] (參數(shù)) const;

使用第一種聲明方式,[ ]不僅可以訪問元素,還可以修改元素。使用第二種聲明方式,[ ]只能訪問而不能修改元素。在實際開發(fā)中,我們應(yīng)該同時提供以上兩種形式,這樣做是為了適應(yīng) const 對象,因為通過 const 對象只能調(diào)用 const 成員函數(shù),如果不提供第二種形式,那么將無法訪問 const 對象的任何元素

例子:

#include <iostream>
using namespace std;
class Array{
public:
    Array(int length = 0);
    ~Array();
public:
    int & operator[](int i);
    const int & operator[](int i) const;
public:
    int length() const { return m_length; }
    void display() const;
private:
    int m_length;  //數(shù)組長度
    int *m_p;  //指向數(shù)組內(nèi)存的指針
};
Array::Array(int length): m_length(length){
    if(length == 0){
        m_p = NULL;
    }else{
        m_p = new int[length];
    }
}
Array::~Array(){
    delete[] m_p;
}
int& Array::operator[](int i){
    return m_p[i];
}
const int & Array::operator[](int i) const{//注意兩個const
    return m_p[i];
}
void Array::display() const{
    for(int i = 0; i < m_length; i++){
        if(i == m_length - 1){
            cout<<m_p[i]<<endl;
        }else{
            cout<<m_p[i]<<", ";
        }
    }
}
int main(){
    int n;
    cin>>n;
    Array A(n);
    for(int i = 0, len = A.length(); i < len; i++){
        A[i] = i * 5;
    }
    A.display();
   
    const Array B(n);
    cout<<B[n-1]<<endl;  //訪問最后一個元素
   
    return 0;
}

結(jié)果:

tip:const加在函數(shù)前后的區(qū)別

重載++和--

前置和后置++例子:

#include <iostream>
#include <iomanip>
using namespace std;
//秒表類
class stopwatch{
public:
    stopwatch(): m_min(0), m_sec(0){ }
public:
    void setzero(){ m_min = 0; m_sec = 0; }
    stopwatch run();  // 運(yùn)行
    stopwatch operator++();  //++i,前置形式
    stopwatch operator++(int);  //i++,后置形式,不寫參數(shù)名形式
    friend ostream & operator<<( ostream &, const stopwatch &);
private:
    int m_min;  //分鐘
    int m_sec;  //秒鐘
};
stopwatch stopwatch::run(){
    ++m_sec;
    if(m_sec == 60){
        m_min++;
        m_sec = 0;
    }
    return *this;
}
stopwatch stopwatch::operator++(){
    return run();
}
stopwatch stopwatch::operator++(int n){
    stopwatch s = *this; // 拷貝構(gòu)造
    run();
    return s; // 符合 用完再加的思想
}
ostream &operator<<( ostream & out, const stopwatch & s){
    out<<setfill('0')<<setw(2)<<s.m_min<<":"<<setw(2)<<s.m_sec;
    return out;
}
int main(){
    stopwatch s1, s2;
    s1 = s2++;
    cout << "s1: "<< s1 <<endl;
    cout << "s2: "<< s2 <<endl;
    s1.setzero();
    s2.setzero();
    s1 = ++s2;
    cout << "s1: "<< s1 <<endl;
    cout << "s2: "<< s2 <<endl;
    return 0;
}

operator++ (int n) 函數(shù)實現(xiàn)自增的后置形式,返回值是對象本身,但是之后(過了這個表達(dá)式)再次使用該對象時,對象自增了,所以在該函數(shù)的函數(shù)體中,先將對象保存,然后調(diào)用一次 run() 函數(shù),之后再將先前保存的對象返回(這個時候沒有自增)。在這個函數(shù)中參數(shù)n是沒有任何意義的,它的存在只是為了區(qū)分是前置形式還是后置形式。

結(jié)果:

重載new和delete

內(nèi)存管理運(yùn)算符 new、new[]、delete 和 delete[] 也可以進(jìn)行重載,其重載形式既可以是類的成員函數(shù),也可以是全局函數(shù)。一般情況下,內(nèi)建的內(nèi)存管理運(yùn)算符就夠用了,只有在需要自己管理內(nèi)存時才會重載

new:

成員函數(shù)形式:

void * className::operator new( size_t size ){
    //TODO:
}

全局函數(shù)形式:

void * operator new( size_t size ){
    //TODO:
}

可以看出:兩種重載形式的返回值相同,都是void *類型,并且都有一個參數(shù),為size_t類型。在重載 new 或 new[] 時,無論是作為成員函數(shù)還是作為全局函數(shù),它的第一個參數(shù)必須是 size_t 類型。size_t 表示的是要分配空間的大小,對于 new[] 的重載函數(shù)而言,size_t 則表示所需要分配的所有空間的總和。(size_t 在頭文件 中被定義為typedef unsigned int size_t;,也就是無符號整型)

重載函數(shù)也可以有其他參數(shù),但都必須有默認(rèn)值,并且第一個參數(shù)的類型必須是 size_t。

delete:

成員函數(shù):

void className::operator delete( void *ptr){
    //TODO:
}

全局函數(shù):

void operator delete( void *ptr){
    //TODO:
}

兩種重載形式的返回值都是 void 類型,并且都必須有一個 void 類型的指針作為參數(shù),該指針指向需要釋放的內(nèi)存空間;

當(dāng)我們以類成員重載了new和delete函數(shù),使用例子:

C * c = new C;  //分配內(nèi)存空間
//TODO:
delete c;  //釋放內(nèi)存空間

如果類中沒有定義 new 和 delete 的重載函數(shù),那么會自動調(diào)用內(nèi)建的 new 和 delete 運(yùn)算符;

例子:

#include<iostream>
using namespace std;

class Foo
{
    public:
        int _id;
        long _data;
        string _str;
    public:
        Foo():_id(0){cout<<"default ctor.this="<<this<<" id="<<_id<<endl;}
        Foo(int i):_id(i){cout<<"ctor.this="<<this<<" id="<<_id<<endl;}
        ~Foo() {cout<<"dtor.this="<<this<<" id="<<_id<<endl;}
        static void* operator new(size_t size);
        static void operator delete(void* pdead,size_t size);
        static void* operator new[](size_t size);
        static void operator delete[](void* pdead,size_t size);
};

void* Foo::operator new(size_t size)
{
    Foo* p = (Foo *)malloc(size);
    cout<<"調(diào)用了Foo::operator new"<<endl;
    return p;
}

void Foo::operator delete(void *pdead,size_t size)
{
    cout<<"調(diào)用了Foo::operator delete"<<endl;
    free(pdead);
}
void* Foo::operator new[](size_t size)
{
    Foo* p  = (Foo*)malloc(size);
    cout<<"調(diào)用了Foo::operator new[]"<<endl;
    return p;
}

void Foo::operator delete[](void *pdead, size_t size)
{
    cout<<"調(diào)用了Foo::operator delete[]"<<endl;
    free(pdead);
}

int main()
{
    Foo* pf = new Foo(7);
    Foo* pf1 = new Foo[2];
    delete pf;
    delete[] pf1;
}

結(jié)果:

重載()

直接看例子:將 double類型強(qiáng)制轉(zhuǎn)換運(yùn)算符 進(jìn)行重載

#include <iostream>
using namespace std;
class Complex
{
    double real, imag;
public:
    Complex(double r = 0, double i = 0) :real(r), imag(i) {};
    operator double() { return real; }  //重載強(qiáng)制類型轉(zhuǎn)換運(yùn)算符 double
};
int main()
{
    Complex c(1.2, 3.4);
    cout << (double)c << endl;  //輸出 1.2
    double n = 2 + c;  //等價于 double n = 2 + c. operator double()
    cout << n;  //輸出 3.2
}

類型強(qiáng)制轉(zhuǎn)換運(yùn)算符是單目運(yùn)算符,也可以被重載,但只能重載為成員函數(shù),不能重載為全局函數(shù)。經(jīng)過適當(dāng)重載后,(類型名)對象這個對 對象 進(jìn)行強(qiáng)制類型轉(zhuǎn)換的表達(dá)式就等價于對象.operator 類型名(),即變成對運(yùn)算符函數(shù)的調(diào)用。

重載強(qiáng)制類型轉(zhuǎn)換運(yùn)算符時,不需要指定返回值類型,因為返回值類型是確定的,就是運(yùn)算符本身代表的類型,在這里就是 double。

重載后的效果是,第 13 行的(double)c等價于c.operator double()

有了對 double 運(yùn)算符的重載,在本該出現(xiàn) double 類型的變量或常量的地方,如果出現(xiàn)了一個 Complex 類型的對象,那么該對象的 operator double 成員函數(shù)就會被調(diào)用,然后取其返回值使用。

例如第 14 行,編譯器認(rèn)為本行中c這個位置如果出現(xiàn)的是 double 類型的數(shù)據(jù),就能夠解釋得通,而 Complex 類正好重載了 double 運(yùn)算符,因而本行就等價于:

double n = 2 + c.operator double();

標(biāo)題名稱:初識C++05:運(yùn)算符重載
轉(zhuǎn)載源于:http://chinadenli.net/article32/dsoijpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、標(biāo)簽優(yōu)化、網(wǎng)站制作、網(wǎng)站設(shè)計公司、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司