c++问题 多态 virtual 和const

class A
{ public:
virtual void f()
{cout<<"A::f()"<<endl;}

void f() const
{
cout<<"A::f() const"<<endl;
}

};

class B:public A
{
public:
void f()
{
cout<<"B::f()"<<endl;

}
void f() const
{
cout<<"B::f() const"<<endl;
}
};
void g(const A* a)
{
a->f();
}

int _tmain(int argc, _TCHAR* argv[])
{
A *a=new B();
a->f();
g(a);
delete a;
}

输出 B::f()
A::f() const
这是为什么呢?没怎么接触多态,求详细指导,谢谢!

C++的动态多态是指对于一个成员函数的调用将根据对象的动态类型信息(多态机制的开销)执行不同的成员函数(这个函数是在基类中声明的虚函数并在派生类中可能被重写)。


但是这里有两个前提: 

    调用成员函数时必须通过基类的指针或者引用调用;

    被调用的成员函数必须是虚函数。


对于一个非虚函数(普通成员函数)的调用将在编译时根据对象的静态类型(由调用表达式推断出来的)来调用成员函数。


你的问题中成员函数f有两个版本,一个是非const虚函数,一个是const非虚函数。(自己去分析吧)


什么时候调用const版本的成员函数?

当对象是const对象时;

当指向对象的指针是const时;

当对象的引用是const引用时

当只有const版本的成员函数时

调用的将是const成员函数。


在main方法中,

A *a=new B();
a->f();

使得基类指针a指向匿名派生类对象B,然后通过指针调用函数f, 由于调用的时虚函数f,所以该调用将根据a所指的对象的实际类型来决定调用派生类B中的成员函数f。


在g函数中,

void g(const A* a)
{
a->f();
}

是通过const基类指针a调用基类的const成员函数f,然而cons版本的f不适虚函数所以调用的将是基类A中的f成员函数。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-09-12
const 与非const 的f是两个的函数,属于重载。
常成员函数不可以访问非常量成员。

a->f();//匹配到非常成员函数,调用子类的f,虚函数。

g(a);//这种场合,子类的f const覆盖了父类的f const,使用的是基类指针,所以只能调用到父类的。
第2个回答  2013-09-12
使用指针访问 虚函数时,编译器根据指针所指对象的类型决定要调用哪个函数(动态联编),而与指针本身的类型无关。

c++问题 多态 virtual 和const
C++的动态多态是指对于一个成员函数的调用将根据对象的动态类型信息(多态机制的开销)执行不同的成员函数(这个函数是在基类中声明的虚函数并在派生类中可能被重写)。但是这里有两个前提:调用成员函数时必须通过基类的指针或者引用调用;被调用的成员函数必须是虚函数。对于一个非虚函数(普通成员函数)...

c++的virtual 多态性的原理?
virtual 多态即指动多态 动多态是通过继承、虚函数(virtual)、指针来实现。class A { public:virtual void func() const { coust << “A::func()” << endl;} } class B : public A { public:virtual void func() const { coust << “B::func()” << endl;} } 使用:A a* = B...

对下面程序里的函数void fun(){}的疑问
这个是一个典型的多态问题,C++的4个基本特点之一。virtual void display() const;中可以看到,display()是一个虚函数,因此在子类中,都可以对它进行新的定义。就是void Base2::display() 和 void Derived::display()。多态最重要的一个好处之一就是,编译器可以根据实际的对象,调用相应的函数,而...

继承与多态性出现的问题“不允许使用抽象类类型的对象” c++
两个子类的 area 和 draw 函数并非是实现了基类的那二个函数,因为基类中这两个函数名后面都有 const, 楼主在子类中加上或者从基类中删除这二个关键字即可。

什么叫做多态性 ?在C++中是如何实现多态的?
动多态则是通过继承、虚函数(virtual)、指针来实现。class A { public:virtual void func() const { coust << “A::func()” << endl;} } class B : public A { public:virtual void func() const { coust << “B::func()” << endl;} } 使用:A a* = B();a->func();...

C++经典面试问题
7,C++中的Const用法 答:char * const p; \/\/ 指针不可改,也就说指针只能指向一个地址,不能更改为其他地址,修饰指针本身 char const * p; \/\/ 所指内容不可改,也就是说*p是常量字符串,修饰指针所指向的变量 const char * const p 和 char const * const p; \/\/ 内容和指针都不能改 const修饰函数参数...

c\/c++ 类的成员函数在内部定实现和外部实现有什么区别?
第一, 代码在内部不过是因为你的参数用到student类型,那个时候student类型还没有了,程序怎么能过呢。第二,外部实现一般都是实现的virtual函数,这相当于一个接口。C++经典的就是封装 继承 多态

什么是静态多态?它与重载有何区别?
动态多态 这就是众所周知的的多态。现代面向对象语言对这个概念的定义是一致的。其技术基础在于继承机制和虚函数。例如,我们可以定义一个抽象基类Vehicle和两个派生于Vehicle的具体类Car和Airplane: \/\/ dynamic_poly.h#include <iostream>\/\/ 公共抽象基类Vehicleclass Vehicle{public: virtual void run() const = 0...

c++中的关键字bad_cast、bad_typeid、bool、catch各是什么意思?_百度...
bad_cast、bad_typeid不是c++关键字 C\/C++ Keywords asm 插入一个汇编指令.auto 声明一个本地变量.bool 声明一个布尔型变量.break 结束一个循环.case 一个switch语句的一部分.catch 处理 thrown 产生的异常.char 声明一个字符型变量.class 声明一个类.const 声明一个常量.const_cast 从一个const...

vc c++ 100多个关键字的中文的含义是什么?作用是什么? vc c++ 有上百...
const_cast extern namespace sizeof typeid continue false new static typename 1.asm(汇编),用法如下:asm (指令字符串);允许在C++程序中嵌入汇编代码。2.auto(自动,automatic)是存储类型标识符,表明变量“自动”具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto 存储...

相似回答