C++说爱你不容易面试题-5

常考面试题

  1. 析构函数必须为虚函数吗?构造函数可以为虚函数吗?⭐⭐⭐⭐⭐

    C++默认析构函数不是虚函数,因为申明虚函数会创建虚函数表,占用一定内存,当不存在继承的关系时,析构函数不需要申明为虚函数。

    若存在继承关系时,析构函数必须申明为虚函数,这样父类指针指向子类对象,释放基类指针时才会调用子类的析构函数释放资源,否则内存泄漏

    构造函数不能为虚函数,当申明一个函数为虚函数时,会创建虚函数表,那么这个函数的调用方式是通过虚函数表来调用。若构造函数为虚函数,说明调用方式是通过虚函数表调用,需要借助虚表指针,但是没构造对象,哪里来的虚表指针?但是没有虚表指针,怎么访问虚函数表从而调用构造函数呢?这就成了一个先有鸡还是先有蛋的问题。

  2. 当类存在继承的情况下,我们需要注意什么?⭐⭐⭐⭐⭐

    若存在继承关系时,析构函数必须申明为虚函数,这样父类指针指向子类对象,释放基类指针时才会调用子类的析构函数释放资源,否则内存泄漏

  3. 说说继承类型和访问属性⭐⭐⭐⭐

    当一个类派生自基类,该基类可以被继承为 public、protectedprivate 几种类型。

    我们几乎不使用 protectedprivate 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:

    • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有保护成员来访问。
    • 保护继承(protected): 当一个类派生自保护基类时,基类的公有保护成员将成为派生类的保护成员。
    • 私有继承(private):当一个类派生自私有基类时,基类的公有保护成员将成为派生类的私有成员。

    总结: 不管是哪种继承方式,派生类中新增成员可以访问基类的公有成员和保护成员,无法访问私有成员。但是只有公有继承中,派生类的对象能访问基类的公有成员。使用友元(friend)可以访问保护成员和私有成员。

    img
  4. 构造与析构的顺序⭐⭐⭐⭐⭐

    构造顺序:基类构造函数》对象成员构造函数》子类构造函数

    析构顺序:子类析构函数》对象成员析构函数》基类析构函数

    从里向外构造,从外向里析构

    答案解析

    我们给一个例子:

    #include <iostream>
    using namespace std;
    class A{
    public:
         A(){cout<<"A::constructor"<<endl;};
         ~A(){cout<<"A::deconstructor"<<endl;};
    };
    class B{
    public:
         B(){cout<<"B::constructor"<<endl;};
         ~B(){cout<<"B::deconstructor"<<endl;};
    };
    class C : public A{
    public:
         C(){cout<<"C::constructor"<<endl;};
         ~C(){cout<<"C::deconstructor"<<endl;};
    private:
    //    static B b;
         B b;
    };
    class D : public C{
    public:
         D(){cout<<"D::constructor"<<endl;};
         ~D(){cout<<"D::deconstructor"<<endl;};
    };
    
    int main(void){
        C* pd = new D();
        delete pd;
        return 0;
    }
    

    运行结果如下:

    A::constructor
    B::constructor
    C::constructor
    D::constructor
    C::deconstructor
    B::deconstructor
    A::deconstructor
  5. 请说说你对多态的理解⭐⭐⭐⭐⭐

    利用虚函数,基类指针指向基类对象时就使用基类的成员(包括成员函数和成员变量),指向派生类对象时就使用派生类的成员。

    换句话说,基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)

  6. 重载和重写的区别⭐⭐⭐⭐⭐

    1. 重载(overload)

      函数名相同,参数列表不同(参数类型、参数顺序),不能用返回值区分。

      特点:

      (1)作用域相同;

      (2)函数名相同;

      (3)参数列表必须不同,但返回值无要求;

      特殊情况:若某一重载版本的函数前面有virtual关键字修饰,则表示它是虚函数,但它也是重载的一个版本

      作用效果:编译器根据函数不同的参数列表,将函数与函数调用进行早绑定,重载与多态无关,与面向对象无关,它只是一种语言特性。

    2. 重写(override)

      派生类重定义基类的虚

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

<p> - 本专刊适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专刊适合于互联网C++软件开发、嵌入式软件求职的学生或人士。 - 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构等一系列知识点的讲解,并且最后总结出了高频面试考点(附有答案)共近400道,知识点讲解全面。不仅如此,教程还讲解了简历制作、笔试面试准备、面试技巧等内容。 </p> <p> <br /> </p>

全部评论
C* pd = new D(); 4.构造与析构的顺序中,为什么可以定义类型D而接收它的指针是类型C
1 回复 分享
发布于 2021-04-26 15:05
感觉6说的重载与多态无关,和16说的重载是编译期间的多态,有点冲突。其实意思是重载也可以看作是多态在编译期间的表现?感觉可以明确一下多态的定义,要不要把重载的多态纳入进来
点赞 回复 分享
发布于 2023-10-28 21:10 北京
第七个不准确哦,在g++中是这样没错。 但是在VC++中,如果派生类虚继承基类的话,当自己定义新的虚函数的时候,VC++为了防止获取虚函数表时转换到虚基类的巨大开销,这时候他会有一个自己的虚函数指针。还有就是多继承的情况下,如果每个基类都有自己的虚函数,这时候也会导致派生类不止一个虚函数指针。
点赞 回复 分享
发布于 2022-08-22 23:34 江苏

相关推荐

05-30 12:03
山西大学 C++
offer来了我跪着...:不是骗子,等到测评那一步就知道为啥这么高工资了
点赞 评论 收藏
分享
06-07 12:20
新余学院 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-11 12:31
以前小时候我最痛恨出轨、偷情的人,无论男女,为什么会出轨?现在我成了自己最讨厌的人,没想到分享的东西在牛客会被这么多人看,大家的评价都很中肯,我也认同,想过一一回复,但我还是收声了,我想我应该说说这件事,这件事一直压在我心里,是个很大的心结,上面说了人为什么出轨,我大概能明白了。我们大一下半年开始恋爱,开始恋爱,我给出了我铭记3年的承诺,我对她好一辈子,我永远不会背叛,我责任心太重,我觉得跟了我,我就要照顾她一辈子,我们在一起3年我都没有碰过她,她说往东我就往东,她说什么我做什么,她要我干什么,我就干什么!在学校很美好,中途也出过一些小插曲,比如男闺蜜、男闺蜜2号等等等。但我都强迫她改掉了,我...
牛客刘北:两个缺爱的人是没有办法好好在一起的,但世界上哪有什么是非对错?你后悔你们在一起了,但是刚刚在一起的美好也是真的呀,因为其他人的出现,你开始想要了最开始的自己,你的确对不起自己,21岁的你望高物远,你完全可以不谈恋爱,去过你想要的生活,你向往自由,在一起之后,你要想的不是一个人,而是两个人,你不是变心了,就像你说的,你受够了,你不想包容了,冷静几天是你最优的选择,爱人先爱己。
社会教会你的第一课
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务