C++个人总结
序
1.内存分区模型–分为代码区、全局区、栈、堆。
程序运行前:
代码区—共享、只读,操作系统控制。
全局区—全局变量、静态变量(static)、常量(字符串常量、const修饰的全局变量),全局区的数据在程序结束后OS释放。
程序运行后;
栈区:编译器自动释放–所以不要返回局部变量的地址–若返回,第一次可以打印正确的数据,第二次已经释放,数据不再保留,是任意值。
堆区:程序员分配释放。关键字:new,delete,利用指针(指针本质是局部变量,放在栈区,但保存的数据在堆区,通过栈区地址索引到堆区数据)。
new语法:new 数据类型
1.利用new创建变量:
int *func(){
int *p = new int(10);
return p;
}
int main(){
int *p=func();
return 0;
}
2.在堆区利用new开辟数组:
void demo(){
int *arr=new int[10];
for(int i=0;i<10;i++){
arr[i]=i+10;
}
for(int i=0;i<10;i++){
cout<<arr[i]<<endl;
}
delete[] arr;//释放堆区数组,要加[]
}
引用
作用:给变量起别名(两个变量指向同一个地址,引用修改,原变量也修改)。
语法:数据类型 &别名=原名;
本质:指针常量。
注:
1.引用必须初始化;
2.一旦初始化,不能发生改变:可以赋值,但不能更改内存地址;
3.引用作为形参(传参),可以改变实参的值;
4.如果函数的返回值是引用,函数调用可以作为左值。
int& test(){
static int a=10;
return a;
}
void func(int& p){//发现是引用,自动转换为:int* const p=&a;
p=20;//*p=20;
}
int main(){
int& ref = test();
cout<<ref<<endl;
test()=100;
cout<<"test()函数调用作为左值"<<ref<<end;
func(ref);
cout<<"func:"<<func<<end;
return 0;
}
5.常量引用
作用:修饰形参,防止误操作导致修改实参。
函数重载
作用:同一个函数名可以有多个不同定义,提高复用性,但只有返回值不同会报错。
条件:
1.同一个作用域;
2.函数名相同;
3.函数参数类型、个数、顺序不同即可。
注:
1.若参数中某一个有了默认参数,从这个位置开始,从左往右都必须有默认值,否则报错;
2.函数的申明有默认参数,函数定义和调用不能有默认参数,即申明和定义只能有一个默认;
(占位参数:只有类型,没有变量)
3.函数重载遇到默认参数,会出现二义性,所以函数重载不要默认参数。
类和对象
面向对象的三大特性:封装、继承、多态。
对象:属性+行为。
封装:
1.将属性和行为放在一个类中;
语法:class 类名{ 访问权限:属性/行为。};
2.控制访问权限:对属性/行为的访问权限可以分开控制。
public:公共权限,类内+类外访问;
protected:保护权限,类内+继承类
private:私有权限,类内
注:struct和class的区别—默认权限不同。
struct默认权限是公共,class默认权限是私有。
构造和析构
对对象的初始化和销毁之前必须的清理数据的设置。
构造函数:初始化 ,没有初始状态,使用后果未知。
析构函数:清理,没有清理会造成安全问题。
编译器会默认提供构造和析构函数,但是是空实现。
默认情况下,c++编译器至少给一个类添加3个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝构造函数,对属性进行值拷贝//若用户自己定义,函数调用顺序会变化
//自行定义有参,则不提供无参
//自行定义拷贝,则不提供无参&有参
//如有需要自己定义
构造函数:
语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
分类:
按参数:有参构造和无参构造;
按类型:普通构造和拷贝构造。
调用:
括号法、显示法、隐式转换法。
//假设已构建Person类
void test(){
//1、括号法
Person p1;//默认构造,不加(),否则编译器会认为是函数申明。
Person p2(10);//有参构造
Person p3(p2);//拷贝构造
//Person (p3);//错误
//不利用拷贝构造函数初始化对象,否则编译会认为是Person (p3)==Person p3;
//2.显示法
Person p1;
Person p2=Person(10);
Person p3=Person(p2);
//Person(10);//匿名对象:当前执行结束,系统会立即回收该对象。
}
调用时机:已经存在一个对象、值传递的方式给函数传参、以值方式返回局部对象。
深浅拷贝: