重载

  • 重载=操作符

    • 1先释放旧对象资源
    • 2用一个对象=给另外一个对象
    • 3函数返回值当左值 返回一个引用
    • 4 数组类 Array& operator=(Array& a1);
    • 5 字符串类:MyString& operator=(const MyString& obj);
    • char& operator[](int index) const;
  • 运算符重载难点
    • 重载=操作符

      • 1先释放旧对象资源
      • 2用一个对象=给另外一个对象
      • 3函数返回值当左值 返回一个引用
      • 4 数组类 Array& operator=(Array& a1);
      • 5 字符串类:MyString& operator=(const MyString& obj);
    • char& operator[](int index) const;
    • 重载[]数组下标
      • 1 返回元素的引用,支持a[i]当左值 a[i]右值
      • 2 数组类 int& operator[](int i);
      • 3 字符串类 char& operator[](int index) const;
    • && 和 || 不能被重载
    • ()重载
  • 案例:数组类 运算符重载优化
  • 案例:字符串类 运算符重载

等号运算符重载

  • 重载=操作符

    • 1 先释放旧对象资源
    • 2 用一个对象=给另外一个对象
    • 3 函数返回值当左值 返回一个引用
    • 4 数组类 Array& operator=(Array& a1);
    • 5 字符串类:MyString& operator=(const MyString& obj);
    • char& operator[](int index) const;
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h> using namespace std; class Student
{
public:
Student()
{
this->id = 0;
this->name = NULL;
} Student(int id, char *name)
{
this->id = id; //this->name = name;
int len = strlen(name);
this->name = new char[len + 1];
strcpy(this->name, name);
} Student(const Student &another)
{
this->id = another.id; //深拷贝
int len = strlen(another.name);
this->name = new char[len + 1];
strcpy(this->name, another.name);
} Student & operator=(const Student &another)
{
//1 防止自身赋值
if (this == &another) {
return *this;
} //2 先将自身的额外开辟的空间回收掉
if (this->name != NULL) {
delete[] this->name;
this->name = NULL;
this->id = 0;
} //3 执行深拷贝
this->id = another.id; int len = strlen(another.name);
this->name = new char[len + 1];
strcpy(this->name, another.name); //4 返回本身
return *this;
} void printS()
{
cout << name << endl;
} ~Student() {
if (this->name != NULL) {
delete[] this->name;
this->name = NULL;
this->id = 0;
}
}
private:
int id;
char *name;
}; int main(void)
{ Student s1(1, "zhang3");
Student s2(s1); s2 = s1; Student s3(2, "li4"); //s2 = s3 = s1;//s2 = 赋值操作符 s1.printS();
s2.printS();
s3.printS(); return 0;
}

自定义数组类运用重载

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "MyArray.h" using namespace std; int main(void)
{ MyArray array1(10);//开辟10元素的数组 //赋值操作
for (int i = 0; i < 10; i++) {
//array1.setData(i, i + 10);
array1[i] = i + 10;//space[1] = 1+10
} cout << "--------" << endl; cout << "array1:" << endl;
for (int i = 0; i < 10; i++) {
cout << array1[i] << " ";
}
cout << endl; MyArray array2 = array1;
cout << "array2:" << endl;
for (int i = 0; i < array2.getLen(); i++) {
cout << array2[i] << " ";
}
cout << endl; cout << " ------------" << endl;
MyArray array3(5); cin >> array3; cout << "array3:" << endl;
cout << array3 << endl;
cout << endl; if (array3 != array1) {
cout << "不相等" << endl;
}
else {
cout << "相等 " << endl;
} return 0;
}

Array.cpp

#include "MyArray.h"

MyArray::MyArray()
{
cout << "MyArray()..." << endl;
this->len = 0;
this->space = NULL;
} MyArray::MyArray(int len)
{
if (len <= 0) {
this->len = 0;
return;
}
else {
this->len = len; //给space开辟空间
this->space = new int[this->len];
cout << "MyArray::MyArray(int len) ..." << endl;
}
}
MyArray::MyArray(const MyArray &another)
{
if (another.len >= 0) {
this->len = another.len; //深拷贝
this->space = new int[this->len];
for (int i = 0; i < this->len; i++) {
this->space[i] = another.space[i];
}
cout << "MyArray::MyArray(const MyArray &another) ..." << endl; }
}
MyArray::~MyArray()
{
if (this->space != NULL) {
delete[]this->space;
this->space = NULL;
len = 0;
cout << "MyArray::~MyArray() ..." << endl;
}
} void MyArray::setData(int index, int data)
{
if (this->space != NULL) {
this->space[index] = data;
}
}
int MyArray::getData(int index)
{
return this->space[index];
}
int MyArray::getLen() const
{
return this->len;
} MyArray& MyArray::operator=(const MyArray& another)
{
if (this == &another) {
return *this;
} if (this->space != NULL) {
delete[]this->space;
this->space = NULL;
this->len = 0;
} if (another.len >= 0) {
this->len = another.len; //深拷贝
this->space = new int[this->len];
for (int i = 0; i < this->len; i++) {
this->space[i] = another.space[i];
}
cout << "MyArray::operator=(const MyArray& another) ..." << endl; } return *this;
} int & MyArray::operator[](int index) const
{
return this->space[index];
} ostream &operator<<(ostream &os,const MyArray &array)
{
os << "遍历整个数组 " << endl;
//array.getLen(); //getLen(&array);
for (int i = 0; i < array.getLen(); i++) {
os << array[i] <<" ";//array.operator[]( i)
} os << "调用的<<操作符重载" << endl; return os;
} istream &operator>>(istream &is, MyArray &array)
{
cout << "请输入" << array.getLen() << "个数" << endl;
for (int i = 0; i < array.getLen(); i++) {
cin >> array[i];
}
return is;
} bool operator==(MyArray &array1, MyArray &array2)
{
if (array1.len != array2.len) {
return false;
} for (int i = 0; i < array1.len; i++) {
if (array1.space[i] != array2.space[i]) {
return false;
}
} return true;
}
bool MyArray::operator!=(MyArray &another)
{
return !(*this == another);
}

Array.h

#pragma once
#include <iostream> using namespace std; class MyArray
{
public:
MyArray();
MyArray(int len);
MyArray(const MyArray &another);
~MyArray(); void setData(int index, int data);
int getData(int index);
int getLen() const ; MyArray& operator=(const MyArray& another); int & operator[](int index) const; friend ostream &operator<<(ostream &os,const MyArray &array);
friend istream &operator>>(istream &is, MyArray &array); friend bool operator==(MyArray &array1, MyArray &array2);
bool operator!=(MyArray &another);
private:
int len;
int *space;
};

重载小括号

#define _CRT_SECURE_NO_WARNINGS
#include <iostream> using namespace std; class Sqr
{
public:
Sqr(int a) {
this->a = a;
} int operator()(int value)
{
return value * value;
} int operator()(int value1, int value2)
{
return value1 * value2;
} private:
int a;
}; void func(int a)
{ } int main(void)
{
Sqr s(10); int value = s(2);
//s.operator()(2); //将一个对象 当成一个普通函数来调用。
//称这种对象是 仿函数,伪函数, 函数对象 cout << value << endl; value = s(10, 20); cout << value << endl; return 0;
}

重载new和delete运算符

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream> using namespace std; class A
{
public:
A()
{
cout << "A()..." << endl;
}
A(int a) {
cout << "A(int)..." << endl;
this->a = a;
} //重载的new操作符 依然会触发对象的构造函数
void * operator new(size_t size)
{
cout << "重载了new操作符" << endl;
return malloc(size);
} void *operator new[](size_t size)
{
cout << "重载了new[]操作符" << endl;
return malloc(size);
}
void operator delete(void * p)
{
cout << "重载了delete操作符" << endl;
if (p != NULL) {
free(p);
p = NULL;
}
} void operator delete[](void *p)
{
cout << "重载了delete[]操作符" << endl;
if (p != NULL) {
free(p);
p = NULL;
}
} ~A() {
cout << "~A().... " << endl;
} private:
int a;
}; int main(void)
{
//char *array = malloc(sizeof(char)* 80); //int *value_p = new int; A *array_p = new A[10]; //array_p->operator new[](sizeof(A[10]));
delete[] array_p; A *ap = new A(10); //ap->operator new(sizeof(A)); delete ap; return 0;
}

重载&&和||(不建议重载)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream> using namespace std; class Test
{
public:
Test(int value) {
this->value = value;
} Test operator+(Test &another)
{
cout << "执行了+操作符重载" << endl;
Test temp(this->value + another.value);
return temp;
} bool operator&&(Test &another)
{
cout << "执行了&&操作符重载" << endl;
if (this->value && another.value) {
return true;
}
else {
return false;
} } bool operator||(Test &another)
{
cout << "重载了||操作符" << endl;
if (this->value || another.value) {
return true;
}
else {
return false;
}
} ~Test(){
cout << "~Test()..." << endl;
}
private:
int value;
}; int main(void)
{
int a = 1;
int b = 20; Test t1(0);
Test t2(20); //重载&&操作符,并不会发生短路现象。 if (t1 && (t1+t2) ) { //t1.operator&&( t1.operator+(t2) )
cout << "为真" << endl;
}
else {
cout << "为假" << endl;
} cout << "------" << endl; if (t1 || (t1 + t2)) {//t1.operator||( t1.operator+(t2) )
cout << "为真" << endl;
}
else {
cout << "为假" << endl;
} return 0;
}

自定义智能指针

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <memory> using namespace std; class A
{
public:
A(int a)
{
cout << "A()..." << endl;
this->a = a;
} void func() {
cout << "a = " << this->a << endl;
} ~A() {
cout << "~A()..." << endl;
}
private:
int a;
}; class MyAutoPtr
{
public:
MyAutoPtr(A * ptr)
{
this->ptr = ptr;//ptr = new A(10)
} ~MyAutoPtr() {
if (this->ptr != NULL) {
cout << "delte ptr" << endl;
delete ptr;
this->ptr = NULL;
}
} A* operator->()
{
return this->ptr;
} A& operator*()
{
return *ptr;
} private:
A *ptr;
}; void test1()
{
#if 0
A* ap = new A(10); ap->func();
(*ap).func(); delete ap;
auto_ptr<int> ptr(new int);
#endif
auto_ptr<A> ptr(new A(10)); ptr->func();
(*ptr).func();
} void test2()
{
MyAutoPtr my_p(new A(10)); my_p->func(); //my_p.ptr -> func()
(*my_p).func(); // *ptr.func()
}
int main(void)
{ //test1();
test2(); return 0;
}

自定义字符串类

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include "MyString.h" using namespace std; int main(void)
{
string s1;
MyString s1("abc");
MyString s2("123"); //cout << s1 + s2 << endl; cout << s1 << endl;
cout << s2 << endl; #if 0
MyString s1("abc");
MyString s2(s1);
MyString s3 = "123"; cout << s1 << endl;
cout << s2 << endl; s1[1] = 'x'; cout << s1 << endl; s1 = s3; cout << s1 << endl; #endif
return 0;
}

String.cpp

#include "MyString.h"

MyString::MyString()
{
this->len = 0;
this->str =NULL;
} MyString::MyString(const char *str)
{
if (str == NULL) {
this->len = 0;
this->str = new char[0 + 1];
strcpy(this->str, "");
}
else {
int len = strlen(str);
this->len = len; this->str = new char[len + 1];
strcpy(this->str, str);
}
} //初始化时候被调用的
MyString::MyString(const MyString &another)
{
this->len = another.len;
this->str = new char[this->len + 1];
strcpy(this->str, another.str);
} MyString::~MyString()
{
if (this->str != NULL) {
cout << this->str << "执行了析构函数" << endl;
delete this->str;
this->str = NULL;
this->len = 0;
}
} char & MyString::operator[](int index)
{
return this->str[index];
} MyString & MyString::operator=(const MyString &another)
{
if (this == &another) {
return *this;
} if (this->str != NULL) {
delete[] this->str;
this->str = NULL;
this->len = 0;
} this->len = another.len;
this->str = new char[this->len + 1];
strcpy(this->str, another.str); return *this;
} ostream & operator<<(ostream &os, MyString&s)
{
os << s.str;
return os;
} istream & operator>>(istream &is, MyString &s)
{
//1 将s之前的字符串释放掉
if (s.str != NULL) {
delete[] s.str;
s.str = NULL;
s.len = 0;
} //2 通过cin添加新的字符串
char temp_str[4096] = { 0 };
cin >> temp_str; int len = strlen(temp_str);
s.str = new char[len + 1];
strcpy(s.str, temp_str);
s.len = len; return is;
} MyString MyString::operator+(MyString &another)
{
MyString temp; int len = this->len + another.len; temp.len = len; temp.str = new char[len + 1];
memset(temp.str, 0, len + 1);
strcat(temp.str, this->str);
strcat(temp.str, another.str); return temp;
}

String.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std; class MyString
{
public:
MyString();
//MyString(int len); //创建一个长度是len的string对象
MyString(const char *str);
MyString(const MyString &another);
~MyString(); //重载操作符[]
char &operator[](int index); //重载操作符>>
friend istream & operator>>(istream &is, MyString &s); //重载=操作符
MyString & operator=(const MyString &another); //重载==操作符 //重载!=操作符 //重载+操作符
MyString operator+(MyString &another); //重载操作符<<
friend ostream & operator<<(ostream &os, MyString&s); private:
int len;
char *str;
};

c++-重载等号,数组,指针,字符串类的更多相关文章

  1. C语言中字符数组和字符串指针分析

    这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么 用到过C,虽然网上这类的文章也有很多,还是决定自己在这 ...

  2. 第二十九节:Java基础知识-类,多态,Object,数组和字符串

    前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...

  3. 指针,数组,字符串的区别(高质量程序设计指南C++/C语言第7章)

    指针: 指针是变量,和平时的那些变量没有本质的差异,不同的只是它的值和类型,.,即解释方式 二进制层面:指针的值是内存单元的地址,而变量是引用内存单元值的别名 语言层面:指针的值就是变量的地址. 对象 ...

  4. php byte数组与字符串转换类

    <?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...

  5. C语言基础:指针类型与指针和数组、字符串的关系

    //指针变量就是用来存储地址的,只能存储地址 格式:  int  *p;  这个p为指针变量:指针变量占8个字节 类型是用来说明这个指针指向的类型: 比如上边的int代表这个指针变量会指向int类型的 ...

  6. 「C」 数组、字符串、指针

    一.数组 (一)数组 概念:用来存储一组数据的构造数据类型 特点:只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素. (二)数组的定义 格式: 类型 数组名[元素个数 ...

  7. C语言基础复习:字符,字符数组,字符串,字符指针

    1. 概述2. 字符2.1 字符定义和大小2.2 字符的输入和输出2.3 字符的计算3. 字符数组3.1 字符数组的定义和大小3.2 字符数组的输入和输出3.3 字符数组的计算4. 字符串4.1 字符 ...

  8. 编码实现字符串类CNString实现运算符重载

    题目描述: 编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下"="运算符."+"运算."[]& ...

  9. [C++基础]那些容易被混淆的概念:函数/数组指针-指针函数/数组,类/函数模板-模板类/函数

    函数指针-指针函数 函数指针的重点是指针.表示的是一个指针,它指向的是一个函数.eg: int (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.eg: int* fun() ...

随机推荐

  1. 一图读懂Spring Core,Spring MVC, Spring Boot,Spring Cloud 的关系与区别

    Spring框架自诞生到现在,历经多次革新,形成了多种不同的产品,分别应用于不同的项目中,为了帮助自己理解这些产品之间的关系,特此整理此图,以便自己记忆和复习.

  2. day48天jQuary

    今日内容 jQuery jQuery引入 下载链接:[jQuery官网](https://jquery.com/),首先需要下载这个jQuery的文件,然后在HTML文件中引入这个文件,就可以使用这个 ...

  3. Linux -- 进程间通信几种方式的总结

    管道 优点 管道文件不占磁盘空间,打开管道时在内存中分配空间: 管道读端会在读取完管道内数据后自动进入阻塞,直到写端再次写入数据: 缺点 管道是半双工的,数据只能从一个方向上流动: 管道大小 PIPE ...

  4. TensorBoard:可视化学习

    数据序列化 TensorBoard 通过读取 TensorFlow 的事件文件来运行.TensorFlow 的事件文件包括了你会在 TensorFlow 运行中涉及到的主要数据.下面是 TensorB ...

  5. 如何使用Selenium来计算自动化测试的投资回报率?

    跨浏览器测试是一种测试,需要大量的精力和时间.通过不同的浏览器,操作系统,设备,屏幕分辨率测试Web应用程序,以评估针对各种受众的Web内容呈现的过程是一项活动.特别是如果手动处理.使用Seleniu ...

  6. 删除排序数组中的重复项II

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  7. centos7更新php5.4到php5.6/php7

    centos7系统yum安装的php版本为5.4. 因业务需求,开发可能需要php5.6环境. 本文应需而生,介绍从php5.4升级到php5.6. 如需更新到php7环境,步骤一样. 如果是线上应用 ...

  8. 腾讯视频缓存 tdl 转 mp4

    找到腾讯视频->设置,看下缓存文件的目录地址,然后cmd,通过命令进行转化.  copy/b *.tdl 1.mp4

  9. 修改PHP上传文件大小限制

    1. 在php.ini中,做如下修改: file_uploads = on upload_tmp_dir = /home/upload upload_max_filesize = 4000M post ...

  10. Yii2 负载均衡找不到JS,CSS

    在部署项目的时候,用了2台服务器.请求的时候用了负载均衡,导致 YII2 的静态文件(js,css...)报 404 ,原因是: 请求一个页面时 A服务器 去处理,但是静态资源缺请求到了 B服务器 , ...