C++的运算符重载--思考1

学习C++ 我们最深刻的体会就是C++不像那个C同学,是那样的单纯,我们表面上一看就透,是啥就是傻。C++中所有的东西都是为面向对象而设计的,所以不免有些黑盒之类到的思想,就是很多表面的东西,在内部是经过复杂的封装的,所以这个C++同学已经别社会污染,变得城府很深了,我们要想了解这位C++同学,就必须从他的外表之下去偷窥他内心那单纯的性格,只有这样才能看到它的内心世界!

今天我想讨论一下运算符重载,其实说白了就是一个函数重载,只是这个函数的名字有点怪而已。看这一点就可以体现出C++ 同学的城府很深吧,在C语言中如果重名了,就不认识了,但是对于C++ 同学他可是可以看透重名的不同哟。

今天只思考一下,既然运算符重载是函数重载,那对于C++来说到底用  成员函数,普通函数,还是友员函数进行重载呢

今天拿复数的四则运算作为一个例子:

1.运算符重载作为普通函数:

/**********************************************************************    
* *   Copyright (c)2015,WK Studios  
* *   Filename:  A.cpp
* *   Compiler: GCC  vc 6.0   
* *   Author:WK    
* *   Time: 2015 4 5  
* **********************************************************************/

#include<iostream>

using std::cout;
using std::cin;

class Complex
{
public:
double real;
	double imag;
private:

};
//普通函数(没有this指针只能访问类的公有部分)
Complex operator+(Complex &a,Complex &b);
Complex operator-(Complex &a,Complex &b);
Complex operator*(Complex &a,Complex &b);
Complex operator/(Complex &a,Complex &b);

int main()
{
   Complex com1(1.1,2.3),com2(2.2,4.3);
   Complex  total;
   total=com1/com2;//隐式调用
   cout<<total.real<<"   "<<total.imag<<"\n";
   total=operator/(com1,com2);//与上面的等价,这是显式调用
   cout<<total.real<<"   "<<total.imag<<"\n";
return 0;
}

Complex operator+(Complex &a,Complex &b)
{
return Complex(a.real+b.real,a.imag+b.imag);
}

Complex operator-(Complex &a,Complex &b)
{
return Complex(a.real-b.real,a.imag-b.imag);
}
Complex operator*(Complex &a,Complex &b)
{
return Complex(a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real);
}
Complex operator/(Complex &a,Complex &b)
{
return Complex((a.real*b.real+a.imag*b.imag)/(b.real*b.real+b.imag*b.imag),(b.real*a.imag-a.real*b.imag)/(b.real*b.real+b.imag*b.imag));
}

对于用重载运算符作为普通函数是很少用的,这样只能访问类的公有部分,当数据与方法在公有部分时候可以使用,但是C++强调安全,封装,这种情况应该很少!

2.运算符重载作为成员函数:

/**********************************************************************    
* *   Copyright (c)2015,WK Studios  
* *   Filename:  A.h
* *   Compiler: GCC  vc 6.0   
* *   Author:WK    
* *   Time: 2015 4 5  
* **********************************************************************/
#include<iostream>

using std::cout;
using std::cin;

class Complex
{
public:
//构造函数
	Complex(double r=0.0,double i=0.0):real(r),imag(i)
	{}
//复数加
	//成员函数
	Complex operator+(Complex &b);
	//复数减
	//成员函数
	Complex operator-(Complex &b);
	//复数乘
	//成员函数
	Complex operator*(Complex &b);
	//复数除
	//成员函数
	Complex operator/(Complex &b);
    void print()
	{
	 cout<<real<<"   "<<imag<<"\n";
	}

private:
	double real;
	double imag;

};

int main()
{
   Complex com1(1.1,2.3),com2(2.2,4.3);
   Complex  total;
   total=com1+com2;//隐式调用
   total.print();
   total=com1.operator+(com2);////与上面的等价,这是显式调用
   total.print();

  return 0;
}

Complex Complex ::operator+(Complex &b)
{
return Complex(real+b.real,imag+b.imag);
}

Complex Complex:: operator-(Complex &b)
{
return Complex(real-b.real,imag-b.imag);
}
Complex Complex:: operator*(Complex &b)
{
return Complex(real*b.real-imag*b.imag,real*b.imag+imag*b.real);
}
Complex Complex:: operator/(Complex &b)
{
return Complex((real*b.real+imag*b.imag)/(b.real*b.real+b.imag*b.imag),(b.real*imag-real*b.imag)/(b.real*b.real+b.imag*b.imag));
}</span>

成员函数对于很多运算符都要重载为这种形式,使用较多

3.运算符重载作为友员函数:

友员函数只属于类,不属于任何对象所以他不需要对象的this指针来确定自己的数据,但是没有指针this就不能使用,在这里这个有点像普通函数,只是只是友员函数时类的朋友,可以访问类的私密数据,单是具体什么时候使用友员函数最好,这是因时而宜!

/**********************************************************************    
* *   Copyright (c)2015,WK Studios  
* *   Filename:  A.h
* *   Compiler: GCC  vc 6.0   
* *   Author:WK    
* *   Time: 2015 4 5  
* **********************************************************************/

#include<iostream>

using std::cout;
using std::cin;

class Complex
{
public:
//构造函数
	Complex(double r=0.0,double i=0.0):real(r),imag(i)
	{}

//友员函数(无this指针)
	friend Complex operator+(Complex &a,Complex &b);

//友员函数(无this指针)
	friend Complex operator-(Complex &a,Complex &b);

	//友员函数(无this指针)
    friend Complex operator/(Complex &a,Complex &b);

//友员函数(无this指针)
     friend Complex operator*(Complex &a,Complex &b);
    void print()
	{
	 cout<<real<<"   "<<imag<<"\n";
	}

private:
	double real;
	double imag;

};

int main()
{
   Complex com1(1.1,2.3),com2(2.2,4.3);
   Complex  total;
   total=com1+com2;//隐式调用
   total.print();
   total=operator+(com1,com2);////与上面的等价,这是显式调用
   total.print();

  return 0;
}

Complex operator+(Complex &a,Complex &b)
{
return Complex(a.real+b.real,a.imag+b.imag);
}

Complex operator-(Complex &a,Complex &b)
{
return Complex(a.real-b.real,a.imag-b.imag);
}
Complex operator*(Complex &a,Complex &b)
{
return Complex(a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real);
}
Complex operator/(Complex &a,Complex &b)
{
return Complex((a.real*b.real+a.imag*b.imag)/(b.real*b.real+b.imag*b.imag),(b.real*a.imag-a.real*b.imag)/(b.real*b.real+b.imag*b.imag));
}

最后说一下运算符重载各种形式函数的适用时候:

时间: 2024-08-20 02:38:11

C++的运算符重载--思考1的相关文章

c/c++ 重载运算符的思考

c/c++ 重载运算符的思考 #include <iostream> using namespace std; class Imaginary{ public: Imaginary():real(0), imag(0){ cout << "c:" << this << endl; } Imaginary(int real, int imag):real(real), imag(imag){ cout << "c:&q

运算符重载的宏观思考The Complex Class

运算符重载是C++中较C语言更加先进和灵活的地方之一,通过运算符重载,使运算符拥有了除了只能完成内置类型的运算操作之外的对于其他自定义类型的运算功能.这使得C++更加灵活,通俗,更加面向对象. 事实上运算符的重载不过是对函数名为"operator 运算符"的函数的定义,根据所操作的对象的不同,可以分为成员函数和友元函数两种定义方法. C++中唯一的三目运算符不能重载,因此所有的运算符重载的形参都不会超过三个,又由于成员函数默认第一个形参必须是自定义类的对象并且默认绑定到*this指针,

C++ 关于运算符重载

转载来源:http://c.biancheng.net/cpp/biancheng/view/216.html 重载运算符的函数一般格式如下:    函数类型 operator 运算符名称 (形参表列)    {        // 对运算符的重载处理    } 例如,想将”+”用于Complex类(复数)的加法运算,函数的原型可以是这样的:    Complex operator+ (Complex& c1, Complex& c2);在上面的一般格式中,operator是关键字,是专门

PKU C++程序设计实习 学习笔记4 运算符重载

第四章 运算符重载 4.1 运算符重载的基本概念 1. 运算符 2. 自定义数据类型与运算符重载 C++提供了数据抽象的手段:用户自己定义数据类型 -- 类 ? 调用类的成员函数->操作它的对象 类的成员函数->操作对象时,很不方便 ? 在数学上,两个复数可以直接进行+/-等运算 Vs. 在C++中,直接将+或-用于复数是不允许的 3. 运算符重载 对抽象数据类型也能够直接使用C++提供的运算符 ? 程序更简洁 ? 代码更容易理解 运算符重载 ? 对已有的运算符赋予多重的含义 ? 使同一运算符

(转)c++的运算符重载

1.前置运算符和后置运算符,左值和右值. 其实很久以来一直都没有怎么搞清楚左值和右值的区别,只知道左值可以放在等号的左边,也可以放在等号的右边,但是右值却只能放在等号的右边,然后形成一个大概直观的印象,知道怎么样做才不出错而已.不过今天看看C++,却发现有了点新的体会. 对于表达式a--=5;这样一个表达式,明显是错误的,究其原因,是因为执行等号左边的自减表达式之后,显示取得a的值,然后才是进行自减操作,所以最终的结果是一个右值,而且就是a的值(变化前的),于是对于赋值语句 b = a--,自然

关于运算符重载

运算符重载需遵循以下原则: 1.除了类所属关系运算符".".成员指针运算符".*".作用域运算符"::".sizeof运算符.三目运算符"?:"之外,C++中所有的运算符都可以进行重载 2.重载运算符限制在C++已有的运算符范围内,不允许创建新的运算符 3.重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符的操作数的个数及语法结构 4.运算符重载不能改变运算符用于内置类型的对象的含义,只能用于自定义类型对象之间,

运算符重载

关键字:operator 相见:<高质量程序设计指南> P255 如果运算符被重载为全局函数,那么只有一个参数的运算符叫做一元运算符,有两个参数的运算符叫做二元运算符. 如果运算符被重载为类的成员函数,那么一元运算符没有参数(但是++和--运算符的后置版本除外),二元运算符只有右侧参数,因为对象自己成了左侧参数. 运算符重载的特殊性 如果重载为成员函数,则this对象发起对它的调用 如果重载为全局函数,则第一个参数发起对它的调用 禁止用户发明该语言运算符集合中不存在的运算符 除了函数调用运算符

C++ 运算符重载

C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.比如对象a和对象b, 那么 a+b 就需要用户自己定义它怎么相加,这时就用到了运算符重载. 运算符重载规则如下: ①. C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符. ②. 重载之后运算符的优先级和结合性都不会改变. ③. 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造.一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对

Kotlin中复合赋值(+=,-=,……)运算符重载

本篇建立在已经了解了kotlin中运算符重载的理念以及如何实现的基础上. 来我们首先写一个简单的类,然后重载运算符+,+=,-,-=这个几个运算符.代码如下: data class Point(var x: Int, var y: Int) { operator fun plus(point: Point): Point { return Point(this.x + point.x, this.y + point.y) } operator fun plusAssign(point: Poin