C/C++(C++拷貝構造器,賦值運算符重載)
阿新 • • 發佈:2018-03-09
拷貝構造 避免 運算 目的 strlen 沒有 成員 fine 這樣的
拷貝構造器
由己存在的對象,創建新對象。也就是說新對象,不由構造器來構造,而是由拷貝構造器來完成。拷貝構造器的格式是固定的。
class 類名
{
類名(const 類名 & another)
拷貝構造體
}
class A
{
A(const A & another)
{}
}
規則:
1 系統提供默認的拷貝構造器。一經實現,不復存在。
2 系統提供的時等位拷貝,也就是所謂的淺淺的拷貝。
3 要實現深拷貝,必須要自定義。
4 淺拷貝,會導致內存重析構。linux下淺拷貝會掛機。double free,在有些情況下(含有堆空間的時候),要實現自拷貝構造
#include <iostream>
#include "mystring.h"
using namespace std;
int main()
{
string s = "assassin";
string ss(s);
cout<<"++++++++++++++++"<<endl;
cout<<ss<<endl;
cout<<"++++++++++++++++"<<endl;
mystring s1 = "intelwisd";
mystring ss1(s1);//淺復制,兩個對象指向同一個地址空間,釋放對象的時候釋放了兩次對象所指向的地址空間。
cout<<"++++++++++++++++"<<endl;
cout<<ss1.c_str()<<endl;
cout<<"++++++++++++++++"<<endl;
string sss = s;
mystring sss1 = s1;//也可以實現,本質也是拷貝,用已有一個對象完成一個對象,從無到有的創建過程。
string ssss;
ssss = s;
mystring ssss1;
ssss1 = s1;//默認的也可以,本質是賦值運算符重載---> this指針。
return 0;
}
#ifndef MYSTRING_H
#define MYSTRING_H
class mystring
{
public:
//mystring();
mystring(const char *s = NULL);//無參的形式包含在裏面
char * c_str();
mystring(const mystring & another);
~mystring();
private:
char * _str;
};
#endif // MYSTRING_H
#include<iostream>
#include "mystring.h"
#include "string.h"
using namespace std;
mystring::mystring(const char *s)
{
if(s == NULL)
{
_str = new char[1];
*_str = ‘\0‘;
}else{
int len = strlen(s);
_str = new char[len+1];
strcpy(_str,s);
}
}
char * mystring::c_str()
{
return _str;
}
mystring::mystring(const mystring & another)
{
//_str = another._str;//同類之間沒有隱私,這樣的淺復制會造成內存重析構。
int len = strlen(another._str);
_str = new char[len+1];
strcpy(_str,another._str);
}
mystring::~mystring()
{
delete []_str;
}
this 指針
系統在創建對象時,默認生成的指向當前對象的指針。這樣作的目的,就是為了帶來方便。
作用
1,避免構造器的入參與成員名相同。
2,基於 this 指針的自身引用還被廣泛地應用於那些支持多重串聯調用的函數中。
class Stu
{
public:
Stu(string name,int age)
{
this->name = name;
this->age = age;
}
void display()
{
cout<<name<<"+++"<<age<<endl;
}
Stu & growUp()
{
this->age++;
return *this;
}
private:
string name;
int age;
}
int main()
{
Stu s("assassin",23);
dout<<"&s:"<<&s<<endl;
s.display();
s.growUp().growUp().growUp().growUp().display();//年齡增加
return 0;
}
賦值運算符重載(Operator=)
用一個己有對象,給另外一個己有對象賦值。兩個對象均己創建結束後,發生的賦值行為。
格式:
類名
{
類名& operator=(const 類名& 源對象)
拷貝體
}
class A
{
A& operator=(const A& another)
{
//函數體
return *this;
}
};
規則:
1 系統提供默認的賦值運算符重載,一經實現,不復存在。
2 系統提供的也是等位拷貝,也就淺拷貝,會造成內存泄漏,重析構。
3 要實現深深的賦值,必須自定義。
4 自定義面臨的問題有三個:1,自賦值
2,內存泄漏
3,重析構。
5 返回引用,且不能用 const 修飾。a = b = c => (a+b) = c
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;
}
完整代碼:
#include<iostream>
#include "mystring.h"
#include "string.h"
using namespace std;
mystring::mystring(const char *s)
{
if(s == NULL)
{
_str = new char[1];
*_str = ‘\0‘;
}else{
int len = strlen(s);
_str = new char[len+1];
strcpy(_str,s);
}
}
char * mystring::c_str()
{
return _str;
}
mystring::mystring(const mystring & another)
{
//_str = another._str;//同類之間沒有隱私,這樣的淺復制會造成內存重析構。
int len = strlen(another._str);
_str = new char[len+1];
strcpy(_str,another._str);
}
mystring::~mystring()
{
delete []_str;
}
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;
}
#ifndef MYSTRING_H
#define MYSTRING_H
class mystring
{
public:
//mystring();
mystring(const char *s = NULL);//無參的形式包含在裏面
char * c_str();
mystring(const mystring & another);
mystring& operator=(const mystring & another);
~mystring();
private:
char * _str;
};
#endif // MYSTRING_H
#include <iostream>
#include "mystring.h"
using namespace std;
int main()
{
string s = "assassin";
string ss(s);
cout<<"++++++++++++++++"<<endl;
cout<<ss<<endl;
cout<<"++++++++++++++++"<<endl;
mystring s1 = "intelwisd";
mystring ss1(s1);//淺復制,兩個對象指向同一個地址空間,釋放對象的時候釋放了兩次對象所指向的地址空間。
cout<<"++++++++++++++++"<<endl;
cout<<ss1.c_str()<<endl;
cout<<"++++++++++++++++"<<endl;
string sss;
sss = s;
mystring sss1;//
sss1 = s1;
return 0;
}
C/C++(C++拷貝構造器,賦值運算符重載)