题目:根据MyString类,编写它的两个构造函数、析构函数、拷贝构造函数、赋值运算符的重载、输出运算符的重载
Mstring类:
class Mystring
{
private:
char* _s;
}
main函数里的测试代码:
int main()
{
Mystring s1("Hello");
Mystring s2(s1);
Mystring s3(6, 'A');
s1 = s3;
cout << s1 << "," << s2 << "," << s3 << endl;
return 0;
}
运行效果:
最终代码:
class Mystring
{
//重载的输出运算符,声明为类的友元函数
friend ostream& operator<<(ostream& o, const Mystring& other);
public:
//构造函数
Mystring(const char* str)
{
_s = new char[strlen(str) + 1]; //给成员变量分配内存空间,最后+1给结束标志
strcpy(_s, str); //将字符串拷贝到成员变量里
}
//拷贝构造函数
Mystring(const Mystring& other)
{
_s = new char[strlen(other._s) + 1]; //给成员变量分配内存空间,最后+1给结束标志
strcpy(_s, other._s); //将字符串拷贝到成员变量里
}
//另一个构造函数
Mystring(int count, char c)
{
_s = new char[count + 1]; //给成员变量分配内存空间,最后+1给结束标志
memset(_s, c, count); //将_s的前count个设为字符c
_s[count] = '\0'; //将最后一个设为结束标识符
}
//析构函数
~Mystring()
{
delete[] _s;
}
//重载赋值运算符
Mystring& operator=(const Mystring& other)
{
delete[] _s; //使用赋值运算符时,对象已经初始化分配了内存空间,所以要将初始的内存空间释放才能新分配空间
_s = new char[strlen( other._s ) + 1]; //给成员变量分配新内存空间,最后+1给结束标志
strcpy(_s, other._s);
return *this; //返回当前对象,因为要考虑赋值运算符的连续使用
}
private:
char* _s;
};
//输出运算符重载为全局函数
ostream& operator<<(ostream& o, const Mystring& other)
{
cout << "\"" << other._s << "\""; //转义字符\"
return o;
}