#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
class MyString{
public:
MyString(const char*str=0)
{
if(str)
{
m_pData = new char[strlen(str)+1];
strcpy(m_pData, str);
}
else{
// 未指定初始值
m_pData = new char[1];
*m_pData = '\0';
}
}
MyString(const MyString&str)
{
m_pData = new char[strlen(str.m_pData)+1];
strcpy(m_pData, str.m_pData);
}
// 考虑以下四点:
/*
1. 是否把返回值类型声明该类型的引用,并在函数结束前返回实例自身的引用。
2. 是否把传入的参数类型声明为常量引用。
3. 是否释放实例自身的已有的内存。
4. 是否判断传入的参数和当前的实例(*this)是不是同一个实例。
*/
MyString& operator = (const MyString&str)
{
if(this == &str)
return *this;
delete[] m_pData;
m_pData = new char[strlen(str.m_pData)+1];
strcpy(m_pData, str.m_pData);
return *this;
}
// 更高级写法
// 考虑到异常安全性的写法, 问题会出现在new char[]狮虎内存分配失败,
// 抛出异常,此时m_pData将会是空指针,会导致程序崩溃。
// 做法:构建临时对象,然后交换实例对象和临时对象的数据,如果有分配失败,
// 在函数跳出if作用域之外,则会自动调用其析构函数,同时还没有改变原来实例
// 对象的内容,他是hi有效的,因此符合异常安全性。
MyString& operator = (const MyString*str)
{
if(this != &str)
{
MyString temp(str);
char*pTemp = temp.m_pData;
temp.m_pData = m_pData;
m_pData = pTemp;
}else{
return *this;
}
}
char*get_str() const {return m_pData;}
~MyString()
{
delete[] m_pData;
}
private:
char*m_pData;
};
int main(int argc, char**argv)
{
cout << __cplusplus << endl;
MyString s1("hello");
MyString s2(s1);
cout << "s1 : " << s1.get_str() << endl;
cout << "s2 : " << s2.get_str() << endl;
MyString s3("world");
cout << "s3 : " << s3.get_str() << endl;
s3 = s2;
cout << "s3 : " << s3.get_str() << endl;
MyString s4;
cout << "s4 : " << s4.get_str() << endl;
s3 = s4;
cout << "s3 : " << s3.get_str() << endl;
return 0;
}
剑指offer:string实现--拷贝构造,赋值构造函数
最新推荐文章于 2024-05-26 16:09:49 发布