GeekBand学习笔记:C++三大函数:拷贝构造、拷贝赋值、析构函数
C++中的类分为两种:带指针的类和不带指针的类,在设计不带指针的类的时候,不需要这三个函数数,因为默认的函数已经足够用了。但是在设计带指针的类的时候,就必须要加上这三个函数,因为默认的函数在拷贝赋值的时候只是单纯的把值赋过去,但是对于指针来说,赋值过去之后两个对象里面的指针指向同一个地方,这样会很危险,因为在程序里面改动一个,另一个将会跟着被改变。这和我们想要达到的目的相违背,因此此时默认的函数是不行的。
对于string类来说:三大函数可以是这样的:
class string
{
public:
string(const char* cstr = 0);
string(const string& str); //拷贝构造函数
string& operator=(const string& str) //拷贝赋值函数
~string(); //析构函数
char *get_c_str() const {return m_data};
private:
char *m_data;
}
注意点:
- 如果一个函数没有对数据做改变,那么要在函数体前加一个const,养成良好习惯!!!
- 拷贝构造和拷贝赋值,都是拷贝动作,但前者发生在创建对象时,后者发生在对象已经存在时。
- 设计带指针的类的时候,一定要自己写三大函数,Big Three
- data域里面的字符串,不要设计为字符数组,因为字符串大小未知。设计为一个字符指针,指向一个字符串,这样更加有“动态性”。
- 带指针的类里面多半会涉及到内存动态分配,因此要设计析构函数,否则就会造成内存泄漏
构造函数的实现:
inline string::string(const char *str = 0)
{
if(str)
{
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
else
{
m_data = new char[1];
*m_data = '\0';
}
}
析构函数的实现:
inline string::~string()
{
delete[] m_data;
}
拷贝构造函数的实现:
inline string::string(const string& str)
{
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
拷贝赋值函数的实现:
inline string& string::operator=(const string& str)
{
//检测是否自我赋值,这个必须要加上,这不只是为了效率,也是为了正确性
if(this == &str)
return *this;
delete[] m_data;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
return *this;
}