面向对象编程(38)

运算符重载

与函数重载类似,C++ 的运算符也可以指定为其他的特定功能。比如:cout  cin 的 <<  >> 就是运算符重载的实例。在实际应用中也会有很多场景:矩阵运算、向量运算、复数运算等等,虽然可以用函数来实现,运算符重载可以提高程序的可读性。

运算符重载:由关键字 operator 和其后要重载的运算符符号构成的。语法:

函数类型 operator 操作符(参数列表);
#include<iostream>
using namespace std;
class complex
{
public: 
	complex(){}
	complex(double x,double y){this->real=x;this->imag=y;}
	complex operator + (complex &x)
	{
		complex t;
		t.real=this->real+x.real;
		t.imag=this->imag+x.imag;
		return t;
	}
	
	double real;
	double imag;
};

int main()
{	
	complex a(1.2,5.6),b(3.5,6.4);
	a=a+b;
	cout<<a.real<<"   "<<a.imag<<endl;
	return 0;
}

1、运算符重载的参数个数不能随意修改,定义成类的成员函数(可以是静态和普通),也可以定义成全局,普通成员函数默认对象(this)参与运算(少一个参)

静态成员函数(全局函数类似):

	static complex operator + (complex &x,complex &y)
	{		
		complex t;
		t.real=x.real+y.real;
		t.imag=x.imag+y.imag;
		return t;
	}

2、不管是运算符重载,还是其他情况下,在对象作为参数的时候要特别注意 引用 的使用,函数调用中,实参要赋值给形参,也就是存在对象赋值,引用则可以避免这种情况。

3、“ . " (成员运算符,调用成员变量或者函数 )、“ :: " ( 作用域 )、“ ?:" (条件运算符)、“sizeof" (求字节运算符)等不能重载。

4、运算符参数类型可以根据情况设计:

complex operator + (int &x)
{
	complex t;
	t.real=this->real+x;
	t.imag=this->imag+x;
	return t;
}

调用时,要用变量(参数用了引用);

5、++  --  有前后两种运算,为了区别,前运算重载函数默认不带参,而后运算则指定必须添加一个int类型的参数:

    complex operator ++ (int x) //前运算
	{	
		//操作尽量对this操作,避免赋值
		return *this;
	}
	complex operator ++ () //后运算
	{	
		return *this;
	}

赋值与拷贝构造函数

对象、结构体赋值与其他数据类型不同,需要对每个分量进行赋值。如果没有重载赋值运算符,系统自动生成一个默认的,实现对分量的拷贝。

拷贝构造函数则是构造函数的一种,原型是: ClassType(const ClassType &);  

#include<iostream>
using namespace std;
class complex
{
public: 
	complex(){}     //无参构造函数
	complex(double x,double y) //构造函数重载
	{
		this->real=x;
		this->imag=y;
	}
	complex(const complex &x)//拷贝构造函数
	{
		this->real=x.real;
		this->imag=x.imag;
	}
	double real;
	double imag;
};

int main()
{
	complex x; //调用无参
	complex y(1.5,2.4);//调用重载的构造函数
	complex z(y); //调用拷贝构造函数
	x=z; //调用系统默认的赋值运算
	return 0;
}

1、常量引用,const 修饰引用的对象可以避免对引用值的修改;

2、指针常量本质是常量,与整型常量一样,不能修改它的值:int * const p = &a;   (常量定义的时候必须初始化),表明指针p保存a变量的地址,p不能再指向其他变量了(常量);

定义: int a,b;   int * const p = &a;  

p = &b; (错误 ,不能修改值)      *p=10;   (正确,可以修改变量的值)

3、常量指针本质是指针变量,它保存常量或者变量的地址,不能通过指针去修改变量的值(看成是常量),如:

定义:const int *p ;     int a;  const int b=20;   

p  =  &a  ;    *p =5 ;(错误,不能通过p修改a的值)     a =10;    (正确)

p  =  &a  ;   p=&b;   (正确,p是指针变量,可以修改值)

4、还可以写成:const int * const p = &a; 则既不能修改p的值(指向其他变量),又不允许修改指向的变量的值。

5、深拷贝与浅拷贝,这个概念对C/C++程序员基本上比较好理解,而其他不包含指针的高级语言就相对比较麻烦:这里涉及到指针,区别比较容易理解。所谓浅拷贝只是对指针赋值,而深拷贝则是针对内容进行复制;找了一个例子:

#include <iostream>
using namespace std;
class A
{
public:
    A(int _size) : size(_size){ data = new int[size]; } //假如其中有一段动态分配的内存
    int Get_Val() {return *data;}
    int *Get_Val_add() { return data; }
    A() {}
    A( const A& _A) : size(_A.size){ data = new int[size]; } //深拷贝
    ~A(){delete[] data; data = NULL; } //析构时释放资源
public:
    int *data;
    int size;
};
int main()
{
    A a(5);
    A b(a);
	cout << a.data << endl;
    cout << b.data << endl;
    return 0;
}

很明显看到深拷贝是重新new了空间,data值不同。如果屏蔽深拷贝函数(系统默认)则data项相同,同时,程序会报错(a、b销毁时都调用析构函数,执行了两次delete)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值