01.数组类
1.目的:设计一个类,该类有数组的功能,可以存储数据,可以删除修改数据
2.设计核心数据
1.属性:指针(指向堆区空间),数组实际存储的元素个数,数组容量
2.方法:构造(开辟堆区空间),尾插,头插,指定位置插入,尾删,头删,获取指定位置的值,指定位置修改值,获取数组元素个数,获取数组容量,析构函数
3.代码实现(看代码)
// array.h
#pragma once
#include<iostream>
using namespace std;
class Array
{
public:
Array();
Array(const Array& arr);
Array(int maxsize, int val = 0);
~Array();
void push_back(int val);
void push_front(int val);
void pop_front();
void pop_back();
int Size();
int Maxsize();
void Insert(int pos, int val);
int& Get(int pos);
void Set(int pos, int val);
private:
int* pArray;
int size;
int maxsize;
};
//array.cpp
#include "array.h"
Array::Array() {
this->maxsize = 20;
this->size = 0;
//堆申请空间
this->pArray = new int[this->maxsize];
//初始化空间
for (int i = 0; i < this->maxsize; i++)
{
pArray[i] = 0;
}
}
Array::Array(const Array& arr) {
this->maxsize = arr.maxsize;
this->size = 0;
//堆申请空间
this->pArray = new int[arr.maxsize];
//初始化空间
for (int i = 0; i < arr.maxsize; i++)
{
pArray[i] = arr.pArray[i];
}
}
Array::Array(int maxsize, int val) {
this->maxsize = maxsize;
this->size = maxsize;
this->pArray = new int[maxsize];
for (int i = 0; i < maxsize; i++)
{
this->pArray[i] = val;
}
}
Array::~Array() {
if (this->pArray != NULL) {
delete[] this->pArray;
this->pArray = NULL;
}
}
void Array::push_back(int val) {
if (this->maxsize == this->size)
return;
this->pArray[size] = val;
this->size++;
}
void Array::push_front(int val) {
if (this->maxsize == this->size)
return;
for (int i = this->size - 1; i >= 0; i--) {
this->pArray[i + 1] = this->pArray[i];
}
this->pArray[0] = val;
this->size++;
}
void Array::pop_front() {
if (this->size == 0) return;
for (int i = 1; i <= this->size - 1; ++i) {
this->pArray[i - 1] = this->pArray[i];
}
this->size--;
}
void Array::pop_back() {
if (this->size == 0) return;
this->size--;
}
int Array::Size() {
return this->size;
}
int Array::Maxsize() {
return this->maxsize;
}
void Array::Insert(int pos, int val) {
if (this->maxsize == this->size)
return;
if (pos < 0 || pos > this->maxsize - 1) {
return;
}
for (int i = this->size - 1; i >= pos - 1; i--) {
this->pArray[i + 1] = this->pArray[i];
}
this->pArray[pos - 1] = val;
this->size++;
}
int& Array::Get(int pos) {
return this->pArray[pos];
}
void Array::Set(int pos, int val) {
if (pos<0 || pos>this->maxsize)
return;
this->pArray[pos - 1] = val;
}
//main.cpp
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#include"array.h"
void PrintArray(Array& arr) {
for (int i = 0; i < arr.Size(); ++i) {
cout << arr.Get(i) << " ";
}
cout << endl;
}
int main() {
Array newarr(20, 1);
PrintArray(newarr);
}
02.运算符重载的概念
1.运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
2.运算符重载的目的是让语法更加简洁
3.运算符重载不能改变本来寓意,不能改变基础类型寓意
4.运算符重载的本质是另一种函数调用(是编译器去调用)
5.这个函数同一的名字叫operator
6.重载函数可以写成全局或成员函数
7.重载函数如果写成全局的,那么双目运算符左边的是第一个参数,右边是第二个参数
8.重载函数如果写成成员函数,那么双目运算符的左边是this,右边是第一个参数
9.不能改变运算符优先级,不能改变运算符的参数个数。
03.加号运算符重载
1.同类型的对象相加
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Maker {
public:
Maker(int age,int id) {
this->age = age;
this->id = id;
}
//成员函数重载
/*Maker operator+(Maker& m2) {
Maker tmp(this->age + m2.age, this->id + m2.id);
return tmp;
}
*/
public:
int age;
int id;
};
// 全局重载
//全局方式 //3.编译器调用这个函数
//2.编译器检查参数是否对应,第一个参数是加的左边,第二参数是加号的右边
Maker operator+(Maker& m1, Maker& m2) {
Maker tmp(m1.age + m2.age, m1.id + m1.age);
return tmp;
}
void test() {
Maker m1(5,10);
Maker m2(10, 5);
//1.编译器看到两个对象相加,那么编译器会去找有没有叫operator+的函数
// Maker tmp(m1 + m2);//调用拷贝构造;
Maker tmp = m1 + m2; //调用拷贝构造
cout << tmp.age <<endl <<tmp.id << " " << "\n";
}
int main() {
test();
}
2.不同类型的对象相加
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Maker
{
public:
Maker(int id, int age)
{
this->id = id;
this->age = age;
}
public:
int id;
int age;
};
class Student
{
public:
Student()
{
mid = 0;
}
Student(int id)
{
mid = id;
}
public:
int mid;
};
Student operator+(Maker &m1,Student &s1) {
Student tmp(m1.age + s1.mid);
return tmp;
}
int main() {
Maker m1(10, 20);
Student m2(2);
Student tmp = m1 + m2;
cout << tmp.mid << endl;
}
04.减号运算符重载(重点)
class Maker
{
public:
Maker(int id)
{
this->id = id;
}
Maker operator-(Maker& m2) {
Maker tmp(this->id - m2.id);
return tmp;
}
public:
int id;
};
int operator-(Maker& m1, int a) {
return m1.id - a;
}
void test()
{
Maker m1(30);
Maker m2(10);
Maker tmp = m1 - m2;
cout << tmp.id << endl;
int k = m1 - 5;
cout << k << endl;
}
int main() {
test();
}
05.左移和右移运算符重载(重点难点)
1.左移运算符重载
1.cout是对象,<<是左移运算符
2.重载左移运算符是为了直接打印对象
3.形参和实参是一个对象
4.不能改变库类中的代码
5.ostream中把拷贝构造函数私有化了
4.如果要和endl一起使用,那么必须返回ostream的对象.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Maker
{
//如果要访问类的私有成员,那么把<<重载函数声明为友元
friend ostream& operator<<(ostream& out, Maker& m);
public:
Maker(int id, string name)
{
this->id = id;
this->name = name;
}
private:
int id;
string name;
};
//1.形参和实参是一个对象
//2.不能改变库类中的代码
//3.ostream中把拷贝构造函数私有化了 所以要引用返回 如果值返回是拷贝构造
//4.如果要和endl一起使用,那么必须返回ostream的对象
// cout 是一个对象 类是ostream
ostream& operator<<(ostream& cout, Maker& m) {
cout << m.id << " " << m.name << endl;
return cout;
}
void test01()
{
Maker m(10, "小花");
cout << m << endl;
}
int main() {
test01();
}
2.右移运算符重载
class Maker
{
friend istream & operator>>(istream &in, Maker &m);
public:
Maker(string name, int age)
{
this->name = name;
this->age = age;
}
int getAge()
{
return age;
}
private:
string name;
int age;
};
istream &operator>>(istream &in, Maker &m)
{
in >> m.age;
in >> m.name;
return in;
}
void test02()
{
Maker m("悟空", 15);
Maker m2("悟空2", 25);
cin >> m>>m2;
cout << m.getAge() << endl;
cout << m2.getAge() << endl;
}
06.赋值运算符重载(重点)
1.编译器默认给类提供了一个默认的赋值运算符重载函数
2.默认的赋值运算符重载函数进行了简单的赋值操作
class Maker
{
public:
Maker()
{
id = 0;
age = 0;
}
Maker(int id, int age)
{
this->id = id;
this->age = age;
}
public:
int id;
int age;
};
void test()
{
Maker m1(10, 20);
Maker m2;
m2 = m1;//赋值操作
//默认的赋值运算符重载函数进行了简单的赋值操作
cout << m2.id << " " << m2.age << endl;
}
3.当类有成员指针时,然后在构造函数中申请堆区空间,在析构函数中释放堆区空间,会出现同一块空间释放2次,然后内存泄漏,所以要重写赋值运算符重载函数
class Student
{
public:
Student(const char *name)
{
pName = new char[strlen(name) + 1];
strcpy(pName, name);
}
//防止浅拷贝
Student(const Student &stu)
{
pName = new char[strlen(stu.pName) + 1];
strcpy(pName, stu.pName);
}
//重写赋值运算符重载函数
Student &operator=(const Student &stu)
{
//1.不能确定this->pName指向的空间是否能装下stu中的数据,所以先释放this->pName指向的空间
if (this->pName != NULL)
{
delete[] this->pName;
this->pName = NULL;
}
//2.申请堆区空间,大小由stu决定
this->pName = new char[strlen(stu.pName) + 1];
//3.拷贝数据
strcpy(this->pName, stu.pName);
//4.返回对象本身
return *this;
}
~Student()
{
if (pName != NULL)
{
delete[] pName;
pName = NULL;
}
}
void printStudent()
{
cout << "Name:" << pName << endl;
}
public:
char *pName;
};
void test02()
{
Student s1("悟空");
Student s2("小林");
s1.printStudent();
s2.printStudent();
s1 = s2;//赋值操作
s1.printStudent();
s2.printStudent();
//复数运算不会出错
//s1 = s2 = s3;
}
4.赋值运算符重载函数中,为什么要返回引用
void test03()
{
Student s1("a");
Student s2("b");
Student s3("c");
s1 = s2 = s3;//s3赋值s2,s2赋值给s1
cout << &(s2 = s3) << endl;
cout << &s2 << endl;
//如果返回的是值,s2=s3这个表达式会产生一个新的对象
//s1=s2=s3,赋值运算符本来的寓意,是s3赋值s2,s2赋值给s1
//也就是说s2=s3这个表达式要返回s2这个对象,所以要返回引用
}
07.关系运算符重载(了解)
class Maker
{
public:
Maker()
{
id = 0;
age = 0;
}
Maker(int id, int age)
{
this->id = id;
this->age = age;
}
bool operator==(Maker &m)
{
if (this->id == m.id && this->age == m.age)
{
return true;
}
return false;
}
bool operator!=(Maker &m)
{
if (this->id != m.id || this->age != m.age)
{
return true;
}
return false;
}
public:
int id;
int age;
};
void test()
{
Maker p1(1, 20);
Maker p2;
if (p1 == p2)
{
cout << "真" << endl;
}
else
{
cout << "假" << endl;
}
if (p1 != p2)
{
cout << "真" << endl;
}
else
{
cout << "假" << endl;
}
}
08.前置加加和后置加加运算符重载(重点难点)
class Maker
{
friend ostream &operator<<(ostream &out, Maker &m);
public:
Maker(int a)
{
this->a = a;
}
//重载前置加加
Maker &operator++()
{
++this->a;
return *this;
}
//后置加加,
Maker operator++(int)//占位参数,必须是int
{
//后置加加,先返回,后加加
Maker tmp(*this);//1.*this里面的值a是等于2
++this->a;//这个对象的a等3
return tmp;
}
private:
int a;
};
ostream &operator<<(ostream &out, Maker &m)
{
out << m.a << endl;
return out;
}
void test02()
{
Maker m1(1);
cout << m1 << endl;//1
cout << ++m1 << endl;//2
//++(++m1);
cout << m1++ << endl;//2 这里返回的拷贝的tmp对象
cout << m1 << endl;//3 这里返回的是++this->a的对象
//同等条件下,优先使用前置加加,不需要产生新的对象和调用拷贝构造
}
09.数组下标运算符重载(重点)
MyArray.h
class MyArray
{
public:
//重写赋值运算符重载函数
Array::operator=(const Array& arr);
//要能当左右值
int &operator[](int index);
};
MyArray.cpp
//重写赋值运算符重载函数
Array& Array::operator=(const Array& arr) {
if (this->pArray != NULL) {
delete[] this->pArray;
this->pArray = NULL;
}
this->maxsize = arr.maxsize;
this->size = arr.size;
this->pArray = new int[arr.maxsize];
for (int i = 0; i < arr.maxsize; ++i) {
this->pArray[i] = arr.pArray[i];
}
return *this;
}
//要能当左右值
int& Array::operator[](int index) {
if (this->size <= index)
this->size++;
//被赋值时候会时会递增自己的size 算法
return this->pArray[index];
}
数组下标重载.cpp
void test02()
{
Array newarr(20, 1);
PrintArray(newarr);
Array newarr1;
newarr1 = newarr;
PrintArray(newarr1);
MyArray arr;
Array a1(20, 1);
for (int i = 0; i < 20; ++i)
a1[i] = i + 10;
PrintArray(a1);
}
标签:int,age,Day5,id,运算符,Array,Maker
From: https://www.cnblogs.com/wbcde116/p/18011153