一.拷贝构造函数和拷贝赋值函数
1.1拷贝构造函数功能,格式
拷贝构造函数是一种特殊的构造函数,用来将一个类对象给另一个类对象初始化使用的。
1> 用一个类对象给另一个类对象初始化时,会自动调用拷贝构造函数。
2> 当一个类对作为函数的实参,传递给形参的过程时,会自动调用拷贝构造函数。
3> 当一个函数返回一个类对象时,会自动调用拷贝构造函数。
类名(const 类名 &other) { 函数体内容; }
1.2浅拷贝和深拷贝(重点)
1> 系统会提供一个默认的拷贝构造函数,如果程序员手动定义,则系统取消默认提供。
2> 系统提供的拷贝构造函数,是将一个类对象给另一个类对象初始化使用的,换句话说,就是将一个类对象的所有数据成员赋值给另一个类对象的所有数据成员。
3> 浅拷贝:系统提供的拷贝构造函数。
4> 如果类中没有指针成员,则调用系统提供的拷贝构造函数,没有问题。如果类中有指针成员,依然调用系统提供的拷贝构造函数,则会造成double free现象。
1.3拷贝构造赋值功能,格式
用一个类对象给另一个类对象进行赋值操作,会自动调用拷贝赋值函数
类名 &operator=(const 类名 &other) { 函数体内容; }
用一个类对象给另一个类对象进行赋值操作,会自动调用拷贝赋值函数。
二.友元函数
2.1 作用和种类
作用:可以让一些函数或者类去访问另一类的私有数据成员。
种类:
1> 全局函数做友元
2> 类做友元
3> 成员函数做友元
2.2全局函数做友元
让一个全局函数访问一个类的私有数据成员。
#include <iostream> using namespace std; //封装一个房间类 class Room { friend void goodGay(Room &r); //声明该函数是本类的好朋友,可以访问本类的私有数据成员 private: string bed_room; //卧室 public: string sitting_room; //客厅 public: //无参构造函数 Room() { bed_room = "卧室"; sitting_room = "客厅"; } }; //全局函数 void goodGay(Room &r) { cout << "好基友正在访问。。" << r.sitting_room << endl; cout << "好基友正在访问。。" << r.bed_room << endl; } int main() { Room r; goodGay(r); return 0; }
2.3类做友元
让一个类去访问另一个类的私有数据成员。
#include <iostream>
using namespace std;
//声明有这样的类
class Room;
//封装好盆友的类
class GoodGay
{
private:
Room *r;
public:
GoodGay();
void visit();
};
class Room
{
friend class GoodGay; //声明该类是本类的好朋友,可以访问本类的私有数据成员
private:
string bed_room;
public:
string sitting_room;
Room()
{
bed_room = "卧室";
sitting_room = "客厅";
}
};
GoodGay::GoodGay()
{
r = new Room;
}
void GoodGay::visit()
{
cout << "好基友的类 正在访问。。" << r->sitting_room << endl;
cout << "好基友的类 正在访问。。" << r->bed_room << endl;
}
int main()
{
GoodGay g;
g.visit();
return 0;
}
2.4成员函数做友元(了解)
让一个类中的成员函数去访问另一个类的私有数据成员。
小结
1> 不要过度的使用友元,会降低或者破坏封装性。
2> 友元不具有交换性、传递性、继承性
三.常成员函数和常对象
类中的成员函数都能对数据成员做修改操作,如果设计一个函数不能对数据成员做修改,则需要用常成员函数来完成。
3.1常成员函数
常成员函数不能修改数据成员。
返回值类 函数名(形参列表)const { 函数体内容; }
3.2常对象
常对象的数据成员不能被改变。
格式: const 类名 对象名;
1】非常对象,既可以调用非常成员函数 ,也可以调用常成员函数,优先调用非常成员函数。
2】常对象只能调用常成员函数,不能调用非常成员函数。
#include <iostream> using namespace std; class Stu { private: string name; int age; public: Stu() {} Stu(string name, int age):name(name),age(age) {} void show() const //常成员函数 this指针原型:Stu const * const this; { //this->age = 48; //this = nullptr; //name = "lisi";//不能对数据成员修改 cout << name << " " << age << endl; } void show() //非 常成员函数 this原型: Stu *const this; { //this->age = 48; //this = nullptr; cout << name << " " << age << endl; } }; int main() { //Stu s1("zhangsan", 18); //非常对象 const Stu s1("zhangsan", 18); //常对象 s1.show(); return 0; }
3.3mutable关键字
mutable修饰的数据成员,表示该数据成员可以在常成员函数中被修改。