• C++面试笔记--面向对象


    说到面向对象,大家第一反应应该就是它的三大特性:封装性、继承性和多态性。那么我们先简单的了解一下这三大特性:

         (1)封装性:封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

    在C++中类中成员的属性有:public, protected, private,这三个属性的访问权限依次降低。

         (2)继承性:继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

         (3)多态性:多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。实现多态,有二种方式,覆盖,重载。

    覆盖,是指子类重新定义父类的虚函数的做法。

    重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

    • 1、C++中空类默认产生哪些类成员函数?

      答案:

      对于一个空类,编译器默认产生4个成员函数:

      (1)默认构造函数

      (2)析构函数

      (3)拷贝构造函数

      (4)赋值函数

    • 2、结构是否可以有构造函数、析构函数及成员函数?如果可以,那么结构和类还有什么区别吗?

      答案:

      区别是class中变量默认是private,struct中的变量默认是public。class继承默认是private继承,而struct继承默认是public继承。struct可以有构造函数、析构函数,之间也可以继承甚至是多重继承,等等。C++中的struct其实和class意义一样,唯一不同就是struct里面默认的访问控制是public,class中默认访问控制是private。C++中存在struct关键字的唯一意义就是为了让C程序员有个归属感,是为了让C++编译器兼容以前用C开发的项目。

      下面我们写一段struct中继承的例子。

       1 #include<iostream>
       2 using namespace std;
       3 enum Bread{Golden,Cairn,Dandie,SheTland,Lab};
       4 
       5 struct mannal{
       6 public:
       7     mannal():itsAge(2),itsWeight(5){}
       8     ~mannal(){}
       9 
      10     int getage()const {return itsAge;}
      11     void setage(int age){itsAge=age;}
      12     int getweight()const {return itsWeight;}
      13     void setweight(int weight){itsWeight=weight;}
      14 
      15     void speak()const{cout<<"mannal sound!"<<endl;}
      16     void sleep()const {cout<<"sleeping!"<<endl;}
      17 
      18 protected:
      19     int itsAge;
      20     int itsWeight;
      21 };
      22 struct dog:public mannal{
      23 private:
      24     Bread itebread;
      25 
      26 public:
      27     dog():itebread(Golden){}
      28     ~dog(){}
      29     Bread getbread()const {return itebread;}
      30     void getbread(Bread bread){itebread=bread;}
      31     void wagtail()const {cout<<"wagging!"<<endl;}
      32     void begforfood()const{cout<<"food!"<<endl;}
      33 
      34 };
      35 int main(){
      36     dog fido;
      37     fido.speak();
      38     fido.wagtail();
      39     cout<<"fiod is  "<<fido.getage()<<"years old!"<<endl;
      40     return 0;
      41 }
    • 3、下面程序哪个语句是错的?

      struct test{
          test(int){}
          test(){}
          void fun(){}
      };
      int main()
      {
          test a(1);//语句一
          test b();//语句二
          a.fun();//
          b.fun();////答案选四,因为test b(),这个声明了一个函数,然而本意是想创建一个对象b,但是这个声明函数的错误在编译的时候是检测不出来的,所以就调用不了fun,所以四错误。
          
      }
    • 4、下面程序打印出的结果是什么?
      #include<iostream>
      using namespace std;
      class base
      {
      private:
          int m_i;
          int m_j;
      public:
          base( int i ) : m_j(i),m_i(m_j) {
          base() : m_j(0),m_i(m_j){}
          int get_i() {return m_i;}
         int get_j() {return m_j;}
      };
      int main ()
      {
          base obj(98);
          cout << obj.get_i() <<endl<< obj.get_j() <<endl;
          return 0;
      }

      解析:本题想得到的结果是“98,98”。但是成员变量的声明是先 m_i ,然后是 m_j;初始化列表的初始化变量顺序是根据成员变量的声明顺序来执行的,因此,先初始化 m_i,但此时 m_j 还未初始化,m_i 会被赋予一个随机值。改变一下成员变量的声明顺序可以得到预想的结果。

      答案:

      输出结果第一个为随机数,第二个是98。

    • 5、析构函数可以为 virtual 型,构造函数则不能,为什么?

      答案:

      虚函数采用一种虚调用的办法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,你势必要知道对象的准确类型,因此构造函数不能为 virtual。

      6、如果虚函数是非常有效的,我们是否可以把每个函数都声明为虚函数?

      答案:

      不行,这是因为虚函数是有代价的:由于每个虚函数的对象都必须维护一个 v 表,因此在使用虚函数的时候会产生一个系统开销。如果仅是一个很小的类,且不行派生其他类,那么根本没必要使用虚函数。

    • 6、哪一种成员变量可以在同一类的实例间共享?

      答案:

      必须使用静态成员变量在一个类的所有实例间共享数据。如果想限制对静态成员变量的访问,必须把它们声明为保护型或私有型。不允许用静态成员去存放某一个对象的数据。静态成员函数是在这个类的所有对象间共享的。如果静态成员数据设为私有的,可以通过共有静态和产能原函数访问。

    • 7、编写类 String 的构造函数、析构函数和赋值函数。

         

      #include<iostream>
      using namespace std;
      class string{
         string(const char *str);
         string(const string &);
         ~string();
         string &operator=(const string &) ;
         private:
             char *m_data;
      };
      
      string::~string(){//析构函数
          delete []m_data;
      }
      string::string(const char *str){//构造函数,利用复制操作进行。
          if(NULL==str){
              m_data=new char[1];
              *m_data='';
          }
          else{
              int length=strlen(str);
              m_data=new char [length+1];
              strcpy(m_data,str);
          }
      }
      string::string(const string & a){
          int lenght=strlen(a.m_data);
          m_data=new char[length+1];
          strcpy(m_data,a,m_data);
      }
      string & string::operator=(const string &a){
          if(this==&other){//检查自赋值
              return *this;
          }
          delete []m_data;//释放原有的内存资源。
          int length=strlen(a.m_data);//分配新内存资源,并复制内容
          m_data=new char[length+1];
          strcpy(m_data,a.m_data);
          return *this;
      }
    • 8、重载与覆盖有什么不同?

      答案:

           虚函数总是在派生类中被改写,这种改写被称为“override”(覆盖)。

           override 是指派生类重写基类的虚函数,重写的函数必须有一致的参数表和返回值。Override这个单词好像一直没什么合适的中文词汇来对应。有些人译为“覆盖”,还贴切一些。

           overload约定成俗地被翻译为“重载”,是指编写一个与自己已有函数同名但是参数表不同的函数。例如一个函数既可以接受整型数作为参数,也可以接收浮点数作为参数。重载不是一种面向对象的编程,而是一种语法规则,重载与多态没什么直接关系。

    • 9、为什么析构函数可以是virtual,但是构造函数不行呢?

      答案:

      虚函数采用的是一种虚调用的方法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道借口而不知道准确对象类型的函数,但是如果要创建一个对象你势必要知道对象的准确类型,因此构造函数不能为虚。

    • 10、友元函数去实现两个点之间的距离,写一个poiny类

      答案:

       1 #include<iostream>
       2 using namespace std;
       3 class point{
       4 private:
       5     double x,y;
       6 public:
       7     point(double a=0.0,double b=0.0):x(a,b){}
       8     friend double distance(point &left,point &right){}
       9 };
      10 double distance(point &left,point &right){
      11     return ((left.x-right.x)^2+(left.y-right.y)^2)^0.5;
      12 }
    • 11、最好不要从析构函数中抛出异常!!!,构造函数中可以抛出异常,虚方法中也是可以抛出异常的。

      答案:

  • 相关阅读:

    字符串比较
    String对象的简单方法(特别讲解length()方法的实现。
    Character类
    线性结构应用实例:多项式加法运算
    队列的顺序和链式存储实现
    堆栈用数组和用链表实现
    广义表和多重链表(十字链表)
    powerDesigner的name和comment转化
    jquery-validate
  • 原文地址:https://www.cnblogs.com/Kobe10/p/5562936.html
Copyright © 2020-2023  润新知