c++基础知识记录

1、const放在函数前分为两种情况,一返回指针,此时该对象只能立即复制给新建的const char,而不能是char,意在强调值被保存在常指针中,二返回一个char也就是值,此时const无意义,应当避免。 const放在函数后表明,该成员函数不得修改本对象任何成员,如果有对成员赋值语句则报错,相当于一种接口规范。

在const左边,不能改变指针指向,在const右边,不能修改所指的值。const默认修饰左边的内容,如果左边没有东西则修饰其右边的内容

2、c++类默认修饰符就是private。
3、当涉及两种类型时,较小的类型就会被转换为较大的类型,表达式低的类型就会被转换为表达式高的类型,各类表达能力从低到高排列;/和%和优先级相同*
int ----->unsigned----》long ----->unsigned long----->float----->double-------->long double。
4、rdquo 双引号;c++单引号是字符型, 双引号是字符串型
5、i++ :先引用后增加,先在i所在的表达式中使用i的当前值,后让i加1
++i :先增加后引用,让i先加1,然后在i所在的表达式中使用i的新值
6、结构体知识:*
定义结构体时只是声明了一种类型,并没有实例化因而也就没有分配内存空间。结构体中,先声明的是低地址,后声明的是高地址。
结构体所占的内存大小:
a.整体所占的内存大小应该是结构中成员类型最大的整数倍,此处最大的类型是int_64t,占8个字节。。即最后所占字节的总数应该是8的倍数,不足的补足;
b.数据对齐原则-内存按结构体成员的先后顺序排列,当排到该成员变量时,其前面所有成员已经占用的空间大小必须是该成员类型大小的整数倍,如果不够,则前面的成员占用的空间要补齐,使之成为当前成员类型的整数倍。
8、只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。 除了类属关系运算符”.“、成员指针运算符”.“、作用域运算符”::“、sizeof运算符和三目运算符”?:“以外,C++中的所有运算符都可以重载。

9、=是赋值运算符啊,优先级仅高于逗号运算符。*
10、list的迭代器不支持算术运算;迭代器不支持用&操作符来初始化。
11、\0 和 0的ASCII码值相同,都是0x00。
12、\为转义字符。
13、
使用内联函数的时候要注意:
(1)递归函数不能定义为内联函数
(2)内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
(3)内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
(4)对内联函数不能进行异常的接口声明。
(5)类内定义的函数都是内联函数,不管是否有inline修饰符。
(6)函数声明在类内,但定义在类外的看是否有inline修饰符,如果有就是内联函数,否则不是。
14、宏会不一定会带来性能损失,如果使用不当,就会降低性能。宏与类型无关,但是c++中函数必须指定返回类型,故宏可以做函数不能做的事。
15、数组指针:定义 int (p)[n]; 本质上是指针,p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。*
指针数组:定义 int p[n]; 本质上是数组,有n个指针类型的数组元素。字符数组赋值,用采用strcpy()函数。*
16、• 一个 shared_ptr 对象实体可被多个线程同时读取;
• 两个 shared_ptr 对象实体可以被两个线程同时写入,“析构”算写操作;
• 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁
17、C++语言将struct当成类来处理的,struct 能包含成员函数 能继承 能实现多态 和class的区别在于默认访问控制类型不同 struct是public的,class是private。C语言struct不是类,不可以有函数,也不能使用类的特征例如public等关键字。
18、左移运算符(<<)优先级大于 或(|)运算符。
19、.capacity()是扩容,vector的内存扩容,是发生在当前容量无法容纳新元素时进行的,并且,每次扩容后的大小是原容量的2倍。————————————————————vector的初始容量为0,插入1个元素后,容量为1,插入2个元素后,容量为2,而当插入第3个元素时,容量变为4,直到4个容量全部用完后,再次插入新元素时,容量将扩充到8。vs2015扩容为1.5倍。
20、空类的大小是1,在C++中空类会占用1个字节,这是为了让对象的实例能够相互区别。具体来说,空类同样可以被实例化,并且每个实例在内存中都有独一无二的地址,因此,编译器会给空类隐含加上一个字节,这样空类实例化后就会拥有独一无二的内存地址。当该空白类作为基类时,该类的大小就优化为零了,子类的大小就是子类本身的大小。这就是所谓的空白基类最优化。
对于虚函数,在64位机器上为8,在32位机器上为4。
静态成员存放在静态存储区,不占用类的大小,普通函数也不占用类的大小。
类中的非静态函数默认是有this指针的,表明为该类的对象所有。
21、数组作为函数的参数是会退化为函数指针的。
23、如果使用指向对象的引用或指针来调用虚方法,程序将使用为对象类型定义的方法,而不是使用为引用或指针类型定义的方法。这称为动态联编或晚期联编。
24、友元关系不能被继承,基类的友元对派生类没有特殊的访问权限。
25、栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
26、List,Set等集合对象都继承自Collection接口;Map是一个顶层结果,不继承自Collection接口。
27、虚函数:在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数。**
用法格式为:
virtual 函数返回类型 函数名(参数表) {函数体};
作用是实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。
方法重载是同一个类中相同的方法名,而虚函数是基类的定义和派生类重写来实现。
基类有纯虚函数,而其派生类中没有重写改函数,则其依然为纯虚函数,这个派生类依然是个抽象类。
Java函数(方法)有静态方法、成员方法、final修饰的不可变方法……,不仅仅是基类/派生类的重写方法。。
虚函数的作用就是实现多态性。
虚函数在基类中定义,子类中可以被重写,也可以忽略。纯虚函数必须在子类中实现。
虚函数就是定义在基类的普通函数,既可被直接继承,也可被重写。
析构函数为类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类的析构函数要定义为虚函数。
构造函数中调用虚函数,虚函数表现为该类中虚函数的行为,即在父类构造函数中调用虚函数,虚函数的表现就是父类定义的函数的表现。

在都不是虚函数的情况下,delete派生类对象(非基类指针指向)调用派生类的析构函数、然后调用基类的析构函数。delete派生类对象(基类指针指向)只调用基类的析构函数。虚函数情况下delete派生类对象(非基类指针指向)和delete派生类对象(基类指针指向)都会调用派生类的析构函数、然后调用基类的析构函数。
28、编译时创建的的虚函数表,编译器对每个包含虚函数的类创建一个虚函数表(vtable),在vtable中,放置这个类的虚函数地址。
29、static不在栈区存储,所以不是局部生存期。
30、strlen()、sizeof()是针对字符的,而length()、size()是针对字符串的。
31、c语言运算符优先级:**

  1. () [] . ->
  2. ! ~ ++ -- + - & (type) sizeof--非常爱考 *
  3. / %*
    • -
  4. << 注:>>是位移符号。可以理解为每次除以2.

  5. >=     <     <= 
  6. == !=
  7. &
  8. ^
  9. |
  10. &&
  11. ||
  12. ? :
  13. = = /= %= += -= >>= <<= &= ^= |= *

32、静态绑定是指指针指向声明时的对象,动态绑定是指指针指向引用的对象。动态联编 只能通过指针或引用标识对象来操作虚函数 ;如果采用一般的标识对象来操作虚函数,将采用静态联编的方式调用虚函数.

33、&lt 表示小于 ; &gt 表示大于
34、指针的++或--或算术运算都是指针的步长乘以一个移动的步长再除以一个指针的步长,也就是++移动的地址是步长,指向下一个元素。
35、 java/C/C++中volatile关键字可以保证并发编程中的:
保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)
禁止进行指令重排序。(实现有序性)
volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。
36、如果子类的函数与父类的名称相同,但是参数不同,父类函数被隐藏(重定义);
如果子类函数与父类函数的名称相同&&参数也相同&&但是父类函数没有virtual,父类函数被隐藏;
如果子类函数与父类函数的名称相同&&参数也相同&&但是父类函数有virtual,父类函数被覆盖(重写)。
37、类模板生成非抽象类,也可以生成生成抽象类;
类是对象的抽象,类模板可以说是类的抽象,用以生成一个类;
类模板与普通类一样,可以使用任意数据类型;
类模板中的成员函数可以有返回值。
38、+ - /都是双目运算符,需要两个参数。如果是成员函数,自身就是其中一个参数,只需再传入另一个参数即可。A?B:C这是一个双目运算符,若语句A为真则执行语句B,否则执行语句C。*
39、STL库中,map和multimap底层都是红黑树实现的,两者的不同在于multimap允许重复的可以,而map中不行。
红黑树的查找复杂度为O(log(n))。
unodered_map/_set底层是哈希表实现的,查找复杂度为O(1)。
40、malloc/free和new/delete的本质区别:
(1).malloc/free 是C/C++语言的标准库函数,new/delete是C++的运算符
(2).new 能自动分配空间大小
(3).对于用户自定义的对象而言,用malloc/free无法满足动态管理对象的要求
对象在创建的时候会自动调用构造函数,对象在消亡之前自动执行析构函数
由于malloc/free是库函数而不是运算符,不在编译器的控制范围,不能把构
造函数和析构函数的任务强加于malloc/free 。一次C++需要一个能够对对象完
成动态分配内存和初始化工作的运算符new,以及一个释放内存的运算符
delete。简单来说就是new/delete能完成跟家详细的对内存的操作,而malloc/
free不能
41、用户自定义标识符由字母、数字和下划线组成,只能由字母或下划线开头。
42、拷贝构造函数从来不显示调用,而是由编译器隐式地调用:
(1)用类的一个对象去初始化另一个对象时;
(2)当函数的形参是类的对象时(也就是值传递时),如果是引用传递则不会调用;
(3)当函数的返回值是类的对象或引用时。

43、(1)try:可能发生异常的语句
(2)catch:捕获,并处理异常(printStackTrace()用来跟踪异常事件发生时执行堆栈的内容)
(3)throw:方法内部抛异常
(4)throws:声明方法异常
(5)finaly:代码中无论是否有异常都会执行,清除资源

44、整数取余用% 浮点数取余用fmod(x,y)

45、(1)%:表示格式说明的起始符号,也是转义符号,有一题 printf(“%%%%”)输出几个?答案输出%% 两个;
(2)-:有-表示左对齐输出,如省略表示右对齐输出;
(3)0:有0表示指定空位填0,如省略表示指定空位不填;
(4)m.n m指域宽,即对应的输出项在输出设备上所占的字符数;
(5)n指精度。用于说明输出的实型数的小数位数。没有指定n时,隐含的精度为n=6位;
(6)e格式表示以指数形式输出实数。

46、转换构造函数只有一个形参,如
Complex(double r) {real=r;imag=0;}
其作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部,虚部为0。用户可以根据需要定义转换构造函数,在函数体中告诉编译系统怎样去进行转换。

在类体中,可以有转换构造函数,也可以没有转换构造函数,视需要而定。几种构造函数可以同时出现在同一个类中,它们是构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型选择形参与之匹配的构造函数。转换构造函数只能有一个参数。如果有多个参数,就不是转换构造函数。

47、抽象类有一下几个特点:
(1)抽象类只能用作其他类的基类,不能建立抽象类对象。
(2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。
(3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。

48、函数声明时,形参可以没有参数名(形参),函数定义时,一定要有参数名(形参),函数调用时,一定要有参数名(实参)。

49、引用是除指针外另一个可以产生多态效果的手段。

50、重载overload:在同一个类中,函数名相同,参数列表不同,编译器会根据这些函数的不同参数列表,将同名的函数名称做修饰,从而生成一些不同名称的预处理函数,未体现多态。
重写override:也叫覆盖,子类重新定义父类中有相同名称相同参数的虚函数,主要是在继承关系中出现的,被重写的函数必须是virtual的,重写函数的访问修饰符可以不同,尽管virtual是private的,子类中重写函数改为public,protected也可以,体现了多态。

多态分为两类
静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
动态多态: 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
静态多态的函数地址早绑定 - 编译阶段确定函数地址
动态多态的函数地址晚绑定 - 运行阶段确定函数地址

51、逗号表达式的要领:
(1) 逗号表达式的运算过程为:从左往右逐个计算表达式。
(2) 逗号表达式作为一个整体,它的值为最后一个表达式(也即表达式n)的值。
(3) 逗号运算符的优先级别在所有运算符中最低。

52、C语言中有数字三种表示:十进制、八进制(0开头)、十六进制(0x开头)。

53、计算机中负数是以补码的形式保存的,将补码转换成原码的计算方式如下:
①. 对于正数,原码与补码相同。
②.对于负数,将补码除符号位之外,按位取反,末位加1,即得到原码。
54、程序运行的时候,静态成员已经加载在内存里面了,但是包含静态成员的对象共享这些静态成员,
比方说,A有一个静态成员public static int i;那么程序运行的时候,这个i就加载进内存了,A的所有对象的i变量都指向这个静态空间的i,也就是说创建对象之前,它就占空间了
1:只有类的成员函数才能说明为虚函数;
2:静态成员函数不能是虚函数;
3:内联函数不能为虚函数;
4:构造函数不能是虚函数;
5:析构函数可以是虚函数,而且通常声明为虚函数

55、记住:virtual 函数是动态绑定,而缺省参数值却是静态绑定。 意思是你可能会 在“调用一个定义于派生类内的virtual函数”的同时,却使用基类为它所指定的缺省参数值。
结论:绝不重新定义继承而来的缺省参数值!(可参考《Effective C++》条款37)。

56、抽象类,不能用来实例化对象,只能作为接口被调用。

57、类初始化成员变量:
(1)const成员变量必须在构造函数的初始化列表中初始化;
(2)成员变量可以在构造函数中初始化;
(3)数组成员是不能在初始化列表里初始化的.

58、dynamic_cast是运行时检查,static_cast,在编译期检查。

59、BSS段:通常是指用来存放程序中未初始化的全局变量的一块内存区域;
数据段:通常是指用来存放程序中 已初始化 的 全局变量 的一块内存区域,static意味着在数据段中存放变量;
代码段:通常是指用来存放 程序执行代码 的一块内存区域;
堆:存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减,这一块在程序运行前就已经确定了;
栈:栈又称堆栈, 存放程序的 局部变量 (不包括static声明的变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务