一、auto
auto:代替一个具体的变量类型,让编译器在初始化时自己去校对,一般使用在变量类型较长的时候。
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
for (list<int>::iterator i = l1.begin(); i!= l1.end(); i++){
cout << i.operator->() << endl;
cout << *i << endl;
}
如上:i的类型为list::iterator,非常的冗长,这时候我们就可以用auto来替代它。
auto i = l1.begin();
注意事项
1、auto不能做返回值
2、auto不能做参数
3、auto不能用来定义数组
二、类和对象的初步理解
类的定义:类的定义需要使用关键字class、struct
(二者不同之处在于class在没有设置权限时默认为私有,而struct默认为公有,并且struct兼容C语言的用法可以作为结构体的定义,不过我们一般定义类是使用class)
类的构成:关键字+类的名称+主体(成员变量、成员函数)
类的访问限定符:
public修饰的成员可以在类外直接被访问,protected和private修饰的成员不可以在类外直接被访问。
class Data
{
public:
void Init(int year, int mouth, int data)
{
_year = year;
_mouth = mouth;
_data = data;
}
void Print()
{
// 这里的 _year 不是 private 中的_year, 而是在main函数中定义的_year
cout << _year << " " << _mouth << " " << _data << endl;
}
private:
// 声明 这里的变量并没有空间,用不了
int _year;
int _mouth;
int _data;
};
类的成员函数声明和定义的分离:
一般我们在做比较大的项目时,要实现代码的模块化,这时候就需要用到声明定义分离。
在类中定义的成员函数会被默认为inline,所以一般代码行数较少功能较简单的我们就可以直接定义在类中。
class Stack
{
private:
//声明
int* a;
double _capacity;
int _top;
public:
//声明
void Init();
//默认在类里定义的就是inline
bool Empty()
{
return _top == 0;
}
};
//定义
void Stack::Init()
{
a = 0;
_top = 0;
_capacity = 0;
}
对象的定义:类名+对象名
Stack s1;//对象
Stack s2;//对象
类和对象的关系:一个类可以有多个对象
类和对象的大小:
没有成员变量的类和对象的大小为一个字节,这个字节不存储有效数据,只标识定义的对象存在过。
class B
{};
class C
{
public:
void f()
{};
};
int main()
{
B b1;
c c1;
cout << sizeof(B) << endl;// 1
cout << sizeof(C) << endl;// 1
cout << sizeof(b1) << endl;// 1
cout << sizeof(c1) << endl;// 1
return 0;
}
如上B、C、b1、c1的大小均为一个字节
有成员变量的类和对象的大小和C语言结构体的大小计算一样,都要遵循对齐规则。成员函数不在对象里,在一个公共区域里,因此不计入对象大小的计算。
由于存储变量地址对齐的问题,计算结构体大小的3条规则:
1、结构体变量的首地址,必须是结构体变量中的“最大基本数据类型成员所占字节数”的整数倍。(对齐)
2、结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节的整数倍。(对齐)
3、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍(补齐)
struct A {
long a1;//4
short a2;//2 基于规则2,a3相对于首地址的偏移量要是整数倍,所以此处要补2 4
int a3;//4 基于规则2,a4相对于首地址的偏移量要是整数倍,所以此处要补4 8
int* a4;//8
};
int main()
{
A a;
A b;
cout << sizeof(A) << endl;//24
cout << sizeof(a) << endl;//24
cout << &a.a1 << endl;//0000004FF78FF678
cout << &a.a2 << endl;//0000004FF78FF67C
cout << &a.a3 << endl;//0000004FF78FF680
cout << &a.a4 << endl;//0000004FF78FF688
return 0;
}
this指针
this 实际上是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给 this。不过 this 这个形参是隐式的,它并不出现在代码中,而是在编译阶段由编译器默默地将它添加到参数列表中。
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//void Print(Date* this)
//{
// cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
//}
private:
int _year;
int _month;
int _day;
};
class A
{
private:
char _ch;
int _a;
};
int main()
{
Date d1;
Date d2;
d1.Init(2023, 10, 7);
d2.Init(2022, 10, 7);
// 不能显示写this相关实参和形参
d1.Print();
d2.Print();
//d1.Print(&d1);
//d2.Print(&d2);
return 0;
}
注意:this指针在参数上是不能被显示的写出来的,但在函数里可以显示的写出来