这是关于一个普通双非本科大一学生的C++的学习记录贴
在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料
那么开启正题
今天继续学习了类和对象,对c++的理解更深了一点点,由于考试周影响进度更新有点慢,下面开始分享
1.类的6个默认成员函数
如果一个类中什么成员都没有,我们叫它空类
但实际上,空类中并不是什么都没有,任何类在上面都没有写的时候,编译器会自动生成6个默认成员函数,这里我们就引入了默认成员函数的概念
默认成员函数:用户没有显示实现,编译器会自动生成的成员函数被称为默认成员函数
默认成员函数的作用主要有三类
1.初始化和清理
a.构造函数主要完成初始化工作
b.析构函数主要完成清理工作
2.拷贝复制
c.拷贝构造是使用同类对象初始化创建对象
d.赋值重载主要是把一个对象赋值给另一个对象
3.取地址重载
e.主要是普通对象和const对象取地址,这两个很少会自己实现
2.构造函数
2.1构造函数概念
观察如下代码
class Date
{
public:
void Init(int year, int month , int day )
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
对于Date类我们每次实例化出一个对象之后就马上紧跟着就要调用Init函数对齐进行初始化,但是这样未免有些麻烦,这里引入的构造函数就帮我们解决了这个问题
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时编译器,以确保每个数据类型都有一个合适的初始值,并且在对象整个生命周期只调用一次
2.2构造函数的特性
构造函数的名字十分具有迷惑性与欺骗性,它实际完成的任务并不是构造,而是对对象的初始化,他的特性如下
1.函数名与类名相同
2.无返回值
3.对象实例化时自动调用对应得构造函数
4.构造函数可以重载
根据如上函数我们可以写出这样的代码
class Date
{
public:
Date()
{
_year = 0;
_month = 1;
_day = 1;
}
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(2024, 1, 8);
d1.Print();
d2.Print();
return 0;
}
以上对象d1,d2实例化时都能正确调用对应函数,要注意的是,d1调用无参数构造函数,它不需要传入参数,也不需要写(),否则就成了函数声明
实际使用中,我们并不喜欢以上这种函数重载的方式,因为需要定义两个函数,有些冗余
class Date
{
public:
Date(int year = 0, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(2024, 1, 8);
d1.Print();
d2.Print();
return 0;
}
这样的全缺省函数让两个函数的功能和而为一了提高了代码的可读性,也更加简洁美观
如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器就不将生成
要注意的是,编译器自动生成的默认构造函数对内置类型并不会处理,而是将调用自定义类型的默认构造函数
class Time
{
public:
Time()
{
cout << "Time()" << endl;
_hour = 0;
_minute = 0;
_second = 0;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
private:
// 基本类型(内置类型)
int _year;
int _month;
int _day;
// 自定义类型
Time _t;
};
int main()
{
Date d;
return 0;
}
以上代码运行后,通过调试窗口我们可以观察到,定义对象d时,他的内置类型并没有被初始化,而他的自定义类型被调用默认构造函数完成初始化并在屏幕上打印了我们预期的字符串
C++11中针对内置成员不初始化的缺陷,又打了补丁::内置成员变量在类的声明中可以给默认值
值得注意的是,我们前文提及的默认构造函数实际上有三种,它们分别是,编译器自己生成的默认构造函数,我们写的无参的默认构造函数,我们写的全缺省的默认构造函数,它们三个两两都不能同时存在,因为如果同时存在,调用时,编译器不知道调用哪一个会报错
3.析构函数
3.1析构函数的概念
析构函数::与构造函数相反,析构函数不是完成对对象本身的销毁,局部对象工作是由编译器完成的,而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作
3.2析构函数的特性
1.析构函数名时类名前面加一个字符~
2.无参数无返回类型
3.一个类只能有一个析构函数.若定义未显示,系统会自动生成默认的析构函数
注意::析构函数不能重载
4.对象生命周期结束是,C++编译系统会自动调用析构函数
类似的,编译器自动生成的析构函数,会对自定义成员调用他的析构函数
注意实例化对象是在栈上存储的,它满足后进先出
总结::C++有一些默认成员函数,它会偷偷的帮我们做一些事情,我们在使用它的时候会方便很多,但是我们在学习的时候也会因为要学习它到底偷偷做了什么事情而感到困难
今天的博客就到这里了,后续内容明天分享,最近因为考试周原因不能更新太多内容,等考试周结束了再"快马加鞭"
新手第一次写博客,有不对的位置希望大佬们能够指出,也谢谢大家能看到这里,让我们一起学习进步吧!!!.