首页 > 其他分享 >Day5

Day5

时间:2024-02-07 17:56:07浏览次数:19  
标签:int age Day5 id 运算符 Array Maker

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

相关文章

  • 云计算学习day5
    首先学习了如何找文件一共有三种:locate格式:locate文件(夹)优点:块(相当于目录寻找)缺点:不全,会列出所有包含内容的文件,新建的搜不到(需刷新update)which只能用于搜索命令位置$PATH(命令文件)echo$PATH(列出所有命令文件所在的文件夹)which命令=whereis(更详细)find缺点:慢(相......
  • 初步学习java的方法 Day5
    命令行传递参数示例图片:初识javaDay5publicstaticvoidmain(String[]args){inti=0;while(i<100){i+=1;System.out.println(i);if(i==30){break;}}}public......
  • winter 2024 day5
    SMU2024winterround17-1最好的文档1#include<bits/stdc++.h>2usingnamespacestd;3#defineintlonglong4//#defineint__int1285#definedoublelongdouble6typedefpair<int,int>PII;7typedefpair<string,int>PSI;8typedef......
  • Day59 接口的定义与实现
    接口的定义与实现1.接口介绍普通类:只有具体实现抽象类:具体实现(普通方法)和规范(抽象方法)都有!接口:只有规范!(比抽象类还要抽象)自己无法写方法专业的约束!约束和实现分离:面向接口编程接口就是规范,定义的是一组规则,体现了现实世界中”如果你是...则必须能...”的思想。如果你是天使,......
  • Day58 抽象类
    抽象类通过abstract修饰符来修饰类就叫抽象类通过abstract修饰符来修饰方法就叫抽象方法Action.java及笔记!packagecom.oop.demo10;//在一个类前面加上abstract就变成了抽象类:类extends:单继承~(接口可以多继承)publicabstractclassAction{//约束~有......
  • Day57 Static关键字详解
    Static关键字详解static加在方法上叫静态方法static加在属性上叫静态属性1.staticpackagecom.oop.demo09;//staticpublicclassStudent{//一.静态属性privatestaticintage;//加了static是静态的变量多线程!privatedoublescore;//没有s......
  • Day55 多态
    多态什么是多态即同一方法可以根据发送对象的不同而采用多种不同的行为方式。一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)多态存在的条件有继承关系子类重写父类方法父类引用指向子类对象注意:多态是方法的多态,属性没有多态性。......
  • 寒假集训Day5
    vector去重unique(a.begin(),a.end());返回一段没有重复的数组的末尾得到去重后的数组:a.erase(unique(a.begin(),a.end()),a.end());二分推荐写法intl=1,r=1e9,ans;while(l<=r){intmid=(l+r)>>1;if(check(mid)){ans=mid;l=mid+1;......
  • Day54 面向对象11:方法重写
    面向对象11:方法重写(子类父类必须为非静态方法,无static)!重点:先看笔记!重写:需要有继承关系,是子类重写父类的方法!//重写只针对方法不针对属性或其它的1.方法名必须相同2.参数列表列表必须相同3.修饰符:范围可以扩大:public>Protected>Default>private4.抛......
  • Java学习日记 Day5 今天开始十点准时下班,身体是革命的本钱。。
    JavaSE:今天终于把集合结束了,这周尽量看完IO、多线程和网络编程吧。①Map的常用方法:基本还是增删改查的那些东西,挑重要的讲了。一个是keySet(),能过获取map中所有的key值,values()方法能够获取map中所有的数据值。但其实获取了key之后通过get(key)遍历也能获得属性值。②HashMap、Ta......