精华内容
下载资源
问答
  • 运算符的重载

    2020-11-21 23:01:17
    运算符实际上是一个函数,所以运算符的重载实际上是函数的重载。 重载运算符的形式与规则 重载运算符的声明形式如下: operator 类型名(); operator是需要重载的运算符,整个语句没有返回值类型,因为类型名就...

    运算符实际上是一个函数,所以运算符的重载实际上是函数的重载。

    重载运算符的形式与规则

    1. 重载运算符的声明形式如下:
    operator 类型名();
    
    1. operator是需要重载的运算符,整个语句没有返回值类型,因为类型名就代表了它的返回值类型。
    2. 重载运算符将对象转换成类型名规定的类型,转换时的形式就像强制转换一样。
    3. 重载运算符不能是新创建的运算符;
      1. 算数运算符:+,-,,/,%,++,–
      2. 位操作运算符:&,|,~,^,>>,<<
      3. 逻辑运算符:!,&&,||
      4. 比较运算符:<,>,>=,<=,==,!=
      5. 赋值运算符:=,+=,-=,
      =,/=,%=,&=,|=,^=,<<=,>>=
      6. 其他运算符:[],(),->, , , new , delete,new[],delete[],->*

    重载运算符注意事项

    1. 重载运算符时不能改变运算符操作数个数。、
    2. 不能改变运算符原有优先级。
    3. 不能改变运算符原有结合性。
    4. 不能改变运算符原有的语法结构。
    5. 重载运算符含义必须清楚。
    展开全文
  • 关于运算符的重载

    2019-03-18 10:36:41
    C++中类中关于运算符的重载问题? C++中,不仅函数能够重载,运算符也能够重载,重载后的运算符根据操作数的类型实现不同的功能。在实际中,&lt;&lt;本身是左移运算符,但是与流对象cout配合使用时,实现了...

     

    C++中类中关于运算符的重载问题?

    C++中,不仅函数能够重载,运算符也能够重载,重载后的运算符根据操作数的类型实现不同的功能。在实际中,<<本身是左移运算符,但是与流对象cout配合使用时,实现了基本的输出功能。

    运算符重载的方式有2种:(1)类成员函数(2)友元函数

    一般情况下,对于单目运算符进行重载时使用类成员函数方式,对双目操作符进行重载时使用友元函数形式。但是需要注意的是:()和[]重载时必须使用成员函数,<<和>>重载时必须使用友元函数。

    重载后的运算符不能改变操作数的个数和运算符的优先级,即使用方式不能发生变化。运算符重载函数不能在参数列表中给参数设置默认值,原因是由于运算符重载不能改变操作数个数,如果使用了默认参数,会导致操作数的个数减少。

    不能重载的5个运算符:(1). 成员访问运算符(2).* 成员函数指针访问运算符(3)::域运算符(4)sizeof 类型大小运算符(5):?  条件运算符

    一个小例子体会运算符重载:编写复数类Complex并实现复数的加减运算。

    class Complex
    {
    private:
    	int _real;//实部
    	int _image;//虚部
    public:
    	Complex(int real = 0, int image = 0)
    		:_real(real)
    		, _image(image)
    	{}
    
    	//将+与-运算符的重载实现成友元函数(也可以写成成员函数)
    	friend Complex operator+(const Complex& c1, const Complex& c2);
    	friend Complex operator-(const Complex& c1, const Complex& c2);
    
    	void print();
    };
    
    //注意:友元函数不是成员函数,不用加作用域::
    Complex operator+(const Complex& c1, const Complex& c2)
    {
    	Complex tmp(c1._real + c2._real, c1._image + c2._image);
    	return tmp;
    }
    Complex operator-(const Complex& c1, const Complex& c2)
    {
    	Complex tmp(c1._real - c2._real, c1._image - c2._image);
    	return tmp;
    }
    void Complex::print()
    {
    	if (_real == 0)//实部为0
    	{
    		cout << _image << "i" << endl;
    	}
    	else if (_real > 0)
    	{
    		cout << _real << "+" << _image << "i" << endl;
    	}
    	else
    	{
    		cout << "-" << _real << "+" << _image << "i" << endl;
    	}
    }
     
     
     
    展开全文
  • C++运算符的重载

    2017-07-08 09:59:22
    C++运算符的重载总结 c++的一大特性就是重载(overload),通过重载可以把功能相似的几个函数合为一个,使得程序更加简洁、高效。在c++中不止函数可以重载,运算符也可以重载。由于一般数据类型间的运算符没有重载的...

                      C++运算符的重载总结

    c++的一大特性就是重载(overload),通过重载可以把功能相似的几个函数合为一个,使得程序更加简洁、高效。在c++中不止函数可以重载,运算符也可以重载。由于一般数据类型间的运算符没有重载的必要,所以运算符重载主要是面向对象之间的。

    1.一般运算符重载

    在进行对象之间的运算时,程序会调用与运算符相对应的函数进行处理,所以运算符重载有两种方式:成员函数和友元函数。成员函数的形式比较简单,就是在类里面定义了一个与操作符相关的函数。友元函数因为没有this指针,所以形参会多一个。

     

    1. class A
    2. {
    3. public:
    4. A(int d):data(d){}
    5. A operator+(A&);//成员函数
    6. A operator-(A&);
    7. A operator*(A&);
    8. A operator/(A&);
    9. A operator%(A&);
    10. friend A operator+(A&,A&);//友元函数
    11. friend A operator-(A&,A&);
    12. friend A operator*(A&,A&);
    13. friend A operator/(A&,A&);
    14. friend A operator%(A&,A&);
    15. private:
    16. int data;
    17. };
    18. //成员函数的形式
    19. A A::operator+(A &a)
    20. {
    21. return A(data+a.data);
    22. }
    23. A A::operator-(A &a)
    24. {
    25. return A(data-a.data);
    26. }
    27. A A::operator*(A &a)
    28. {
    29. return A(data*a.data);
    30. }
    31. A A::operator/(A &a)
    32. {
    33. return A(data/a.data);
    34. }
    35. A A::operator%(A &a)
    36. {
    37. return A(data%a.data);
    38. }
    39. //友元函数的形式
    40. A operator+(A &a1,A &a2)
    41. {
    42. return A(a1.data+a2.data);
    43. }
    44. A operator-(A &a1,A &a2)
    45. {
    46. return A(a1.data-a2.data);
    47. }
    48. A operator*(A &a1,A &a2)
    49. {
    50. return A(a1.data*a2.data);
    51. }
    52. A operator/(A &a1,A &a2)
    53. {
    54. return A(a1.data/a2.data);
    55. }
    56. A operator%(A &a1,A &a2)
    57. {
    58. return A(a1.data%a2.data);
    59. }
    60. //然后我们就可以对类的对象进行+、-、*、/了。
    61. void main(void)
    62. {
    63. A a1(1),a2(2),a3(3);
    64. a1=a2+a3;
    65. //或者
    66. a1=a2.operator+(a3);
    67. }

    注意:在进行a2+a3的时候会出错,因为我们在上面对+定义了两种方法,去掉一种即可。

    2.关系运算符重载

    因为函数体比较简单,后面我就只给出成员函数形式的函数声明了,关系运算符有==,!=,<,>,<=,>=。

     

    1. bool operator == (const A& );
    2. bool operator != (const A& );
    3. bool operator < (const A& );
    4. bool operator <= (const A& );
    5. bool operator > (const A& );
    6. bool operator >= (const A& );

    3.逻辑运算符重载

    1. bool operator || (const A& );
    2. bool operator && (const A& );
    3. bool operator ! ();

    4.单目运算符重载

    这里的+、-是正负的意思,放在对象前面。

    1. A& operator + ();
    2. A& operator - ();
    3. A* operator & ();
    4. A& operator * ();

    5.自增减运算符重载

    ++和--根据位置的不同有四种情况,都可以重载。

    1. A& operator ++ ();//前置++
    2. A operator ++ (int);//后置++
    3. A& operator --();//前置--
    4. A operator -- (int);//后置--

    6.位运算符重载

    按位操作。

    1. A operator | (const A& );
    2. A operator & (const A& );
    3. A operator ^ (const A& );
    4. A operator << (int i);
    5. A operator >> (int i);
    6. A operator ~ ();

    7.赋值运算符重载

    没有=哦。

    1. A& operator += (const A& );
    2. A& operator -= (const A& );
    3. A& operator *= (const A& );
    4. A& operator /= (const A& );
    5. A& operator %= (const A& );
    6. A& operator &= (const A& );
    7. A& operator |= (const A& );
    8. A& operator ^= (const A& );
    9. A& operator <<= (int i);
    10. A& operator >>= (int i);

    8.内存运算符重载

    1. void *operator new(size_t size);
    2. void *operator new(size_t size, int i);
    3. void *operator new[](size_t size);
    4. void operator delete(void*p);
    5. void operator delete(void*p, int i, int j);
    6. void operator delete [](void* p);

    9.特殊运算符重载

    上面的运算符重载都有两种方式,而下面的运算符只能用一种,特殊吧。 这些运算符的重载只能是成员函数。

    1. A& operator = (const A& );
    2. char operator [] (int i);//返回值不能作为左值
    3. const char* operator () ();
    4. T operator -> ();
    5. //类型转换符
    6. operator char* () const;
    7. operator int ();
    8. operator const char () const;
    9. operator short int () const;
    10. operator long long () const;
    11. //还有很多就不写了

    而这些只能以友元函数的形式重载

    1. friend inline ostream &operator << (ostream&, A&);//输出流
    2. friend inline istream &operator >> (istream&, A&);//输入流

    10.总结

    两种重载方式的比较:

    • 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
    • 以下一些双目运算符不能重载为类的友元函数:=、()、[]、->。
    • 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。 C++提供4个类型转换函数:reinterpret_cast(在编译期间实现转换)、const_cast(在编译期间实现转换)、stactic_cast(在编译期间实现转换)、dynamic_cast(在运行期间实现转换,并可以返回转换成功与否的标志)。
    • 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
    • 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
    • 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部 类型的对象,该运算符函数必须作为一个友元函数来实现。
    • 当需要重载运算符具有可交换性时,选择重载为友元函数。

    注意事项:

    1. 除了类属关系运算符"."、成员指针运算符".*"、作用域运算符"::"、sizeof运算符和三目运算符"?:"以外,C++中的所有运算符都可以重载。
    2. 重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
    3. 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
    4. 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
    5. 运算符重载不能改变该运算符用于内部类型对象的含义。它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
    6. 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。
    展开全文
  • C++前置自增运算符和后置自增运算符的重载

    千次阅读 多人点赞 2020-04-12 21:20:50
    在看本文之前,您需要了解运算符的重载的基本概念。如果不懂,也没关系,请进下面的传送门。 浅显易懂的C++运算符重载 理论: 前置单目运算符,重载函数没有形参。 后置单目运算符,重载函数需要一个int形参。只起...

    本文是关于重载单目运算符的实战讲解,用两个例子进行说明。理论不多,重在理解前置++和后置++的区别。在看本文之前,您需要了解运算符的重载的基本概念。如果不懂,也没关系,请进下面的传送门。

    浅显易懂的C++运算符重载

    理论:

    1. 前置单目运算符,重载函数没有形参。
    2. 后置单目运算符,重载函数需要一个int形参。只起到区别前置运算符的的作用。

    人狠话不多,来,小二,上茶~~~

    例如下面的例子:
      我们创建一个时间的类,使其能够实现时间的自增操作,包括前置自增和后置自增。

    在类中我们声明了两个个++运算符的重载类型的函数:

    • Clock& operator++();,它是没有形参的,并且它的返回值类型是Clock类对象的引用,是一个左值。
    1. 在函数的实现中。我们先让当前对象的second值加一,然后对hour和minute值进行进位操作。
    2. 最后,我们返回指向当前对象的引用。可以看到它的值就是进行加一之后的值。
    Clock& Clock::operator++()//返回的是加一操作之后的值的引用,是一个左值。
    {
            this->second++;
            if (second >= 60)
            {
                   this->second = this->second - 60;
                   this->minute++;
                   if (minute >= 60)
                   {
                           this->minute = this->minute - 60;
                           this->hour = (this->hour + 1) % 24;
                   }
            }
            return *this;//返回加一之后的值。
    }
    
    • Clock operator++(int);,它有一个int型的形参,该形参没有什么之实际作用,只是用来区别前置自增运算符的重载函数,并且它的返回值是一个Clock类对象。
    1. 在函数实现中,我们先将当前对象拷贝一份,然后再对当前对象进行加一操作。
    2. 我们这里调用的是上面的前置加一操作,而没有将上面的代码再拷贝一份,那样做是愚蠢的。
    3. 我们这里使用的是24小时制来表示时间,如果我们想用12小时制来表示,我们这种写法,只需在一个函数中修改即可。而不用在两处都修改。保证了代码的可维护性。
    Clock Clock::operator++(int)//返回加一操作之前的值的副本,是一个右值
    {
            Clock old = *this;
            ++(*this);//调用前置“++”运算符
            return old;//返回++之前的值。
    }
    
    /*
    
    操作数是自定义类
    //*/
    #include<iostream>
    using namespace std;
    class Clock
    {
    public:
            Clock(int h=0,int m=0,int s=0);
            void showTime() const;
            Clock& operator++();//前置++
            Clock operator++(int);//后置++,只是和前置区分开,没有实际作用
            ~Clock();
    private:
            int hour, minute, second;
    };
    Clock::Clock(int h,int m,int s)
    {
            if (0 < h&&h < 24 && 0 < m&&m < 60 && 0 < s&&s < 60)
            {
                   this->hour = h;
                   this->minute = m;
                   this->second = s;
            }
            else
            {
                   cout << "Time Erro" << endl;
            }
    }
    Clock::~Clock()
    {
            /*cout << "析构函数" << endl;*/
    }
    void Clock::showTime()const
    {
            cout << this->hour << ":" << this->minute << ":" << this->second << endl;
    }
    //前置++
    //先加一,后使用,使用的是加一之后的值。
    Clock& Clock::operator++()//返回的是加一操作之后的值的引用,是一个左值。
    {
            this->second++;
            if (second >= 60)
            {
                   this->second = this->second - 60;
                   this->minute++;
                   if (minute >= 60)
                   {
                           this->minute = this->minute - 60;
                           this->hour = (this->hour + 1) % 24;
                   }
            }
            return *this;//返回加一之后的值。
    }
    //后置++
    //看起来是:先使用后加一,但实际上,它已经加一了,只不过我们使用的是它加一之前的值。
    Clock Clock::operator++(int)//返回加一操作之前的值的副本,是一个右值
    {
            Clock old = *this;
            ++(*this);//调用前置“++”运算符
            return old;//返回++之前的值。
    }
    int main()
    {
            Clock c1(23, 59, 59);
            cout << "当前时间:";
            c1.showTime();
            cout << "后置++:";
            (c1++).showTime();
            cout << "前置++:";
            (++c1).showTime();
            return 0;
    }
    

    我们把当前时间设置为:23:59:59
    进行加一操作之后的值如下:

    输出:
    当前时间:23:59:59
    后置++:23:59:59
    前置++:0:0:1

    在我们刚接触编程时,我们可能会记得:

    1. i++:是先使用当前的值,再进行加一操作。
    2. ++i:是先进行加一操作,再使用加一后的值。
      通过上面我们自己实现前置自增和后置自增,我们可以看到,都是先对当前对象进行加一操作,然后再使用,只不过,在后置自增时,我们使用的是自增之前的旧值,而当前对象实际上也已经进行了加一操作。
    3. 在上面的输出中,我们可以看到,使用后置++时,输出的值仍然是23:59:59,好像并没有进行加一操作。然而并不是的,实际上它是进行了加一操作的。
    4. 使用前置++时,我们看到当前时间是:0:0:1,相对我们设置的时间:23:59:59,加了两秒,这就证明了我们的后置++确实是进行了操作的。

    再看一个例子:
      定义Point类,有坐标x,y两个成员变量;对Point类重载“++”(自增)、“–”(自减)运算符,实现对坐标值的改变。

    自减和自增的写法一样。就不作过多的赘述了。

    #include<iostream>
    using namespace std;
    class Point
    {
    public:
    	Point();
    	Point(double x, double y);
    	~Point();
    	Point& operator++();//前置
    	Point operator++(int);
    	Point& operator--();//前置
    	Point operator--(int);
    	Point operator+(const Point &p)const;
    	void display() const;
    private:
    	double x;
    	double y;
    };
    Point::Point()
    {
    	this->x = 0;
    	this->y = 0;
    }
    Point::Point(double x, double y)
    {
    	this->x = x;
    	this->y = y;
    }
    Point::~Point()
    {
    	//cout << "析构函数" << endl;
    }
    Point& Point::operator++()
    {
    	this->x++;
    	this->y++;
    	return *this;
    }
    Point Point::operator++(int)
    {
    	Point oldpoint = *this;
    	++(*this);
    	return oldpoint;
    }
    Point& Point::operator--()
    {
    	this->x--;
    	this->y--;
    	return *this;
    }
    Point Point::operator--(int)
    {
    	Point oldpoint = *this;
    	--(*this);
    	return oldpoint;
    }
    Point Point::operator+(const Point &p)const
    {
    	//创建一个临时无名对象并返回给调用者。
    	return Point(this->x + p.x, this->y + p.y);
    }
    void Point::display() const
    {
    	cout << "(" << this->x << "," << this->y << ")" << endl;;
    }
    int main()
    {
    	int x1, y1, x2, y2;
    	cout << "请输入P1点的x和y值:" << endl;
    	cin >> x1 >> y1;
    	cout << "请输入P2点的x和y值:" << endl;
    	cin >> x2 >> y2;
    	Point P1(x1, y1), P2(x2, y2);
    	cout << "------P1,P2-----" << endl;
    	P1.display();
    	P2.display();
    	cout << "------P1自增-----" << endl;
    	cout << "P1++:";
    	(P1++).display();
    	cout << "++P1:";
    	(++P1).display();
    	cout << "------P2自增-----" << endl;
    	cout << "P2++:";
    	(P2++).display();
    	cout << "++P2:";
    	(++P2).display();
    
    	cout << "------P1自减-----" << endl;
    	cout << "P1--:";
    	(P1--).display();
    	cout << "--P1:";
    	(--P1).display();
    
    	cout << "------P2自减-----" << endl;
    	cout << "P2--:";
    	(P2--).display();
    	cout << "--P2:";
    	(--P2).display();
    
    	cout << "------当前P1,P2-----" << endl;
    	cout << "P1: ";
    	P1.display();
    	cout << "P2: ";
    	P2.display();
    	cout << "----重载+运算符的使用----" << endl;
    	Point SumP3 = P1 + P2;
    	cout << "SumP3: ";
    	SumP3.display();
    	return 0;
    }
    
    展开全文
  • 主要内容: 一、运算符重载基本概念;...二、赋值运算符的重载; 三、运算符重载为友元函数; 四、流插入运算符和流提取运算符的重载; 五、类型转换运算符和自增、自减运算符的重载; 六运算符重载的注意事项。
  • 流插入运算符和流提取运算符的重载 问题 cout cout 是在 iostream 中定义的ostream 类的对象。 “ 考虑,怎么重载才能使得cout 有可能按以下方式重载成 ostream类的成员函数: void ostream::operator(int n) ...
  • // 前置自增运算符的重载函数,函数参数是空 T & operator--(); // 前置自减运算符的重载函数,函数参数是空 后置运算符作为二元运算符重载,多写一个没用的参数,重载为成员函数的个数如下: T operator
  • 运算符的重载 operator

    2017-07-05 18:39:40
    一、运算符的重载 运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 在复杂数据类型中,编译器不能识别运算符,如c++中,对象+对象,编译器无法知道怎么运算,所以就需要编写...
  • 自加/自减运算符的重载 自加 (++)/自减(--) 运算符有前置/后置 之分 前置运算符 前置运算符作为一元运算符重载 • 重载为成员函数: T & operator++(); T & operator--(); • 重载为全局函数: T & operator++(T &)...
  • 一、运算符重载的定义 所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之同一个函数名可以用来代表不同功能的函数。...{ 对运算符的重载处理 } 例如,想将“+”用于Complex类(复数)的
  • 日期date类的运算符的重载 今天为2019年1月16日,如果想要知道自己的假期还有多长时间,或者想知道离过年还有多少天,是不是需要计算一下呢?掰着手指算的话,那可能很麻烦,如果有一个可以计算日期的函数那可能就...
  • c++插入运算符和输出运算符的重载

    千次阅读 2016-03-17 21:17:49
    C++中对插入运算符和输出运算符的重载
  • 文章目录一、主要运算符的重载1.赋值运算符 = 的重载2.加号运算符号 + 的重载3.输入输出运算符 << , >>的重载4.判断运算符 == , != 的重载二、运算符重载完整代码实例总结 提示:以下是本篇文章正文...
  • 1.重载的形式自增运算符和自减运算符是有「前置」和「后置」之分的,如...C++规定:「前置」运算符作为一元运算符重载,重载为成员函数的形式如下:// 前置自增运算符的重载函数,函数参数是空T & operator++();...
  • 算术运算符的重载 重定义或重载 C# 中内置的运算符。因此,程序员也可以使用自定义类型的运算符。重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。 使用方法 class Person { ...
  • 类外定义的运算符的重载

    千次阅读 2017-03-27 20:33:08
    在进行运算符的重载时,必须定义一个运算符重载函数,名字为operator,后随一个要重载的运算符。如: operator +; operator -;operator *;operator /; C++中运算符重载的规则: 1.C++中绝大部分的运算符都可以重载,...
  • 2.赋值运算符的重载 3.运算符重载为友元函数 4.运算符重载实例:可变长数组类的实现 5.流插入运算符和流提取运算符的重载 6.类型转换运算符、自增自减运算符的重载 5.流插入运算符和流提取运算符的重载 cout <<...
  •    所谓运算符的重载,我们可以这样理解;我们知道C语言中,我们所使用的“+,-,*,/”等符号都是用于数学运算表达的,可以用于数值与非数值之间,还可以用于表达式和变量常量之间,其表达的含义各不相同,所以...
  • C#运算符的重载一元二元运算符

    千次阅读 2015-03-30 19:33:27
    一元运算符的重载:一元操作符只作用于一个对象那个,此时参数表为空,对象作为操作符的单操作数,需要注意的是类中的字段为public ,重载方法为static 二元运算符的重载:参数表中有一个参数,当前该对象作为...
  • 实验八 多态:运算符的重载 1 实验目的 学习面向对象程序设计中“多态机制”的一种实现方法——运算符重载,包括: (1)学习如何定义运算符的重载; (2)学习如何使用重载的运算符。 2 实验内容 2.1 改进《实验三 ...
  • Python3之运算符的重载

    千次阅读 2018-09-10 23:40:08
    运算符重载 让自定义类生成的对象能够使用运算符进行操作 ...算数运算符的重载 方法名(双下划线打不出来) 运算符和表达式 说明 add(self, rhs) self + rhs 加法 sub(self, rhs) self - rhs ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,590
精华内容 9,036
关键字:

运算符的重载