序言:本篇文章用于记录C++学习的构造器、拷贝构造器、析构器、赋值运算符重载的记录,该文章以自己实现stringl类型为实例进行练习。
1.mystring.h文件(函数声明)
class mystring{
public:
mystring(const char*p = NULL); //构造器
mystring(const mystring & another); //拷贝构造器
mystring& operator=(const mystring & another); //赋值运算符重载
~mystring(); //析构器
char * c_str();
private:
char * _str;
};
2.mystring.cpp文件(函数实现)
#include <iostream>
#include "mystring.h"
#include <string.h>
using namespace std;
//构造器
//1.在对象创建时自动调用,完成初始化相关工作
//2.无返回值,与类名相同
//3.可以重载,可默认参数(默认参数在声明阶段)
//4.系统提供默认无参空体,自己实现的话系统不提供默认
mystring::mystring(const char* p){
if(p == NULL){
_str = new char[1];
*_str = '\0';
}else{
int len = strlen(p);
_str = new char[len+1];
strcpy(_str,p);
}
}
//拷贝构造器(由已存在的对象来创建新的对象,由拷贝构造器来完成)
//1.格式 A(const A & another);
//2.若不提供,系统会提供默认,自己实现的话系统不提供默认
//3.系统提供的默认,是一种等位拷贝。也就是“浅浅的拷贝”
//4.浅拷贝会导致内存重析构。double free
//5.拷贝构造器发生的时期:(1)制作对象的副本、(2)以对象作为参数和返回值
mystring::mystring(const mystring & another)
{
//在同类之间是没有隐私的,这就是浅拷贝,_str和another._str指向同一个地址,
//析构的时候会将这一个地址析构两遍
//_str = another._str;
//_str重新执行一个新地址,将原地址的内容拷贝到新地址里,深拷贝
int len = strlen(another._str);
_str = new char[len+1];
strcpy(_str,another._str);
}
//赋值运算符重载
//1.系统提供默认,系统提供的默认也是一种等位赋值,自己实现的话系统不提供默认
//2.浅赋值,有可能会导致自身内存泄露和重析构
//3.自赋值
mystring& mystring::operator=(const mystring & another)
{
if(this == &another)
return *this;
delete []this->_str; //先把自己内存释放掉
int len = strlen(another._str);
this->_str = new char[len+1];
strcpy(this->_str,another._str);
return *this;
}
char* mystring::c_str()
{
return _str;
}
//析构器
//1.对象销毁时自动调用,完成对象的销毁等善后工作。
//2.无返回值,与类名相同,前面有一个“~”号,无参,不可以重载和有默认参数
//3.系统提供默认空析构器,自己实现的话系统不提供默认
mystring::~mystring()
{
delete []_str;
}
3.mystringmain.cpp文件(函数调用)
#include <iostream>
#include "mystring.h"
using namespace std;
int main()
{
string s1;
string s2("usa");
cout<<s1.c_str()<<endl;
cout<<s2.c_str()<<endl;
cout<<"--------------------"<<endl;
mystring ms("china"); //创建对象ms,默认调用构造函数
mystring ms2(ms); //由已存在的对象ms来创建新的对象ms2,默认调用拷贝构造函数
//用一个已有的对象,给另外一个对象赋值。两个对象均已创建结束后,
//发生的赋值行为会调用赋值运算符重载
mystring ms3;
ms3=ms2;
mystring ms4; //等价于上面的一个操作
ms4.operator=(ms3);
cout<<ms.c_str()<<endl;
cout<<ms2.c_str()<<endl;
cout<<ms3.c_str()<<endl;
cout<<ms4.c_str()<<endl;
return 0;
}