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、生成一个临时对象作为函数的返回结果。

相关内容