C++笔记
创建项目,创建文件,编写代码,运行程序
Helloworld
变量的使用
1.方便管理内存空间
2.变量创建的语法
常量
记录程序中不可以更改的数据
#define 常量名 常量 //宏常量
const 数据类型 常量名 =常量 //const修饰的变量
常量不能修改
内存四区
代码区
存放函数体的二进制代码,由操作系统进行管理
全局区
存放全局变量和静态变量以及常量
const修饰的
函数外定义的全局变量
static定义的
栈区
由编译器自动分配释放,存放函数的参数值,局部变量
形参在栈区
注意事项:
不要返回栈区的地址
存放在了栈区,函数执行完了之后释放
第一次解引用时可以取到数据,因为编译器做了保留,第二次不可以
堆区
由程序员分配和释放,若程序员不释放,程序结束由操作系统回收
利用new可以在堆区开辟数据
分区是为了灵活编程,生存周期不一样
程序执行前有代码区和全局区
代码区是共享和可读的
new
int *p=new int(10);
int* func(){
int *p=new int(10);//指针本质上也是局部变量,放在栈上,指针对应的数据在堆区
return p;
}
int main(){
//在堆区开辟数据
int *p=func();
}
delete p;
创建数组
int *arr=new int[10];
for(int =0;i<10;i++){
arr[i]=i+100;
}
delete[] arr;
C++中的引用
1.
给变量起一个别名
int a=10;
数据类型 &别名=原名;
注意事项
引用必须初始化,不能int &b;
初始化之后就不能改变了,不能变更成c的别名
引用做函数参数
有值传递和地址传递
值传递不可以修饰实参,地址传递可以
地址传递
传地址,用指针接收
引用传递
引用做函数的返回值
不要返回局部变量的引用
函数的调用可以作为左值
第一次正确,编译器做了保留,第二次不行
函数的返回值是引用,这个函数调用可以作为左值
引用的本质
本质在C++内部的实现是一个指针常量
int& ref=a;
内部转换为int *const ref=&a;
ref=20;
内部会发现是引用,自动为我们转换为*ref=20;
本质是指针常量
所有的指针的操作都是编译器帮我们做了
常量引用
堆区和栈区都是可以直接引用的,引用必须引用一块合法的空间
int &ref=10;是错误的
const int &ref=10;是正确的
const int &ref=10;编译器做的操作是int temp=10;const int &ref=temp;
加入const之后是只读不可修改
使用场景
int a=100;
void showValue(const int &Val){
//Val会报错
cout <<Val<<endl;
}
函数高级
函数的默认参数
返回值类型 函数(数据类型 变量名=默认值)
注意
1.某个位置有了默认参数,这个位置从左向右都必须有默认值
2.没有传入就是默认值,传入就是传入的数据
3.函数的声明有默认的参数,函数的实现就不能有默认的参数了
声明和实现只能有一个有默认参数
函数占位参数
函数重载
满足条件:
1.同一个作用域下
2.函数名称相同
3.函数的参数类型不同或者个数不同或者顺序不同
可以让函数相同。提高函数复用性
函数的返回值类型不能重载
注意事项:
1.引用作为重载的条件
func(10);会调用:
void func(const int &a);
func(a);会调用:
void func(int &a);
2.函数重载碰到默认参数
类和对象
三大特征:封装,继承和多态
相同性质的对象抽象为类
封装
意义:
将属性和行为作为一个整体,表现生活中的事物
将属性和行为加以权限控制
封装的访问权限:
公共权限 public 类内可以访问,类外也可以
保护权限 protected 类内可以访问,类外不可以访问,子类可以访问
私有权限 private 类内可以访问,类外不可以访问,子类不能访问
struct和class区别
class默认的权限是私有
struct默认是公共
成员属性私有化
将所有成员设置为私有,可以自己控制读写权限、
对于写权限,我们可以检测数据的有效性
对象的初始化和清理
对象的常识化和清理是两个非常重要的安全问题
一个对象或者变量没有初始状态,对其使用的后果是未知的
同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
C++利用了构造和析构函数来解决上述问题,这两个函数将被编译器自动调用,完成对象的初始化和清理工作
我们不提供构造和析构,编译器可以提供的构造和析构函数是空实现
构造函数
主要作用于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用
1.没有返回值也不写void
2.函数名称与类名相同
3.构造函数可以有参数,因此可以发生
4.程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数
主要作用于对象销毁前系统自动调用,执行一些清理工作
1.没有返回值也不写void
2.函数名称与类名相同,在名称前加上符号~
3.析构函数不可以有参数,因此不可以发生重载
4.程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
test01中的Person是栈上面的数据
写在main函数中不会调用析构函数
函数的分类以及调用
按参数分为:有参构造和无参构造
按类型分为:普通构造和拷贝构造
三种调用方式:
括号法
显示法
隐式转换法
调用默认构造函数时候不要加();
void func();和Person p1();形式一样,会被编译器理解为函数声明
拷贝构造函数调用时机
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式来给函数传值
以值方式返回局部对象
构造函数的调用规则
默认情况下,C++会为一个类添加3个函数:
1.默认构造函数
2.默认析构函数
3.默认拷贝构造函数
如果用户定义了有参构造函数,C++不会提供无参构造函数,但是会提供默认拷贝构造
如果用户定义拷贝构造函数,C++不会提供其他构造函数
深拷贝与浅拷贝
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝工作
析构代码,将堆区开辟的数据做释放操作
释放是先进后出,后面的先释放
浅拷贝的问题:堆区的问题重复释放
m_Height是一个指针
编译器默认的拷贝
m_Height=p.m_Height
深拷贝操作应该是
有属性是堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
初始化列表
类对象作为类成员
C++类中的成员可以是另一个类的对象,称该成员为对象成员
静态成员
静态成员变量
所有对象共享一份数据
在编译阶段分配内存
类内声明,类外初始化
1.通过对象进行访问
2.通过类名进行访问
静态成员变量也是有访问权限的
静态成员函数
静态成员函数可以访问静态成员变量
静态成员函数不可以访问非静态成员变量
C++对象模型和this指针
空对象占用的内存空间是1
C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
每个空对象也有一个独一无二的的内存地址
静态的成员变量不属于类的对象上面
非静态成员函数不属于类的对象上
只有非静态的成员变量属于类的对象上
this指针的用途
C++的成员变量和成员函数是分开储存的
this指针指向被调用的成员函数所属的对象
this指针是隐含与每一个非静态成员函数的一种指针
this指针不需要定义,直接使用即可
当形参和成员变量同名时,可用this指针来区分
在类的非静态成员函数中返回对象本身,可使用return *this
this->age=age;
return *this;
Person&
空指针访问成员函数
C++空指针也是可以调用成员函数,但是也要注意有没有用到this指针
如果用到this指针。需要加以判断代码的健壮性
const修饰成员函数
常函数
成员函数加const后我们称这个函数为常函数
常函数内不可以修改成员属性
成员属性声明时加关键字mutable,在常函数中依然可以修改
常对象
声明对象前加const称该对象为常对象
常对象只能调用常函数
this指针的本质是指针常量,指针的指向是不能修改的
友员
关键字 friend
友元的三种实现
全局函数做友元
类做友元
成员函数做友元
- 点赞
- 收藏
- 关注作者
评论(0)