目录
-
- 在main执行之前和之后执行的代码可能是什么?
- 指针和引用的区别
- 在传递函数参数时,什么时候该使用指针,什么时候该使用引用呢?
- 你觉得堆快一点还是栈快一点?
- 区别以下指针类型?
- 被free回收的内存是立即返还给操作系统吗?
- 宏定义和函数有何区别?
- 变量声明和定义区别?
- 定义和声明的区别
- a和&a有什么区别?
- 数组名和指针(这里为指向数组首元素的指针)区别?
- C++中const和static的作用
- C++的顶层const和底层const
- final和override关键字
- 拷贝初始化和直接初始化
- 初始化和赋值的区别
- C和C++的类型安全
- public,protected和private访问和继承权限/public/protected/private的区别?
- 如何用代码判断大小端存储?
- volatile、mutable和explicit关键字的用法
- 什么情况下会调用拷贝构造函数
- C++中有几种类型的new
- C++的异常处理的方法
- 形参与实参的区别?
- 值传递、指针传递、引用传递的区别和效率
- 静态变量什么时候初始化
- delete和delete[]区别?
- delete p、delete [] p、allocator都有什么作用?
- new和delete的实现原理,delete是如何知道释放内存的大小
- malloc申请的存储空间能用delete释放吗
- malloc与free的实现原理?
- malloc,calloc,realloc的区别
- 类成员初始化方式?
- 成员初始化列表的概念
- 有哪些情况必须用到成员列表初始化?作用是什么?
- C++中新增了string,它与C语言中的 char *有什么区别吗?它是如何实现的?
- 对象复用的了解,零拷贝的了解
- 介绍面向对象的三大特性
- 函数调用过程栈的变化,返回值和参数变量哪个先入栈?
- C++中将临时变量作为返回值时的处理过程
- 写C++代码时有一类错误是 coredump ,很常见,你遇到过吗?怎么调试这个错误?
- 说说移动构造函数
- 引用是否能实现动态绑定,为什么可以实现?
- 指针加减计算要注意什么?
- 怎样判断两个浮点数是否相等?
- 如果想将某个类用作基类,为什么该类必须定义而非声明?
- 继承机制中对象之间如何转换?指针和引用之间如何转换?
- 知道C++中的组合吗?它与继承相比有什么优缺点吗?
- 结构体变量比较是否相等
- 你知道printf函数的实现原理是什么吗?
- 为什么模板类一般都是放在一个h文件中
- cout和printf有什么区别?
- 你知道重载运算符吗?
- 当程序中有函数重载时,函数的匹配原则和顺序是什么?
- static函数与普通函数有什么区别?
- 说一下你理解的 ifdef endif代表着什么?
- 隐式转换,如何消除隐式转换?
- 如何在不使用额外空间的情况下,交换两个数?你有几种方法
- 你知道strcpy和memcpy的区别是什么吗?
在main执行之前和之后执行的代码可能是什么?
指针和引用的区别
最本质的区别:int a = 10; int &b = a; 在编译器看来, 等价于 int * const b = &a;对b的任何操作都会自动解引用成a,也因此会看到b和a的地址相同,内存大小相同,好像b就是a,但其实不是,这是编译器造成的假象。
表层的区别:
指针可以有多级,引用只有一级
指针声明和定义可以分开,引用在定义时必须初始化
指针在初始化后可以改变指向,而引用在初始化之后不可再改变
当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,两者指向的地址相同,但不是同一个变量,在函数中改变这个变量的指向不影响实参,而引用却可以。
可以有const指针,但是没有const引用;
如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄露。
在传递函数参数时,什么时候该使用指针,什么时候该使用引用呢?
需要返回函数内局部变量的内存的时候用指针。使用指针传参需要开辟内存,用完要记得释放指针,不然会内存泄漏。而返回局部变量的引用是没有意义的。
对栈空间大小比较敏感(比如递归)的时候使用引用。使用引用传递不需要创建临时变量,开销要更小
类对象作为参数传递的时候使用引用,这是C++类对象传递的标准方式
你觉得堆快一点还是栈快一点?
毫无疑问是栈快一点。
因为操作系统会在底层对栈提供支持,会分配专门的寄存器存放栈的地址,栈的入栈出栈操作也十分简单,并且有专门的指令执行,所以栈的效率比较高也比较快。
而堆的操作是由C/C++函数库提供的,在分配堆内存的时候需要一定的算法寻找合适大小的内存。并且获取堆的内容需要两次访问,第一次访问指针,第二次根据指针保存的地址访问内存,因此堆比较慢。
区别以下指针类型?
被free回收的内存是立即返还给操作系统吗?
不是的,被free回收的内存会首先被ptmalloc使用双链表保存起来,当用户下一次申请内存的时候,会尝试从这些内存中寻找合适的返回。这样就避免了频繁的系统调用,占用过多的系统资源。同时ptmalloc也会尝试对小块内存进行合并,避免过多的内存碎片。
宏定义和函数有何区别?
变量声明和定义区别?
声明仅仅是把变量的声明的位置及类型提供给编译器,并不分配内存空间;定义要在定义的地方为其分配存储空间。
相同变量可以在多处声明(外部变量extern),但只能在一处定义。
定义和声明的区别
a和&a有什么区别?
数组名和指针(这里为指向数组首元素的指针)区别?
二者均可通过增减偏移量来访问数组中的元素。
数组名不是真正意义上的指针,可以理解为常指针,所以数组名没有自增、自减等操作。
当数组名当做形参传递给调用函数后,就失去了原有特性,退化成一般指针,多了自增、自减操作,但sizeof运算符不能再得到原数组的大小了。
C++中const和static的作用
C++的顶层const和底层const
final和override关键字
override指定了子类的这个虚函数是重写的父类的,如果你名字不小心打错了的话,编译器是不会编译通过的
当不希望某个类被继承,或不希望某个虚函数被重写,可以在类名和虚函数后添加final关键字,添加final关键字后被继承或重写,编译器会报错。
拷贝初始化和直接初始化
当用于类类型对象时,初始化的拷贝形式和直接形式有所不同:
直接初始化直接调用与实参匹配的构造函数,
拷贝初始化总是调用拷贝构造函数。拷贝初始化首先使用指定构造函数创建一个临时对象,然后用拷贝构造函数将那个临时对象拷贝到正在创建的对象。
初始化和赋值的区别
赋值操作是在两个已经存在的对象间进行的,而初始化是要创建一个新的对象,并且其初值来源于另一个已存在的对象。编译器会区别这两种情况,赋值的时候调用重载的赋值运算符,初始化的时候调用拷贝构造函数。如果类中没有拷贝构造函数,则编译器会提供一个默认的。这个默认的拷贝构造函数只是简单地复制类中的每个成员。
C和C++的类型安全
类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域。
C只在局部上下文中表现出类型安全,比如试图从一种结构体的指针转换成另一种结构体的指针时,编译器将会报告错误,除非使用显式类型转换。
相比于C语言,C++提供了一些新的机制保障类型安全:
操作符new返回的指针类型严格与对象匹配,而不是void*
C中很多以void*为参数的函数可以改写为C++模板函数,而模板是支持类型检查的;
引入const关键字代替#define constants,它是有类型、有作用域的,而#define constants只是简单的文本替换
一些#define宏可被改写为inline函数,结合函数的重载,可在类型安全的前提下支持多种类型,当然改写为模板也能保证类型安全
C++提供了dynamic_cast关键字,使得转换过程更加安全