c++ 虚函数 如何调父类 而非子类

如题所述

1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩)

2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)

3,如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。

虚拟函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。

如果你预期衍生类由可能重新定义一个成员函数,那么你就把它定义成虚拟函数( virtual )。
polymorphism就是让处理基础类别对象的程序代码能够通透的继续适当地处理衍生类对象。

纯虚拟函数:
virtual void myfunc ( ) =0;
纯虚拟函数不许定义其具体动作,它的存在只是为了在衍生类钟被重新定义。只要是拥有纯虚拟函数的类,就是抽象类,它们是不能够被实例化的(只能被继承)。如果一个继承类没有改写父类中的纯虚函数,那么他也是抽象类,也不能被实例化。
抽象类不能被实例化,不过我们可以拥有指向抽象类的指针,以便于操纵各个衍生类。
虚拟函数衍生下去仍然是虚拟函数,而且还可以省略掉关键字“virtual”。

看个例子:
#include <iostream>
using namespace std;
class A
{
public:
virtual void foo()
{
cout << "A's foo()" << endl;
bar();
}
virtual void bar()
{
cout << "A's bar()" << endl;
}
};
class B: public A
{
public:
void foo()
{
cout << "B's foo()" << endl;
A::foo();
}
void bar()
{
cout << "B's bar()" << endl;
}
};
int main()
{
B bobj;
A *aptr = &bobj;
aptr->foo();
A aobj = *aptr; //转化为A类对象
aobj.foo();
}

aptr->foo()输出结果是:
B's foo()//这个明白,多态性
A's foo()//这个也明白,执行A::foo();
B's bar()//虽然调用的是这个函数:A::foo(); 但隐式传入的还是bobj 的地址,所以再次调用bar();调用时还是会调用B的函数, 与虚函数指针有关

aobj.foo()输出结果是:
A's foo() //这个不是指针,aobj完全是一个A的对象,与多态没有关系
A's bar()
温馨提示:内容为网友见解,仅供参考
第1个回答  2014-01-14
只要指针指向父类的对象,那调用的时候就是父类的成员函数
第2个回答  推荐于2016-06-25
如果是用基类指针的方式,只能将指针指回基类对象,再调用,

如果不用指针,而直接用对象来调用的话,直接就用基类对象来调用相应的函数就行

虚函数主要是体现在c++多态性上

而实现多态性,就需要基类指针指向基类或者子类对象,本回答被提问者和网友采纳
第3个回答  2014-01-14
#include <stdio.h>
class A {
public:
virtual void test() { printf ("A\n");};
};

class B : public A{
public:
virtual void test() { printf ("B\n");}
};

int main ()
{
A* a = new B;
a->test();
a->A::test(); //调用父类的
}

C++基类子类中,虚函数究竟是怎样判断该调用哪个函数的??
有虚函数时,每个对象的this指针都指向一个虚函数表(Virtual Table)的地址,这个表里存的就是虚函数的地址。编译的时候就决定了,普通函数调用时直接CALL这个函数的地址,而是虚函数时,是从这个虚表里取地址去调用的。

C++中虚函数的作用和虚函数的工作原理
虚函数在C++中实现多态性,主要作用在于实现动态绑定。基类定义虚函数,子类可以重写该函数。当子类重新定义了父类的虚函数后,当父类的指针指向子类对象的地址时,程序根据对象的实际类型动态调用子类的该函数,而不是父类的函数。这种动态调用发生在运行阶段,称为动态联编。非虚函数的静态联编效率更高,...

C++中用父类指针指向子类实例,用父类指针调用虚函数,问调用的是子类的...
如果是虚函数,是可以通过基类的指针调用子类的函数的。如果不是虚函数基类指针就只能调用基类函数

虚函数作用
当函数前加上"virtual"关键字,该函数就会成为虚函数。例如,如果子类继承了父类的某个函数,并使用父类的指针或引用指向子类实例,那么调用这个函数时,会根据指针或引用的实际类型调用相应的子类版本,而非父类版本。动态联编的规则要求,必须通过指向基类的指针或基类对象的引用来调用虚函数,如:指针变...

C++ 用子类定义的对象 怎么调用父类的成员函数?
不一定,要按继承方式分三种情况讨论。public继承:可以调用基类中被protected和public修饰的成员变量与成员函数。protected继承:可以调用基类中被public修饰的成员变量与成员函数。private继承:不可以调用基类中任何成员变量与成员函数。

c++中的虚函数是什么?
C++中的虚函数是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多...

C++中是不是每个类(有虚函数)都对应一个virtual function table?_百...
你理解的是对的,子类和父类各有一个虚函数表,并且虚函数指针也是指向各自的。子类先是从父类复制了一个虚函数表,如果子类对父类的虚函数进行了覆盖,则在子类的虚函数表将会用子类的函数地址覆盖父类的,如果没有覆盖,则还是使用父类的函数地址,这样就实现了多态。

c++ 父类子类转换
\/\/子类向父类类型转换,直接强制转换就可以了,但实际仍然指向子类对象 pPoint = (CPoint*)&point3D;pPoint->f(); \/\/调用的仍然是子类的函数,这便是虚函数的魅力所在 \/\/父类向子类类型转换,要用dynamic_cast pPoint3D = dynamic_cast(pPoint);pPoint->f(); \/\/pPoint实际指向一个CPoint3D...

C++父类中声明了一个虚函数以后 是不是在子类 以及子类的子类中 都要...
基类声明虚函数只是提供一个接口,也就是实现多态的关键,子类基本都要继承的,如果有一个子类不需要实现这个函数,说明你的继承关系有问题,最好改变一下继承体系

C++问题: 通过怎样的方式父类的对象可以直接调用子类的成员~~,求解...
不可以吧!如果实在想访问,可以通过虚函数方式进行访问,比如:class father { public:virtual void* getElementsAddr(){ return null;} };class child : public father { public:virtual void* getElementsAddr(){ return &element;} private:int element;} void main(){ father &cFather = child...

相似回答