您的位置:首页 > 编程语言 > C语言/C++

c++的默认成员函数

2018-03-27 11:08 183 查看
1.this指针首先我们来看一段代码#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>class Date{public:     void date()     {           printf("%d-%d-%d ", _year, _month, _date);           //cout << _year << "-" << end1;     }private:     int _year = 2018;     int _month = 03;     int _date = 18;};int main(){     Date A;     A.date();     return 0;}
这段代码打出来的内容是2018-03-18,那么我们可以发现,我们又没有对这个函数进行传参。那为什么函数打出来成员变量的值呢?

其实类的每一个成员函数都会有一个this指针特点:每个成员函数都会有一个隐藏的参数即this指针编译器会对this指针进行处理,在对象调用函数的时候,类的地址作为一个实参传递给成员函数的第一个形参this指针此this指针为编译器自己处理的,我们不可以在函数的定义中定义此this指针,也不能在调用时显示调用此函数的对象的地址给this指针(即不能调用,但可以在函数内部使用)
2.类的默认成员函数类的默认成员函数有6个分别为:构造函数,拷贝构造函数,析构函数,赋值运算符重载,取地址操作符重载,const修饰的取地址操作符重载
构造函数我们一般在定义成员变量的时候,一般都会将这些变量定义为私有的不允许外部去改变它的值,那么我们怎么去初始化这些私有的成员变量呢我们的c++里就给我们带了一个默认的初始化的函数,这个函数在我们定义对象的时候,调用一次对变量进行初始化特点:函数名为:类名函数无返回值(无参的构造函数说它无参数,其实他的形参里有一个this指针将对象的地址作为参数传入函数,对这个对象进行初始化)在构造对象的时候编译器直接调用一次构造函数可以重载构造函数可以在类外定义也可以在类里定义如果我们在定义类的时候没有电话已构造函数,那么c++编译器里会自动生成一个缺省的构造函数,但是只要我们定义了一个构造函数,那么这个编译器里自带的构造函数就不会生效我们在定义构造函数的时候,无参的构造函数和全部缺省的构造函数都认为是缺省的构造函数所以只能有一个(因为我们在调用这两个构造函数的时候,都是无参的,那么编译器会不知道调用的是哪个函数,所以这两个函数只能有一个)
构造函数可以有多个可以被重载,可以带参数在实例化出对象之前,调用构造函数之后会得到一个匿名对象拷贝构造函数拷贝构造函数就是在实例化一个新对象的同时,将另一个它同类的对象的值拷贝给这个新对象特点:此函数就是构造函数的一个重载拷贝构造必须使用引用传参,不然会导引发递归的无穷调用如果我们没有人为的定义一个拷贝构造函数,那么c++的编译器也会自带一个缺省的拷贝构造函数,然后这个默认的函数便会生效
那么我们思考一下不用引用传参的话为什么会导致递归的无穷调用呢?class Date{    private:    int _year;    int _month;    int _day;};

int main(){    Date d;    Date(d2);//调用拷贝构造函数}如果在调用我们自己定义的拷贝构造函数(参数为传值)的时候,我们知道在传参的时候,形参是实参的一份临时拷贝,而我们在将实参传递给形参的时候就要调用一次拷贝函数而在调用拷贝函数的时候又要进行参数的拷贝,这是一个死循环,所以我们在传参的时候一定要传引用,就可以很顺利的将值拷贝进去
那么什么时候回调用到拷贝构造函数呢?1)在我们用一个对象初始化另一个对象的时候2)一个对象以值传递的方式进入函数体(形参的实例化,形参是实参的一份临时拷贝)3)一个对象以值传递的方式从函数返回(将此值放入一个临时的寄存器里进行返回)

我们要注意的是在进行指针的拷贝的时候一定要自己写,不能使用默认的拷贝构造函数,因为我们拷贝出来的指着指向同一块内存,在进行析构函数调用的时候就会有问题,因为你两个对象要析构两次,但两次都是析构同一块内存,就会报错

析构函数当一个函数的声明周期结束的时候,c++编译器会自动调用一个函数来销毁我们在堆上开辟的空间,此函数就为析构函数
特点:函数名为:~类名析构函数无参无返回值一个类有且只有一个析构函数,我们没有人为的定义,编译器会自动生成一个缺省的析构函数对象的生命周期结束的时候,编译器自动调用析构函数析构函数并不是删除对象,而是做一些清理工作当一个类的生命周期结束的时候,函数的调用栈桢自动销毁,但是如果我们在堆上开辟了空间,编译器是不会自动销毁的,这就需要我们人为的去释放空间,这就是析构函数的作用
析构函数只能有一个,不能被重载不能带参数运算符重载
首先我们来看一个最要的赋值运算符的重载:重点是区分赋值运算符的重载和拷贝构造函数赋值运算符是在给一个已经定义好了的对象进行赋值,而拷贝构造函数则是对一个对象进行定义的同时进行赋值例如:拷贝构造函数Date A;Date();//调用构造函数Date B(A);//
赋值运算符重载:Date A;Date();Date B;B=A;//此为赋值运算符的重载
那我们接下来再看一个Date A;Date();Date B=A;//此还是拷贝构造函数
最后我们来说一个构造函数,拷贝函数,赋值运算符的重载的不同:当我们定义一个空类的时候这几个函数都默认都存在
但是在使用的时候,我们要一定要区分请拷贝构造和赋值运算符的重载只需记住这三句话就可以:对象不存在,且没用别的对象来初始化,就是调用了构造函数;对象不存在,且用别的对象来初始化,就是拷贝构造函数;对象存在,用别的对象来给它赋值,就是赋值函数;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: