一个案例理解C++面向对象之运算符重载
时间:2021-08-13
本文章向大家介绍一个案例理解C++面向对象之运算符重载,主要包括一个案例理解C++面向对象之运算符重载使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
运算符重载是C++面向对象基础知识,本文通过一个自定义的string类完全理解运算符重载并且能够温习const与引用的相关知识:
- 首先构造一个字符串类,既然是字符串类,基本的两个属性应该是必需的:字符串和字符串长度
// String类的组成
class String
{
private:
char* str;
int len;
}
- 其次为了完成字符串的初始化需要定义构造函数,为了保证内存不泄露需要定义析构函数,为了保证深拷贝定义复制拷贝函数
class String
{
public:
String();
String(char* s);
~String();
String(const String & s);
}
- 为了完成字符串的运算操作需要重载‘+’,‘*’,‘<<','>>'运算符
// 使用const成员函数实现右乘即“ str*3 <=> strstrstr ”的功能
String operator*(int num) const;
// 使用成员函数实现赋值运算即“ String1 = String2 = "string" ”的功能
String & operator=(const String & s);
// 使用成员函数实现中括号索引运算即“ String[1] ”的功能
char & operator[](int num);
// 使用const成员函数实现常对象的中括号索引运算即“ String[1] ”的功能
const char & operator[](int num) const;
// 使用友元函数重载实现左乘即“ 3*str <=> strstrstr ”的功能
friend String operator*(int num,const String & s);
// 使用友元函数实现加法即“ str1+str2 <=> str1str2 ”的功能
friend String operator+(const String & s1,const String & s2);
// 使用友元函数实现输出即“ cout<<str ”的功能
friend std::ostream & operator<<(std::ostream & os,const String & s);
// 使用友元函数实现输入即“ cin>>str ”的功能
friend std::istream & operator>>(std::istream & is,String & s);
- 为了保证自定义String类和字符串指针的等价转换需要定义转换函数
// 使用转换函数完成类类型到字符串指针的转换即“ char* ch = String ”的功能
// 仅含一个参数的构造函数可以作为参数类型到类类型的转换
// 使用explicit关键字限制只能进行强制类型转换
explicit operator char*();
- 完整的String类的定义如下:
String.h
class String
{
private:
char* str;
int len;
public:
// 构造函数和析构函数
String();
String(char* s);
~String();
// 重载运算符
String operator*(int num) const;
friend String operator*(int num,const String & s);
friend String operator+(const String & s1,const String & s2);
friend std::ostream & operator<<(std::ostream & os,const String & s);
friend std::istream & operator>>(std::istream & is,String & s);
// 强制类型转换函数
explicit operator char*();
};
- 完整的实现为:
String.cpp
#include <iostream>
#include "String.h"
using namespace std;
String::String()
{
// 默认构造函数
str = new char[1]; // 保证析构函数delete的一致性
str[0] = '\0';
len = 0;
}
String::String(const char* s)
{
// 使用字符串指针构造
len = strlen(s);
str = new char[len+1];
strcpy(str, s);
}
String::~String()
{
// 析构函数释放内存
len = 0;
delete [] str;
}
String::String(const String & s)
{
// 复制构造函数
len = s.len;
delete [] str;
str = new char[len+1];
strcpy(str,s.str);
}
String String::operator*(int num) const
{
// 字符串乘法(成员函数)
String result;
result.len=len*3;
delete [] result.str; // 释放原有内存
result.str=new char[result.len+1];
result.str[0]='\0';
for(int i=0;i<num;i++)
result.str=strcat(result.str,str);
return result;
}
String & String::operator=(const String & s)
{
// 赋值重载函数需要注意:
// 1. 释放以前的内存
// 2. 防止赋值给自身
// 3. 返回引用值
if(this == &s)
return *this;
len=s.len;
delete [] str;
str=new char[len+1];
strcpy(str,s.str);
}
char & String::operator[](int num)
{
// 中括号重载,因为结果可为可修改的左值,所以返回值为非const引用
return str[num];
}
const char & String::operator[](int num) const
{
// 中括号重载,适用于常对象的数据访问
return str[num];
}
String operator*(int num,const String & s)
{
// 字符串乘法(友元函数)
return s*num;
}
String operator+(const String & s1,const String & s2)
{
// 字符串加法
String sum;
sum.len = s1.len + s2.len;
delete [] sum.str;
sum.str = new char[sum.len+1];
strcpy(sum.str,s1.str);
strcat(sum.str,s2.str);
}
ostream & operator<<(ostream & os,const String & s)
{
// 重定义<<
os<<s.str;
return os;
}
istream & operator>>(istream & is,String & s)
{
// 重定义>>
is>>s.str;
s.len=strlen(s.str);
}
String::operator char*()
{
// 转换函数(String类->字符串指针)
char* s=new char[len+1];
strcpy(s,str);
return s;
}
- 上述代码中涉及返回对象的选择,const、引用和普通对象,需要从实际含义去理解
原文地址:https://www.cnblogs.com/wheel-maker/p/15138899.html
- 零代码如何打造自己的实时监控预警系统
- 一步一步在Windows中使用MyCat负载均衡 上篇
- 你真的会玩SQL吗?之逻辑查询处理阶段
- javascript中如何正确将日期(Date)字符串转换为日期(Date)对象?
- 全面迎接.Net3.0时代的到来(WCF/WF/WPF/LINQ)
- SQL Server 2005 正则表达式使模式匹配和数据提取变得更容易
- [基础]datagridview绑定数据源的几种常见方式
- c#:winform鼠标拖动窗口大小时,设定窗口最小尺寸
- 在非SqlServer数据库上实现MemberShip和Role功能(自定义MemberShipProvider和RoleProvider)
- 一种实用的表格行鼠标点击高亮效果
- Lucene:QueryParser中操作符的疑惑
- 利用Boost影响Lucene查询结果的排序
- 利用Boost影响Lucene查询结果的排序
- linq to sql取出随机记录/多表查询/将查询出的结果生成xml
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法