目录
先定义一个类
定义构造和析构函数
用out<<
用s1.clear();清空数组
用s1.size();返回字符个数
加入扩容数组函数
用s2.append("world");和s1 += "nihao";追加数组数据
用if(s1 == s2)比较两个对象的数组
用if(s1 == "123456")比较对象的数组和字符串
用if(s1.compare(s2) == 0)和s1.compare("123456")比较两个的数组
用if(s1.find("123456")!=NULL)查找对象的数组中是否有字符串
思考s7 = s6;会发生什么
思考MString s9 = s8;会发生什么
先定义一个类
//char类型的数组类
class MString
{
public:MString(){}~MString(){}
private:char *m_str;int m_size;
};
定义构造和析构函数
如果我想用不同的方法创建类的对象:例如
MString s0;
MString s1(10); //10代表的是数组的元素的个数
MString s2("hello"); //创建一个数据为hello的数组
MString s3('c',20);// 字符c 连续拷贝20个数组 cccccccccccccccccc
代码
public:MString(int size = 1024) // MString s0; MString s1(10);{this->m_size = size;this->m_str = new char[this->m_size];memset(this->m_str,0,this->m_size);}MString(const char*str) // MString s2("hello");{//数组是一个动态数组 ,按需分配this->m_size = strlen(str) + 1;this->m_str = new char[this->m_size];strcpy(this->m_str,str);}MString(char ch,int length) // MString s3('c',20);{//数组是一个动态数组 ,按需分配this->m_size = length + 1;this->m_str = new char[this->m_size];for(int i=0; i<length; i++){m_str[i] = ch;}}~MString(){//释放堆的内容delete []this->m_str;}
用out<<s3<<endl;直接输出数组
ostream& operator<<(ostream &out,MString &ra)
{out<<ra.m_str;return out;
}在类中定义友元函数
friend ostream& operator<<(ostream &out,MString &ra);
用s1.clear();清空数组
public:void clear(){memset(this->m_str,0,this->m_size);}
用s1.size();返回字符个数
public:int size(){return m_size;}
加入扩容数组函数
public://扩容void setSize(int size){if(m_size >= size)return ;//1、先保存原来的空间的数据char temp[this->m_size];memset(temp,0,this->m_size);strcpy(temp,m_str);//2、释放原来的空间delete []this->m_str;//3、申请更大的堆空间this->m_str = new char[size];this->m_size = size;memset(m_str,0,this->m_size);//4、重新把数据赋值回去strcpy(m_str,temp);}
用s2.append("world");和s1 += "nihao";追加数组数据
public:void append(const char*str){//如果原来的空间不够。那么必须扩容if(strlen(m_str)+strlen(str)+1 > this->m_size){//1、先保存原来的空间的数据char temp[this->m_size];memset(temp,0,this->m_size);strcpy(temp,m_str);//2、释放原来的空间delete []this->m_str;//3、申请更大的堆空间this->m_size = strlen(m_str)+strlen(str)+1;this->m_str = new char[m_size];memset(m_str,0,this->m_size);//4、重新把数据赋值回去strcpy(m_str,temp);}sprintf(this->m_str,"%s%s",this->m_str,str);}void operator+=(const char*str){append(str);}
用if(s1 == s2)比较两个对象的数组
public:int operator==(MString &ra){return !strcmp(this->m_str,ra.m_str);}
用if(s1 == "123456")比较对象的数组和字符串
public:int operator==(const char*str){return !strcmp(this->m_str,str);}
用if(s1.compare(s2) == 0)和s1.compare("123456")比较两个的数组
public:int compare(const char*str) //compare 如果相同 返回 0 不同 非0{return strcmp(this->m_str,str);}int compare(MString &ra){return strcmp(this->m_str,ra.m_str);}
用if(s1.find("123456")!=NULL)查找对象的数组中是否有字符串
public:char* find(const char*str){return strstr(this->m_str,str);}
思考s7 = s6;会发生什么
s7 = s6; ------编译器在编译的时候 会自动转换成 运算符函数调用 s7.operator=(s6)
如果类中有 指针成员 指向堆空间,最好自定义赋值运算符函数public://如果没有自定义赋值运算符函数,那么此时编译器会自动给你生成默认的赋值函数void operator=(MString &ra) //MString &ra = s6{cout<<"void operator=(MString &ra)"<<endl;this->m_str = ra.m_str;this->m_size = ra.m_size;}//编译器默认生成的赋值函数 可能会造成内存泄漏//---------------------------------------------------------------------//这个可以防止内存泄漏void operator=(MString &ra) //MString &ra = s6{strcpy(this->m_str,ra.m_str);this->m_size = ra.m_size;}
思考MString s9 = s8;会发生什么
-
在定义一个类对象的时候,通过另外一个对象来初始化,调用拷贝构造函数
-
MString s9 = s8;------->MString s9(s8);
public:MString(const MString& other) {// 实现复制构造函数的代码}