目录
一、 类和对象(熟练掌握)
1. 面向对象和面向过程的理解
2. 面向对象三大特性是什么?
2.1. 封装
2.2 继承
2.3 多态
3. 8个默认成员函数
3.1 构造和析构
3.1.1构造函数
3.2 拷贝构造和拷贝赋值
3.2.1 拷贝构造
3.2.2 拷贝赋值
3.3 移动构造和移动赋值
3.3.1 移动构造
3.3.2 移动复制
3.4 operator& 不关注
3.5什么情况下会默认生成?默认生成的都干了什么?
3.5.1什么情况下会默认生成
3.5.2默认生成的都干了什么?
3.6 构造函数初始化列表
3.6.1 初始化列表价值
3.6.2 哪些成员必须在初始化列表初始化
4. 对象实例化
4.1 对象大小计算--(注意)内存对齐
4.2 空类的大小?为什么是1
5. this
5.1 什么是this指针
5.2 this存在哪?
编辑哪些运算符不能重载
.运算符重载意义是什么
7. static成员
8. 友元
8.1 友元函数
8.2 友元类
一、 类和对象(熟练掌握)
1. 面向对象和面向过程的理解
面向对象:关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。典型语言又c++,java
面向过程:关注的是过程,分析出求解问题的步骤,典型语言是C语言,C语言通过函数调用逐步解决问题。
2. 面向对象三大特性是什么?
2.1. 封装
封装是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。 封装本质上是一种管理,让用户更方便使用类。
比如:对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。
2.2 继承
2.3 多态
3. 8个默认成员函数
3.1 构造和析构
3.1.1构造函数
3.1.2析构函数
更对详细参考(70条消息) 类和对象—6个默认成员函数_对象的默认成员_秋秋是个小菜鸡的博客-CSDN博客
3.2 拷贝构造和拷贝赋值
3.2.1 拷贝构造
3.2.2 拷贝赋值
拷贝赋值与拷贝构造的区别:
拷贝构造函数是一个对象初始化一块内存区域,这块内存就是新对象的内存区,而赋值构造函数时对于一个已经被初始化的对象来进行赋值操作。
拷贝赋值,拷贝构造,构造函数三者使用场景
对象不存在,且没用别的对象来初始化,就是调用了构造函数;
对象不存在,且用别的对象来初始化,就是拷贝构造函数
对象存在,用别的对象来给它赋值,就是赋值函数
3.3 移动构造和移动赋值
3.3.1 移动构造
3.3.2 移动复制
移动赋值和移动构造类似,区别类似于拷贝构造和拷贝赋值
3.4 operator& 不关注
3.5什么情况下会默认生成?默认生成的都干了什么?
3.5.1什么情况下会默认生成
我们定义一个空类。编译器会为我们默认生成一些函数。如果我们没有声明,编译器会帮我生成一个拷贝构造函数、一个拷贝赋值操作符和一个析构函数。同时如果我们声明构造函数的话,也会生成一个默认的构造函数
3.5.2默认生成的都干了什么?
1、默认构造函数不带任何参数,在对象初始化的时候调用。例如 Empty e1;
2、默认copy construct(拷贝构造)函数,用一个对象初始化另一个新对象的时候调用。例如Empty e2 = e1;
3、默认copy assignment(赋值)操作符,赋值的时候调用. 例如 Empty e2 ; e2 = e1;
4、默认析构函数,对象析构的时候调用.
说明:默认拷贝构造函数和默认赋值函数的实现基本上是一样的。会一一拷贝对象中的non-static成员数据。如果成员数据是基本类型,则直接进行赋值操作 e1.a=e2.b;
如果成员数据是自定义类型,则调用数据成员对应的默认拷贝构造函数,e1.a(e1.b);
如果数据对象是数组,则对每个元素进行拷贝操作 e1.arrayi;
copy construct 和 copy assignment 的区别在于调用场景不同。
如果是生成一个新对象则用 copy construct,
例如 Empty e1 = e2(e1是个新对象);
如果是赋值一个已有的对象则用copy assignment,
例如 Empty e1, e1 = e2(e1 是个已有的对象);
3.6 构造函数初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式。 注意:每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
3.6.1 初始化列表价值
1.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化
2.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关 。
3.6.2 哪些成员必须在初始化列表初始化
- 引用成员变量
- const成员变量
- 自定义类型成员(且该类没有默认构造函数时)
4. 对象实例化
用类类型创建对象的过程,称为类的实例化
4.1 对象大小计算--(注意)内存对齐
#include<iostream>
using namespace std;
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1() {}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
int main()
{
cout << sizeof(A1)<<endl;
cout << sizeof(A2) << endl;
cout << sizeof(A3) << endl;
return 0;
}
4.2 空类的大小?为什么是1
ps:结构体内存对齐规则1. 第一个成员在与结构体偏移量为 0 的地址处。2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS 中默认的对齐数为 83. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
5. this
5.1 什么是this指针
5.2 this存在哪?
this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
6. 运算符重载
哪些运算符不能重载
这5个不能重载
.*
::
sizeof
?:
.
运算符重载意义是什么
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
7. static成员
8. 友元
8.1 友元函数
class Date
{
friend ostream& operator<<(ostream& _cout, const Date& d);
friend istream& operator>>(istream& _cin, Date& d);
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
_cin >> d._year;
_cin >> d._month;
_cin >> d._day;
return _cin;
}
int main()
{
Date d;
cin >> d;
cout << d << endl;
return 0;
}
8.2 友元类
class Time
{
friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:
Time(int hour = 0, int minute = 0, int second = 0)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};