zoukankan      html  css  js  c++  java
  • C++面试题

    1、引用和指针的区别

      1)引用被创建的时候需要初始化,指针可以等到任何时候再初始化

      2)引用不能指向NULL,指针可以指向NULL

      3) 引用被初始化后,不能再绑定到其它对象,而指针初始化后,可以改变他指向的对象

      对于第3条的理解:

              int m=90;

              int &n=m;

              int b=99;

              n=b;

              b=999;

              cout<<n<<endl;//结果是99而不是999,因为引用n第二次并没有绑定到b上

     2、面向对象的特征

      封装、继承、多态

      封装:增强安全性和简化编程,使用者不需要了解具体的实现细节,而只要通过外部借口和特定的访问权限来使用类的成员

      继承:可以使用现有类的所有功能,继承可以使一个对象直接使用另外一个对象的属性和方法

      多态:使得能够利用基类指针指向不同类的对象,根据所引用对象的不同,以不同方式执行相同的操作

     3、C++三种继承方式

      public继承:基类成员保持自己的访问权限,public在子类中仍是public,proctected在子类仍是protected,基类private成员在子类中不可见

      protect继承:基类成员中的public和protected成员都变成protected成员,基类private成员在子类中不可见

      private继承:基类成员中的public和protected成员都变成private,基类private成员在子类中不可见

     4、class和struct的区别

      class默认是private,struct默认是public

       5、多态

      多态简单描述:一个接口,多种实现

      主要作用:提高程序的可复用性,精简了代码的编写量

     6、重载,覆盖(重写),隐藏

        比较好的解释来源:http://blog.csdn.net/kendiv/article/details/675940

       重载:相同的函数名,不同的参数类型(不同的参数类型,不同的参数个数,不同的参数顺序【参数类型必须不一样】),不能呢个通过访问权限,返回类型,抛出异常进行重载

       覆盖(重写):基类有virtual关键字,派生类和基类的函数名相同,参数类型相同,返回类型也要一样

         隐藏:a)如果派生类和基类的函数名和参数类型都相同,但是基类没有virtual关键字,此时基类的函数被隐藏 b)如果派生类的函数和基类的函数函数名相同,但是参数类型不同,此时不论    

        基类是否有virtual 关键字,基类的函数都被隐藏。========对于隐藏的另外理解就是,除了函数名相同,不满足覆盖的条件就是隐藏。

      7、复制构造函数和赋值运算符

        复制构造函数 A(const A &a)

        赋值运算符 A& operator=(const A& a)

        赋值运算函数的编写需要注意的事项:a)是否把返回类型声明为该类型的引用,如果返回类型是void就不能连续赋值,如str1=str2=str3,在函数的末尾返回*this

         b)是否把传入的参数声明为常量引用,如果传入的参数不是引用而是实例,会调用一次复制构造函数,这样做是为了提高代码效率。同时为了不改变传入的实例的状态,加上const关键字

        c)是否释放已有的内存,如果没有释放已有的内存,将会造成内存泄漏

        d)是否判断传入的参数和实例的*this是同一个实例,如果不判断,释放自身内存后,传入参数的内存也就被释放掉了,就找不到赋值的内容

        CMyString& CMyString::operator=(const CMyString &str)

      {

         if(this==&str)

            return *this;

        delete []m_pData;

        m_pData=NULL;

        m_pData=new char[strlen(str.m_pData)+1];

        strcpy(m_pData,str.m_pData)

        return *this;

      } 

         但是如果new失败,分配内存失败,上面代码没有处理,来看下面的代码

    CMyString& CMyString::operator=(const CMyString &str)

      {

         if(this!=&str)

      {

           CMyString strTemp(str);

         char *pTemp=strTemp.m_pData;

         strTemp.m_pData=m_pData;

        m_pData=pTemp;

      }

        return *this;

      }

        定义了一个局部变量strTemp,然后将原来的内存和新定义的局部变量strTemp交换,这样出了if的时候,将会自动调用strTemp的析构函数,也就将以前的内存释放掉了

      复制构造函数的调用时期: 1)用一个已有的对象初始化新对象的时候 A(object B), 2)当对象以值传递的方式传入到函数中 3)当变量以值的方式从函数中返回

         B b1(b2)和B b1=b2是一样的,也就是声明变量的时候,调用的是复制构造函数,而赋值运算符是两个对象都存在的时候=才调用赋值运算符。

     

  • 相关阅读:
    排序算法的实现(冒泡,选择,插入 O(N*N)--理解方法实现
    HTTPS工作原理和TCP握手机制
    HTTP协议学习
    IP头,TCP头,UDP头,MAC帧头定义
    单链表的实现
    数字图像处理------中值滤波
    对于矩阵的理解-- by 孟岩老师
    java编码问题总结
    jsp数据库连接大全和数据库操作封装到Javabean
    构建一个高可扩展性javabean和jsp连接数据库操作
  • 原文地址:https://www.cnblogs.com/wuxiangli/p/5617971.html
Copyright © 2011-2022 走看看