Day4知识点:
myString类对象自我实现以及部分实验源代码:
//myString.h
#ifndef MYSTRING_H
#define MYSTRING_H
#include <stdio.h>
class myString
{
public:
myString(const char *p =NULL);
myString(const myString& another);
myString& operator=(const myString& another); //运算符重载
myString operator+(const myString& another);
bool operator>(const myString& another);
bool operator<(const myString& another);
bool operator==(const myString& another);
char& operator[](int idx);
char at(int idx);
char* str();
private:
char* _str;
};
#endif // MYSTRING_H
//myString.cpp
#include "mystring.h"
#include <string.h>
myString::myString(const char* p)
{
if(p == NULL)
{
_str =new char[1];
*_str = '\0';
}
else
{ _str = new char[strlen(p)+1];
strcpy(_str,p);
}
}
myString::myString(const myString& another)
{
_str = new char[strlen(another._str)+1];
strcpy(_str,another._str);
}
myString& myString::operator=(const myString& another)
{
if(this == &another)
return *this;
delete []_str;
_str = new char[strlen(another._str)+1];
strcpy(_str,another._str);
return *this;
}
myString myString::operator+(const myString& another)
{
myString tmp;
delete []tmp._str;
int len = strlen(this->_str);
len +=strlen(another._str);
tmp._str = new char[len+1];
memset(tmp._str,0,len+1);
strcat(tmp._str,this->_str);
strcat(tmp._str,another._str);
return tmp;
}
bool myString::operator>(const myString& another)
{
if(strcmp(this->_str,another._str)>0)
return true;
else
return false;
}
bool myString::operator<(const myString& another)
{
if(strcmp(this->_str,another._str)<0)
return true;
else
return false;
}
bool myString::operator==(const myString& another)
{
if(strcmp(this->_str,another._str)==0)
return true;
else
return false;
}
char& myString::operator[](int idx)
{
return this->_str[idx];
}
char myString::at(int idx)
{
return this->_str[idx];
}
char* myString::str()
{
return _str;
}
//main函数
#include <iostream>
#include "mystring.h"
using namespace std;
#if 0
int main()
{
// string a("***************");
// string b;
// string c("china");
// cout<<a<<endl;
// cout<<b;
// cout<<c<<endl;
myString a("***************");
myString b;
myString c("china");
cout<<a.str()<<endl;
cout<<b.str();
cout<<c.str()<<endl;
myString s("aa");
myString s3(s);
myString s4;
s4 = s;
myString s5("bb");
s5 = s5;
cout<<s.str()<<endl;
cout<<s3.str()<<endl;
cout<<s4.str()<<endl;
cout<<s5.str()<<endl;
return 0;
}
#endif
#if 0
int main()
{
myString s1("abc");
myString s2("def");
myString s3 = s1 + s2;
cout<<s3.str()<<endl;
}
#endif
int main()
{
myString s1("bbc");
myString s2("aef");
if(s1>s2)
cout<<"s1 > s2"<<endl;
else if(s1 ==s2)
cout<<"s1 == s2"<<endl;
else
cout<<"s1 < s2"<<endl;
return 0;
}
1. 拷贝构造器,格式:A(const A & another) ;若不提供,系统会自动提供默认的。
myString::mystring(const myString& another)
{
_str = another._str; //此处_str为myString类的私有成员,在同类之间是没有隐私的
}
2.如2中的浅拷贝myString s(s3);(在类中开辟空间的情况下)若不作处理或用系统提供的默认构造函数,会导致内存的重析构 double free,原因(s和s3的_str指向相同的内存空间,在析构时会析构两次)。应该如此修改
myString::myString(const myString& another)
{
_str = new char[strlen(another._str)+1];
strcpy(_str,another._str);
}
3.拷贝构造
1) 格式 类名(const 类名 &another),依附于原有对象创建新对象;
A a;
A b(a);
A c = b;
2)若不提供,系统会提供默认,一旦自定义,系统不再提供默认;
3)系统提供的默认,是一种等位拷贝。也就是浅拷贝;
4)浅拷贝,在某些情况下,会导致内存重析构(如2所示,含有堆空间的情况下),即double free(有些系统编译时提示错误,有些系统编译通过).要自己实现拷贝构造。
4.赋值重载
1)格式 类名 operator=(const myString& another);两个对象都已经创建好之后的赋值行为。
A c;
A a;
c = a;
2)编译器提供默认,一旦自定义,系统不再提供默认;
3)默认赋值运算符也是一种等位赋值,浅赋值;
4)浅赋值,可能会导致:a)自身发生内存泄漏;b)内存发生重析构;c)自赋值。应该如此修改
myString& myString::operator=(const myString& another)
{
if(this == &another)
return *this;
delete []_str;
_str = new char[strlen(another._str)+1];
strcpy(_str,another._str);
return *this;
}
5.建立类时的必要构造函数
Class A
{
pubilc:
A(); //一般情况下要标配,即无参的情况包含默认数据,如A(int i = 0):a(i){}
~A();
A(const A& another);
A& operator=(const A& another);
}