运算符重载语法:返回值类型  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. VWMare CentOS 6.5 静态IP设置

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVmYXVsdDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  2. 【c++】虚函数描写叙述符override

    在C++11中为了帮助程序猿写继承结构复杂的类型,引入了虚函数描写叙述符override,假设派生类在虚函数声明时使用了override描写叙述符,那么该函数必须重载其基类中的同名函数,否则代码将无法 ...

  3. [Redux] Using withRouter() to Inject the Params into Connected Components

    We will learn how to use withRouter() to inject params provided by React Router into connected compo ...

  4. codeblocks创建和使用静态库(C语言)

    静态库  (扩展名为 .a 或 .lib) 是包含函数的文件,用于在link阶段整合执行程序,动态链接库(扩展名  .dll)是不在link阶段整合进执行程序中的. DLL文件在执行阶段动态调用 下面 ...

  5. atlassian-jira-confluence-bitbucket破解

    ==================================================================================================== ...

  6. springmvc 返回xml

    需求: 1.springmvc返回xml: 技术及环境: Spring 4.3.1.RELEASE JDK 1.8 IDEA 15.0.6 Maven 3 实现: spirngxml的配置主要如下: ...

  7. jquery.qrcode和jqprint的联合使用,实现html生成二维码并打印(中文也ok)

    在公司的生产现场中,常常会在一些部品或设备上贴上二维码,用于扫描录入数据,免去手动输入的麻烦. 以前曾经做过winform的程序,生成二维码,并打印出来,使用的是zxing的类库, 但是如果二维码是附 ...

  8. CS=0xFFFF IP=0x0000与CS=F000 IP=FFF0

    计算机自动上电后,有些书上说CS=0xFFFF IP=0x0000,例如linux内核设计的艺术(第三版).也有一些书说CS=F000 IP=FFF0,例如赵炯的linux内核完全注释. 其实并不是说 ...

  9. PHP四种传参方式

    test1界面: <html> <head> <title>testPHP</title> <meta http-equiv = "co ...

  10. windows server 2003 系统重装蓝屏

    错误码:0X0000007B 这个代码和硬盘有关系,不过不用害怕,不是有坏道了,是设置问题或者病毒造成的硬盘引导分区错误.如果您在用原版系统盘安装系统的时候出这个问题,那说明您的机器配置还是比较新的, ...