类中的六个默认函数
在c++类中有六个默认函数,这些默认函数的存在是为了我们在使用类的时候更加“自然”,让我们来认识一下这六个默认函数的作用机极其实现方法和使用方法
- 构造函数
- 析构函数
- 拷贝构造函数
- 赋值运算符重载
- const成员函数
- 取地址及const取地址操作符重载
一、构造函数与析构函数
构造函数的作用是给创建的对象中的成员变量一个合适的值,可以有多种方式
函数体赋值
Class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
初始化列表
在声明构造函数的时候在函数的括号后面以冒号开始,把需要赋值的成员变量后面跟上一个括号,括号里面是用来初始化成员变量的表达式
Class Date
{
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
为什么要搞一个初始化列表呢, 引用成员变量 const成员变量还有没有默认构造函数的自定义类型只能通过初始化列表初始化
成员变量的初始化顺序是按照声明顺序来的,与初始化列表的顺序无关
二、拷贝构造函数
这个函数的作用是用一个已经存在的对象初始化一个刚刚创建的对象
MyClass c(10, 'k');
MyClass b(c);
但是我们要注意,编译器自动生成的拷贝构造函数只是简单粗暴的将内存中的字节一个一个的复制过去,在一些简单的类中是可以行得通的,但是在类似栈这种有在堆上开空间之类的复杂对象,编译器默认生成的拷贝构造就显得有点矬了,这种时候我们就要自己定义拷贝构造函数了
其实我们在使用带有返回值为类的的函数或者参数为类的函数的时候,也会调用拷贝构造函数
MyClass func(MyClass a1)
{
return a1;
}
int main()
{
MyClass c(10, 'k');
MyClass b=(func(c))
}
上面的代码一共会调用3次拷贝构造函数
1.在给func函数传参的时候
2.func函数传返回值时
**3.使用拷贝构造函数初始化对象b的时候 **
但是比较新的编译器会将同一行代码中出现多次构造和拷贝构造优化成一次,来提高效率
三、赋值运算符重载
一、运算符重载
在了解赋值运算符重载的,我们先要知道运算符重载的概念
运算符重载的概念在之前的一篇里有详细介绍
https://blog.csdn.net/qq_44950489/article/details/130476778?spm=1001.2014.3001.5501
二、赋值运算符重载
如果我们没有用定义赋值运算符,编译器会自己生成一个赋值,实现方式类似于编译器自己生成的拷贝构造,都是逐字节的拷贝,对于日期类这种简单类是可以行得通的,对于栈这种需要额外开空间的复杂类就行不通了,这个时候我们就需要自己定义赋值赋值运算符重载了 2. static成员
四、static成员
由static关键字修饰的成员函数叫静态成员函数,static修饰的成员变量叫静态成员变量
- 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
- 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
- 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
- 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
- 静态成员也是类的成员,受public、protected、private 访问限定符的限制
五、友元
1.友元函数
我们在实现运算符重载>>和<<的时候,如果把重载函数写成内部成员函数的话,函数的第一个默认参数会被this指针所占据,这样我们无法很好的实现,友元函数的出现就是为了解决这个问题
友元函数是定义在类外部的普通函数,只需要在类的内部声明一下,在函数前加上 friend 关键字,这样这个函数就成为了这个类的友元函数,友元函数可以直接访问类的私有成员
友元类
当一个类是另一个类的友元类时候,当前这个类的所有成员函数都都是另一个类的友元函数,可以直接访问它的非公有成员
友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。
内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外
部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中
的所有成员。但是外部类不是内部类的友元。
特性:
- 内部类可以定义在外部类的public、protected、private都是可以的。
- 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
- sizeof(外部类)=外部类,和内部类没有任何关系。