C++拷貝構造函數以及運算符重載例子 (Linux 下編譯)

裏定義一個複數的類,並演示了它的用法

複數類 COMPLEX 的定義頭文件:complex.h
-------------------------------------------------------
class COMPLEX
{
public:
        COMPLEX(double r=0, double i=0);                      //默認構造函數


        COMPLEX(const COMPLEX &other);                   //拷貝構造函數
        ~COMPLEX();                                                       //析構函數
        void print();                                                            //打印複數
        COMPLEX operator +(const COMPLEX &other); //重載加法運算符(二元)
        COMPLEX operator -(const COMPLEX &other);   //重載減法運算符(二元)
        COMPLEX operator -( );                                        //重載求負運算符(一元)
        COMPLEX operator =(const COMPLEX &other); //重載賦值運算符(二元)
protected:
        double real;                                                           //複數的實部
        double image;                                                       //複數的虛部
};
-------------------------------------------------------

複數類 COMPLEX 的實現文件:complex.cpp
-------------------------------------------------------
#include <iostream>
#include "complex.h"
using namespace std;

//默認構造函數
COMPLEX::COMPLEX(double r, double i)
{
        real = r;
        image = i;
        cout<<"Default Constructing real: "<<r<<", image: "<<i<<" .\n";
        return;
}

//拷貝構造函數
COMPLEX::COMPLEX(const COMPLEX &other)
{
        real = other.real;
        image = other.image;
        cout<<"Copy Constructing real: "<<other.real<<", image: "<<other.image<<" .\n";
        return;
}

//析構函數
COMPLEX::~COMPLEX()
{
        cout<<"Destructing real: "<<real<<", image: "<<image<<" .\n";
        return;
}

//打印複數
void COMPLEX::print()
{
        cout<<real;
        if (image > 0)
        {
                cout<<"+"<<image<<"i";
        }
        else if (image < 0)
        {
                cout<<image<<"i";
        }
        cout<<"\n";
        return;
}

//重載加法運算符(二元)
COMPLEX COMPLEX::operator +(const COMPLEX &other)
{
        COMPLEX temp;

        temp.real = real + other.real;
        temp.image = image + other.image;
        cout<<"----- operator x + y start -----.\n";
        cout<<"this->real: "<<real<<", this->image: "<<image<<" .\n";
        cout<<"other.real: "<<other.real<<", other.image: "<<other.image<<" .\n";
        cout<<"temp.real: "<<temp.real<<", temp.image: "<<temp.image<<" .\n";
        cout<<"----- operator x + y end -----.\n";
        return temp;
}

//重載減法運算符(二元)
COMPLEX COMPLEX::operator -(const COMPLEX &other)
{
        COMPLEX temp;

        temp.real = real - other.real;
        temp.image = image - other.image;
        cout<<"----- operator x - y start -----.\n";
        cout<<"this->real: "<<real<<", this->image: "<<image<<" .\n";
        cout<<"other.real: "<<other.real<<", other.image: "<<other.image<<" .\n";
        cout<<"temp.real: "<<temp.real<<", temp.image: "<<temp.image<<" .\n";
        cout<<"----- operator x - y end -----.\n";
        return temp;
}

//重載求負運算符(一元)
COMPLEX COMPLEX::operator -()
{
        COMPLEX temp;

        temp.real = -real;
        temp.image = -image;
        cout<<"----- operator -x start -----.\n";
        cout<<"this->real: "<<real<<", this->image: "<<image<<" .\n";
        cout<<"temp.real: "<<temp.real<<", temp.image: "<<temp.image<<" .\n";
        cout<<"----- operator -x end -----.\n";
        return temp;
}

//重載賦值運算符(二元)
COMPLEX COMPLEX::operator =(const COMPLEX &other)
{
        cout<<"----- operator x = y start -----.\n";
        cout<<"other.real: "<<other.real<<", other.image: "<<other.image<<" .\n";
        cout<<"this->real: "<<real<<", this->image: "<<image<<" .\n";
        real = other.real;
        image = other.image;
        cout<<"other.real: "<<other.real<<", other.image: "<<other.image<<" .\n";
        cout<<"this->real: "<<real<<", this->image: "<<image<<" .\n";
        cout<<"----- operator x = y end -----.\n";
        return *this;               //這裏返回的是當前對象,*this表示取指向當前對象指針的值,也就是當前對象
                                         //實際上這裏返回的是一個當前對象的副本,該對象副本通過拷貝構造函數創建
}
-------------------------------------------------------

演示覆數類 COMPLEX 的用法文件:main.cpp
-------------------------------------------------------
#include <iostream>
#include "complex.h"

using namespace std;

int main()
{
        cout<<"COMPLEX c1(1,2);\n";
        COMPLEX c1(1,2);                    //定義一個值爲 1+2i 的複數
        cout<<"COMPLEX c2(2);\n";
        COMPLEX c2(2);                       //定義一個值爲 2 的複數
        cout<<"COMPLEX c3(c1);\n";
        COMPLEX c3(c1);                     //用拷貝構造函數創建一個值與c1相同的新複數c3

        cout<<"\nc3.print();\n";
        c3.print();                                  //打印c3原來的值

        cout<<"\nc1 = c1 + c2 + c3;\n";
        c1 = c1 + c2 + c3;                     //將c1加上c2再加上c3賦值給c1

        cout<<"\nc2 = -c3;\n";
        c2 = -c3;                                    //將c3求負後賦值給c2

        cout<<"\nc3 = c2 - c1;\n";
        c3 = c2 - c1;                             //將c2減去c1賦值給c3

        cout<<"\nc3.print();\n";
        c3.print();                                 //打印運算後c3的值
        cout<<endl;

        return 0;
}
-------------------------------------------------------

Linux 下的Makefile文件內容
-------------------------------------------------------
exe=complex

all: $(exe).o main.o
        g++ -o $(exe) main.o $(exe).o
main.o: main.cpp $(exe).h
        g++ -g -c $< -o $@
$(exe).o: $(exe).cpp $(exe).h
        g++ -g -c $< -o $@

.PHONY: clean

clean:
        rm -rf $(exe) *.o
-------------------------------------------------------
編譯程序:make
執行程序:./complex
執行結果:
-------------------------------------------------------
COMPLEX c1(1,2);
Default Constructing real: 1, image: 2 .           //調用默認構造函數創建對象c1,值爲:1+2i
COMPLEX c2(2);
Default Constructing real: 2, image: 0 .           //調用默認構造函數創建對象c2,值爲:2
COMPLEX c3(c1);
Copy Constructing real: 1, image: 2 .              //調用拷貝構造函數創建對象c3,值爲:1+2i

c3.print();
1+2i                                                                 //打印c3原來的值爲:1+2i

c1 = c1 + c2 + c3;
Default Constructing real: 0, image: 0 .          //調用默認構造函數創建臨時對象temp1,值爲:0
----- operator x + y start -----.                         //開始計算c1+c2,這個是調用c1的 “+” 運算符函數
this->real: 1, this->image: 2 .                         //c1,通過this指針隱式地將c1傳遞給c1的“+”運算符函數
other.real: 2, other.image: 0 .                        //c2,將c2傳遞給c1的“+”運算符函數
temp.real: 3, temp.image: 2 .                        //相加的結果保存在臨時對象temp1中,所以temp1值爲:3+2i
----- operator x + y end -----.                        //c1+c2計算結束,將結果temp1返回調用處
Default Constructing real: 0, image: 0 .   //調用默認構造函數創建臨時對象temp2,值爲:0
----- operator x + y start -----.                  //開始計算temp1+c3,這個是調用temp1的 “+” 運算符函數
this->real: 3, this->image: 2 .          //temp1,通過this指針隱式地將temp1傳遞給temp1的“+”運算符函數
other.real: 1, other.image: 2 .         //c3,將c3傳遞給temp1的“+”運算符函數
temp.real: 4, temp.image: 4 .          //相加的結果保存在臨時對象temp2中,所以temp2值爲:4+4i
----- operator x + y end -----.           //temp1+ c3計算結束,將結果temp2返回調用處
----- operator x = y start -----.          //開始做賦值運算:c1 = temp2;這裏調用c1的“=”運算符函數
other.real: 4, other.image: 4 .         //賦值前temp2的值爲:4+4i
this->real: 1, this->image: 2 .          //賦值前c1的值爲:1+2i
other.real: 4, other.image: 4 .         //賦值後temp2的值不變,依然爲:4+4i
this->real: 4, this->image: 4 .          //賦值後c1的值爲:4+4i
----- operator x = y end -----.           //賦值運算結束,返回當前對象的副本,這裏*this就是c1了
Copy Constructing real: 4, image: 4 . //通過拷貝構造函數創建c1的一個副本返回,c1副本的值爲:4+4i
Destructing real: 4, image: 4 .             //析構c1的副本
Destructing real: 4, image: 4 .             //析構temp2
Destructing real: 3, image: 2 .             //析構temp1

c2 = -c3;
Default Constructing real: 0, image: 0 . //調用默認構造函數創建臨時對象teMP3,值爲:0
----- operator -x start -----.                      //開始計算 -c3 ,這個是調用c3的 “-” 求負運算符函數
this->real: 1, this->image: 2 .                  //求負前c3的值爲:1+2i
temp.real: -1, temp.image: -2 .               //求負後將其結果保存在臨時對象teMP3中,temp3的值爲:-1-2i
----- operator -x end -----.                      // -c3 計算結束,將teMP3返回到調用處
----- operator x = y start -----.                //這裏是賦值運算:c2 = teMP3; 這裏調用c2的“=”,過程同上
other.real: -1, other.image: -2 .
this->real: 2, this->image: 0 .                //賦值前c2的值爲:2
other.real: -1, other.image: -2 .
this->real: -1, this->image: -2 .             //賦值後c2的值爲:-1-2i
----- operator x = y end -----.
Copy Constructing real: -1, image: -2 . //通過拷貝構造函數創建c2的一個副本返回,c2副本的值爲:-1-2i
Destructing real: -1, image: -2 .             //析構c2的副本
Destructing real: -1, image: -2 .             //析構teMP3

c3 = c2 - c1;
Default Constructing real: 0, image: 0 . //調用默認構造函數創建臨時對象teMP4,值爲:0
----- operator x - y start -----.                  //開始計算 c2 -c1 ,這個是調用c2的 “-” 減運算符函數
this->real: -1, this->image: -2 .               //c2,通過this指針隱式地將c2傳遞給c2的“-”減運算符函數
other.real: 4, other.image: 4 .                //c1,將c1傳遞給c2的“-”減運算符函數
temp.real: -5, temp.image: -6 .              //相減的結果保存在臨時對象teMP4中,所以temp4值爲:-5-6i
----- operator x - y end -----.                  //c2 - c1計算結束,將結果teMP4返回調用處
----- operator x = y start -----.                //這裏是賦值運算:c3 = teMP4; 這裏調用c3的“=”,過程同上
other.real: -5, other.image: -6 .
this->real: 1, this->image: 2 .                //賦值前c3的值爲:1+2i
other.real: -5, other.image: -6 .
this->real: -5, this->image: -6 .             //賦值後c3的值爲:-5-6i
----- operator x = y end -----.
Copy Constructing real: -5, image: -6 . //通過拷貝構造函數創建c3的一個副本返回,c3副本的值爲:-5-6i
Destructing real: -5, image: -6 .             //析構c3的副本
Destructing real: -5, image: -6 .             //析構teMP4

c3.print();
-5-6i                                                      //經過上述計算後,打印c3的值爲:-5-6i

Destructing real: -5, image: -6 .            //析構c3
Destructing real: -1, image: -2 .            //析構c2
Destructing real: 4, image: 4 .               //析構c1
-------------------------------------------------------

從上述結果可以總結出,拷貝構造函數主要在以下3種情況下起初始化作用
1、在聲明語句中用一個對象初始化另一個對象
2、將一個對象作爲參數按值調用方式傳遞給另一個對象時生成對象副本
3、生成一個臨時對象作爲函數的返回結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章