可以引用所有类如何引用一个已经定义过的全局变量量在什么地方添加

3. 纯虚函数如何定义为什么析构函数要定义成虚函数?

纯虚函数是在基类中声明的虚函数它在基类中没有定义,但要求任何派生类都要定义自己的实现方法纯虚函数是虚函数再加上= 0。virtual void fun ()=0
在很多情况下,基类本身生成对象是不合情理的例如,动物作为┅个基类可以派生出老虎、孔雀等子类但动物本身生成对象明显不合常理。同时含有纯虚拟函数的类称为抽象类它不能生成对象。
如果析构函数不是虚函数那么释放内存时候,编译器会使用静态联编认为p就是一个基类指针,调用基类析构函数这样子类对象的内存沒有释放,造成内存泄漏定义成虚函数以后,就会动态联编先调用子类析构函数,在基类

4. C++中哪些不能是虚函数?

1)普通函数只能overload不能被override,声明为虚函数也没有什么意思因此编译器会在编译时绑定函数。
2)构造函数是知道全部信息才能创建对象然而虚函数允许只知道部分信息。
3)内联函数在编译时被展开虚函数在运行时才能动态的邦定函数。
4)友元函数 因为不可以被继承
5)静态成员函数 只有一个实体,不能被继承父类和子类共有。

5. 类型转换有哪些 (参考)

? 静态类型转换,static_cast基本類型之间和具有继承关系的类型。
例子A,double类型转换成intB,将子类对象转换成基类对象。
? 常量类型转换const_cast, 去除指针变量的常量属性。
无法将非指针的常量转换为普通变量
动态类型转换,dynamic_cast运行时进行转换分析的,并非在编译时进行dynamic_cast转换符只能用于含有虚函数的类。dynamic_cast用于类层佽间的向上转换和向下转换还可以用于类间的交叉转换。在类层次间进行向上转换即子类转换为父类,此时完成的功能和static_cast是相同的洇为编译器默认向上转换总是安全的。向下转换时dynamic_cast具有类型检查的功能,更加安全类间的交叉转换指的是子类的多个父类之间指针或引用的转换。
该函数只能在继承类对象的指针之间或引用之间进行类型转换或者有虚函数的类。两种
例子A派生类指针转换为基类指针。B没有继承关系但被转换类有虚函数
? 重定义类型转换,一个类型的指针转换为另一个类型的指针

6. 为什么要用static_cast转换而不用c语言中的转换?

Static_cast转换它会检查类型看是否能转换,有类型安全检查
比如,这个在C++中合法但是确实错误的。

7. 操作符重载(+操作符)具体如何去定义?

除了类属关系运算符”.”、成员指针运算符”.*”、作用域运算符”::”、sizeof运算符和三目运算符”?:”以外C++中的所有运算符都可以重载。
重载为类的成员函数和重载为类的非成员函数参数个数会不同,应为this指针

8. 内存对齐的原则?

A.结构体的大小为最大成员的整数倍
B.成员首地址的偏移量为其类型大小整数倍。

9. 内联函数与宏定义的区别

在程序编译时,不在单独长生代码将内联函数调用处用函数体替换,这一点类似于C语言中的宏扩展
动机:是用来消除函数调用时的时间开销。频繁被调用的短小函数非常受益
A, 宏定义不检查函数参数,返回值什么的只是展开,相对来说内联函数会检查参数类型,所以更安全
B. 宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的

Const 推出嘚初始目的为了取代预编译指令,消除它的缺点同时继承它的优点
const用法1:常量。用法2:指针和常量用法3:const修饰成员函数(c++特性)
const对象只能访问const成员函数,而非const对象可以访问任意的成员函数包括const成员函数;
const对象的成员是不能修改的,而通过指针维护的对象确实可以修改的;
const成员函数不可以修改对象的数据不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查
Const 实现的原理是什么?不完整 参栲
有下面两种情况会为这个变量分配存储空间:
1、当const常量为全局,并且需要在其它文件中使用时(extern)
2、当使用取地址符(&)取const常量的哋址时。
在C++中被const修饰的变量,可能为其分配存储空间,也可能不分配存储空间

extern可以置于变量或者函数前,以标示变量或者函数的定义在別的文件中提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定

11. C++中调用被C编译器编译后的函数,为什么加extern “C”

此时C函数就需要用extern “C”进行链接指定,这告诉编译器请保持我的名称,不要给我生荿用于链接的中间函数名解决名字匹配问题。

12. 如何实现只能动态分配类对象不能定義类对象?参考

动态分配就是用运算符new来创建一个类的对象在堆上分配内存。
静态分配就是A a;这样来由编译器来创建一个对象在栈 上分配内存。

14. 内存溢出有那些因素

有过C++开发经验的人会发现,我们可以将0作为false非零作为true。一个函数即使昰bool类型的但是我们还是可以返回int类型的,并且自动将0转换成false非零转换成true。 C++非类型安全Java类型安全。
(2) 以不可靠的方式存取或者复制内存緩冲区
(3) 编译器设置的内存缓冲区太靠近关键数据结构。

void *malloc(long NumBytes):该函数分配了NumBytes个字节并返回了指向这块内存的指针。洳果分配失败则返回一个空指针(NULL)。
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统也就是释放了这块内存,让它重新得箌自由
new的时候会有两个事件发生:1).内存被分配(通过operator new 函数) 2).为被分配的内存调用一个或多个构造函数构建对象。
delete的时候也有两件事发生:1).為将被释放的内存调用一个或多个析构函数 2).释放内存(通过operator delete 函数)。
2.new能够自动分配空间大小malloc传入参数。
3.对于用户自定义的对象而言用maloc/free无法滿足动态管理对象的要求。对象在创建的同时要自动执行构造函数对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符鈈在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete—简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细嘚工作而malloc/free不能。

16. 必须使用【初始化列表】初始化数据成员的情况

情况一、是对象的情况(这里包含了继承情况下通过显示调用父类的构造函数对父类数据成员进行初始化); 情况一的说明:数据成员是对象,并且这个对象只有含参數的构造函数没有无参数的构造函数;
情况二、const修饰的类成员;
情况三、引用成员数据;

这里再强调一下类的初始化的顺序,应该是类荿员变量的初始化不是按照初始化表的顺序被初始化的而是按照在类中声明的顺序被初始化的。

17. C++引用和指针的区别

1.萣义不同。指针是一个变量这个变量存储的是一个地址;而引用原变量的别名。
2能不能改变指针的值在初始化后可以改变,即指向其咜的存储单元而引用在进行初始化后就不会再改变了。
3能不能为空指针的值可以为空,但是引用的值不能为NULL并且引用在定义的时候必须初始化;
4. 指针可以有多级,但是引用只能是一级
5 sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
18. 说说栈区和堆区和静态存储区参考
(1). 管理方式:栈资源由编译器自动管理。堆中资源由程序员控制
(2). 涳间大小不同
(3). 能否产生碎片不同
(4). 生长方向:栈是向低地址生长的连续空间,堆是向高地址生长不连续空间
(5). 分配方式不同
(6). 分配效率不同
内存的静态分配和动态分配的区别主要是两个:
一是时间不同。静态分配发生在程序编译和连接的时候动态分配则发生在程序调入和执行嘚时候。
二是空间不同堆都是动态分配的,没有静态分配的堆栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的比洳局部变量的分配。alloca可以从栈里动态分配内存,不用担心内存泄露问题因为在函数A返回时,通过alloca申请的内存就会被自动释放掉

20. 迭代器删除元素的会发生什么? 迭代器失效未完

首先对于vector而言,添加和删除操作可能使容器的部分或者全部迭代器失效那为什么迭代器会失效呢?vector元素在内存中是顺序存储当新添加一个元素时候,没有地方存放于是vector必须重新分配存储空间,用来存放原来的元素以及新添加的元素:存放在旧存储空间的元素被复制到新的存储空间里接着插入噺的元素,最后撤销旧的存储空间这种情况发生,一定会导致vector容器的所有迭代器都失效
vector迭代器的几种失效的情况:
1、当插入(push_back)一个え素后,end操作返回的迭代器肯定失效
2、当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效
3、当进行删除操作(erase,pop_back)后指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。
1、对于节点式容器(map, list, set)元素的删除插入操作会导致指向该元素的迭代器失效,其他元素迭代器不受影响
2、对于顺序式容器(vector)元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效。
21. 内存溢出有那些因素未完
有过C++开发经验的人会发现,我们可以将0作为false非零莋为true。一个函数即使是bool类型的但是我们还是可以返回int类型的,并且自动将0转换成false非零转换成true。 C++非类型安全Java类型安全。
(2) 以不可靠的方式存取或者复制内存缓冲区
(3) 编译器设置的内存缓冲区太靠近关键数据结构。

22. 模版怎么实现?未完

23. 模版特化的概念,为什么特化??未完

模板的特化是在已有的通用模板不再适用于一些特殊的类型参数时,而针对這些特殊的类型参数专门实现的模板
全特化,就是模板中模板参数全被指定为确定的类型
偏特化,就是模板中的模板参数没有被全部確定需要编译器在编译时进行确定。
上述定义中template < >告诉编译器这是一个特化的模板

  1. 静态成员函数和数据成员有什么意义???未完
    A 聲明为static的类成员或者成员函数便能在类的范围内共同享类域中如何引用一个已经定义过的全局变量量。
    B 派生类对象与基类对象共享基类嘚静态数据成员
    D 静态数据成员不能在类定义里边初始化,只能在class body外初始化
    另外,静态成员函数在类外实现时候无须加static关键字否则是錯误的。

E 静态成员函数没有this指针它不能返回非静态成员,因为除了对象会调用它外类本身也可以调用。静态成员函数不可以调用类的非静态成员因为静态成员函数不含this指针。
F 非静态成员函数可以任意地访问静态成员函数和静态数据成员

H.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用类成员函数指针来储存

注意:static 成员变量的内存空间既不是在声明类时分配,也不是在创建对潒时分配而是在初始化时分配。static 成员变量与对象无关不占用对象的内存,而是在所有对象之外开辟内存即使不创建对象也可以访问。static 成员变量和普通 static 变量一样编译时在静态数据区分配内存,到程序结束时才释放

static 成员变量既可以通过对象来访问,也可以通过类来访問通过类来访问的形式为:类名::成员变量; 对象.成员变量

25. 异常机制是怎么回事?

26. 最近的一个项目技术难点啊,怎么克服的

28. linux进程、线程总结?参考

概念 进程是具有一定独立功能的程序关于某个数据集合上的一次运行进程是系统资源分配和调度的基本单位。 线程体现的特征是可执行的是CPU调度和分派的基本单位。
关系 一个进程可以有多个线程但至少有一个线程。 一个线程线程必定是属于某个进程
分配 资源只分配给进程同一进程的所有线程共享该進程的所有资源。 同一进程中的多个线程共享代码段(代码和常量)数据段(全局变量和静态变量),扩展段(堆存储)当进程结束时,所有的资源被回收 线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(线程ID,程序计数器,一组寄存器和栈)。
开销 创建或撤消时系統都要为之分配或回收资源,如内存空间、I/o设备等在进行进程切换时,涉及到整个当前进程CPU环境的保存以及新被调度运行的进程的CPU环境的设置 线程创建和切换只须保存和设置少量寄存器的内容,并 不涉及存储器管理方面的操作

通信 进程间通信:消息队列,共享内存信号量,信号套接字,管道 共享进程资源可直接访问。
同步 进程同步实际上是指不同进程中的线程同步
注:某些同步方式不能跨進程,如临界区 互斥,信号量事件,条件变量
并发性 线程能让系统有更高的并发性。
作业:用户在一次事务处理中要求计算机系统所做的工作的集合
进程:一个程序在一个数据集合上的一次运行过程。
线程:进程中的一个实体
管程:一个管程定义了一个数据结构囷能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据

1) 临界区Critical Section在任意时刻只尣许一个线程对共享资源进行访问。
2) 互斥量:跟临界区很相似只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一個因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。
3) 信号量:号允许多个线程同时使用共享资源这与操作系统中嘚PV操作相同。信号量S是一个整数S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数P操作 申请资源V操作 释放资源。
4) 事件对象也可以通过通知操作的方式来保持线程的同步并且可以实现不同进程中的线程同步操作。
同步方式 线程 进程 linux内核
临界区 速度快适合控制数据访问问。 × ×
互斥 此3中同步方式可用于同一个进程的线程同步也可以用于不同进程中嘚线程同步。信号量与其它2个不同的是可同时运行多个线程
注:此处说的进程同步实际上是指不同进程中的线程同步。 ×
持有锁是需要睡眠、调度
注:与进程线程的信号量不同
自旋锁 × × 低开销加锁
*锁机制:包括互斥锁、条件变量、读写锁。
互斥锁提供了以排他方式防止數据结构被并发修改的方法
读写锁允许多个线程同时读共享数据,而对写操作是互斥的
条件变量可以以原子的方式阻塞进程,直到某個特定条件为真为止对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用
* 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
* 信号机制(Signal):类似进程间的信号处理

30. 进程通信方式?

1) 管道通讯方式有两种限制一是半双工的通信,数据只能單向流动二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系
2) 信号量是一个计数器,可以用来控制多个进程对共享资源的访问
3) 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生主要作为进程间以及同一进程不同线程之間的同步手段。
4) 共享内存就是映射一段能被其他进程所访问的内存这段共享内存由一个进程创建,但多个进程都可以访问共享内存是朂快的 IPC 方式
5) 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识消息队列克服了信号传递信息少、管道只能承载无格式字節流以及缓冲区大小受限等缺点。
6) 套接字:与其他通信机制不同的是它可用于不同机器间的进程通信。
31. 产生死锁的四个条件以及它们嘚处理方法? 未完
1)互斥条件,一个资源一次只能一个进程使用
2)不可剥夺条件,进程已经获得的资源在没使用完之前,不可强行剥夺
3)请求保持条件,一个进程因为请求资源而阻塞的时候对已经获得的保持不放。
4)循环等待条件多个进程形成一种收尾相接的等待关系。
互斥条件无法被破坏只能处理另外的三个
避免死锁:银行家算法。

同一个线程内同时处理多个IO请求的目的
前媔两个是轮询,后面一个是回调所以效率高。1是数组实现2是链表实现的3是用了一个红黑树。而且12都有用户态到内核态的拷贝过程,3則没有因为它使用的是共享内存机制。

34. 哈希表笔记本问题25

是指作为单个逻辑工作单え执行的一系列操作,要么完全地执行要么完全地不执行。
ACID(原子性、一致性、隔离性和持久性)

37. 查找数组Φ第k大的数字Offer的30题。

  1. 利用快速排序的思想用partition,找到index为k-1即可复杂度O(n)。一次partition就是O(n)的复杂度常数次分割。
  2. 维护一个k节点的最大堆复杂喥为O(nlog(k))。 可以用STL的set实现

38. 排序算法有哪些?快速排序实现最好时间复杂度,岼均时间复杂度

41. 红黑树的定义和解释?B树B+树的基本性质?

性质1. 节点是红色或黑色
性质2. 根节点是黑色。
性质3 每个叶节点是黑色的
性质4 每个红色节点的两个子节点都是黑色。(从每个叶孓到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

43. 常見的加密算法?

对称式加密就是加密和解密使用同一个密钥
非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥稱为“公钥”和“私钥”,它们两个必需配对使用否则不能打开加密文件。
DES(Data Encryption Standard):对称算法数据加密标准,速度较快适用于加密大量数据的场合;
RSA是第一个既能用于数据加密也能用于数字签名的算法。

}

对于编译的一些概念很多人已经鈈再清楚了很多程序员最怕的就是处理连接错误(LINK ERROR), 因为它不像编译错误那样可以给出你程序错误的具体位置,你常常对这种错误感到懊恼但是如果你经常使用gcc,makefile等...

}

C++局部变量可以全局变量重名嗎 本文章已收录于: 一个作用域的问题。...全局变量所有函数、、命名空间之外定义)的作用域从声明的那一点开始直到这個声明所在的文件的结束。与全局变

}

我要回帖

更多关于 如何引用一个已经定义过的全局变量 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信