运算符重载语法:返回值类型  operator运算符(参数列表) {  代码逻辑。。。
}

C++中的运算符重载是通过函数来实现的,可以将重载的运算符看作是类成的一个成员函数,向普通函数一样调用。如重载String类的 + 运算符,调用的时候可以这样:

class {
// .....
String operator+(const String &str)
{ .... }
} String str1 = "hello ";
String str2 = "cplusplus";
String str3 = str1.operator+(str2);

从上述代码中可以看出,operator+就像是String类的一个函数,可以像普通函数一样调用,将要相加的字符串对象作为实参传递给函数即可。所以从这可以得出一个函数重载的步聚:(以上述+重载为例)

1、写出运算符的函数原型

str1.operator+(str2); 

从这可以得知,+ 需要两个操作数,str1和str2(即两个字符串对象),返回值类型为String对象(加法运算后的结果)。由于是作为类的成员函数重载,所以str1在进行 + 运算时作为this指针传给函数,函数只需要一个参数即可,即被相加的字符串对象str2。

2、写出函数声明

从函数原型可以得出函数声明:String operator+(const String &str);

3、实现函数细节

String String::operator+(const String &str)
{
if (str.buff == nullptr)
{
return *this;
} size_t totallen = str.len + this->len + 1;
char *buff = new char[totallen]; strcpy(buff, this->buff);
strcat(buff, str.buff); String temp(buff);
return temp;
}

下面这个示例重载了字符串操作的常用操作符:

//
// String.h
// C++运算符重载
//
// Created by 杨信 on 14-5-8.
// Copyright (c) 2014年 yangxin. All rights reserved.
// #ifndef __C______String__
#define __C______String__ #include <iostream> using namespace std; class String
{
private:
char *buff;
size_t len; public:
String(); // 用一个字符串初始化对象
String(const char *buff); // 拷贝构造
String(const String &str); // 析构
~String(); // 设置字符串内容
void setString(const char *buff); // 获取字符串的长度
size_t length() const; // 获取字符串内容
char * getStr() const; // 比较两个字符串是否相等
bool operator==(String &str); // 比较两个字符串是否不相等
bool operator!=(String &str); // 比较两个字符串的大小
bool operator>(String &str); // 比较两个字符串的大小
bool operator<(String &str); // 获取或修改字符串中的某一个字符
char& operator[](int index); // 赋值构造函数
String& operator=(const String &str); // 两个字符串相加
String operator+(const String &str); // 字符串累加
String& operator+=(const String &str); // 从输入流中获取字符串
friend istream& operator>>(istream &input, String &str); // 将字符串输出到输出流
friend ostream& operator<<(ostream &output, const String &str); }; #endif /* defined(__C______String__) */ //
// String.cpp
// C++运算符重载
//
// Created by 杨信 on 14-5-8.
// Copyright (c) 2014年 yangxin. All rights reserved.
// #include "String.h"
#include <string>
#include <cassert>
#include <cmath> String::String()
{
this->buff = nullptr;
this->len = 0;
} // 用一个字符串初始化对象
String::String(const char *buff):buff(nullptr), len(0)
{
setString(buff);
} // 拷贝构造
String::String(const String &str)
{
setString(str.buff);
} // 析构
String::~String()
{
// 释放内存
if (this->buff != nullptr)
{
delete[] buff;
buff = nullptr;
len = 0;
}
} void String::setString(const char *buff)
{
if (buff == nullptr)
{
return;
} if (this->buff != nullptr) {
delete[] this->buff;
this->buff = nullptr;
this->len = 0;
} size_t len = strlen(buff);
this->buff = new char[len + 1];
this->len = len;
strcpy(this->buff, buff);
} // 获取字符串的长度
size_t String::length() const
{
return this->len;
} // 获取字符串内容
char * String::getStr() const
{
return this->buff;
} // 获取或修改字符串中的某一个字符
char& String::operator[](int index)
{
assert(index < this->len); return this->buff[index];
} // 比较两个字符串是否相等
bool String::operator==(String &str)
{
if (this->len != str.len)
{
return false;
} for (int i = 0; i < this->len; ++i)
{
if (this->buff[i] != str[i])
{
return false;
}
} return true;
} // 比较两个字符串是否不相等
bool String::operator!=(String &str)
{
return !(*this == str);
} // 比较两个字符串的大小
bool String::operator>(String &str)
{
char *pstr = this->buff;
char *pstr2 = str.buff;
while (*pstr != '\0' && *pstr2 != '\0')
{
if (*pstr > *pstr2) {
return true;
}
pstr++;
pstr2++;
}
return false;
} // 比较两个字符串的大小
bool String::operator<(String &str)
{
return !(*this > str);
} // 赋值构造函数
String& String::operator=(const String &str)
{
setString(str.buff); return *this;
} // 两个字符串相加
String String::operator+(const String &str)
{
if (str.buff == nullptr)
{
return *this;
} size_t totallen = str.len + this->len + 1;
char *buff = new char[totallen]; strcpy(buff, this->buff);
strcat(buff, str.buff); String temp(buff);
return temp;
} // 字符串累加
String& String::operator+=(const String &str)
{
if (str.buff == nullptr)
{
return *this;
} // 创建一个临时缓冲区,存储对象本身的字符串和相加的字符串
size_t len = this->len + str.length();
char *temp = new char[len + 1];
strcpy(temp, this->buff);
strcat(temp, str.buff); // 设置新的字符串给对象本身
setString(temp); return *this;
} // 从输入流中获取字符串
istream& operator>>(istream &input, String &str)
{
// 在堆区创建临时缓冲区,接收用户输入
int size = 1024 * 10;
char *tempbuff = new char[size];
memset(tempbuff, 0, size); // 获取用户输入
input.getline(tempbuff, size); // 将临时缓冲中的字符串保存到str对象的字符串缓冲区中
str.setString(tempbuff); // 释放临时缓冲区数据
delete[] tempbuff;
tempbuff = nullptr;
return input;
} // 将字符串输出到输出流
ostream& operator<<(ostream &output, const String &str)
{
output << str.getStr();
return output;
} // 测试用例
//
// main.cpp
// String(运算符重载)
//
// Created by 杨信 on 14-5-8.
// Copyright (c) 2014年 yangxin. All rights reserved.
// #include <iostream>
#include "String.h"
#include <cmath> using namespace std; int main(int argc, const char * argv[])
{ // 初始化
String str1("helloz");
String str2("helloz"); // 获取字符中内容
cout << str1.getStr() << endl; // 获取字符串的长度
cout << "长度:" << str1.length() << endl; // 获取第字符串中的第一个字符
cout << "第1个字符:" << str1[0] << endl; // 比较两个字符串是否相等,相等返回1,否则返回0
bool isequal = str1 == str2;
cout << isequal << endl; // 比较两个字符串的大小,str1大于str2返回1,否则返回0
cout << (str1 > str2) << endl; // 修改字符串中的第2个字符为C
String s = "Hello";
s[1] = 'C';
cout << s << endl; // 测试用一个字符串去初始化另外一个字符串
String str3 = str2;
cout << str3.getStr() << endl;
String str4;
str4 = str3;
cout << str4.getStr() << endl; // 测试两个字符串相加
String str5 = str1 + str2;
cout << &str5 << endl;
cout << str5.getStr() << endl; // 测试字符串连等
String str6;
String str7 = str6 = str5;
cout << str6.getStr() << " | " << str7.getStr() << endl; // 测试字符串累加
String str8 = "i love c++ ";
str8 += "i love c ";
cout << str8.getStr() << endl; // 从输入流读取字符串
String str9;
cout << "Please a string:";
cin >> str9; // 将字符串输出到输出流
cout << str9 << endl; return 0;
}

运算符重载注意事项:

  • 友元函数重载运算符时需要传递所有操作数
  • 成员函数重载,会将操作数本身做为this指针作为参数传入函数,如果是多元操作符,只需与它被操作的数传入函数即可
  • = 号重载时,如果对象中有新分配内存的成员,要先delete,再new,如果要支持连等操作,需要返回对象本身的引用

  • 函数返回值作左值时,返回值必须为引用

  • 只有C++预定义的操作符集中的操作符才可以被重载(不能自己随便写一个操作符,如:+-)
  • 重载操作符不能改变操作符的优先级,例如:先乘徐,后加减
  • 重载操作符不能改变操作数的个数

以下几种运算符不能被重载:

  •  .    :成员选择运算符
  • ::    :作用域运算符
  • *     : 指针运算符
  • #    :预处理标志
  • ?:   :三目运算符,没有确定性,重载没有意义

玩转C++运算符重载的更多相关文章

  1. PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天

    PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数    1  构造  2  析构   3  赋值  4 拷贝构造  5 oper ...

  2. swift:高级运算符(位运算符、溢出运算符、优先级和结合性、运算符重载函数)

    swift:高级运算符 http://www.cocoachina.com/ios/20140612/8794.html 除了基本操作符中所讲的运算符,Swift还有许多复杂的高级运算符,包括了C语和 ...

  3. [b0018] python 归纳 (四)_运算符重载

    # -*- coding: UTF-8 -*- """ 测试运算符重载 加法 总结: python 运算符表达式其实都是调用 类中方法 __xxx__ + <--- ...

  4. C++ 运算符重载时,将运算符两边对象交换问题.

    在C++进行运算符重载时, 一般来讲,运算符两边的对象的顺序是不能交换的. 比如下面的例子: #include <iostream> using namespace std; class ...

  5. C#高级编程笔记2016年10月12日 运算符重载

    1.运算符重载:运算符重重载的关键是在对象上不能总是只调用方法或属性,有时还需要做一些其他工作,例如,对数值进行相加.相乘或逻辑操作等.例如,语句if(a==b).对于类,这个语句在默认状态下会比较引 ...

  6. C++运算符重载

    C++运算符重载 基本知识 重载的运算符是具有特殊名字的函数,他们的名字由关键字operator和其后要定义的运算符号共同组成. 运算符可以重载为成员函数和非成员函数.当一个重载的运算符是成员函数时, ...

  7. 标准C++之运算符重载和虚表指针

    1 -> *运算符重载 //autoptr.cpp     #include<iostream> #include<string> using namespace std ...

  8. python运算符重载

    python运算符重载就是在解释器使用对象内置操作前,拦截该操作,使用自己写的重载方法. 重载方法:__init__为构造函数,__sub__为减法表达式 class Number: def __in ...

  9. 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换

    [源码下载] 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 运算符重载 自 ...

随机推荐

  1. LabVIEW系列——自定义错误

    1.自定义错误代码文本文件在labview中三处:      a).E:\Program Files\National Instruments\LabVIEW 8.6\project\errors   ...

  2. linux下配置php Apache mysql

    一 Apache部分 http://www.cnblogs.com/bluewelkin/p/3805107.html里面是纠正了原文的一些小错误,即可正常安装 1.su 命令2.安装apr-1.3. ...

  3. Android(java)学习笔记174:SharedPreferences(轻量级存储类)

    1.SharedPreferences是Android平台上一个轻量级的存储类,简单的说就是可以存储一些我们需要的变量信息.2个activity 之间的数据传递除了可以他通过intent来传递数据,还 ...

  4. JDBC操作数据库 封装好的工具类

    mysql sqlserver oracle 数据库的驱动jar包http://download.csdn.net/download/csdn576038874/8833683package cn.h ...

  5. Migration of ASP.NET app from IIS6 to IIS7 (7.5)

    For many of us familiar problem. You developing applications under IIS6 and you're about to move the ...

  6. 各种vpn协议介绍(重点介绍sslvpn的实现方式openvpn)

    vpn介绍:   VIrtual Private Network 虚拟专用网络哪些用户会用vpn?    公司的远程用户(出差.家里),公司的分支机构.idc机房.企业间.FQ常见vpn协议有哪些?  ...

  7. JavaScript单例模式

    一.什么是单例 意思是指获取的对象只有一份. 二.最通用的单例 任何时刻获取SingLeton.instance都是同一个对象 var SingLeton={ instance:{ property: ...

  8. jquery 提示信息显示后自动消失的具体实现

    方法一: 复制代码 代码如下: $("#errormsg").html("您的信息输入错误,请重试!").show(300).delay(3000).hide( ...

  9. c语言_链表实例讲解(两个经典例子)

    建立一个学生成绩的线性链表,对其实现插入,删除,输出,最后销毁. demo1 // lianbiao.cpp : Defines the entry point for the console app ...

  10. ios7--系统自带的向右滑动手势返回上一个界面

    当从控制器A push到控制器B,我们返回控制器A,除了使用按钮返回 [self.navigationController pushViewController:Vc animated:YES]; 还 ...