拷贝构造函数(string str1 = str2/string str1(str2都会调用拷贝构造)
cpp
my_class_type(const my_class_type & another)
若不提供,系统会提供默认;
系统提供的默认是一种等位拷贝(浅拷贝),浅拷贝导致两个指针指向同一块内存地址,析构时会导致内存重析构
同类之间没有隐私(可以访问private类成员)
在含有堆空间的情况下,要自实现拷贝构造
cpp
#include <iostream>
#include <string.h>
using namespace std;
class mystring
{
public:
mystring(const char * mystr = "");
mystring(const mystring & another);
~mystring();
char* c_str();
private:
char * p;
int len;
};
mystring::mystring(const char * mystr)
{
if(mystr == nullptr)
{
len = 1;
*p = '\0';
}
else
{
len = strlen(mystr) + 1;
p = new char[len];
strcpy(p,mystr);
}
}
mystring::mystring(const mystring &another)
{
len = another.len;
p = new char[len];
strcpy(p,another.p);
}
mystring::~mystring()
{
delete []p;
}
char* mystring::c_str()
{
return p;
}
int main()
{
mystring str1;
mystring str2("abcdefg");
mystring str3(str2);
cout << str1.c_str() << endl;
cout << str2.c_str() << endl;
cout << str3.c_str() << endl;
return 0;
}
this指针
只能在类内部使用
是在创建对象时附带的指向当前对象的指针
cpp
#include <iostream>
using namespace std;
class stu
{
public:
stu(string name = "bob",int age = 18);
void show();
stu & growup();
private:
string name;
int age;
};
stu::stu(string name,int age)
{
this->name = name;
this->age = age;
}
void stu::show()
{
cout << "name is " << name << " ----- age is " << age << endl;
}
stu & stu::growup()
{
this->age ++;
return *this;
}
int main()
{
stu stu1;
stu stu2("dick",20);
stu1.show();
stu2.show();
stu2.growup().growup().growup().growup().growup().growup().show();
}
赋值运算符重载
cpp
my_class_type& operator=(const my_class_type & another)
对于运算符重载的固定格式classname& operator运算符 (classname myclass1,classname myclass2),加不加&要看会不会产生一个新对象,如果产生则不加&,因为返回引用通常用于修改调用对象或者返回某个已存在的对象
系统会默认提供,是等位拷贝赋值(浅赋值),会导致重析构、自身内存泄漏以及无法完成自赋值
cpp
mystring & mystring::operator=(const mystring &another)
{
if(this == &another)
return *this;
delete []this->p;
this->len = another.len;
this->p = new char[this->len];
strcpy(this->p,another.p)
return *this;
}
拷贝构造函数发生的时机:
-
使用一个已有对象创建一个新对象,mystring str2 = str1;或者mystring str2(str1);
-
传参或者函数返回对象(对于普通对象,传引用效果不明显,但对于类对象,传引用可以比传参少进行一次拷贝构造和析构)
传引用等价于扩大了原对象的作用域
栈上的对象是可以返回的(会产生一个中间变量去接收,即使这个函数中的变量消亡也不影响)
栈上的引用不可返回(函数内的变量消亡,其引用也会消亡)除非返回对象本身(return *this)
补充:
my_class_type& operator=(const my_class_type & another)不加上my_class_type后的&会导致(a=b)=c本来应该是a为c的大小,但是这里会变成b的大小,因为不返回引用就需要在栈上创建一个新的对象以保存中间变量,但是栈很快就会销毁,导致无法传回