c++的概述
c++的编程思想:面向对象、泛型编程。
1.第一个c++程序
本文用的是QT,VS之类的也可
2.c++面向对象的三大特性(重要)
封装:将相同属性的数据和方法封装在一起,加权限区分,用户只能借助公共方法操作 私有数
据。
继承:体现在类和类之间的关系,如果A类继承于B类,那么A类直接拥有B类的数据和方法。
多态:一个接口(函数),多种功能。
::作用域运算符
::解决归属问题(谁是谁的谁)
单独使用,可以优先使用全局变量
命名空间
使用关键字namespace, 控制标名称的作用域。
命名空间的本质:对符号常量、变量、函数、结构、枚举、类和对象等等进行封装
小结:C中说xx本质,考虑内存,C++说本质想三大特性,封装,继承,多态
创建一个命名空间
命名空间 只能定义在全局
命名空间可以嵌套
可以随时将新的成员加入命名空间
前面写了namespace A{xx},后面还可以再写一遍namespace A{}把要写的再加上
命名空间中 函数的声明和实现分开
无名命名空间
无名命名空间 只能在 本源文件使用。
namespace {int n=10}等价于 static int n=10,只能在当前文件使用
命名空间取别名
使用using申明命名空间中的某几个成员 可用
但是using 申明某个成员 容易造成名字冲突
using 申明制定成员函数 遇到函数重载
1 namespace B {
2 void fun01(void)
3 {
4 cout<<"B中的fun01 void"<<endl;
5 }
6 void fun01(int a)
7 {
8 cout<<"B中的fun01 int"<<endl;
9 }
10 void fun01(int a, int b)
11 {
12 cout<<"B中的fun01 int int"<<endl;
13 }
14 }
15 void test02()
16 {
17 //函数重载 命名空间的所有同名函数 都被申明 可用
18 using B::fun01;
19
20 fun01();
21 fun01(10);
22 fun01(10,20);
23 }
using申明整个命名空间 可以直接通过成员名 使用
加作用域解决冲突
类型增强
1、全局变量检测增强
int a;不行
2、c++的函数形参必须有类型
c语言:允许函数形参无类型(可以传任意参数) c++不允许
3、如果函数没有参数,建议写void
4、更严格的类型转换
5、结构体类型增强
6、c++新增bool类型
bool类型拥有两个值, true false,用法 bool a=true if(a)xxx
bool类型占一个字节,可以对其赋值tuue ,false 也可以赋值具体值,0为假其余为真,-1是真
7、三目运算符增强
返回的是引用(可以对其赋值),而c语言中返回的是值
8、左值和右值(c++ c共有)
左值:能放在=左边,(能被赋值的值 就是左值)
右值:只能放在=右边 (不能被赋值的值 就是右值)
c++的const
1、c++和c中的const都是修饰变量为 只读。
2、c语言 严格准许 const修饰的是只读变量。C语言中修饰的变量名,变量名不能改,但是,可以通过指针用*p来改
3、c++的const 会对变量 优化
1、如果以常量 初始化const修饰的变量 编译器会将变量的值 放入符号常量表中,不会立即给变量开辟空间平替宏定义
2、只有当对a 取地址时 编译器才会给a开辟空间(只读变量)
但是此时,a=10,用指针指向,令*p等于100会出现两个结果
3、如果以变量 初始化const修饰的只读变量,没有符号常量表,立即开辟空间
int b=10; const int a=b;现在a跟*p结果就一样了
4、如果以const修饰的是自定义类型的变量 也不会有符号常量表,立即开辟空间
5、c++中尽量使用const代替define
1、 const有类型,可进行编译器类型安全检查。#define无类型,不可进行类型检查
2、const有作用域,而#define不重视作用域,宏不能作为命名空间、结构体、类的
成员,而const可以(宏定义不符合C++封装特性!不能作为命名空间、结构体、类的成员)
引用
1、引用的定义
引用的本质:就是给变量名取个别名。
引用定义的步骤:
1 &别名
2 给哪个变量取别名 就定义该变量
3 从上往下整体替换
案例1:给普通变量取别名
案例2:给数组取别名
1 void test02()
2 {
3 int arr[5]={10,20,30,40,50};
4 int n = sizeof(arr)/sizeof(arr[0]);
5
6 int (&myArr)[5] = arr;
7 int i=0;
8 for(i=0;i<n;i++)
9 {
10 cout<<myArr[i]<<" ";
11 }
12 cout<<endl;
13 }
案例3:给指针变量取别名
案例4:给函数取别名
2、引用作为函数的参数
函数内部可以 通过 引用 操作外部变量。(节约空间)
3、引用作为函数的返回值类型(链式操作)
注意不要返回局部变量的引用,局部变量会被释放
链式操作
分析 ,ob1.printStu(ob1,100)调用函数返回值还是结构体(去了别名叫ob)返回值.printStu(xx)
4、常引用
const int &a = 10;//a就是10的别名
不能通过常引用 修改 内容。
常引用 作为函数的参数:防止函数内部修改外部的值。
5、引用的本质:常量指针
1 int a=10;
2 int &b = a;//b为a的别名 int * const b = &a;
3 b = 100;//a的值为100 *b = 100;
内联函数
内联函数:在编译阶段 将内联函数中的函数体 替换函数调用处。避免函数调用时的开销。
内联函数 必须在定义的时候 使用关键字inline修饰, 不能在声明的时候使用inline
1、宏函数和内联函数的区别(重要)
宏函数和内联函数 都会在适当的位置 进行展开 避免函数调用开销。
宏函数的参数没有类型,不能保证参数的完整性。
内联函数的参数有类型 能保证参数的完整性。
宏函数在预处理阶段展开
内联函数在编译阶段展开
宏函数没有作用域的限制,不能作为命名空间、结构体、类的成员
内联函数有作用域的限制,能作为命名空间、结构体、类的成员
2、内联函数的注意事项
在内联函数定义的时候加inline修饰
类中的成员函数 默认都是内联函数(不加inline 也是内联函数)
有时候 就算加上inline也不一定是内联函数(内联函数条件)
不能存在任何形式的循环语句
不能存在过多的条件判断语句
函数体不能过于庞大
不能对函数取地址
有时候不加inline修饰 也有可能是内联函数。
内不内联 由编译器决定。
函数重载
函数重载 是c++的多态的特性(静态多态)。
函数重载:用同一个函数名 代表不同的函数功能。
函数重载的条件
同一作用域,函数的参数类型、个数、顺序不同 都可以重载。(返回值类型不能作为重载的条
件)
c++中 不能直接将函数名作为函数的入口地址(为啥呢?)
函数名和参数 共同决定函数的入口地址
函数的缺省参数
在函数声明处 给函数参数一个默认的值,如果函数调用处,用户没用传实参,编译器就可以使用
这个默认的值。
如果函数的某个参数设置为默认参数, 那么这个参数的右边的所有参数 都必须是默认参数。
占位参数
没有形参名的形参叫占位参数 int or int=0(缺省参数做占位参数)
默认参数和函数重载同时出现 一定要注意二义性
第一个参数不知道该传给谁