C++编程中常遇到的问题

一、路径中不能存在空格数组

二、for等循环结构中,若是判断条件的变量是size_t或者unsigned时,最好不要采用“--i”来递减变量,由于这两种类型没有负数。函数

三、引用的引用不可用: int& &i ;(不合法,且注意两个&之间有空格,不然就会被声明为右值引用)。优化

四、int *p[10] ; sizeof(p) 是指数组所占的长度,虽然p自己是一个指针。ui

五、if判断语句中,当要配合else使用时,最好不要在条件语句中同时存在多个判断语句。设计

六、由于引用自己并不是对象,因此不存在指向引用的指针: int& *ptr;(不合法)。指针

七、字面值常量字符串 ”aaa“的通过sizeof函数后计算的空间是4,在其最后存在一个空字符。对象

八、在执行读取操做时,string对象会自动忽略开头的空白并从第一个真正的字符开始直至遇到下一个空白。继承

九、对于一个复杂类型的变量声明(eg: int *&r),以变量名为中心,从右到左分析。若是有括号那么先括号内而后遇括号跳出括号继续从右到左分析。索引

十、常量表达式是值不会改变且在编译过程当中就能得知结果的表达式,数组的维度必须是一个常量表达式。接口

十一、指针也是迭代器,指针相减的结果类型是ptrdiff_t。

十二、标准库类型(string、vector)的下标索引必须是无符号类型,而内置的下标运算无此要求便可以是负数,如内置数组,只要arr[-2]等价于*(arr-2)指向的元素还在数组内就ok。

1三、char *p = "abc", char p[] = "abc"; 这两个p虽然都是都是指针,但不同。前者只想的是一个字符串字面量,开辟的存放空间在常量区,因此不能用指针去修改其值。然后者不存在这样的问题。

1四、关于后置递增运算符(i++),在语句中使用前,先求值产生一个等于原值的右值副本temp_i,而后将这个副本应用于这条语句中。执行完该语句后 i 在自加1。

1五、C\C++中,当给cout一个字符指针的时候,它就一直输出,直到遇到 ‘\0’ 这个结尾,若是不存在‘\0’ 则会发生输出错误。

1六、int a[10]{}; *(a+1)是a中的第一个元素,*(&a+1)指向的下一个类型int(*)[10]的数组。

1七、memset是以字节为单位,初始化内存块。void *memset(void *s, int ch, size_t n);将s中前n个字节 (typedef unsigned int size_t )用ch替换并返回s.

1八、无符号数与有符号数相比较,会将有符号书转化为无符号数,负数会变成一个很大的无符号数。

1九、二维数组定义中,行能够省略,列不能。

20、程序占用三种类型的内存:静态内存、栈内存、堆内存; 
静态内存: 
用来保存局部static对象、类static数据成员以及定义在任何函数以外的变量 
栈内存: 
用来保存定义在函数内的非static对象。分配在静态内存或栈内存中的对象由编译器自动建立和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用以前分配,在程序结束时销毁。
堆内存: 
在程序运行时分配。动态对象的生存周期由程序(用户)来控制。

2一、深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另一个对象形成影响。浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不一样(名称不一样)。对其中任何一个对象的改动都会影响另一个对象。

2二、const int* const a = &b;等价于 int const* const a = &b;

2三、传引用、传指针最终传的都是地址。

2四、回调函数就是一个经过函数指针调用的函数。

2五、使用volatile关键字声明的变量,系统老是从新从它所在的内存中读取数据,即便它前面的指令刚刚从该处读取过数据,并且读取的数据马上被保存;相反,若没有使用volatile,编译器可能会作优化处理,可能暂时使用寄存器中的值,而若是该变量由别的程序更新了的话,将会出现不一致的现象!

2六、面向对象的五个基本原则: 

单一职责原则(Single-Resposibility Principle):一个类,最好只作一件事,只有一个引发它的变化。单一职责原则能够看作是低耦合、高内聚在面向对象原则上的引伸,将职责定义为引发变化的缘由,以提升内聚性来减小引发变化的缘由。
开放封闭原则(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。
Liskov替换原则(Liskov-Substituion Principle):子类必须可以替换其基类。这一思想体现为对继承机制的约束规范,只有子类可以替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。
依赖倒置原则(Dependecy-Inversion Principle):依赖于抽象。具体而言就是高层模块不依赖于底层模块,两者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。
接口隔离原则(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口

2七、构造函数不能声明为虚函数的缘由是: 

1 )构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间肯定实际类型的。而在构造一个对象时,因为对象还未构形成功。编译器没法知道对象 的实际类型,是该类自己,仍是该类的一个派生类,或是更深层次的派生类。没法肯定。
2) 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工做,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表尚未被初 始化,将没法进行。虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候,这个对象的动态类型还不完整,没有办法肯定它究竟是什么类型,故构造函数不能动态绑定。(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数以前,这个对象根本就不存在,它怎么动态绑定?)
编译器在调用基类的构造函数的时候并不知道你要构造的是一个基类的对象仍是一个派生类的对象。

2八、很是量引用定义时,其初始化的对象必须为左值!(int &a = 3;非法)

2九、大小端:小端中低地址低字节,高地址高字节;大端相反。80X86是小端模式。

30、 派生类的构造函数执行过程,析构函数的执行过程通常与构造函数执行的过程相反。

       1)、建立派生类的对象,基类的构造函数函数优先被调用(也优先于派生类里的成员类);
  2)、若是类里面有成员类,成员类的构造函数优先被调用;
  3)、基类构造函数若是有多个基类则构造函数的调用顺序是某类在类派生表中出现的顺序而不是它们在成员初始化表中的顺序;
  4)、成员类对象构造函数若是有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序而不是它们出如今成员初始化表中的顺序;
  5)、派生类构造函数
  做为通常规则派生类构造函数应该不能直接向一个基类数据成员赋值而是把值传递给适当的基类构造函数不然两个类的实现变成紧耦合的(tightly coupled)将更加难于正确地修改或扩展基类的实现。(基类设计者的责任是提供一组适当的基类构造函数)。

3一、 函数的退出一般有两种状况,正常退出和异常退出,不管是什么状况下的退出,局部对象都会被销毁。但经过new开辟的内存空间,在对应的delete以前发生了异常是不会释放该空间的。所以推荐使用智能指针,老是能正确的释放内存。

3二、符号不明确:多是由于定义的符号与命名空间中的某些符号相同,换一个符号可能就行。

3三、类型不完整,多是因为未包含相关的头文件。