IT评测·应用市场-qidao123.com

标题: 《C++知识梳理及常见面试题》 [打印本页]

作者: 大连全瓷种植牙齿制作中心    时间: 2025-3-17 09:36
标题: 《C++知识梳理及常见面试题》
缺省参数

全缺省、半缺省
   
  函数重载

同一作用域的功能类似同名函数,同名函数的参数差异(参数个数、类型、类型次序)。
为什么C语言不支持函数重载而C++支持函数重载?
   C/C++程序运行起来,要颠末:预处置惩罚(.i)、编译(.s)、汇编(.o)、链接。
   
  引用

给变量取别名,与引用的变量共用一块内存空间,引用类型和引用变量类型相同。
   
  
  1. const int c = 1;
  2. //int& rc = c;//error
  3. const int& rc = c;
复制代码
  1. int& Add(int a, int b) {
  2.    int c = a + b;
  3.    return c; }
  4. int main()
  5. {
  6.    int& ret = Add(1, 2);
  7.    Add(3, 4);
  8.    cout << "Add(1, 2) is :"<< ret <<endl;//返回一个已经销毁的局部变量的引用会导致未定义行为,因为引用指向的内存已经无效。
  9.    return 0; }
复制代码
如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用 引用返回,如果已经还给系统了,则必须使用传值返回。
   传值和传引用的服从比较        
    引用和指针的差异

          内联函数

以inline修饰,一种特殊的函数,在编译时,编译器会实验将内联函数的函数体代码直接插入到调用该函数的地方,而不是像普通函数那样举行函数调用的跳转操纵。如许可以淘汰函数调用的开销(生存恢复寄存器、参数传递),进步程序的执行服从。
   
  面试题:宏的优缺点?

优点:
   1.增强代码的复用性。
  2.进步性能。
  缺点:
   1.不方便调试宏。(因为预编译阶段举行了替换)
  2.导致代码可读性差,可维护性差,轻易误用。
  3.没有类型安全的检查 。
  C++有哪些技术替代宏
     auto(C++11)

        使用auto界说变量时必须对其举行初始化,在编译阶段编译器需要根据初始化表达式来推导auto 的现实类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量现实的类型。      
    C++实现封装的方式

          在C++语言中实现封装,可以通过类将数据以及操纵数据的方法举行有机结合,通过访问权限来 隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。class的默认访问权限为private,struct为public(因为struct要兼容C)访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
         面试题:C++struct和class的区别

   解答:C++需要兼容C语言,所以C++中struct可以当成布局体使用。另外C++中struct还可以用来界说类。和class界说类是一样的,区别是struct界说的类默认访问权限是public,class界说的类默认访问权限是private。
  面试题:面向对象的三大特性

      封装、继承、多态。       封装:将数据和操纵数据的方法举行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象举行交互。封装本质上是一种管理,让用户更方便使用类
    类对象的大小

      一个类的大小,现实就是该类中”成员变量”之和,固然要留意内存对齐。
   留意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。
       面试题:布局体内存对齐

   布局体内存对齐规则
                   1. 平台缘故原由(移植缘故原由)
   不是所有的硬件平台都能访问恣意地点上的恣意数据的,某些硬件平台只能在某些地点处取某些特
   2. 性能缘故原由
   数据布局(尤其是栈)应该尽可能地在自然边界上对齐。缘故原由在于,为了访问未对齐的内存,处置惩罚器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
   
  面试题:怎样让布局体按照指定的对齐参数举行对齐?

  能否按照3、4、5即恣意字节对齐?
     能。pragma pack(4);//设置默认对齐数 pragma pack();//恢复默认对齐数。虽然理论上有些编译器可能支持指定 3 或 5 字节对齐,但并不是所有编译器都能保证支持。因为在现实的硬件架构中,对齐通常是按照 2 的幂次方举行优化的,如许可以进步内存访问的服从。在 GCC 编译器中,#pragma pack主要支持 2 的幂次方值(如 1、2、4、8、16 等),对于非 2 的幂次方值(如 3、5),可能无法正常工作或者产生未界说举动。
    联合

  联合也是一种特殊的自界说类型这种类型界说的变量也包罗一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
              联合的大小至少是最大成员的大小。              当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。            
  面试题:什么是大小端?怎样测试某台机器是大端照旧小端,有没有遇到过要思量大小端的场景。

  在计算机系统中,数据通常以字节为单位存储。对于多字节的数据类型(如 int、long 等),它们由多个字节组成,这些字节在内存中的存储次序有两种方式,即大端字节序(Big - Endian)和小端字节序(Little - Endian)。
也称为大端序或大端模式,在大端字节序中,数据的高位字节存放在内存的低地点处,低位字节存放在内存的高地点处。这就犹如我们誊写数字一样,高位在前,低位在后。比方,对于一个 4 字节的整数 0x12345678,在大端字节序的内存中存储如下。
   
  也称为小端序或小端模式,在小端字节序中,数据的低位字节存放在内存的低地点处,高位字节存放在内存的高地点处。对于上述 4 字节的整数 0x12345678,在小端字节序的内存中存储如下:
   
  

  使用指针
  1. // 测试机器大小端的函数
  2. int check_endian_pointer() {
  3.     int num = 1;
  4.     char *ptr = (char *)&num;
  5.     // 如果低地址存储的是 1,说明是小端序
  6.     return (*ptr == 1);
  7. }
复制代码
   使用联合体   
  1. // 测试机器大小端的函数
  2. int check_endian() {
  3.     union {
  4.         int i;
  5.         char c;
  6.     } un;
  7.     un.i = 1;
  8.     // 如果低地址存储的是 1,说明是小端序
  9.     return (un.c == 1);
  10. }
复制代码
this指针

         面试题:this指针存在那里?

   (也就是存在进程地点空间的哪个区域?)
     答:栈上的,因为他是一个形参。(ps:vs下是在ecx这个寄存器来传递)
      this指针可以为空吗?   
  1. class A
  2. {
  3. public:
  4.    void PrintA()
  5.   {
  6.        cout<<_a<<endl;
  7.         //cout<<"PrintA()"<<endl;
  8.   }
  9. private:
  10. int _a;
  11. };
  12. int main()
  13. {
  14.    A* p = nullptr;
  15.    p->PrintA();
  16.    return 0; }
复制代码
当成员函数不访问成员变量时,this指针可以为空;当成员函数访问成员变量时,this指针不能为空,访问成员变量是,this->_a会解引用空指针,导致未界说举动,引发程序崩溃。
  默认成员函数

   用户没有表现实现,编译器会生成的成员函数。   
  构造函数

      编译器默认生成的默认的构造函数(无参构造函数),对内置类型没什么用,会对自界说类型成员,调用它的默认成员函数。              无参、全缺省、不写编译器默认生成的(无参)都是默认构造函数,默认构造函数只能有一个。    析构函数

             拷贝构造函数

  只有单个形参,该形参是对本类类型对象的引用(一样平常常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
              若未显式界说,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
      
                     留意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请              时,则拷贝构造函数是一定要写的,否则就是浅拷贝。            运算符重载

         C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数                                      
  1.  bool operator==(const Date& d2)
  2. {
  3.        return _year == d2._year;
  4.            && _month == d2._month
  5.            && _day == d2._day;
  6. }
复制代码
     赋值运算符重载

                        
  1. Date& operator=(const Date& d)
  2. {
  3. if(this != &d)
  4.       {
  5.            _year = d._year;
  6.            _month = d._month;
  7.            _day = d._day;
  8.       }
  9.        
  10.        return *this;
  11. }
复制代码
    赋值运算符只能重载成类的成员函数不能重载成全局函数
         
  1. // 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
  2. Date& operator=(Date& left, const Date& right) {
  3. if (&left != &right)
  4. {
  5. left._year = right._year;
  6. left._month = right._month;
  7. left._day = right._day;
  8. }
  9. return left; }
  10. // 编译失败:
  11. // error C2801: “operator =”必须是非静态成员
复制代码
            缘故原由:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。
                              用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注              意:内置类型成员变量是直接赋值的,而自界说类型成员变量需要调用对应类的赋值运算符              重载完成赋值。                       既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实              现吗?                           留意:如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。
              
         前置++和后置++重载

      
  1. // 前置++:返回+1之后的结果
  2. // 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
  3. Date& operator++()
  4. {
  5. _day += 1;
  6. return *this;
  7. }
  8. // 后置++:
  9. // 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
  10. // C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器
  11. 自动传递
  12. // 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存
  13. 一份,然后给this+1
  14. //       而temp是临时对象,因此只能以值的方式返回,不能返回引用
  15. Date operator++(int)
  16. {
  17. Date temp(*this);
  18. _day += 1;
  19. return temp;
  20. }
复制代码
   取地点及const取地点操纵符重载

    这两个默认成员函数一样寻常不消重新界说 ,编译器默认会生成初始化列表。
                      类中包罗以下成员,必须放在初始化列表位置举行初始化:            
                自界说类型成员(且该类没有默认构造函数时成员变量在类中声明次序就是其在初始化列表中的初始化次序,与其在初始化列表中的先后次序无关。                      explicit关键字

    构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值别的均有默认值 的构造函数,还具有类型转换的作用。
        
  1. // 隐式类型转换:将 int 类型的值 10 转换为 MyClass 类型的对象
  2.     MyClass obj2 = 10;
  3.     obj2.printData();
复制代码
           用explicit修饰构造函数,将会克制构造函数的隐式转换
static

        
    面试题:实现一个类,计算程序中创建出了多少个类对象

  
  1. class A
  2. {
  3. public:
  4.     A()
  5.     {
  6.         ++_scount;
  7.     }
  8.     A(const A& t)
  9.     {
  10.         ++_scount;
  11.     }
  12.     ~A()
  13.     {
  14.         --_scount;
  15.     }
  16.     int getadd()
  17.     {
  18.         return _scount;
  19.     }
  20.     static int GetACount()
  21.         // 静态成员函数可以直接访问静态成员变量,而不需要通过对象来访问。
  22.         // 静态成员函数不与任何对象绑定,它没有隐含的 this 指针。
  23.         // 这意味着调用静态成员函数时不需要创建类的对象,可以直接通过类名来调用
  24.     {
  25.         return _scount;
  26.     }
  27. private:
  28.     static int _scount;
  29. };
  30. int A::_scount = 0;
  31. void TestA()
  32. {
  33.     cout << A::GetACount() << endl;
  34.     A a1, a2;
  35.     A a3(a1);
  36.     cout << A::GetACount() << endl;
  37. }
  38. int main()
  39. {
  40.     TestA();
  41.     return 0;
  42. }
复制代码
面试题:静态成员函数可以调用非静态成员函数吗?

     
    如果静态成员函数确实需要调用非静态成员函数,需要通过传递对象指针或引用的方式来实现。示比方下:
   
  1. #include <iostream>
  2. class MyClass {
  3. public:
  4.     static void staticFunc(MyClass& obj) {
  5.         obj.nonStaticFunc();
  6.     }
  7.     void nonStaticFunc() {
  8.         std::cout << "Non-static function called." << std::endl;
  9.     }
  10. };
  11. int main() {
  12.     MyClass obj;
  13.     MyClass::staticFunc(obj);
  14.     return 0;
  15. }
复制代码
  非静态成员函数可以调用类的静态成员函数吗?
      非静态成员函数可以直接使用类名或者省略类名来调用静态成员函数。静态成员函数属于整个类,而不是某个具体的对象实例。它不依靠于任何对象,没有隐含的 this 指针。
   面试题:sizeof与strlen

   
           malloc/free和new/delete的区别

                      malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。差异的地方是:             
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4