运算符重载语法:返回值类型  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. mybatis14 动态sql

    动态sql(重点) mybatis重点是对sql的灵活解析和处理. 1.1需求 将自定义查询条件查询用户列表和查询用户列表总记录数改为动态sql 1.2if和where <!-- 自定义查询条件 ...

  2. 8 Pratical Examples of Linux “Touch” Command--reference

    In Linux every single file is associated with timestamps, and every file stores the information of l ...

  3. 文件MD5查看器工具与源码实现及下载

    由于工作中经常需要查看文件的MD5值,先前网上找了几个MD5值查看工具,但基本都是选择文件,还没有复制功能,于是今天我就自己编写了个MD5查看工具,支持文件拖拽查看,并可以复制功能. 由于本工具比较小 ...

  4. 【Android】数据库的简单应用——升级数据库

    假如我们已经创建好了一个数据库,随着功能需求的增加,想在数据库中再添加一个表,如果直接在之前的代码中插入一个表,会发现创建表失败,这是因为该数据库已经存在.该如何解决呢? 1.卸载程序,重新编译安装. ...

  5. eclipse中svn插件的安装

    Svn(Subversion)是近年来崛起的版本管理工具,在当前的开源项目里(J2EE),几乎95%以上的项目都用到了SVN.Subversion项目的初衷是为了替换当年开源社区最为流行的版本控制软件 ...

  6. Linux服务器常用性能监控命令汇总

    1.ifconfig 网卡数目.ip地址.Mac地址.MTU大小 eth0 Link encap:Ethernet HWaddr 00:0d:3a:50:12:e9 inet addr:10.0.0. ...

  7. PHP金字塔的输出

    相信学习语言的最初的时候,学到循环的时候,开始一定有种摸不着头脑,想砸电脑的冲动吧 这里就是记录我当初学习的时候,为了通过这个循环,学习的金字塔的输出 1.首先,要了解一个金字塔的输出就要去看它的表达 ...

  8. [条形码] BarCodeToHTML条码生成类 (转载)

    点击下载 BarCodeToHTML.zip 过多的我就不多说了大家直接看代码吧,这是一个帮助大家生成条码的类,大小大家可以自由的设定 /// <summary> /// 类说明:条码生成 ...

  9. Error:Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessException

    异常Log: Error:Execution failed for task ‘:app:dexDebug’. > com.android.ide.common.process.ProcessE ...

  10. A题笔记(4)

    No. 1384 这题没啥 不过网考成绩出了,发现我的口语分数相较其他人还挺高的~~~哈哈哈 Code::Blocks 有时在程序运行结束后,.exe 并没有结束,因而之后无论怎么调试和修改代码,运行 ...