首页 > 试题广场 >

下面程序执行结果是?

[单选题]
下面程序执行结果:
using namespace std; 
class A{ 
    public: 
        virtual void f() { cout << "A::f() "; } 
        void f() const { cout << "A::f() const "; } 
}; 
class B : public A { 
    public: 
        void f() { cout << "B::f() "; } 
        void f() const { cout << "B::f() const "; } 
}; 
void g(const A* a) { 
    a->f(); 
} 
int main(int argc, char *argv[]) { 
    A* p = new B(); 
    p->f(); 
    g(p); 
    delete(p); 
    return 0; 
}
  • B::f() B::f() const
  • B::f() A::f() const
  • A::f() B::f() const
  • A::f() A::f() const
推荐
答案 B
解释
g(p); 执行的是父类的f() const ,因为他不是虚函数

编辑于 2015-02-09 16:29:14 回复(0)
常量指针指向常量对象,常量对象只能调用常成员函数。
发表于 2017-08-06 15:51:38 回复(0)
动态绑定问题,基类的指针与虚函数
const作用符,作用于const对象
发表于 2017-03-04 20:34:13 回复(0)
p->f()调用 void f() { cout << "B::f() "; };
g(p)->调用void g(const A* a) { a->f();} ,
在调用父类的voidf() const;

发表于 2016-04-02 14:39:08 回复(0)
常量指针指向常对象, 常对象只能调用其常成员函数,因此通过g(const A* a)调用的是void f() const;

发表于 2015-06-27 19:05:44 回复(2)
由于f()在基类中声明为虚的,则p->f()根据对象类型(B)调用B::f(),此时编译器对虚方法使用动态联编,输出B::f()。
由于f() const在基类中未声明为虚的,故p->f() const 根据指针类型(A)调用A::f() const,此时编译器对非虚方法使用静态联编,输出A::f() const。
发表于 2016-09-21 17:16:10 回复(0)
该问题包含两个关键点:(1)基类指针指向派生类的问题;(2)const相关
当基类指针指针指向派生类:a. 如果调用的成员函数在基类中定义为虚函数,在派生类中重写了(函数覆盖),则该成员函数指的是派生类中的;b. 相反如果未在基类中定义成为虚函数,则调用的函数其实是基类中的。

函数覆盖(多态)的条件:

  • 1: 基类中的成员函数被virtual关键字声明为虚函数;
  • 2:派生类中该函数必须和基类中函数的名称、参数类型和个数等完全一致;
  • 3:将派生类的对象赋给基类指针或者引用,实现多态。
至于const, 加了const的成员函数可以被非const对象和const对象调用     但不加const的成员函数只能被非const对象调用


发表于 2020-10-28 10:58:27 回复(3)
(1)当基类函数为虚函数时,派生类重写此虚函数可以不加virtual,所以对于p->f(); 基类指针指向派生类,函数f()在基类和派生类皆为虚,故动态编联指向派生类;
(2)第二部分实际是 const A* a = new B(); 本质还是基类指针指向派生类,并且由于a为常指针,只能指向常函数,所以肯定是调用f() const;具体调用基类还是派生类中的f() const;呢?由于此const函数在基类和派生类中都不是虚函数,所以采用静态编联,调用基类的f() const;
发表于 2020-07-04 00:02:49 回复(0)
虚函数和非虚函数同名了,怎么判断调用哪个
发表于 2017-04-27 15:16:22 回复(2)
没有常属性的对象可以调用常成员函数,也能够调用普通成员函数,但会优先调用普通成员函数
发表于 2018-05-31 19:26:55 回复(0)
父类指针指向子类,父类函数是虚函数时执行子类的函数。父类函数没有虚函数则直接使用父类的函数。
发表于 2020-02-02 14:49:31 回复(0)
问一下,class B 没有指明是虚函数也可以吗?
发表于 2017-10-02 14:39:16 回复(2)
p->f(),观察程序,可知其满足多态条件,则调用的是子类的函数,
而,在g(p),则知函数名相同,构成隐藏,调用的是父类的函数。
发表于 2017-05-30 11:27:08 回复(1)
常对常,不常对不常
发表于 2023-10-09 11:56:21 回复(0)
  1. 先找类型下是否有普通成员函数,没有的话看对象是否有普通成员函数或虚函数,
  2. 如果直接对象也没有,则按照对象的继承一层层网上找,找到那一层有对应签名的即调用
发表于 2023-03-24 20:01:51 回复(0)
被重写的虚函数与普通成员函数
发表于 2022-08-09 19:04:15 回复(0)
<p>new B()不是应该先调用基类构造函数,再调用子类构造函数吗?求指导</p><p><br></p>
发表于 2020-05-26 11:48:55 回复(0)
常量指针指向常对象, 常对象只能调用其常成员函数,因此通过g(constA* a)调用的是voidf()const;
发表于 2020-02-27 14:53:48 回复(0)
看错了,以为f是虚函数。。。。 
发表于 2019-03-21 22:22:27 回复(0)
常量指针指向常对象,常对象只能调用其常成员函数
编辑于 2018-08-20 09:00:20 回复(0)
常对象只能调用常成员函数。因为普通成员函数可以通过this指针改变对象。
发表于 2018-07-23 13:15:49 回复(0)