类的6个默认成员函数
构造函数、拷贝构造函数、
析构函数、赋值操作符重载、
取地址操作符重载、const修饰的取地址操作符重载
1.构造函数
构造函数:(就是初始化函数)
(1)函数名与类名相同,无返回值
(2)创建对象时,编译器自动调用对应的构造函数
(3)构造函数可以重载
(4)构造函数可以在类中定义,也可以在类外定义 (一般在类内)
(5)如果没有显式定义构造函数,编译器会自动生成一个无参的默认构造函数;反之,则使用用户定义的
类的成员变量放的时随机值
*编译器生成的构造函数有以下作用:
基本类型:int / char / double...数组,(不处理);
自定义类型:class / struct / (调用自定义类型的构造函数)
(6)无参的构造函数和全缺省的构造函数都称为缺省构造函数,并且缺省构造函数只能有一个
常用全缺省
Date(int year = 2000, int month = 1, int day = 1) //全缺省的构造函数
{
_year = year;
_month = month;
_day = day;
}
2.析构函数
析构函数(就是清理函数)
(1)在对象被销毁时,编译器自动调用,完成类的一些资源清理和汕尾工作
(2)函数名在类名前加上字符~,无参数,无返回值(一般做释放空间的工作)
(3)一个类只有一个析构函数,若未显式定义,系统会默认生成析构函数:
~Date(){}
(4)对象生命周期结束时,系统会自动调用析构函数
注意:析构函数体内不是删除对象,而是做一些删除对象前的清理工作
(5)一般自定义时可以在函数中释放动态开辟的空间
3.拷贝构造函数
拷贝构造函数(也是一种构造函数的重载)
(1)只有单个形参,该形参是对本类对象的引用(一般用const修饰),用已存在的对象创建新对象
时,编译器自动调用
Date(const Date& d){}
注意:如果不加&会造成无限递归问题,因为d又是一个实体的拷贝
(2)若未显式定义。系统会默认生成拷贝构造函数,这个函数会按照成员的声明顺序依次将其初始
化(这就是浅拷贝)
浅拷贝:按字节进行赋值,因此不能拷贝指针,这样会导致两个对象的成员指针指向同一块空
间,造成错误
4.赋值运算符重载(增强代码可读性)
赋值运算符重载
格式:返回值类型 operator 需要重载的操作符(参数列表)
Date& operator=(const Date& d) //运算符重载,返回引用,可以支持连等
{
if (this != &d)
{
this->_year = d._year;
this->_month = d._month;
this->_day = d._day;
}
return *this;
}
注意:一个类如果没有显式的定义赋值运算符重载,编译器也会实现一个,完成值的拷贝工作
5.取地址及const取地址操作符的重载
这两个默认成员函数一般不用重新定义,编译器会自动默认生成
class Date
{
public:
Date* operator& ()
{
return this;
}
const Date* operator& () const //后边的const修饰this指针
{
return this;
}
private:
int _year;
int _month;
int _day;
};
注意:编译器会自动生成这两个函数,只有特殊情况下,才需要重载,例如让别人获取到指定内容
6.const成员
6.1const 修饰普通变量
在C++中,const修饰的变量已经为一个常量,具有宏的属性,即在编译期间,编译器会将const所修饰的常量进行替换
const Date* p1; // 修饰 *p1
Date const *p2; //修饰 *p2
Date* const p3; //修饰 p3
6.2const修饰类的成员函数
将const修饰的类的成员函数称为const成员函数,const修饰类的成员函数,实际是修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
int main()
{
const Date d1(2018,10,28);
d1.Display(); //const对象可以调用const成员函数
d1.Print(); //const对象不能调用非const成员函数
Date d2(2000, 6, 12);
d2.Print(); //非const对象可以调用非const成员函数
d2.Display(); //非const对象可以调用const成员函数
//const成员函数内可以调用其它的const成员函数,但不能调用非const成员函数
//非const成员函数内可以调用其它的const成员函数和非const成员函数
}
class Date
{
public:
void Print()
{
cout << "i am print!" << endl;
}
void Display() const
{
test();
cout << "i am display!" << endl;
}
void test() const
{
cout << "i am test!" << endl;
}
}
注意:const成员函数中一定要修改某个成员变量,可以在该成员变量前加 mutable 关键字