紧接着上一篇的 “第二点sizeof解释”这次从第三点开始
5,C++中的赋值操作符
参考:《剑指offer》42页《C++程序设计教程》《高质量C++编程》
注意点:
1,返回值是否为该类型的引用,并在函数结束前返回实例自身引用(*this)。
只有返回一个引用才可以允许连续赋值。否则如果函数的返回值是void,应用该赋值运算符将不可以连续赋值即:str1 = str2 = str3,这样将会编译不通过。
2,是否把把传入的参数声明为常量的引用。如果传入的不是引用而是实例,那么从形参到实参会调用一次拷贝构造函数。如果将其声明为引用,将避免不必须要的消耗。同时将其声明为const这个就不多说了
3,是否释放自身的内存,不然可能造成内存泄露。
4,是否判断传入参数和当前实例是不是同一个实例,如果是同一个则不进行赋值直接返回。如果不判断将会产生严重后果,后面如果delete将会删除该实例,或者其他操作将会产生严重后果(如果直接删除,则传入的参数也被删除,这样后面的复制就毫无意义),或者产生多余的复制操作。
下面给出String类的部分实现。
#include<iostream>
using namespace std;
class String
{
public:
String(const char *str = NULL);
String(const String &other);
~String(void);
String & operator=(const String &other);
bool operator==(const String &str);
// friend ostream & operator<<(ostream& o,const String &str);
private:
char *m_data;
};
/*
构造、析构、拷贝构造、赋值运、流输出运算
*/
String::String(const char *str)
{
if (str == NULL){
m_data = new char[1];
*m_data='\0';
}else{
int len=strlen(str);
m_data = new char[len+1];
strcpy(m_data,str);
}
}
String::~String(void)
{
delete [] m_data;
}
String::String(const String &other)
{
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);
}
String & String::operator=(const String &other)
{
if (this == &other)
return *this;
delete []m_data;
int len = strlen(other.m_data);
m_data = new char[len+1];
strcpy(m_data,other.m_data);
return *this;
}
bool String::operator==(const String &str)
{
return strcmp(m_data,str.m_data) == 0;
}
/*
ostream & operator<<(ostream &o,const String &str)
{
o<<str.m_data;
return o;
}
*/
int main()
{
String s = "hello";
String s2 = s;
String ss = "hello";
cout<<"s = "<<s<<endl;
cout<<"s2 = "<<s2<<endl;
cout<<boolalpha<<(ss == s)<<endl;
return 0;
}
对于string类赋值运算符的高级实现,可参见我 从stackoverflow翻译的另一篇《copy-and-swap idiom》http://blog.csdn.net/zh533749/article/details/19837253