首页 > 试题广场 >

编译运行后,程序输出结果是:

[单选题]
对下面的程序段
#include<bits/stdc++.h>
using namespace std;
class CA
{
public:
    virtual void f1()
    {
        cout<<"CA::f1( )"<<endl;
        f2();
    }
    void f2()
    {
        cout<<"CA::f2( )"<<endl;
    }
};
class CB : public CA
{
public:
    void f1()
    {
        cout<<"CB::f1( )"<<endl;
        f2();
    }
    void f2()
    {
    cout<<"CB::f2( )"<<endl;
    }
};
class CC:public CB
{
public:
    virtual void f2()
    {
        cout<<"CC:f2()"<<endl;
    }
};
int main()
{
    CC c;
    CA *pA = &c ;
    pA->f1();
    return 0;
}





编译运行后,程序输出结果是()

  • CB::f1() CC::f2()
  • CB::f1() CB::f2()
  • CB::f1() CA::f2()
  • CA::f1() CC::f2()
答案是B。
CA* pa = &c;这句话是父类指针指向子类对象,调用pa->f1()时,因为父类中的f1()是虚函数,所以将发生动态绑定,调用子类CB中的f1()函数,先输出CB::f1()
在CB类的f1()函数中,调用非虚函数f2(),但因为其父类CA中的f2()函数并不是virtual函数,所以将调用CB类中的f2()函数,输出CB::f2()。如果将CA类中的f2()改成虚函数,那么将输出CC::f2();如果将CB类中的f2()改成虚函数,也将输出CC::f2(),这是满足动态绑定的。
发表于 2017-01-19 09:01:39 回复(6)
在虚函数CB::f1()中调用非虚函数一定是调用CB类的函数,因为this指针是属于CB类的,调用f2非虚函数时,把CB类的this指针传入第一个参数,所以调用的是CB::f2();
发表于 2017-01-23 07:57:03 回复(2)
CA* pa = &c;这句话是父类指针指向子类对象,所以产生动态绑定,调用pa->f1()时,因为pa是CC类对象c的指针,所以优先调用CC类的f1()函数,因为CC类中没有f1()函数,所以调用父类的f1(),先输出CB::f1();f1()中调用f2()函数,因为CB类中的f2()函数与其父类CA类中的f2()函数同名且参数也相同,且CA中f2()函数不是virtual修饰的虚函数,所以CA中的f2()会被CB中的f2()函数隐藏(如果CA中f2()有virtual,则是重写或者覆盖)所以会输出CB::f2()。
发表于 2018-08-08 13:09:33 回复(2)
父类CA指针指向子类CC对象,则指针访问的是类CC的虚函数表,子类CC的虚函数表函数指针是CB::f1() ,CC::f2();CA的父类中已经隐式声明f1()为虚函数(父类声明为虚函数后,子类中同名同参函数也默认为虚函数,即使没有virtual关键字);同样的似乎也应该输出CCf2(),BUT!编译器可不是这么认为的,因为CC类从CB继承来了实函数f2(),编译器将直接静态绑定f2()实函数,而不会有执行时的动态绑定,所以输出的是CB::f2()。这种父实子虚的写法,个人认为实际工作中,不能写出这种继承关系,这违背了多态实现的一般规律父虚子实。 ==欢迎大家一起谈论学习。
编辑于 2019-12-28 10:36:28 回复(0)
此题考查虚函数的继承:
        虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联。
        因此会输出CB::f1
         紧接着,在CB类的f1()中,调用非虚函数f2(),但因为其父类CA中的f2()函数并不是虚函数,因此将调用CB类中的f2()函数,输出CB::f2()
发表于 2021-05-06 10:22:03 回复(0)
虚函数动态绑定,上行转换
发表于 2019-11-01 16:27:48 回复(0)
我说下我的理解,可能不大正确。首先CC中的f2因为声明为了虚函数,而父类中的f2为普通函数,所以此种情况构不成重写条件,即父类的f2在子类中是不可见的。又由于使用了基类指针指向子类对象,所以还是可以通过虚函数表找到原父类的方法f2。 执行过程如下,运行过程中发现是CC类对象,所以会访问CC类的虚函数表,表中f1方法已被CB类重写,所以f1方法所在的表项实则指向CB的f1方法,因为f1调用的f2方法是基于CB类的虚函数表进行的,而CC类并没有对该函数进行重写,CC类只是在表中另一个偏移量位置重新定义了新的方法,屏蔽了原f2。但通过cb类的虚函数还是可以访问到原f2的。
发表于 2017-11-15 21:10:10 回复(0)
评论里很多问为什么不调用CA::f2的,我说一下我的见解,还望各位指正。 题目中CA类和CB类中的f2函数都不是虚函数,因此下面讨论的是普通函数。 跑了一下代码,我发现pA->f2()调用的就是CA中的f2。 所以我的理解是,对于一个类成员函数中所调用的普通函数(不是虚函数),由于隐藏特性,他所调用的是本类的成员函数。而如果用指针来调用普通函数,所调用的函数取决于这个指针类型,用基类指针调用的就是基类函数,用派生类指针调用的就是派生类成员函数。(注意以上说的成员函数都不是虚函数)
发表于 2023-03-26 11:41:51 回复(0)
为什么不是CA::f2
发表于 2020-11-15 10:57:17 回复(1)
考察的是函数隐藏,派生类中调用f2是调用自己的函数
发表于 2022-10-01 18:35:46 回复(0)
虚函数是继承的,父类定义的虚函数,在子类中也为虚函数。而子类才定义的虚函数,并不能反过来让父类函数成为虚函数,只能让孙子类继承为虚函数。
发表于 2022-06-27 18:12:33 回复(0)
记住下面的原则:    1) 当一个对象调用一个非虚函数时, 与对象的声明类型绑定的, 并不是与实际的对象的类型绑定的。    2)在虚函数中调用非虚函数的时候, 调用的非虚函数是与虚函数所在的类是一致的   3) 在非虚函数中调用虚函数的时候, 调用的虚函数是与对像的实际类一致的。  
发表于 2021-09-28 22:10:37 回复(0)
总之是考察动态绑定时,派生类的同名函数对基类中虚函数和非虚函数覆盖与否。
发表于 2021-03-09 19:24:50 回复(0)
当子类重新定义了父类的虚函数后,当父类的指针指向子类对象的地址时,[即B b; A a = &b;] 父类指针根据赋给它的不同子类指针,动态的调用子类的该函数,而不是父类的函数(如果不使用virtual方法,请看后面★*),且这样的函数调用发生在运行阶段,而不是发生在编译阶段,称为动态联编。而函数的重载可以认为是多态,只不过是静态的。注意,非虚函数静态联编,效率要比虚函数高,但是不具备动态联编能力。
★如果使用了virtual关键字,程序将根据引用或指针指向的 对 象 类 型 来选择方法,否则使用引用类型或指针类型来选择方法。
发表于 2020-08-10 21:39:21 回复(0)
CB中的 f1()执行时会输出CB::f1(),还会执行f2().问题是这个f()具体指的是哪个f2(),由于指针指的是CC,是优先执行CC里的f2()还是优先执行CB里的f2()
发表于 2020-02-28 17:22:54 回复(0)
#include <iostream>
#include <stdio.h>
using namespace std;

class CA
{
  public:     virtual void f1()     {       cout << "CA::f1()" << endl;       f2();     }     void f2()     {       cout << "CA::f2()" <<endl;     }
};

class CB:public CA
{
  public:     void f1()     {       cout << "CB::f1()" << endl;       f2();     }     void f2()     {       cout << "CB::f2()" <<endl;     }
};

class CC:public CB
{
  public:     virtual void f2()     {       cout << "CC:f2()" << endl;     }
};

int main()
{
  CC c;
  CA *pA = &c;
  pA->f1();
  return 0;
}
输出:
CB::f1()
CB::f2()
发表于 2019-07-12 19:45:53 回复(0)
virtual是函数签名的一部分。
发表于 2019-05-13 12:37:38 回复(0)
class B中的f2并没有定义为虚函数,所以只会调到b中的f2
发表于 2018-02-11 07:43:54 回复(0)
A中的f2()不是虚函数
发表于 2017-07-26 00:50:18 回复(0)