C++基础知识(五)--- 智能指针类&字符串类

目录

一. 智能指针类(重点)

指针运算符的重载

二. 仿函数

三. 其他重载

四. 字符串类(了解)


一. 智能指针类(重点)

作用:管理另一个类的对象的释放。

怕你忘记delete导致内存泄漏,所以搞了个智能指针。

class Maker
{
public:
	Maker()
	{
		cout << "无参构造" << endl;
	}
	void printMaker()
	{
		cout << "hello Maker" << endl;
	}
	~Maker()
	{
		cout << "析构函数" << endl;
	}
};

class SmartPoint
{
public:
	SmartPoint(Maker* m)
	{
		this->pMaker = m;
	}
	~SmartPoint()
	{
		if (this->pMaker != NULL)
		{
			cout << "SmartPoint析构函数" << endl;
			delete this->pMaker;
			this->pMaker = NULL;
		}
	}
private:
	Maker* pMaker;
};

void test01()
{
	Maker* p = new Maker; //这里的Maker不是在栈区,test函数结束时,如果不写delete,这里是不会被释放的
	SmartPoint sm(p);  //这里局部变量是在栈区,test函数结束时是会调用其析构函数释放空间的
					   //在它的析构函数中delete了Maker的对象,会调用到Maker的析构函数。
}

 

指针运算符的重载

Maker* operator->()
{
	return this->pMaker;
}
Maker& operator*()
{
	return *pMaker;  //返回一个对象,所以用引用
}

void test()
{
	Maker* m = new Maker;
	Point p(m);
	
	p->printMaker();   p-> 在这里等价于 pMaker->
	(*p).printMaker();
}

二. 仿函数

一个类如果重载了函数调用符号,那么这个类实例化出的对象也叫仿函数。

class Maker
{
public:
	Maker()
	{
        cout << "构造函数" << endl;
		name = "sun";
	}
	void printMaker()
	{
		cout << "name:" << name+" handsome" << endl;
	}

	void operator()()
	{
		cout << "hello" << endl;
	}
	void operator()(int a,int b)
	{
		cout << a + b << endl;
	}

	~Maker()
	{
		cout << "析构函数" << endl;
	}
public:
	string name;
	int a;
};

void test()
{
	Maker func;
	func();  //看起来像函数,其实是对象
	func.printMaker();
	func(1, 2);
}

输出为:

构造函数
hello
name:sun handsome
3
析构函数

三. 其他重载

重载 bool,!

class Maker
{
public:
	Maker()
	{
		a = 0;
	}
    void SetA(int val)
    {
        a = val;
    }
    //没有返回值,也没有void
	operator bool()
	{
		if (a <= 0)
			return false;
		else
			return true;
	}

	bool operator!()
	{
		if (a <= 0)
			return true;
		else
			return false;
	}
public:
	int a;
};

void test()
{
	Maker m;
	m.SetA(10);
	if (m)
		cout << "true" << endl;
	else
		cout << "false" << endl;
	
	if (!m)
		cout << "false" << endl;
	else
		cout << "true" << endl;
}

四. 字符串类(了解)

class MyString
{
	friend ostream& operator<<(ostream& out, MyString& str);
	friend istream& operator>>(istream& in, MyString& str);
public:
	MyString()
	{
		this->pM = new char[1];
		this->pM[0] = '\0';
		this->mSize = 0;
	}
	MyString(int n, char c) //用户可以设定初始字符串,n个c组成的字符串
	{
		this->pM = new char[n + 1];
		for (int i = 0; i < n; i++)
		{
			this->pM[i] = c;
		}
		this->pM[n] = '\0';
		this->mSize = n;
	}
	MyString(const MyString& str)
	{
		this->pM = new char[strlen(str.pM) + 1];
		strcpy(this->pM, str.pM);
		this->mSize = str.mSize;
	}
	~MyString()
	{
		if (this->pM != NULL)
		{
			delete[] this->pM;
			this->pM = NULL;
		}
	}
	MyString& operator=(const MyString& str)
	{
		//1.释放原来空间
		if (this->pM != NULL)
		{
			delete[] this->pM;
			this->pM = NULL;
		}
		//2.申请空间
		this->pM = new char[strlen(str.pM) + 1];
		//3.拷贝数据
		strcpy(this->pM, str.pM);
		this->mSize = str.mSize;

		return *this;
	}
	MyString operator+(const MyString& str)
	{
		//MyString s3=s1+s2; this是s1,str是s2
		//获取s3要开辟的空间大小
		int newlen = this->mSize + str.mSize + 1;
		//1.定义一个临时变量
		MyString tmp;
		//2.释放原来的空间
		if (tmp.pM != NULL)
		{
			delete[] tmp.pM;
			tmp.pM = NULL;
		}
		//3.申请新的空间
		tmp.pM = new char[newlen];
		memset(tmp.pM, 0, newlen);
		tmp.mSize = this->mSize + str.mSize;
		//4.追加字符到空间中
		strcat(tmp.pM, this->pM);
		strcat(tmp.pM, str.pM);

		return tmp;
	}
	MyString operator+(const char* s)
	{
		int newlen = this->mSize + strlen(s);
		char* newspace = new char[newlen + 1];
		memset(newspace, 0, newlen + 1);

		strcat(newspace, this->pM);
		strcat(newspace, s);

		MyString tmp;
		if (tmp.pM != NULL)
		{
			delete[] tmp.pM;
			tmp.pM = NULL;
		}
		tmp.pM = newspace;
		tmp.mSize = newlen;
		
		return tmp;
	}
	MyString& operator+=(const MyString& str)
	{
		//1.获取两个字符串的总字符个数
		int newlen = this->mSize + str.mSize;
		//2.申请新空间
		char* newspace = new char[newlen + 1];
		memset(newspace, 0, newlen + 1);
		//3.追加数据
		strcat(newspace, this->pM);
		strcat(newspace, str.pM);
		//4.释放本身的空间
		if (this->pM != NULL)
		{
			delete[] this->pM;
			this->pM = NULL;
		}
		this->pM = newspace;
		this->mSize = newlen;

		return *this;
	}
	MyString& operator+=(const char* s)
	{
		//1.获取两个字符串的总字符个数
		int newlen = this->mSize + strlen(s);
		//2.申请新空间
		char* newspace = new char[newlen + 1];
		memset(newspace, 0, newlen + 1);
		//3.追加数据
		strcat(newspace, this->pM);
		strcat(newspace, s);
		//4.释放本身的空间
		if (this->pM != NULL)
		{
			delete[] this->pM;
			this->pM = NULL;
		}
		this->pM = newspace;
		this->mSize = newlen;

		return *this;
	}
	int Size()
	{
		return this->mSize;
	}
	char& operator[](int index)
	{
		return this->pM[index];
	}
private:
	char* pM;
	int mSize;
};

ostream& operator<<(ostream& out, MyString& str)
{
	out << str.pM;
	return out;
}
istream& operator>>(istream& in, MyString& str)
{
	//用户输入的字符串要存储到s4.pM指向的堆区空间
	//定义临时空间
	char tmp[64] = { 0 };
	//获取用户输入的信息
	in >> tmp;
	//释放s4的空间
	if (str.pM != NULL)
	{
		delete[] str.pM;
		str.pM = NULL;
	}
	//申请新的空间
	str.pM = new char[strlen(tmp) + 1];
	memset(str.pM, 0, strlen(tmp) + 1);
	//拷贝用户输入的信息到堆区空间
	strcpy(str.pM, tmp);
	str.mSize = strlen(tmp);

	return in;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值