day5-C++学习

1.加号运算符重载

如果想让自定义的数据类型进行+运算,那么就需要重载 + 运算符
重载+运算符时可以选择在成员函数或者全局函数中重写一个+运算符的函数
结构:函数名 operator+ () {}

第一种
class Person
{
public:
	Person() { m_A = 0, m_B = 0; };
	Person(int a, int b) :m_A(a), m_B(b)
	{}

	//+号运算符重载,成员函数
	Person operator+(Person& p)
	{
		Person temp;
		temp.m_A = this->m_A + p.m_A;
		temp.m_B = this->m_B + p.m_B;
		return temp;
	}
	
	int m_A;
	int m_B;
};
void test()
{
	Person p1(9, 111);
	Person p2(9, 111);
	
	Person p3 = p1 + p2;//关键字operator可以省略不写
	cout << p3.m_A << endl;//18
	cout << p3.m_B << endl;//222
}
第二种
class Person
{
public:
	Person() { m_A = 0, m_B = 0; };
	Person(int a, int b) :m_A(a), m_B(b)
	{}
	int m_A;
	int m_B;
};
//利用全局函数进行+号运算符的重载
Person operator+(Person& p1, Person& p2)
{
	Person temp;
	temp.m_A = p1.m_A + p2.m_A;
	temp.m_B = p1.m_B + p2.m_B;
	return temp;
}

void test()
{
	Person p1(9, 111);
	Person p2(9, 111);
	
	Person p3 = p1 + p2;//关键字operator可以省略不写
	cout << p3.m_A << endl;//18
	cout << p3.m_B << endl;//222
}

2.左移运算符重载

要注意:不要随意乱用符号重载;内置数据类型(如int)的运算符不可以重载
左移运算符cout<<是为了对自定义的数据类型进行输出

class Person
{
	//如果重载时候想访问 p1的私有成员,那么全局函数要做Person的友元函数
	friend ostream& operator<<(ostream& cout, Person& p);
public:
	Person() { m_a = 0, m_b = 0; };
	Person(int a, int b)
	{
		this->m_a = a;
		this->m_b = b;
	}

	//void operator<<()//重载左移运算符不可以写到成员函数中,因为在调用的时候会出现值在cout<<左边的情况,但我们需要的是cout<<值。
	//{

	//}
private:
	int m_a;
	int m_b;
};
//ostream是c++中的输出流,是一个定义输出到显示(输出)设备上的一个类&c++中表示引用,即使用的当前值,而不是通过自动复制的
ostream& operator<<(ostream& cout, Person& p)//第一个参数cout 第二个参数p1
{
	cout << "m_a = " << p.m_a << "m_b = " << p.m_b;

	return cout;//可做左值
}

void test()
{
	Person p1(10, 10);
	cout << p1 << endl;
	//operator<<(cout, p1);
	cout << p1 <<"hello" << endl;
}

3.前置后置的递增递减运算符重载

前置理念——先++ 后返回自身
后置理念——先保存住原有值 ,内部++ 返回临时数据

class MyInteger
{
	friend ostream& operator<<(ostream& cout, const MyInteger& myint);
public:
	MyInteger()
	{
		m_num = 0;
	}
	//重载++运算符 operator++() 前置   operator++(int) 后置
	//前置++重载 返回引用
	MyInteger& operator++()
	{
		this->m_num++;
		return *this;
	}
	//后置++重载 返回值
	MyInteger operator++(int)
	{
		//先保存目前数据
		MyInteger temp = *this;
		m_num++;
		return temp;//临时数据
	}

	//前置--重载
	MyInteger& operator--()
	{
		this->m_num--;
		return *this;
	}
	//后置--重载
	MyInteger operator--(int)
	{
		//先保存目前数据
		MyInteger temp = *this;
		m_num--;
		return temp;
	}
	int m_num;
};

ostream& operator<<(ostream& cout, const MyInteger& myint)
{
	cout << myint.m_num;
	return cout;
}

void test()
{
	MyInteger myint;
	myint++;//后置++
	++myint;//前置++
	cout << ++(++myint) << endl;
	cout << myint << endl;
	cout << myint++ << endl;
	cout << myint.m_num << endl;
}

4.指针运算符重载

class Person
{
public:
	Person(int Age)
	{
		this->age = Age;
	}
	void showage()
	{
		cout << "年龄为:" << this->age << endl;
	}

	~Person()
	{
		cout << "析构函数调用" << endl;
	}

	int age;
};

//智能指针,用来托管自定义类型的对象,让对象进行自动释放
class smartPointer
{
public:

	smartPointer(Person* person)
	{
		this->person = person;
	}

	//重载->让智能指针对象像Person * p一样使用
	Person* operator->()
	{
		return this->person;
	}
	//重载*
	Person& operator*()
	{
		return *this->person;
	}

	~smartPointer()
	{
		cout << "smartPointer析构调用" << endl;
		if (this->person != NULL)
		{
			delete this->person;
			this->person = NULL;
		}
	}
private:
	Person* person;
};
//有了智能指针,让智能指针托管这个Person对象,对象的释放就不用操心了,让智能指针管理
//为了让智能指针想普通的Person*指针一样使用 就要重载 -> 和*

void test()
{
	//Person p1(18);//开辟在栈上,自动析构

	//Person* p1 = new Person(18);//开辟在堆上
	//p1->showage();

	//delete p1;
	//如果new出来的Person对象,就要让程序员自觉的去释放 delete

	smartPointer sp(new Person(18));//开辟到了栈上,自动释放
	sp->showage();//sp->->showage();编译器优化了写法

	(*sp).showage();

}

5.赋值运算符重载

//一个类默认创建默认构造、析构、拷贝构造、operator=赋值运算符 进行简单的值传递
class Person
{
public:
	Person(int a)
	{
		this->m_a = a;//int类型
	}

	int m_a;
};

void test()
{
	Person p1(10);

	Person p2(0);

	p2 = p1;//赋值

	cout << p2.m_a << endl;
}

class Person2
{
public:
	Person2(const char* name)
	{
		this->pname = new char[strlen(name) + 1];//字符串
		strcpy(this->pname, name);
	}

	//重载=赋值运算符
	Person2& operator=(const Person2& p)
	{
		//判断如果原来堆区已经有内容,先释放
		if (this->pname != NULL)
		{
			delete[] this->pname;
			this->pname = NULL;
		}
		this->pname = new char[strlen(p.pname) + 1];
		strcpy(this->pname, p.pname);

		return *this;
	}

	~Person2()
	{
		if (this->pname != NULL)
		{
			delete[] this->pname;
			this->pname = NULL;
		}
	}

	char* pname;
};

void test2()
{
	Person2 p1("狗蛋");

	Person2 p2("狗剩");

	Person2 p3("");

	p3 = p2 = p1;

	cout << p3.pname << endl;
}

6.强化训练-数组类的封装

首先建立头文件MyArray.h

class MyArray
{
public:
	MyArray();//默认构造函数  默认100容量

	MyArray(int capacity);//有参构造

	MyArray(const MyArray& array);//拷贝构造

	~MyArray();//析构

	//尾插法
	void push_Back(int val);//元素插入数组的最后一位

	//根据索引来获取值
	int& getData(int index);//根据数组元素对应的索引返回值

	//根据索引设置值
	void setData(int index, int val);//根据数组元素对应的索引设置值

	//获取数组的大小
	int getSize();

	//获取数组容量
	int getCapacity();

	//[]运算符重载
	int& operator[](int index);//通过[]来对数组元素进行设置和访问

private:

	int* pAddress;//指向真正存储数据的指针

	int m_Size;//数组的大小

	int m_Capacity;//数组的容量
};

然后再MyArray.cpp文件中对相应的函数进行声明

#include "MyArray.h"

//默认构造
MyArray::MyArray()
{
	this->m_Capacity = 100;//默认100容量
	this->m_Size = 0;//默认数组的大小为0
	this->pAddress = new int[this->m_Capacity];
}

//有参构造,提供一个参数为数组容量
MyArray::MyArray(int capacity)
{
	cout << "有参函数调用" << endl;
	this->m_Capacity = capacity;
	this->m_Size = 0;
	this->pAddress = new int[this->m_Capacity];
}

//拷贝构造
MyArray::MyArray(const MyArray& array)
{
	cout << "拷贝构造函数调用" << endl;
	this->pAddress = new int[array.m_Capacity];
	this->m_Size = array.m_Size;
	this->m_Capacity = array.m_Capacity;

	for (int i = 0; i < array.m_Size; i++)
	{
		this->pAddress[i] = array.pAddress[i];
	}
}

//析构
MyArray::~MyArray()
{
	cout << "析构函数调用" << endl;
	if (this->pAddress != NULL)
	{
		delete[] this->pAddress;
		this->pAddress = NULL;
	}
}

void MyArray::push_Back(int val)
{
	//判断越界? 用户自己处理
	this->pAddress[this->m_Size] = val;
	this->m_Size++;
}

int& MyArray::getData(int index)
{
	return this->pAddress[index];
}

void MyArray::setData(int index, int val)
{
	this->pAddress[index] = val;
}

int MyArray::getSize()
{
	return this->m_Size;
}

int MyArray::getCapacity()
{
	return this->m_Capacity;
}

//[]重载实现
int& MyArray::operator[](int index)
{
	return this->pAddress[index];
}

测试案例

void test()
{
	//堆区创建数组
	MyArray* array = new MyArray(30);

	MyArray* array2 = new MyArray(*array);//new方法来指定调用拷贝构造函数
	
	MyArray array3 = *array; //构造函数返回的本体

	MyArray* array4 = new MyArray(*array);
	delete array;
	//MyArray * array4 = array; 
	//这个是声明一个指针,和array执行的地址相同,所以不会调用拷贝构造

	//尾插法测试
	for (int i = 0; i < 10; i++)
	{
		array2->push_Back(i);
	}
	//获取数据测试
	for (int i = 0; i < 10; i++)
	{
		cout << array2->getData(i) << endl;
	}
	//根据索引设置值
	array2->setData(0, 1000);
	cout << array2->getData(0) << endl;

	cout << "array2的数组大小为:" << array2->getSize() << endl;
	cout << "array2的数组容量为:" << array2->getCapacity() << endl;

	//获取 设置 数组内容  如何用[]进行设置和访问
	array3.push_Back(100000);
	cout << array3.getData(0) << endl;//100000
	cout << array3[0] << endl;//100000
	array3.getData(0) = 4;
	cout << array3.getData(0) << endl;//4
	array3[0] = 100; // 100000 = 100
	cout << array3[0] << endl;//100


	/*cout << array4[0] << endl;
	array4[0] = 10;*/
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值