推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

最全,面中率最高的C++经典面试题分享!

   2023-08-02 网络整理佚名1330
核心提示:这就说明:对于内建简单数据类型,和[]功能是相同的。内部数据类型没有析构函数,所以问题不大。答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。将“引用”作为函数参数有哪些特点?(1)传递引用给函数与传递指针的效果是一样的。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?

1.新的、、、自由关系

对象的析构函数会被调用,new对应的free只会释放内存,new会调用构造函数。 和free是C++/C语言的标准库函数,new/是C++的运算符。

它们可用于申请动态内存和释放内存。 对于非内部数据类型的对象,单独使用maloc/free无法满足动态对象的要求。

对象在创建时必须自动执行构造函数,对象在消亡前必须自动执行析构函数。

由于/free是库函数而不是操作符,因此不在编译器的控制权限之内,不能将执行构造函数和析构函数的任务强加给/free。

因此,C++语言需要一个可以完成动态内存分配和初始化的 new,以及一个可以完成清理和释放内存的。 请注意,new/ 不是库函数。

2.与[]的区别

析构函数只会被调用一次,而[]会调用每个成员的析构函数。

More C++中有更详细的解释:“当对数组使用运算符时,它会为每个数组元素调用析构函数,然后调用释放内存。” 匹配新的,[]匹配新的[]

MemTest *mTest1 = new MemTest[10];

MemTest *mTest2 = new MemTest;

Int *pInt1 = new int [10];

Int *pInt2 = new int;

delete[]pInt1; //-1-

delete[]pInt2; //-2-

delete[]mTest1;//-3-

delete[]mTest2;//-4-

在-4-处报告错误。

这意味着:对于内置的简单数据类型,[]的功能是相同的。

对于自定义复杂数据类型,[] 不能互换使用。 [] 删除数组,删除指针。

简单来说就是删除new分配的内存; 用new[]分配的内存用[]删除。 [] 将调用数组元素的析构函数。

内在数据类型没有析构函数,所以这没什么大不了的。 如果不带括号使用它,它会认为它指向单个对象,否则,它会认为它指向一个数组。

3、C++有哪些特性(面向对象的特性)

封装、继承和多态。

4、子类析构时是否应该调用父类的析构函数?

析构函数的调用顺序是先析构派生类,再析构基类,也就是说,当调用基类的析构函数时,派生类的所有信息都已经被销毁了。

定义对象时,先调用基类的构造函数,然后调用派生类的构造函数; 析构时则正好相反:先调用派生类的析构函数,然后调用基类的析构函数。

5.多态、虚函数、纯虚函数

多态性:不同的对象收到相同的消息时会产生不同的动作。 C++的多态性体现在运行和编译两个方面:程序运行时的多态性通过继承和虚函数体现;

多态性体现在程序编译时函数和运算符的重载;

虚函数:基类中用关键字标记的成员函数。 它提供了一个接口接口。 允许在派生类中重新定义基类虚函数。

纯虚函数的作用:在基类中为其派生类保留一个函数名,以便派生类可以根据需要进行定义。 纯虚函数作为接口,不具备函数的功能,一般不能直接调用。

从基类继承的纯虚函数在派生类中仍然是虚函数。 如果一个类至少有一个纯虚函数,那么这个类就称为抽象类(class)。

抽象类不仅包括纯虚函数,还包括虚函数。 抽象类必须用作派生其他类的基类,并且不能用于直接创建对象实例。 然而,使用抽象类的指针仍然支持运行时多态性。

6.找到以下函数的返回值()

int func(x) 
    int countx = 0
    while(x) 
    { 
        countx ++; 
        x = x&(x-1); 
    } 
    return countx; 

假设 x = 9999。答案:8

思路:将x转成二进制,看其中包含的1的个数。

7. 什么是“参考”? 声明和使用“引用”时应注意哪些问题?

答:引用是目标变量的“别名”(别名),对应用程序的操作与直接对变量的操作完全相同。

声明引用时,请记住对其进行初始化。

声明引用后,意味着目标变量名有两个名称,即目标的原始名称和引用名,并且引用名不能用作其他变量名的别名。

声明引用并没有定义一个新的变量,它仅仅意味着引用名是目标变量名的别名,它本身并不是数据类型,所以引用本身不占用存储单元,系统也不会占用存储单元。分配存储单元以供参考。 无法创建对数组的引用。

8、使用“”作为函数参数有什么特点?

(1) 传递函数的引用与传递指针具有相同的效果。

此时,被调用函数的形参作为原调用函数中实参变量或对象的别名,因此被调用函数中对形参变量的操作就是对应的目标对象(在main中)调用函数)调用函数)操作。

(2)函数的参数采用引用传递,在内存中不生成实参的副本,直接对实参进行操作; 而函数的参数是通过一般变量传递的,当函数调用发生时,需要分配存储给形参单元,形参变量是实参变量的副本;

如果传递一个对象,复制构造函数也会被调用。 因此,当参数传递的数据较大时,引用的效率和占用的空间都比一般变量要好。

(3)虽然使用指针作为函数参数也可以达到使用引用的效果,但是在被调用的函数中,还必须给形参分配存储单元,并以“*指针变量名”的形式进行操作” 需要重复。 这样容易出错,程序的可读性较差; 另一方面,在调用函数的调用点,必须使用变量的地址作为实参。 另一方面,参考文献更易于使用且更清晰。

9. 什么时候需要使用“常量引用”?

如果你想使用引用来提高程序的效率,并保护传递给函数的数据不被在函数中改变,那么你应该使用常量引用。

常量引用声明方法:const类型标识符&引用名=目标变量名;

portant;overflow-wrap: inherit !important;word-break: inherit !important;">例1int a;

const int &ra=a;

ra=1//错误

a=1//正确

2

string foo( );

void bar(string & s);

那么下面的表达式就是非法的:

bar(foo( ));

bar("hello world");

原因是 foo() 和“hello world”字符串都会生成一个临时对象,而在 C++ 中,这些临时对象是 const 类型。

所以上面的表达式试图将 const 类型的对象转换为非 const 类型,这是非法的。 如果引用参数可以定义为const,则应尽可能定义为const。

10. 使用“引用”作为函数的返回值类型时的格式、好处和要遵循的规则是什么?

格式:类型标识符&函数名(形参列表和类型描述){ //函数体}

好处:内存中没有返回值的副本; (注:正是因为这个原因,不建议返回局部变量的引用。因为随着局部变量的生命周期结束,相应的引用也会失效,产生错误!

防范措施:

(1) 无法返回对局部变量的引用。 本文可以参考C++[1]的Item 31。 主要原因是函数返回后局部变量会被销毁,因此返回的引用变成了“无”引用,程序会进入未知状态。

(2)不能返回函数内部new分配的内存的引用。 本文可以参考C++[1]的Item 31。 虽然不存在被动销毁局部变量的问题,但是对于这种情况(返回函数内部new分配的内存的引用),却面临着其他尴尬的情况。 例如,函数返回的引用只以临时变量的形式出现,而没有被分配实际的变量,那么该引用指向的空间(由new分配的)就无法释放,造成泄漏。

(3) 可以返回对类成员的引用,但最好是const。 这个原理可以参考C++[1]的Item 30。 主要原因是,当一个对象的属性与某个业务规则(规则)关联时,其赋值往往与该对象的一些其他属性或状态相关,因此需要将赋值操作封装在业务规则中。 如果其他对象可以获得对该属性的非常量引用(或指针),那么仅仅对该属性进行赋值就会破坏业务规则的完整性。

(4) 流运算符重载的返回值被声明为“引用”:

流运算符,这两个运算符常常被期望连续使用,例如:cout

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON