C++类与对象
类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
类的两种定义方式
1. 声明和定义全部放在类体中,置于.h文件
2. 声明放在.h文件中,类的定义放在.cpp文件中
注意: 一般情况下编写时更偏向于采用第二种定义方式。
原因: 如果把一个在.h文件中定义成员函数的程序提供给别人作为库时,别人就会看到程序的实现,而在.cpp中定义,人家使用时调用的是库文件,看到的只是头文件中的声明,而不知道实现过程。
访问限定符:public protected private
1. public修饰的成员在类外可以直接被访问,protected和private修饰的成员在类外不能直接被访问
计算类对象的大小
见博客:
https://blog.csdn.net/fiskerzero/article/details/109205303.
类对象的存储方式
只保存成员变量,成员函数存放在公共的代码段。
结构体内存对齐规则
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
this指针
1.是一个指针,里面放置的是当前对象的地址(成员函数执行时调用该成员函数的对象)。
2. 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。
3. 只能在“成员函数”的内部使用。
4. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
5. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
构造函数
class Date
{
public:
void SetDate(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Display()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次。
构造函数的主要任务并不是开空间创建对象,而是初始化对象。
特征
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载。
析构函数
~Date();
与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。
析构函数是特殊的成员函数。
特征
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值。
3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
拷贝构造函数
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
拷贝构造函数是构造函数,只有单个形参,参数比较特殊,是对象。
场景:用一个已经存在的对象创建和它本身完全相同的对象时,编译器自动调用拷贝构造函数。
特征
1. 拷贝构造函数是构造函数的一个重载形式。
2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。
**3.**用对象创建新的对象时自动调用。
**4.**参数必须为引用类型,最好加上const限制。
**5.**如果不显示定义,编译器会自动生成。
**6.**自动生成的拷贝构造完成字节拷贝/内存拷贝/浅拷贝。
**7.**什么时候拷贝构造必须自己定义:当对象有资源时。
赋值运算符重载
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)。
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year;
&& d1._month == d2._month
&& d1._day == d2._day;
}
赋值运算符主要有四点:
1. 参数类型
2. 返回值
3. 检测是否自己给自己赋值
4. 返回*this
5. 一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的值拷贝。
const修饰类的成员函数
将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
int* const ptr
ptr不能变,*ptr可以变
const int*ptr2
ptr2可以变,*ptr2不能变
const int* const ptr3
ptr3可以变,*ptr3不能变
重点:
1.const对象不能调用非const成员函数。
2.非const对象可以调用const成员函数。
3.const成员函数内不能调用其他非const成员函数。
4.非const成员函数内可以调用其他const成员函数。
Date日期类实现
见博客:https://blog.csdn.net/fiskerzero/article/details/109206815.