小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)

小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

涉及到本文所讲知识点的博文:
C++之析构函数探究
C++之常引用和浅拷贝探究
C++之一个函数链的简单例子(分文件实现)
C++之Big Three:拷贝构造、拷贝赋值、析构函数探究
C++之操作符重载探究(五):赋值运算符重载和拷贝赋值函数(深拷贝)
Big Three:拷贝构造、拷贝赋值、析构函数(针对带着指针成员变量的类)。 例1: 小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

例1分析:打字手累,直接贴好久好久以前研究本例知识点的笔记,有点啰嗦: 笔记第一页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第二页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第三页:

笔记第四页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第五页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第六页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第七页:(啥也没记)
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第八页:(啥也没记)
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第九页:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

笔记第十页:(啥也没记)
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

附本例代码:

//小问学编程 #include #include using namespace std; 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; }; #include inline String::String(const char* cstr) { if (cstr) { m_data = https://www.it610.com/article/new char[strlen(cstr)+1]; strcpy(m_data, cstr); } else { m_data = new char[1]; *m_data ='\0'; } }inline String::~String() { delete[] m_data; }inline String& String::operator=(const String& str) { if (this == &str) return *this; delete[] m_data; m_data = https://www.it610.com/article/new char[ strlen(str.m_data) + 1 ]; strcpy(m_data, str.m_data); return *this; }inline String::String(const String& str) { m_data = new char[ strlen(str.m_data) + 1 ]; strcpy(m_data, str.m_data); }ostream& operator<<(ostream& os, const String& str) { os << str.get_c_str(); return os; }int main() { String s1("hello"); String s2("world"); String s3(s2); cout << s3 << endl; s3 = s1; cout << s3 << endl; cout << s2 << endl; cout << s1 << endl; }

运行结果:
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

补充:拷贝构造函数 【小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)】??拷贝构造函数:通过拷贝一个已经存在的对象来创建新的对象,也就是说,这个构造函数的参数就是另外一个对象。
??Vector(Vector& v);
?? ? \spadesuit ? 用一个已存在的对象初始化另一个对象:
??classT object(another_object);
??classT object=another_object;
??(第二种情况编译器会调用拷贝构造函数而不是赋值操作。)
?? ? \spadesuit ? 以传值的方式,给函数传递一个对象或从函数返回一个对象,也将调用拷贝构造函数;
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

注意:
??拷贝构造函数的参数,必须传引用,不能传值!!!
??如果拷贝构造函数的参数用传值的方式,那么当实参传递给拷贝构造函数的时候,拷贝构造函数的形参,为了复制实参,则又需要调用拷贝构造函数,即调用它自己,于是形成死循环。
补充:拷贝赋值函数(赋值运算符重载) ??下面的代码将调用赋值运算符重载:
??classT object; //创建一个对象
??classT another_object; //创建另一个对象
??object=another_object; //把一个对象赋值给另一个对象
补充:析构函数 小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

例2:拷贝构造函数示例
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

附例2代码:
//小问学编程 #include using namespace std; class Vector { public: Vector(int s=0); Vector(int*,int); Vector(const Vector& v); ~Vector(){dispose(); } int get_size()const {return size; } const Vector& operator=(const Vector& x); int& operator[](int index){return rep[index]; } const int& operator[](int index)const{return rep[index]; } private: int* rep; int size; void clone(const Vector& a); void dispose(); }; void Vector::clone(const Vector& a) { this->size=a.size; rep=new int[size]; for(int count=0; count; ++count) rep[count]=a[count]; }void Vector::dispose() { delete[] rep; }Vector::Vector(int s):size(s) { if(size<=0) rep=NULL; else { rep=new int[size]; for(int count=0; count; ++count) rep[count]=0; } }Vector::Vector(int* a,int s):size(s),rep(new int[s]) { for(int count=0; count; ++count) rep[count]=a[count]; }Vector::Vector(const Vector& v) { clone(v); }const Vector& Vector::operator=(const Vector&x) { if(this!=&x) { delete[] rep; this->size=x.size; rep=new int[size]; for(int count=0; count; ++count) rep[count]=x[count]; } return *this; }ostream& operator<<(ostream& os,const Vector& x) { int s=x.get_size(); for(int i=0; i; ++i) os<

例3:构造函数析构函数调用示例
小问C++笔记|C++之Big Three(拷贝构造、拷贝赋值、析构函数探究)
文章图片

附例3代码:
//小问学编程 #include using namespace std; class Demo { public: Demo(int n=0); //默认构造 Demo(const Demo& a); //拷贝构造,参数必须传引用 ~Demo(); //析构函数 const Demo& operator=(const Demo& a); //拷贝赋值 private: int i; }; Demo::Demo(int n):i(n)//默认构造 { cout<<"default constructor called"<i=a.i; cout<<"assignment operator used"<

    推荐阅读