精选文章

Android下使用TCPDUMP抓包Wireshark分析数据 如果想分析Android下某个APP的网络数据交互,需要在Android手机上抓包,最常用的抓包工具非tcpdump莫属,用tcpdump生成Wireshark识别的pcap文件,然后将pcap文件下载到电脑上,用电脑上的Wireshark加载pcap文件,通过Wireshark分析tcpdump抓取的数据。...

继续阅读

Mac下部署Android开发环境附加NDK 作为开发者,我们深有体会,不管是进行什么开发,为了部署开发环境,我们往往需要折腾很长时间、查阅很多资料才能完成,而且这次折腾完了,下次到了另一台新电脑上又得重新来过,整个部署过程记得还好,要是不记得又得重新开始,而且遇到Android这种GFW阻隔了开发资源下载链接的环境部署,又尤其浪费时间。所以这也是我写下这篇教程的初衷跟动力源泉,希望大家参考了这篇教程以后可以轻轻松松在Mac系统下将Android环境部署好。...

继续阅读

稍顯嚴肅的台中 坦白說,留在腦海中的台中影像並不多,來台灣之前在Booking上只訂到了台中的一家青旅,第一次住青旅有些不習慣,幹什麼都放不開。 同屋的一個男生是台灣人,不過一年中四分之三的時間在上海跟北京,這麼說來跟我還是比較有共同話題的。得之我準備花15天的時間環島,覺得太倉促了,他們大學時期花一個半月的時間也不見得能將台灣島給逛完。我只能無奈地表示,兩岸允許的簽證時間有限,自己的空閒時間更有限,只能用打卡式的旅行了,我深知正真地旅行應該慢下來,融入當地的環境,感受他們的風土人情,但第一次只能這樣作罷,以後換成民進黨上台,形勢會變成怎樣還不得而知,能否再過來還是個未知數。而我一向信奉的人生格言是秉燭夜遊,活在當下,所以,理解自己吧。...

继续阅读

為之留戀的新竹 來新竹之前本沒有對她有過高的期待,慢慢對她加分要從桃園火車站出發前往新竹開始。 在桃園火車站的候車月台上,有醒目的旅遊資料發放處,這上面的擺放的全是新竹的旅遊宣傳資料,關鍵的是資料做得非常簡潔易懂,而接下來一天的新竹之行就全部是依據這份寶典的指引來完成的。...

继续阅读

從桃園開始台灣之行 初到台灣恰逢華夏銀行系統升級,特意準備的華夏銀聯卡在桃園機場沒能派上用場,只好用建行在機場5000塊,算下來是很不划算的,但是沒辦法,誰叫我出機場就得花錢呢。 從機場打車到桃園的酒店,花了將近六百塊新台幣,到酒店時五點多,天已經漸亮了,洗漱完等到七點吃過早餐就開始補覺囉,一覺醒來已是中午,帶著換下來的衣服外出找自助洗衣店,順便覓食。...

继续阅读

  • Prev
  • Next

C++运算符重载

文章分类 : C++

C++自带的运算符,像加减乘除,只支持一些基本的类型,很多时候,我我们需要用运算符实现一些复杂或抽象类型的计算,计算原理或形式虽然符合该计算符,但类型不支持,比如定义一个包含实部跟虚部的复数类,标准C++要实现该类对象的加减乘除运算显然不行,但是我们可以通过C++运算符重载的办法来实现这一功能。

下面就以此例,来抽象出一个复数类,并实现针对该类的加减乘除运算的重载函数。
我们知道,若复数z1=a+bi,z2=c+di,其中a,b,c,d∈R,则
z1±z2=(a+bi)±(c+di)=(a±c)+(b±d)i,
(a+bi)·(c+di)=(ac-bd)+(bc+ad)i,
(a+bi)÷(c+di)=(ac+bd)/(c^2+d^2) +(bc-ad)i/(c^2+d^2)
所以不难得出该类复数抽象出来的类以及复数加减乘除运算符重载如下:

#include <iostream>
using namespace std;
class Plural {
        private:
                double  real;   //实部
                double  imag;   //虚部
        public:
                void display()
                {
                        cout << real; 
                        if (imag > 0)
                                cout << "+";
                        cout << imag << 'i' << endl;
                }
                Plural()
                {
                        real = 0;
                        imag = 0;
                }
                Plural(double a, double b)
                {
                        real = a;
                        imag = b;
                }
                Plural operator + (const Plural &a)
                {
                        Plural  temp;
                        temp.real = real + a.real;
                        temp.imag = imag + a.imag;
                        return  temp;
                }
                Plural operator - (const Plural &a)
                {
                        Plural  temp;
                        temp.real = real - a.real;
                        temp.imag = imag - a.imag;
                        return  temp;
                }
                Plural operator * (const Plural &a)
                {
                        Plural  temp;
                        temp.real = real * a.real - imag * a.imag;
                        temp.imag = imag * a.real + real * a.imag;
                        return  temp;
                }
                Plural operator / (const Plural &a)
                {
                        Plural  temp;
                        temp.real = (real * a.real + imag * a.imag) / ( a.real *  a.real + a.imag * a.imag);
                        temp.imag = (imag * a.real - real * a.imag) / (a.real * a.real + a.imag * a.imag);
                        return  temp;
                }
};

int main(void)
{
        Plural  a(1, -2);
        Plural  b(-3, 4);
        Plural  c;

        cout << "a = ";
        a.display();

        cout << "b = ";
        b.display();

        c = a + b;
        cout << "a + b = ";
        c.display();

        c = a - b;
        cout << "a - b = ";
        c.display();

        c = a * b;
        cout << "a * b = ";
        c.display();

        c = a / b;
        cout << "a / b = ";
        c.display();

        return 0;
}
运行结果:
a = 1-2i
b = -3+4i
a + b = -2+2i
a - b = 4-6i
a * b = 5+10i
a / b = -0.44+0.08i

C++编译器把a+b解释为a.operator(b)以后再调用,它返回一个临时变量temp然后赋值给c对象。

1、运算符重载与一般函数重载的区别:

区别主要在参数个数跟是否必须有返回值上。C++运算符所能操作的操作数是约定好了的,在二元运算的时候只能指定两个参数,一元运算的时候只能指定一个参数,而函数重载没有参数个数限制。函数重载对返回值没有限制,可有可无,但是一个运算的结果通常要供别的运算符使用或者能赋值给一个变量或对象,所以必须指定一个非void的返回类型(赋值运算符除外)。

2、友元运算符与类运算符的取舍:

通常情况下,由于友元运算符不要求第一个参数一定要为某个类的对象,故二元运算符重载为一个友元运算符比重载为成员运算符便于使用。一元运算符重载为成员函数最恰当,重载为友元也可以,但增1减1运算符重载为友元运算符时必须使用引用参数。

3、赋值运算符重载:

赋值(=)是二元运算符,赋值运算符重载与拷贝构造函数相似而又不同:它们都必须是类的成员函数而不允许是友元函数,也不能被派生类继承,都有且仅有一个参数;赋值运算符重载函数允许有返回值,而拷贝构造函数以及所有构造函数则不允许。
下面是String类的拷贝构造函数跟赋值重载函数:

String::String(const String &other)
{
        int length = strlen(other.m_data);
        m_data = new char[length+1];
        strcpy(m_data, other.m_data);
}
//赋值运算符重载函数
String & String::operate =(const String &other)
{
        if(this == &other)
                return *this;
        delete [] m_data;
        int length = strlen( other.m_data );
        m_data = new char[length+1];
        strcpy( m_data, other.m_data );
        return *this;
}
或
void String::operate =(const String &other)
{
        if(this == &other)
                return ;
        delete [] m_data;
        int length = strlen( other.m_data );
        m_data = new char[length+1];
        strcpy( m_data, other.m_data );
}

4、下标运算符重载:

它是一个双目运算符,第一个运算符是数组名,第二个运算符是数组下标,C++不允许将其作为友元函数来定义,它之允许是非静态的成员函数,其一般定义形式如下:
T1 T::operator[](T2);

5、增1减1运算符重载:

对类T的对象a,下表列出其增1和减1运算符重载函数的定义和调用形式:
运算符名    成员函数定义形式    外部函数定义形式      调用形式
前缀++    T operator ++ ()             T operator ++ (T&)            ++a
后缀++    T operator ++ (int)           T operator ++ (T&,int)      a++
前缀–   T operator — ()             T operator — (T&)            –a
后缀–   T operator — (int)       T operator — (T&,int)      a–

6、类型转换运算符重载:

类型转换是c语言中的一个关键特征,c++提供两种方法来自动地处理类型转换。第一种是建立类的构造函数。转换构造函数可以将外来类型转换成类的一个对象。第二中是建立转换运算符重载函数,它可以将一个对象自身的类型转换为其他类型。定义一个转换函数使用关键字operator,后跟要转换的类型的名字。转换函数有以下限制:
(1).转换函数不能带任何参数,并且总是成员函数。
(2).不能说明类型转换函数的返回类型。隐含的返回类型是要转换的类型。在函数体中,适当的值必须返回。转换函数也可以通过显示类型转换表达式被调用,或使用名字直接调用。

除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。

本文地址:https://www.cpplive.com/html/580.html

这里因为你的留言而存在!!!

You must be logged in to post a comment.