c++运算符重载(1) -- 数学运算符重载

运算符重载

1) 简述 

运算符我们在程序中经常使用,数学运算符,赋值运算符,比较运算符等。我们可以使用这些运算符对一些基本类型(int,float,double等)进行运算。但是,是没有办法对自定义的类型进行运算的。

但是,如果我们想要对我们自定义的数据类型进行运算怎么办呢? 

 比如,我们定义一个类,创建两个类对象,我们直接对这两个类对象进行运算,如果直接运算是做不到的,这时候就需要我们使用运算符重载函数来实现了。

2)运算符重载函数

运算符重载函数可以有两种形式,成员函数全局函数。 

 成员函数:  编译器会自动传入一个调用此函数的对象,所以使用成员函数可以少传一个参数。

全局函数:   需要传入所有参数。 

3)运算符重载 

一: 重载的运算符

重载的运算符一般都为二元或者一元的。 

对于运算符重载函数,一元只需要一个参数(调用函数的一方),二元需要两个(调用函数的一方和参与运算的一方)。

二: 对于谁调用重载函数

 在程序中,对于一元运算符,调用函数的是参与运算的, 对于二元运算符,调用函数的是运算符左侧的函数。

三: 重载函数的参数个数

成员运算符重载函数:          一元:   没有参数    二元:  一个参数 

全局友元运算符重载函数:   一元:  一个参数   二元:  两个参数 

四:   哪些运算符不可以重载

c++规定,赋值运算符=,x下标运算符[],函数调用运算符(),箭头运算符->只能在函数类内部作为成员函数进行重载。 

五:   哪些运算符只能在类中重载

长度运算符sizeof, 条件运算符:?,成员选择符.,域解析运算符:: 是不能够进行重载的。

其余的运算符都可以重载。(但是有些不常用) 

六:   重载后运算符的优先级是否修改

我们在运算的时候,运算符是有优先级的, 2+5*8是先计算乘法。 

运算符重载不会改变运算符的优先级。 

数学运算符重载 

 对+,-,*,/等数学运算符进行重载。

 1. 使用成员函数进行重载:

class Human {
public:
	Human(int age, int salary, const char* name);
	Human operator+(const Human& man);

	int getAge()const;
private:
	int age;
	int salary;
	string name;
};

int main(void) {
	Human man1(18,15000,"ABC");
	Human man2(19, 20000, "BCD");

	// Human man3 = man1.operator+(man2);
	Human man3 = man1 + man2;
    
	cout << man3.getAge() << endl;  // 37,man3是man1和man2两个对象年龄的和

	system("pause");

	return 0;
}

Human::Human(int age, int salary, const char* name)
{
	this->name = name;
	this->salary = salary;
	this->age = age;
}

/*
  对象相加的本质还是对其内部的基本类型的数据进行相加,
  所以,相加的时候是按照我们指定的相应规则进行相加的。

  此处只需要对Human类对象的年龄进行相加
*/
Human Human::operator+(const Human& man)
{
	int age_tmp = man.age + this->age;

	return Human(age_tmp, man.salary, (man.name).c_str());
}

int Human::getAge() const
{
	return age;
}

上面的代码是使用局部函数实现+运算符的重载。 

1)代码分析: 

 1.  使用运算符重载函数,对类对象进行相加,其实是对其内部的相应数据进行相加,有些数据不需要相加,所以我们运算符重载函数需要根据一定的规则对相应数据进行运算

2.   上面代码,我们定义了Human类的两个对象,然后对对象进行相加。--  按照规则: 对对象中的年轻进行相加。 

3.   Human operator(const Human& man);  是成员函数+运算符重载函数的原型。 

    在这个方法中对两个对象的age进行相加,存放在age_tmp中,在返回是创建新的对象返回。赋值给man3。最后我们打印,man3.age 结果为37。 

2. 使用友元全局函数进行重载 

class Human {
public:
	Human(int age, int salary, const char* name);

	friend Human operator+(const Human& man1, const Human& man2);

	int getAge()const;
private:
	int age;
	int salary;
	string name;
};

int main(void) {
	Human man1(18,15000,"ABC");
	Human man2(19, 20000, "BCD");

	// Human man3 = operator+(man1,man2);
	Human man3 = man1 + man2;
    
	cout << man3.getAge() << endl;  // 37,man3是man1和man2两个对象年龄的和

	system("pause");

	return 0;
}

Human::Human(int age, int salary, const char* name)
{
	this->name = name;
	this->salary = salary;
	this->age = age;
}

Human operator+(const Human& man1, const Human& man2) {
	int age_tmp = man1.age + man2.age;

	return Human(age_tmp, man1.salary, man1.name.c_str());
}

int Human::getAge() const
{
	return age;
}
1)代码分析:  

1.  上面代码使用全局函数实现了+运算符重载,按照规则,我们在+运算符重载函数中对两个对象的age属性进行相加。所以在函数中我们需要访问对象内部的私有属性。 

    但是此时运算符重载函数是全局函数,不是类内部的成员函数,所以它是没有办法直接访问类内的私有属性呢? 当然你定义公共接口去访问当然没问题,但是比较麻烦。

   我们可以将这个运算符函数设置为类内的友元函数,这样就可以访问类内部的私有属性了,会比较方便。 

2.  Human operator+(const Human& man1, const Human& man2);  是友元全局函数的声明,其实和成员函数类似,就是多了一个参数。 

3. 此处为+运算符重载,其余的数学运算符重载函数和+运算符重载函数类似。 

总结:  

上面我们使用成员函数和全局函数分别实现了+运算符的重载。其实看起来两者区别并不大。 

区别就是:  使用成员函数,编译器会自动传入调用运算符重载函数对象,不需要我们自己传入,所以可以少写一个参数。(从上述的代码中也能看出来)

你可能感兴趣的:(c++,开发语言)