题:编写类String的构造函数、析构函数和赋值函数。【中国某著名综合软件公司2005年面试题】
答案:
已知类String的原型为:
class String
{
public:
//普通构造函数
String(const char *str = NULL);
//拷贝构造函数
String(const String &other);
//析构函数
~String(void);
//赋值函数
String & operator=(const String &other);
private:
//用于保存字符串
char *m_data;
};
编写String的上述4个函数。
1、String的析构函数
为了防止内存泄漏,我们还需要定义一个析构函数。当一个String对象超出它的作用域时,这个析构函数将会释放它所占用的资源。代码如下:
String::~String()
{
delete[] m_data;
//由于m_data是内部数据类型,也可以写成delete m_data;
}
2、String的构造函数
这个构造函数可以帮助我们根据一个字符串常量创建一个MyString对象。这个构造函数首先分配了足量的内存,然后把这个字符串常量复制到这块内存,代码如下:
String::String(const char *str)
{
if(NULL == str)
{
m_data = new char[1];
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1];
strcpy(m_data,str);
}
}
strlen函数返回这个字符串常量的实际字符数(不包括NULL终止符),然后把这个字符串常量的所有字符赋值到我们在String对象创建过程中为m_data数据成员新分配的内存中。有了这个构造函数后,我们可以像下面这样根据一个字符串常量创建一个新的String对象:
string str("hello");
3、String的拷贝构造函数
所有需要分配系统资源的用户定义类型都需要一个拷贝构造函数,这样我么可以使用这个的声明:
Mystring s1("hello");
Mystring s2 = s1;
拷贝构造函数还可以帮助我们在函数调用中以传值方式传递一个Mystring参数,并且在当一个函数以值的形式返回Mystring对象时实现“返回时复制”。
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data,other.m_data);
}
4、String的赋值函数
赋值函数可以实现字符串的传值活动:
Mystring s1(“hello”);
Mystring s2;
s1 = s2;
代码如下:
String & String::operator =(const String &other)
{
if(this == &other)
{
return *this;
}
//释放原有的内存资源
delete[] m_data;
//分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data,other.m_data);
//返回本对象的引用
return *this;
}