既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
冒号开始
,接着是一个以
逗号分隔的数据成员列表
,每个
"
成员变量
"
后面跟一个放在括号中的初始值或表达式。初始化列表是成员变量定义(分配内存空间)的地方,包括自定义类型,内置类型成员。
class A//类A
{
public:
A()
{
cout<<"调用A的默认构造 A()"<<endl;
_a=i;
}
A(int i)
{
cout << "调用A的带参构造 A(int)" << endl;
_a = i;
}
private:
int _a;
};
class Date//类Date
{
public:
Date(int year = 1, int month = 1, int day = 1)//构造函数
:_year(year),//构造函数的初始化列表(为成员变量分配空间)
_month(month),
_day(day),
a()
{
//构造函数函数体
}
private:
//成员变量的声明
int _year;//内置类型成员
int _month;
int _day;
A a;//自定义类型成员
};
初始化列表是构造函数不可缺少的,就算不手动写编译器也会默认添加。默认添加的初始化列表为内置类型分配空间,但不指定值(随机值)。对自定义类型成员会调用自定义类型的默认构造函数。
public:
Date(int year = 1, int month = 1, int day = 1)//构造函数
/*:_year(), //编译器默认添加,会为成员分配内存空间,是随机值
_month(),
_day(),
a()*/ //对自定义类型会调用自定义类型的默认构造函数
{
}
1.内置类型成员在参数列表中的定义
此时上面的构造函数未手动添加初始化列表,这时创建一个对象
Date d1;
d1.Print();
打印d1的内置类型成员变量。
是随机值,因为默认初始化列表只为内置类型成员变量分配了内存空间,并没有给成员变量赋值。
此时赋值操作既可以在手动添加的初始化列表中完成,也可以在函数体中完成赋值。
(1).手动添加的初始化列表中完成赋值
Date(int year = 1, int month = 1, int day = 1)//构造函数
:_year(year),
_month(month),
_day(day)
{
}
Date d1;
d1.Print();
运行结果:
(2).函数体内完成赋值
public:
Date(int year = 1, int month = 1, int day = 1)//构造函数
/* :_year(),
_month(),
_day()*/ //默认参数列表
{
_year = year;
_month = month;
_day = day;
}
Date d1;
d1.Print();
运行结果:
总结:内置类型成员变量的定义(分配内存空间)只能在初始化列表中一次性完成,不管写不写都会有这个过程,手动写可以顺便在定义时赋值。不写编译器的默认参数列表会将成员变量定义为随机值,之后再函数体中再次赋想要的值。
2.自定义类型成员在参数列表中的定义
当我们不手动添加初始化列表,默认的初始化列表会调用自定义类型成员的默认构造函数
例如:当构造函数是这样时
Date(int year = 1, int month = 1, int day = 1)//构造函数
//:_year(),//默认初始化列表
//_month(),
//_day(),
//a() 默认构造函数的调用
{
//构造函数函数体
}
Date d1;
运行结果:
当我们手动写初始化列表时,就可以选择性的调用自定义类型的构造函数,可以是带参的,也可以是默认构造函数。
Date(int year = 1, int month = 1, int day = 1)//构造函数
:_year(year),//默认初始化列表
_month(month),
_day(day),
a(2) //选择调用带参构造函数
此时
Date d1;
运行结果
总结:默认构造函数对自定义类型自动调用自定义类型的默认构造方法本质是默认构造函数的默认初始化列表调用自定义类型的默认构造方法。只要构造方法使用默认初始化列表,对自定义类型就会调用它的默认构造方法。反之,手动添加初始化列表就可以选择性的调用自定义类型的构造方法。
3.初始化列表解决的三大问题
(1)类中的引用成员变量
引用在定义的时候必须初始化,否则会出现编译错误,详见重生之我要学C++第二天_无极太族的博客-CSDN博客
类中的成员都是在初始化列表中定义的,如果成员有引用类型就必须在初始化列表中初始化。
#include<iostream>
using namespace std;
class A
{
public :
A(int a)
{
_a = a;//初始化
}
private:
int& _a;
};
int main()
{
int tmp = 2;
A a(tmp);
return 0;
}
此时,引用_a的定义在默认初始化列表中已经完成,在构造函数函数体中在赋值初始化会导致编译错误(定义处未初始化)。
解决方案:在构造函数中手动添加初始化列表,在初始化列表中定义和初始化一并进行。
A(int a)
:
_a(a)
{
}
(2)const成员变量
const成员变量容易出问题和引用的原理相同。都是定义处必须初始化。
(3)自定义类型成员没有默认构造函数时的问题
我们知道,构造函数不写初始化列表时,默认初始化列表会调用自定义类型的默认构造函数
默认构造函数:
详见:重生之我要学C++第四天_无极太族的博客-CSDN博客
但是如果此时这个自定义类型没有默认构造方法,会出现编译错误。
这时候就必须手动添加参数列表,选择性的调用自定义类型具有的构造方法。
运算符重载的应用
第四天我们学习了运算符重载,在这里举两个例子让读者感受到运算符重载的魅力!
(1)顺序表中的运算符重载
先写一个简陋的顺序表
#include<iostream>
using namespace std;
class Sequence
{
public:
Sequence()
{
//初始化
_a = (int*)malloc(4 * sizeof(int));
_size = 0;
_capcity = 4;
}
void Push(int x)
{
//检查容量:此处忽略
_a[_size] = x;
_size++;
}
void Print()
{
for (int i = 0; i < _size; i++)
{
cout << _a[i] << " ";
}
}
private:
int* _a;
int _size;
int _capcity;
};
int main()
![img](https://img-blog.csdnimg.cn/img_convert/af6a44d6c1cad307b947f09c94214e90.png)
![img](https://img-blog.csdnimg.cn/img_convert/ea6d3afdaa9447a261d7f38a0e9b1072.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
apcity;
};
int main()
[外链图片转存中...(img-A5yBRdJz-1715674773095)]
[外链图片转存中...(img-vjXC0PDp-1715674773095)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**