- c++与c的关系
- c++是c的增强版,是几乎完全兼容c的
- C++在c的基础上增加了很多新的内容
- 编程思想发生了转变,c更多的是面向过程,c++是面向过程+面向对象,面向对象是通过面向过程来实现的
- 命名空间
作用:为了解决命名冲突的问题
定义:
Namespace 命名空间名
{
变量名;
函数名;
类型名;
....
};
访问方式:
- 命名空间名::变量名
- Using namespace 命名空间名; 变量
其中:”::”是作用域运算符
- 标准输入输出流
操作流就是在操作文件
Cin:标准输入流对象
Cout:标准输出流对象
Cin >> a; //通过键盘输入给a赋值
Cout << a; //将a的值输出到显示屏
- 引用目的:
- 弱化指针,原来需要使用指针的地方现在用引用也可以达到相同的效果,而且用来还更方便
- 减少临时空间的产生
引用:就是变量的别名
定义:数据类型 &引用名=变量名;
Int a = 10; Int &b = a;
- 访问引用就是在访问变量
- 引用不会开辟空间
- 引用必须被初始化
Const修饰的引用:
Const:只读
- 防止实参被修改
- 可以是常量的别名
Const int &a = 100; <===>#define a 100
- 函数重载
功能类似,函数名相同,参数不同(个数和类型),与返回值无关,这样的函数就互为重载
想要成功调用某个函数,是通过函数名来查找的。
编译完成后就知道要调用哪个函数了,函数名就是函数的入口地址。
gcc编译器不会对函数名进行处理。
g++编译器会对函数进行重命名。
函数重载的原理?
g++在编译的时候会对函数名结合参数类型和个数进行重命名,所以在函数调用时是按照重命名之后的函数名进行调用的
- 默认参数
函数在声明时形参可以有默认值,如果函数在调用时传参了就使用传进来的值,否则就使用默认值,注意:默认值必须从依次从右向左
- C++如何调用c库的函数
如何告诉g++不要重命名?
如何判断此时的编译器是gcc还是g++?
笔试题:
如果是g++就打印”g++”,如果是gcc就打印”gcc”?(如何判断此时的编译器是gcc还是g++?)
- g++中定义了__cplusplus这个宏,而gcc没有
#Ifdef __cplusplus
Printf(“g++\n”);
#else
Printf(“gcc\n”);
- Sizeof(字符常量)的结果不一样
在gcc中。sizeof(字符常量)的值为4;g++中为1.
- extern “c” { }
告诉g++,下列函数是外部的C库函数,不需要重命名
- 类和对象
回忆结构体的作用:描述一类事物的属性的自定义的数据类型
学生的属性:学号、姓名、年龄、性别、班级
行为:上课、睡觉、学习、运动。。。。
笔试题1:c的结构体和c++的结构体的区别?
- c的结构体中不能有函数,但c++可以
- c中空结构体内存大小为0,但c++为1
类:描述一类事物的属性和行为的自定义的数据类型
笔试题2:c++中的结构体和类的区别?
结构体的默认的访问限定符是public,而类是private
访问限定符:
Public修饰的成员既可以在类内被访问,也可以在类外被访问
Private和protected修饰的成员只能在类内被访问
对象:用类这种自定义的数据类型定义的变量
类的数据类型(定义数据类型系统不会分配空间)是抽象的,对象是具体的实体(定义变量会分配空间)
所以:用类的数据类型定义变量的过程叫实例化对象
- 封装
c++三大特性:封装、继承、多态
封装:把一类事物的属性和行为用类这种自定义的数据类型包起来,把需要隐藏的隐藏起来,把可以暴露的暴露出来,这就叫封装
你对封装怎么理解的?
封装设计思想:隐藏对象的属性和实现细节,仅对外提供公共访问方式,把该隐藏的隐藏起来,该暴露的暴露出来。
封装的意义:
封装把一个对象的属性私有化,同时提供一些可以被外界访问属性的方法,如果不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。
封装提供了一个有效的途径来保护数据不被意外的破坏。相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fields)定义为私有的(private)在很多方面会更好。私有的数据可以用两种方式来间接的控制。第一种方法,我们使用传统的存、取方法。第二种方法我们用属性(property),使用属性不仅可以控制存取数据的合法性,同时也提供了“读写”、“只读”、“只写”灵活的操作方法。
- This指针
This指针:指向当前类对象,谁正在调用成员函数,谁就是当前类对象
Public:成员在类内和类外都可以被访问
类内:在成员函数中可以直接被访问
类外:必须先有对象,然后通过对象进行访问
不管在类内还是类外,访问成员必须要有对象,通过对象.成员或者对象指针->成员
的方式进行访问
- 构造函数和析构函数
构造函数:
构造函数:给成员变量初始化的
谁调用的:系统自动调用的
什么时候调用的:实例化对象时
也就是:对象有了,这个函数也执行完了
我们没有自定义构造函数时,系统会提供一个无参函数体啥都没写的构造函数,一旦我们自己定义了构造函数,系统就不提供了
构造函数的定义:
- 函数名和类名相同
- 无返回值
- 参数不限制(构造函数可以有多个,可以重载)
默认构造函数:
有且只能有一个。
没有定义时由系统提供。
自定义了无参的构造函数。
自定义了有参的而且所有参数都有默认值的构造函数
析构函数:
当一个对象生命周期结束的时候,系统会自动调用析构函数,如果没有定义,系统提供,如果定义了,系统就不提供了。
定义:
- 函数名是~类名
- 无参
- 无返回值
作用:回收资源,比如在构造函数中在堆区申请空间,在析构函数里去释放
- 深拷贝和浅拷贝
New和delete运算符:
New:在堆区申请空间
Delete:释放堆区的空间
Int *p = (int *)malloc(sizeof(int));
Int *p = new int;
Free(p);
Delete p;
Int *p = (int *)malloc(sizeof(int)*5);
Int *p = new int[5];
Free(p);
Delete []p;
面试题1:New、delete和malloc、free的区别?
- malloc和free是标准c库的函数,new和delete是c++的运算符
- Malloc需要强制类型转换,而new不需要
- Malloc需要计算开辟空间的大小,而new不需要
面试题2:为什么有了malloc和free,还需要有new和delete?
因为malloc和free是c库函数,不会自动调用构造和析构,而new和delete会
拷贝构造函数:参数必须为对象的引用的构造函数,没有定义时系统提供,定义了系统就不提供了
什么时候调用拷贝构造呢?
通过一个已有的对象给新实例化的对象初始化时