类的6个默认成员函数--超详解

当一个类中没有定义成员函数时,编译器会自己自动生成6个默认成员函数,以便能够完成一下对类的正常操作。这六个自动生成的默认函数分别对应不同的功能,前四个默认成员函数是需要重点掌握的,后面两个我们也需要了解,下面将会逐一介绍则6个默认成员函数。

1.构造函数

1.1概念

构造函数是一个特殊的成员函数,其函数名与类名是相同的,并且没有函数返回值,在创建类对象时构造函数会进行自动调用,其作用是初始化对象,以便初始化生成类成员变量的合适值,其调用只会在创建对象时完成一次调用,后续不再进行调用


1.2特性

  • 函数名与类名相同
  • 无返回值
  • 可以有重载函数
  • 初始化类对象时自动调用

构造函数是可以通过用户自己定义的,如果成员函数中没有出现构造函数,编译器会自动生成默认构造,如果用户自己定义了构造函数,那编译器将不再生成默认构造函数。在初识化类对象的时候变为自动调用用户直自己定义的构造函数。

#include<iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "." << _month << "." << _day << endl;
	}
};

用户自己在定义构造函数时可以配合缺省参数使用,在初始化类对象的时候,我们可以直接在对象后接自定义构造函数的参数,完成对类对象的初始化,需要注意的是,如果是自定义构造函数为全缺省参数时,在对类对象的初始化时不需要在后面加上(),这个与系统生成的默认构造是相同的额,不需要进行传参,也不需要加上(),否则就变为了函数的声明。此外构造函数可以重载,但各个构造重载函数在调用是不能出现歧义,比如存两个同时不传递参数,将有歧义,无法确定调用哪个默认构造。


1.3 默认构造初始化的规则

我们常常会发现类中的成员变量未被初始化的到的许多变量的值大多为随机值,这是怎么回事呢,不是有默认构造函数会初始化成员变量的值吗?许多人可能会有这样的异或,但实际上,默认构造函数并不是会对所以类型的成员变量进行处理,而是选择性取处理初始化某一类成员变量。

C++中,将类型分为了两种,一个是内置类型,另一个是自定义类型,其中内置类型就是语言本身所提供的类型,我们可以直接使用的类型,如char、int,int*等等,而自定义的类型是由用户自己定义的一个类型,例如由class或struct所定义的类这个类型就是一个自定义类型,了解了C++中的两种类型后,我们就可以更好的知道默认构造进行初始化类成员变量的规则,首先结论是:

默认构造的初始化不对内置类型的成员变量做处理,只对自定义类型的成员变量进行初始化,而对自定义类型的处理则是去调用自定义类型中的默认构造函数,这样我们就可以解释为什么默认构造被调用后,内置类型仍然是随机值的原因。


1.31对内置类型的初始化的优化

针对于默认构造不初始化内置类型的缺陷,在后来的C++11中优化了这个缺陷,使得内置类型可以声明默认值,不需要默认构造的初始化也能定义一个默认值。


1.32对自定义类型的初始化

默认构造对于自定义类型的处理是通过调用自定义类型自己的默认构造函数,以达到初始化自定义类型的处理。

#include<iostream>
using namespace std;
class Time
{
private:
	int _hour;
	int _second;
	int _minute;
public:
	Time()
	{
		cout << "Time()" << endl;
		_hour = 0;
		_second = 0;
		_minute = 0;
	}
};
class Date
{
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
	Time t;
};

 看上面的代码,在类Date中我们将另一个类Time作为其成员变量,其中类Time中定义了自己的默认构造函数,Time(),为了确定默认构造是否会被调用,我们使用打印Time()来确定,一旦默认构造被调用,就会打印出Time(),然后我们在定义类Date的一个对象d1,我们会发现,编译器的确打印出了Time(),也就是说,对于类Date的默认构造,去调用了,自定义类Time中自己的默认构造去初始化自定义类Time成员变量。


1.4默认构造和构造函数的关系

默认构造与构造函数,可能很多人分不清楚这两者有什么关系,作为刚开始学习C++的小白,我感同身受,实际上,这两者还是有很大的区别的。

  • 默认构造是不需要用户自己传递参数就可以调用的,在定义类对象的时候会自动调用
  • 默认构造只能有一个,但是构造函数可以有多个重载
  • 无参数的构造函数或者全缺省的构造函数可以取代成为默认构造,但是只能存在一个默认构造
  • 一旦定义了构造函数,默认构造就不会在自动生成。

明白了上面这些,就能够知道,类对象在被定义的时候如果不传递参数则默认为调用默认,传递参数的则为调用构造函数,但是如果定义了构造函数,却没有能够成为取代默认构造的构造函数,此时定义类对象时不传递参数,编译器仍然会识别为调用默认构造,但是此时默认构造不存在,此时编译器将会报错,我们应当避免出现这种情况。

所以,当我们定义构造函数时,如果是需要调用默认构造进行初始化类对象时,应当要定义一个不含参的或者全缺省的构造函数取代默认构造,如果是想要通过传递参数进行初始化类对象,此时不需要调用默认构造,则可以定义带有参数或半缺省的构造函数,在实际我们需要根据需要来定义。


2.析构函数

2.1概念

析构函数与构造函数相对应,是一个特殊的成员函数其作用是起到销毁成员变量的作用,当类对象的生命周期结束时会自动调用析构函数,完成对成员变量的清理工作。


2.2特性

  • 函数名与类名相相同
  • 函数名前加~
  • 无返回值
  • 当用户没有定义时会自动生成,定义后不再自动生成,自定义时也只能存在一个,没有重载
  • 当对象的生命周期结束时自动调用一次

 析构函数同样是可以通过用户自定义的,与构造函数一样,如果用户没有自定义析构函数,编译器会自动生成一个析构函数,在对象生命周期结束时调用,但是,用户定义的析构函数只能是一个,无法进行重载


2.3析构函数销毁的规则

这里可以参考默认构造的处理规则,系统自动生成的析构函数是与其相同的,对于内置类型的成员变量,销毁时不需要进行资源清理,析构函数不做处理,而对于自定义类型的成员变量,不知道是否有资源清理,会去调用该自定义类型自身的析构函数做处理。用户自己定义的析构函数可以做任意处理,但对于内置类型我们实际上一般不需要处理,内置类型不占有资源,在其生命和周期结束后会被自动销毁,而自定义类型可以有消耗空间资源的行为,在生命周期结束后是需要做处理的,否则会造成资源泄露。

#include<iostream>
using namespace std;
class Time
{
private:
	int _hour;
	int _minute;
	int _second;
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
};
class Date
{
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
	Time t;
public:
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

对于上面的代码,我们可以看到,分别在定义了类Time和类Date,对于这两个类又分别自定义了其析构函数,使得在进行了析构操作后会打印出对应的析构函数。在定义了这两个类的对象后,我们看到共调用了两次类Time的析构函数,调用一次类Date的析构函数,这是由于自定义类型Time作为类Date中的成员变量,在对Date进行析构时,同时去调用了Time自身的析构函数,而类Time定义的对象在生命周期结束时也进行了一次析构调用,所以类Time总共完成了两次析构。此外我们发现了析构的调用先后顺序是先调用了Date的析构,之后再联系调用了两次Time的析构,这是因为,后定义的类Date所定义的对象的生命周期被判定为先结束,先定义的类TIme所定义的对象生命周期后结束,这就使得Date先调用析构函数,而包含在其成员变量中的Time类在Date类被销毁的时候也被调用了析构,第二次Time的析构调用则是Time类所定义对象的生命周期结束所进行的调用。


2.4析构函数的优点

析构函数在对于没有资源开销的类的使用时我们可能感觉不到它的作用,但是在对于有资源开销的类型使用时十分的方便,它不需要我们取手动释放销毁类有资源开销的成员变量,此外对于经常会忘记释放空间开销的人来说,是一个好帮手,不用再担心对于有资源消耗忘记释放销毁导致资源泄露的问题。


3.拷贝构造函数

3.1概念

拷贝构造函数是类中的一个特殊函数,它的只含有一个该类的参数,如果用户没有定义拷贝构造函数,系统也会生成一个默认的拷贝构造函数,拷贝构造函数会在已经存在的类对象创建新的对象时被自动调用,也就是相当类对象被拷贝一份相同的对象时会被自动调用进行拷贝。


3.2特性

  • 函数名与类名相同,实际上是构造函数的一个重载形式,也就是只能存在一个拷贝构造函数。
  • 仅有一个参数,这个参数类型为该类类型,且该类类型是引用的形式。
  • 用户未定义时,编译器会自动生成一个默认构造
  • 在进行该类类型的传递参数拷贝工作时会自动调用

 拷贝构造函数的参数类类型一定是引用形式的,否则,在调用拷贝构造函数后会陷入无穷递归状态,则是因为,如果不是以引用形式传递类对象参数时,传值调用的类对象进行传参时先需要将传递的参数类本身进行一次拷贝,才可以得到调用函数中的形参,进行相关操作,但是需要对该类对象的拷贝操作又会引发新的一次拷贝构造的调用,拷贝构造函数中的参数同样需要完成拷贝才能得到,之后才能进行拷贝操作,所以会再一次调用拷贝构造完成该函数参数的拷贝,这就导致了不断的反复如此调用拷贝构造函数,从而会陷入无穷递归的情况。


3.21拷贝构造函数的自动调用

拷贝构造函数在传递已经存在的类对象的参数时会进行自动调用拷贝构造函数,下面让我们来看一个例子来更好的理解拷贝构造的自动调用。

#include<iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(const Date& d)" << endl;
	}
};
void Test(Date d)
{
	Date D(d);
}

我们看上面所定义的类,其在运行时总计调用了两次拷贝构造函数,在调用函数Test()时,所传递的实参类对象d1先调用了拷贝构造函数,完成了对形参d的拷贝,之后在Test()函数的内部,又定义了另一个类对象D,此时类对象的定义是由传递类类型的参数完成定义的,在定义的时候同样发生了拷贝构造的调用,完成了类对象D的定义。


3.22默认拷贝构造拷贝的规则

实际上,对于拷贝构造,对类类型的拷贝本质上是对于类中成员变量的拷贝,而对于不同的成员变量类型,默认拷贝构造同样会有不同的处理。对于内置类型的成员变量,编译器自动生成的默认拷贝构造,会完成其拷贝,而对于自定义类型的成员变量,拷贝构造函数会去调用该自定义类型的拷贝构造函数。下面我们来看一段代码来理解理解

#include<iostream>
using namespace std;
class Time
{
private:
	int _hour = 1;
	int _minute = 1;
	int _second = 1;
public:
	Time()
	{}
	Time(const Time& t)
	{
		_hour = t._hour;
		_minute = t._minute;
		_second = t._second;
		cout << "Time(const Time& t)" << endl;
	}
};
class Date
{
private:
	int _year;
	int _month;
	int _day;
	Time _t;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

 在上面的代码中,我们定义了两个类类型Time、Date,其中类Date中包含了类Time,类Date没有定义拷贝构造函数,类Time定义了拷贝构造函数,在被调用时会打印出该函数名,以显示该拷贝函数被调用过。我们首先定义了Date类对象d1,然后使用d1去初始化d2,在初始化d2的过程中类Time的拷贝构造函数被调用,这是因为在类Date中,由传递已经存在的对象d1去初始化d2,其内置类型的成员变量会自动被Date的默认拷贝构造处理完成拷贝,而对于自定义类型Time的成员变量,在拷贝时会去调用Time自己的拷贝构造。

但需要注意的是,只有编译器自己生成的默认拷贝构造,会做上述的处理,对于用户自定义的拷贝构造,是由我们自己控制的,不会自动调用自定义类型的拷贝构造完成拷贝,需要我们手动调用。

class Date
{
private:
	int _year;
	int _month;
	int _day;
	Time _t;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(const Date& d)" << endl;
	}
};

对于上述代码,我们只改变类Date的成员函数,增加类Date的拷贝构造函数,在不改变其他代码的情况下,再次执行上面的同样操作,用类Date对象d1去初始化d2,我们会发现,运行结果只显示了对于类Date拷贝构造函数的调用,而没有调用类Time的拷贝构造函数,用户自定义的拷贝构造函数中,编译器不会去自动调用自定义类型的拷贝构造函数,也就是说,如果用户所定义的拷贝构造没有对自定义成员变量进行拷贝处理那对于自定义成员就不再处理,达不到拷贝类对象的目的,在使用进行类对象的拷贝操作时就会出问题,所以对于自定义类型的成员变量,用户所定义的拷贝构造函数中需要手动调用自定义成员的拷贝构造。

如下在类Date的拷贝构造手动调用,自定义类型Time的拷贝构造函数,实现正常对类对象的拷贝。

class Date
{
private:
	int _year;
	int _month;
	int _day;
	Time _t;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		Time(d._t);//手动调用自定义类Time的拷贝构造
		cout << "Date(const Date& d)" << endl;
	}
};


3.23拷贝的两种方式 

实际上,拷贝也分为了两种不同的拷贝程度,一种是按逐个字节拷贝的方式,我们称这种拷贝方式为浅拷贝,另一种是拷贝是需要进行资源开销的拷贝,例如对类对象拷贝时开辟相同大小的空间给拷贝后的对象,并且,两者空间中成员变量的值也完全相同,这种拷贝我们称之为深度拷贝

  • 默认拷贝构造的浅拷贝

编译器自动生成的拷贝函数的拷贝方式为浅拷贝,不需要进行资源的申请,这种拷贝对于上面的日期Date类这种简单的类来说,可以不需要用户自定义就能够完成类对象的拷贝。

  • 深拷贝

 对于简单的类类型,用户可以不写拷贝构造函数,让使用编译器默认生成的构造函数,但是并不是所有的类类型的拷贝都可以交给编译器默认生成的拷贝构造去处理,对于类中有进行资源开销的成员,如果继续使用默认构造的浅拷贝,那在拷贝完后可能会出现一些问题。让我们看看以下一些类。

#include<iostream>
using namespace std;
class Stack
{
private:
	int* _a;
	int _top;
	int _capacity;
public:
	Stack(int capacity = 4)
	{
		int* temp = (int*)malloc(sizeof(int) * capacity);
		if (nullptr == temp)
		{
			perror("malloc fail");
			exit(-1);
		}
		_a = temp;
		_top = 0;
		_capacity = capacity;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_top = _capacity = 0;
	}
};
void Test(Stack& s)
{
	Stack _s(s);
}

 

 上面的代码中,我们定义了一个Stack类型,Stack类型的成员变量_a在初始化时是需要在堆区上动态开辟一块内存空间的,我们定义了成员函数默认构造Stack,以及用于销毁的析构函数~Stack,我们首先定义了Stack类的对象s1,并将s1作为引用传参传递给Test函数,之后又在Test函数中用参数s通过系统生成的默认拷贝函数,定义了另一个Stack类对象_s,最后我们会发现结果是程序跑崩掉了,显示器上打印出两次析构函数的调用。这里如果没有了解拷贝函数的拷贝方式的话,可能会认为两次析构函数的调用是合理的,一个是Tset函数中定义的类对象的销毁,另一个是最初定义的类对象的销毁,但实际上,这只是表象上是如此,但真正两次析构函数销毁的空间是指向同一块的,同过调试,我们能够发现,Test函数中定义的类对象与引用传递的参数的地址空间是完全一样的,这就导致了,对于两个不同类对象的销毁,最后对于一块相同的堆区上的空间进行了两次销毁处理,使得最后程序跑崩掉。

为了避免发生如上相同的情况,我们需要自定义一个能够完成深拷贝的拷贝构造函数,使用深拷贝使得两个不同类对象在进行资源开销时,指向不同的空间,例如对于Stack类加上我们自定义的深度拷贝构造。

class Stack
{
private:
	int* _a;
	int _top;
	int _capacity;
public:
	Stack(int capacity = 4)
	{
		int* temp = (int*)malloc(sizeof(int) * capacity);
		if (nullptr == temp)
		{
			perror("malloc fail");
			exit(-1);
		}
		_a = temp;
		_top = 0;
		_capacity = capacity;
	}
	Stack(const Stack& s)
	{
		_a = (int*)malloc(sizeof(int) * s._capacity);
		if (nullptr == _a)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(_a, s._a, sizeof(int) * s._capacity);
		_top = s._top;
		_capacity = s._capacity;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		cout << &_a << endl;
		free(_a);
		_top = _capacity = 0;
	}
};

此外也加入了对要析构销毁空间的打印,我们在显示器上最后看到两次析构函数的调用,这两次析构销毁的空间是指向不同的地方。所以当我们所定义的类的成员变量中如果有申请资源开销的情况,我们一定要自己定义能够实现深度拷贝的拷贝构造函数,而对于较为简单,没有申请资源开销的类类型,我们可以不写靠拷贝构造函数,使用编译器自动生成的默认拷贝构造。


4.赋值运算符重载

4.1运算符的重载

C++中,为了增强对于代码的可读性,引用了运算符重载,运算符重载是一个具有特殊函数名的函数,其函数名是由关键字operator后接运算符构成的,运算符重载也具有有返回值、函数参数,函数原型为:返回类型 operator 运算符 (函数参数)。

但需要注意的是,运算符的重载有多种重载,但只有赋值运算符重载 operator= 为类中的默认成员函数,用户不写编译器会自动生成,其余运算符重载则不会。


4.11运算符重载的特性

  • 重载的运算符函数参数中必须要有类类型的参数
  • 不能对内置类型的运算符进行重载,例如改变整数的加减
  •  .*  ::  sizeof  ?:(三目运算符)  .   以上5个运算符不能重载

运算符的重载函数的参数中一定要有类类型,不能只包含内置类型,需要注意的是,这里的类类型实际上是已经包含了C语言中的自定义类型struct,在C++中,struct所定义的自定义类型同样被视为类类型;同时,运算符的重载是可以声明定义在类之外的,只有类的默认成员函数--赋值运算符重载是被限制在类中重载的。


4.12运算符重载的使用

运算符重载的使用时可以直接用运算符号进行调用的,不需要指明所调用的运算符重载函数,编译器会自动识别处理,这方便了我们对于运算符重载的使用。其中需要注意的是,运算符的左边是对应运算符重载的第一个参数,这一点是默认的。看下面一段代码来帮助我们理解

class Date
{
private:
	int _year ;
	int _month ;
	int _day;
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Date& d)
	{
		return (d._year == _year && d._month == _month && d._day == _day);
	}
};

 看上面一段代码,对于Date类的运算符重载函数 operator== ,我们先后使用两个值来接收两个类对象值的比较,得到两个相同的结果,我们发现直接通过 == 去比较两个对象和手动调用对应的运算符重载,得到的效果是一样的,实际上,在我们使用运算符的操作对象是类类型的时候编译器会首先去识别是否有对应的运算符重载函数,有编译器则会自动调用对应重载函数,如果没有对应的重载函数,编译器则会报错,其中运算符左边的默认为运算符重载函数的第一个参数,如果运算符重载是定义在类中的,那么这个参数就是隐藏参数this指向的对象。


4.2赋值运算符重载

赋值运算符的重载是运算符重载中唯一一个类中的默认成员函数,当用户没有定义时,编译器会自动生成一个默认赋值重载,此外,特别需要注意的是,赋值运算符重载只能重载在类的成员函数中,不能重载成全局函数


4.22赋值运算符的重载格式

函数返回参数类型:返回类型为类类型的引用,也就是直接返回this指针所指类对象*this,这里我们使用引用返回,可以提高传递返回的效率,同时对于返回类类型的原因是为了能够支持连续赋值的操作。

函数参数类型:这里我们使用const+引用来修饰函数参数,使用引用同样是因为引用的传参效率更高,而使用const的目的是为了防止传递的引用参数被修改。

#include<stdio.h>
using namespace std;
class Date
{
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
public:
Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
        return *this;
	}
    void Print()
	{
		cout << _year << "." << _month << "." << _day << endl;
	}
};

以类类型的引用为返回值,我们可以直接返回this所指向的对象,对于上面的代码我们使用已经初始化的类对象d1来赋值d2、d3,能够达到连续赋值的效果。


4.22默认赋值运算符重载函数的特性

  • 当用户未定义,编译器会自动生成
  • 函数反回值为赋值后的类对象
  • 对内置类型直接进行逐个字节的值拷贝,对自定义类型则去调用它的赋值运算符重载

实际上,我们发现编译器自动生成的默认赋值重载,也与上面所介绍的默认成员函数的特性相同,对于内置类型,默认赋值重载会处理完成赋值,而对于自定义类型的成员,它会去调用自定义类型的默认赋值重载;此外,我们发现默认赋值的赋值的规则与默认拷贝构造是完全相同的,它所完成的是逐个字节上的值拷贝而实现的赋值,是利用浅拷贝完成的,通过前面的拷贝构造我们也知道,浅拷贝是有所弊端的,对于有资源申请开销的情况下,是会出现问题的,这里就不再多赘述。


4.3前置自增/减和后置自增/减的重载 

在运算符的重载中,自增和自减运算符的重载同样是被允许的,但由于不好区分前置和后置的重载区别,所以对于前后置自增自减运算符的重载做出来一些不同的处理。

4.31前置和后置重载的区别

前置重载:重载函数无参数,函数返回值是类对象的引用。

后置重载:重载函数有一个int类型的参数,用于区分与前置重载的不同。函数返回值是类对象。

例如:

class A
{
private:
	int _a;
public:
	A(int a = 0)
		:_a(a)
	{}
	A& operator++()//前置++
	{
		_a += 1;
		return *this;
	}
	A operator++(int)//后置++
	{
		A a(*this);
		_a += 1;
		return a;
	}
};

前置++重载的返回值是类对象的引用, 相当于直接对类对象进行++,返回得到的值;而后置++返回的是当前对象的拷贝,但是同样会对类对象做自增处理,这样就起到了,既返回了类对象的原来的值,又对类对象做了自增操作。

前后置的自减运算符的使用是一样的,这里也就不多赘述。

5.取地址和const取地址操作符的重载

作为最后介绍的两个类中的成员函数,这两个成员函数同样为类的默认成员函数,相比于前面四个默认成员函数要简单很多,同样的,它们在用户未定义时,编译器会自动生成。


5.1取地址操作符的重载

返回值:对应类地址

这个函数我们实际上已经十分熟悉了,就是我们经常使用的取地址操作,这个默认成员函数通常是不许要我们去手动定义的,它也是十分简单的,以下给一个简单的例子。

class A
{
private:
	int _a = 0;
	int _b = 0;
public:
	A* operator&()
	{
		return this;
	}
};

5.2const取地址操作符的重载

返回值:const 所修饰的类地址

 const取地址操作符的重载,其实际上重载的是const & ,为了区分则两个成员函数,函数的const是写函数的最后面的,其返回值也是由const所修饰的类对象的地址。下面是一个简单的例子:

class A
{
private:
	int _a = 0;
	int _b = 0;
public:
	const A* operator&()const
	{
		return this;
	}
};

结语

这节对于C++中类的重要的默认成员函数的介绍到这里就结束了,下期将继续带来有关类成员函数知识的补充,感谢各位的观看,有错误或者需要改进的地方还请指出,如果有帮助的话,还请点个赞呀!大家互相学习,一起进步。

​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值