1.string类的加号“+”相当于拼接的作用,a+b说明a在前面,和b+a的结果是不一样的,a+=b等价于a=a+b;

2.atoi是c++内置函数,itoa并不是,只有VS编译器环境下可以使用,需要原int型数据、char指针和目标进制数(int型)三个参数;

3.VS编译环境下不能用cout直接输出string,需要c_str()方法处理后输出,在GCC编译环境下则可以直接输出;

4.32位系统中所有的指针大小都是4B,64位都是8B;

5.vector的实质还是数组,其大小是固定的,只不过每次push_back的时候若超出内存会重新申请内存(一般为原内存的两倍),然后有个拷贝过程,这个效率比较低。

6.C++的常量字符串是存在单独的内存区域中(和储存局部变量的栈不同),如果用指针指向相同字符常量,则两个指针指向相同(为了节省内存)。但是如果用相同字符常量给两个字符数组赋值,情况则不同,两个数组会分别申请空间,其头指针指向不同。

7.new和malloc的区别:

malloc是标准库函数,new是C++运算符,malloc只能完成内存分配不能对所对获得内存进行初始化。

对象创建是需要调用构造函数,消亡是需要调用析构函数,对于自定义结构,由于malloc是标准库函数,不在编辑器的控制范围内,所以不能把调用构造函数和析构函数的任务附   加给malloc。

8.为什么构造函数不能是虚函数,而析构函数可以。

调用虚函数需要虚函数表,但是在类完成构造之前对象还没有被分配空间,自然也就不存在虚函数表。

再一个虚函数本身就是因为需求不明而暂不实现,而构造函数的存在目标很明确,就是为了初始化实例,所以从这个层面把构造函数定义成虚函数也没有意义。

而我们通常情况下把析构函数定义成虚函数是因为,很多时候我们都是通过父类指针来调用和释放子类,这时候析构函数如果不是虚函数,那么只会调用父类的析构函数不会调用   子类的析构函数。

9.关于static的初始化问题。

因为static型变量本身是静态的,像在如下函数中,

void Func()
{const static int num=0;cout << num << endl;num++;
}

如果在同一函数中调用此函数两次,按照static的设计初衷就是为了num可以得到累加,所以输出的是

0

1

所以static变量的初始化(第一句)只会在编译时被执行一次。

如果num变为非const型:

void Func()
{static int num;num=0;cout << num << endl;num++;
}

这样相对容易出错些,因为非const变量没有要求声明时赋值,所以如果程序按照上面方式赋值,那么程序结果可能不是我们想要的。

0

0

这是因为虽然num初始化语句只在编译时执行了一次,但是作为赋值语句,num=0在每次调用Func()时都会被执行,所以在定义非const型变量时最好在声明时赋值。

10.虚函数的问题

c++的面试,虚函数应该是被问得最多的知识点了,做下总结。

先谈谈普通函数的调用,普通函数在编译的时候,就已经成型了(参数类型,个数,函数体),所以通过重载和模板实现的多态通常称为编译时多态。

class A
{
public:void fun(){cout <<"A" << endl;}
};class B:public A
{
public:void fun(){cout <<"B" << endl;}
};int main()
{ A *a=new A;A *b=new B;a->fun();b->fun();
}

上述代码的结果是A,A,就是因为在编译时a,b被当做静态类型即都是A类,编译过后对应调用的fun()都是A::fun()所以结果都是A,所以要想实现运行时多态还需要虚函数才行。

而虚函数其存在是为了实现运行时多态,即在运行阶段才决定(计算出)函数的地址。虽然和编译时多态被划为两类,虚函数机制也是通过编译器来实现的。

简单来说,虚函数是为了实现:调用一个虚函数时,被执行的代码必须和调用函数对象的动态类型相一致。

大部分编译器是通过虚函数表(vtbl)和虚函数指针(vptr)来实现的。

虚函数表:当一个类中定义了虚函数,那么在构造类的时候就会生成该类自己的虚函数表,也就是说虚函数表是和类一一对应的,而不是和类实例。

虚函数表的主要内容就是该类中所有虚函数的地址。

虚函数指针:含有虚函数类的实例,除了包含变量之外,还包含指向该类虚函数表的指针,就是虚函数指针,用于找到类的虚函数表。

子类的虚函数表会包含所有父类的虚函数地址,后面还跟着自己独有的虚函数地址。

如果子类重写了父类的虚函数,那么子类虚函数表中原来父类寻函数指针的位置会被子类重写的虚函数指针所覆盖。

所以这样以后调函数,只会调到子类的函数,不会调用父类的。

如果一个子类有多个父类(多继承),那么子类的实例中会有多个vptr(个数和继承的个数相同),我的理解是这个子类有多个虚函数表(每个父类对应一个)。

这样不同的父类指针指向子类的时候,会查询不同的虚函数表来调用自己实际的虚函数。

这时候子类自己独有的虚函数一般附在第一个父类对应的虚函数表中(大多编译器是这样的,不过编译器有选择不同方式的自由)。

虚函数的调用过程:

1. 通过实例对象得到类的虚函数指针,一般为对象的前4个字节(32位系统)。

2. 通过虚函数表找到需要调用的虚函数的地址。

3. 通过地址调用虚函数。

附:

1.虚函数的缺点:

主要从指针多次偏转的代价(时间),虚函数表大小、虚函数指针大小(空间)两个方面来分析。

2.另外虚函数对安全性也提出了考验。(下面第二个链接的后半部分)

(1)子类中独有的虚函数是不能通过父类指针来调用的(编译时便会错误)。

(2)通过虚函数表可以调用父类中的non-public虚函数(通过获得public类虚函数的地址做偏移)。

(3)父类可以直接调用子类中的non-public虚函数。

class A:
{
public:virtual fun(){cout << "base." << endl;}
};class B: public A
{
private:virtual fun(){cout << "derive." << endl;}
};int main()
{A *a=new B;a->fun();return 0;
}

上面代码的输出结果是:derive.

是什么原因呢?

这似乎要牵扯到虚函数编译时的一些过程处理。

在编译的时候(上述代码中为a->fun();)实例对象的类型是按静态类型来处理的,这时候a的类型就是A,而A中的fun()是public的,所以编译并不会发生错误。

在实际的调用中,采用的是(*a->vptr[1])(a)来调用的,即a的动态类型其实是B。

运行时获取到的是B::fun()的地址,所以输出结果是derive,这也就是动态运行的机理。

再来一个更邪乎的···

class A
{
public:   virtual void fun(int i = 1)      {     std::cout << "base fun called, " << i;     }
};  class B: public A
{
private:    virtual void fun(int i = 2)      {     std::cout << "derive fun called, " << i;     }
};int main()
{A *a=new B;a->fun();return 0;
}

按照之前的解释,输出的字符部分是derive fun called没问题,可是后面跟的数字会是什么呢?

答案竟然是1!而解释呢?

其实这是一种不规范的代码实现,effective c++中要求我们绝不重新定义继承而来的默认参数,说的就是以上的这样情况。

因为虚函数的动态绑定的,而默认参数(缺省参数)是静态绑定的。

所以最后函数的调用方式其实是(a->vptr[1])(a,1),答案自然是像上面所说的那样,但是这样的程序真的很容易给人误导。

具体的图片不太好画,可以参照一下两篇博客。

点击打开链接

点击打开链接

11.联合体和结构体

说实在的,大二学的c,现在早忘了联合体是什么了,今天查了查。

联合体:可以包含几种不同的数据类型,共用一段内存,所以说联合体的大小应该是其中最大的数据类型的大小。

结构体:可以包含几种不同的数据类型,不同的类型是同时存在的,不相互影响,所以说结构体的大小应该是所有数据类型内存对齐后的总大小。

union un
{int a;char b[2];
};

如上联合,int占4个字节,char数组占2个字节,所以联合体大小为4字节,windows x86编译器为是小端模式,所以其内存结构应该是:

a

b[0] b[1]

*    *    *    *

un tmp;
tmp.a=0x12345678;

现在我们做如上赋值,则内存的实际情况如下:(一个16进制数占2bit,一个char可以接受两个16进制数)

a

b[0]  b[1]

78    56    34    12

所以此时如果我们输出

printf("%x\n",tmp.b[0]);

会输出78

tmp.b[0]=0x34;

修改之后,输出tmp.a

printf("%x\n",tmp.a);

会输出12345634。

12.大小端

大端:数据的低位存放在内存的高位

小端:数据的低位存放在内存的低位

int a = 0x12345678;

地址---->递增

大端:12    34    56    78

小端:78    56    34    12
可以看见大端模式其实是更符合我们的直观想法的,而Windows x86编译器为小端模式。

c++新技能不断get中相关推荐

  1. 谷歌 Daydream 实验室:VR中学习新技能是一种怎样的体验?

    谷歌 Daydream 实验室:VR中学习新技能是一种怎样的体验? 本文作者:逸炫 编辑:田苗 2017-07-26 10:56 导语:要学做一桌满汉全席,还是得撸起袖子下厨房. 雷锋网按:在VR中, ...

  2. crossover卸载 linux,新技能!在Ubuntu 中卸载CrossOver

    原标题:新技能!在Ubuntu 中卸载CrossOver 想要在Ubuntu中使用 Windows程序,可以安装一个CrossOver系统兼容软件,想必大家都知道了,但是如何在Ubuntu中卸载Cro ...

  3. AI时代,产品经理需要掌握的5项新技能

    不同于传统的产品经理,AI时代的产品经理更加注重的如何将技术应用在业务问题上.AI时代,产品经理最重要的职责就是提供数据规范,所以这也要求产品经理对数据有足够的认识.文章对AI时代产品经理需要掌握的新 ...

  4. 学习新技能时,大脑在如何发生改变?

    来源:中国生物技术网 众所周知,无论是一项运动.一种乐器还是一门手艺,掌握一项新技能都是需要花费时间并进行训练的.虽然我们都知道健康的大脑能够应付的来,但是为了开发出新行为大脑如何发生改变科学家们对此 ...

  5. 开课吧python学费-分享一个小白也能月赚2万的新技能

    原标题:分享一个小白也能月赚2万的新技能 这两年,每天都听身边人吐槽:"最近太累了,加班多.事情杂.离家远......可到手的工资却少得可怜." 辞职.跳槽,已然成为一种常态. 这 ...

  6. 2030年,逾1亿中国人需要学习新技能并转换岗位,这就是摩擦性失业

    在自动化的浪潮中,全社会需要解决好四个问题:一是需要保持积极的稳健增长,以保证工作岗位的增加:二是提供工作培训机会,帮助个人学习适应市场需求的新技能:三是提高商业社会乃至劳动力市场的活力和流动性:四是 ...

  7. 云开发数据库又增新技能!

    开篇彩蛋 由于近期小程序·云开发将上线付费功能(付费功能针对非基础资源配额,基础资源配额仍可免费使用).为了给开发者更充足的时间进行调整,对于截止 2019-06-21 日前通过邮件申请调整的配额(非 ...

  8. 高效掌握新技能的「树型思维」

    大家好,我是Z哥. 不知道你有没有过这样的困惑,想学习某项新技能,但是很容失败.比如,出于职业发展的考虑,想学习一门新的编程语言,或者想了解一个新的技术框架:又或者看了某些综艺节目后想玩一玩滑板.练一 ...

  9. linux通讯录软件带头像,小程序新技能 Get!保存微信好友头像到手机通讯录

    原标题:小程序新技能 Get!保存微信好友头像到手机通讯录 亲爱的朋友,你知道来电时能看到好友的头像是一种怎样的体验吗? 你是否注意过这样一件事:每当打开自己的微博.微信等社交软件,除了扑面而来的信息 ...

最新文章

  1. 一文详解实时稀疏点云分割
  2. c语言中空格字符怎么表示_漫画:腾讯面试题,请实现把字符串中的空格替换为“%20”...
  3. 如何设置Linux操作系统shell命令的默认语言
  4. java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用
  5. jboss eap 6.2 ear包 下使用log4j日志
  6. sqlserver关键字
  7. Python笔记-多线程爬虫实例
  8. ansible解决python版本依赖
  9. 在场景中添加光线——给光线添加更高的细节:逐像素光照
  10. linux下的git 编辑器,vim - 如何让Git使用我选择的编辑器进行提交?
  11. 十、Mysql执行计划详细解析
  12. 家用计算机存储容量,计算机内存储器容量有多大?
  13. 代码美化网站,让你的代码别具一格
  14. 第三代oid铺码软件_点读笔的原理
  15. H5播放器和flash播放器的区别
  16. 华为ICT题目-云服务题库1
  17. 怎么锻炼孩子的想象力创造力_如何培养孩子的想象力和创造力?
  18. 游戏测试好还是软件测试好,浅学软件测试 软件测试和游戏测试哪个有前途?...
  19. 中国自由软件推广先锋的自述,心潮澎湃的一往无前,一定要看!作者:洪峰...
  20. Firefox支持Websocket

热门文章

  1. el-table 大数据量渲染,页面卡顿的解决方案
  2. Centos下安装桌面环境和Flash插件
  3. 10649物联卡查询, 10649物联卡官网
  4. matlab 中图字体设置,关于matlab绘图中字体及图片大小等的设置
  5. Python+Miner解析PDF
  6. CSS实现的带头像的彩色垂直菜单源码
  7. 【前端技术】一篇文章搞掂:uni-app
  8. 使用YASM编程 - 01
  9. 如何设置Foxmail收取yahoo.com.cn和yahoo.cn以及yahoo.com等邮箱的方法
  10. 浏览器打开微信公众号h5页面,增加cookie绕过微信授权登录