栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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] = '';
		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] = '';
		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;
}

 

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号