一、设计类 抽象类
class 类名
{
public 公共权限
设置 成员属性
设置 成员函数
}
使用类 创建对象 实例化对象
类名 对象名
通过对象 来设置属性 调用成员函数
类和对象的关系?类是对对象的抽象,对象是对类的实例。
二.内联函数
给编译器一个建议,加上关键字,编译器不一定按照内联处理,不加关键字,也许编译器还会偷摸的加上inline,成员函数默认加上关键字
三、函数默认参数
参数可以有默认值,如果有一个位置有了默认值,那么从这个位置开始,从左往右都必须有默认值,函数声明和实现只能有一个默认值
四、函数占位参数
void func(int) 占位参数调用时必须提供这个参数
占位参数也可以有默认值
五、函数重载
C++ 中函数名称可以重复,必须再同一个作用域下,函数名称相同,函数的参数个数不同,或者类型不同或者顺序不同。
六、extren浅析
解决了C++ 中调用c语言代码
#ifdef __cplusplus
extern "C"{
#endif
.........
#ifdef __cplusplus
}
#endif
七、封装
c++中的封装严格类型转换检测,让属性和行为绑定到一起
- 属性和行为作为一个整体来表示生活中的事物
- 控制权限 public 公有权限 private 私有权限 protected 保护权限
八、构造函数和析构函数
对象的初始化和清理,系统默认调用析构和构造函数,空实现
class Person
{
public: //必须写在public下
//构造函数写法
// 与类名相同,没有返回值,不写void ,可以发生重载(可以有参数)
//构造函数有编译器自动调用,而不是手动,而且只会调用一次
Person()
{
cout << "构造函数" << endl;
}
Person(int a)
{
cout << "构造函数" << endl;
}
//析构函数写法
//与类名相同, 类名前面加一个符号 “~”,也没有返回值,不写void,不可以有参数。
//自动调用,而且只会调用一次
~Person()
{
cout << "析构函数" << endl;
}
};
九、构造函数的分类及调用
- 按照参数分类
- 无参构造函数(默认)
- 有参构造函数、
- 类型分类
- 拷贝构造函数
- 普通构造函数
class Person
{
public:
Person()
{
cout << "构造函数" << endl;
}
Person(int a)
{
cout << "构造函数" << endl;
}
// 拷贝构造函数
Person(const Person & p) //不加&为值传递,开辟一个新的数据,调用拷贝构造,进入死循环。
{
cout << "拷贝构造函数" << endl;
}
};
//括号法调用
Person p1(1); //有参
Person p2(p1); //拷贝
Person p3; //默认构造函数不要加(), Person p3();编译器会认为这行是函数的声明;
//显示法调用
Person p4 = Person(100);
Person p5 = Person(p4);
Person(100) //叫匿名对象,如果编译器发现对象是匿名的,那么在这行代码结束时就释放
//不能直接用拷贝构造函数,初始化匿名对象
Person(p5); //编译器会认为写成了Person p5;对象的生命
-
隐式类型转换
-
拷贝构造函数的调用时机
1、用已经创建好的对象来初始化新的对象
2、以值传递的方式给函数参数传值
3、以值方式返回局部对象
4、release下有优化 -
构造函数调用规则
1.系统默认给一个类提供3个函数:默认构造,拷贝构造,析构函数
2、当我们提供一个有参构造函数,那么系统不会在我们提供一个默认构造函数了,但是系统还会提供一个默认拷贝构造函数
3、当我们提供了拷贝构造,系统就不会提供其他构造函数
十、深拷贝和浅拷贝
- 系统默认提供的拷贝构造会进行简单的值拷贝
- 如果属性里有指向堆区空间的数据,那么简单的浅拷贝会导致重复释放内存的异常
- 解决上诉问题,需要我们自己提供拷贝构造函数,进行深拷贝。
十一、初始化列表
- 构造函数后面 + :属性(参数),属性(参数)
class Person{
Person() : m_a(10),m_b(10),m_c(10)
{}
Person(int a, int b, int c) : m_a(a),m_b(b),m_c(c)
{}
int m_a;
int m_b;
int m_c;
}
十二、类对象作为成员
- 构造顺序先将类对象一一构造,然后构造自己
- 析构顺序先析构自己,在析构类对象,和构造顺序相反
十三、explicit关键字
- 防止隐式类型转换 Mystring str3 = 10;
十四、new运算符
//Person p1; //栈区开辟
Person* p2 = new Person; //堆区开辟 所有new出来的对象都会返回该类型的指针
delete p2;//配合new用
- 如果在new表达式中使用[],必须在相应的delete表达式中也使用[],如果在new表达式中不适用[],一定不要在相应的delete表达式中使用[].