目录
一. 智能指针类(重点)
作用:管理另一个类的对象的释放。
怕你忘记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;
}