虚函数是在父类中显示声明为
virtual
的函数,或更高一级的类继承而来。
继承类可以提供自己的特殊实现,也可以直接继承父类的实现。
继承的虚函数自动成为虚函数,无需特别声明( virtual )。
每一个类的虚函数指针存入 VTBL,在运行时间(runtime),根据实例的实际类型调用。
虚函数是在父类中定义为 = 0 的函数成为纯虚函数,继承类必须提供自己的实现。
函数重载
以下是一个简单的示例程序基运行结果,希望能帮助你理解(VC 6.0 ):
class A
... {
public:
virtual void f() ...{ puts("class A: f called"); };
virtual void f1() ...{ puts("class A: f1 called"); };
void f2() ...{ puts("class A: f2 called"); };
void f3() ...{ puts("class A: f3 called"); };
} ;
class B: public A
... {
public:
void f() ...{ puts("class B: f clalled"); };
void f1() ...{ puts("class B: f1 called"); }; //automatically virtual
void f2() ...{ puts("class B: f2 called"); };
} ;
int main( int argc, char * argv[])
... {
A aInst;
B bInst;
A *pA;
B *pB;
// instances
puts("instances");
aInst.f();
aInst.f2();
aInst.f3();
bInst.f();
bInst.f2();
bInst.f3();
//pointers to instances
puts("pointers to instances");
pA = &bInst;
pA->f();
pA->f2();
pA->f3();
pB = (B *)&aInst;
pB->f();
pB->f2();
pB->f3();
return 0;
}
运行结果:
instances
class A: f called
class A: f2 called
class A: f3 called
class B: f clalled
class B: f2 called
class A: f3 called
pointers to instances
class B: f clalled
class A: f2 called
class A: f3 called
class A: f called
class B: f2 called
class A: f3 called
继承类可以提供自己的特殊实现,也可以直接继承父类的实现。
继承的虚函数自动成为虚函数,无需特别声明( virtual )。
每一个类的虚函数指针存入 VTBL,在运行时间(runtime),根据实例的实际类型调用。
虚函数是在父类中定义为 = 0 的函数成为纯虚函数,继承类必须提供自己的实现。
函数重载
以下是一个简单的示例程序基运行结果,希望能帮助你理解(VC 6.0 ):
class A
... {
public:
virtual void f() ...{ puts("class A: f called"); };
virtual void f1() ...{ puts("class A: f1 called"); };
void f2() ...{ puts("class A: f2 called"); };
void f3() ...{ puts("class A: f3 called"); };
} ;
class B: public A
... {
public:
void f() ...{ puts("class B: f clalled"); };
void f1() ...{ puts("class B: f1 called"); }; //automatically virtual
void f2() ...{ puts("class B: f2 called"); };
} ;
int main( int argc, char * argv[])
... {
A aInst;
B bInst;
A *pA;
B *pB;
// instances
puts("instances");
aInst.f();
aInst.f2();
aInst.f3();
bInst.f();
bInst.f2();
bInst.f3();
//pointers to instances
puts("pointers to instances");
pA = &bInst;
pA->f();
pA->f2();
pA->f3();
pB = (B *)&aInst;
pB->f();
pB->f2();
pB->f3();
return 0;
}
运行结果:
instances
class A: f called
class A: f2 called
class A: f3 called
class B: f clalled
class B: f2 called
class A: f3 called
pointers to instances
class B: f clalled
class A: f2 called
class A: f3 called
class A: f called
class B: f2 called
class A: f3 called
前一些时间里对这三类的重载不太了解.概念上有一些混.
今天做了一个这样的例子来测试了一下到底这个几种函数的
不同.
基类:
class A
... {
public:
A();
void f1();
virtual void f2();
virtual void f3()=0;
virtual ~A();
} ;
子类:
class B : public A
... {
public:
B();
void f1();
void f2();
void f3();
virtual ~B();
} ;
主函数:
int main( int argc, char * argv[])
... {
A *m_j=new B();
m_j->f1();
m_j->f2();
m_j->f3();
delete m_j;
return 0;
}
f1()是一个普通的重载.
调用m_j -> f1();会去调用A类中的f1(),它是在我们写好代码的时候就会定好的.
也就是根据它是由A类定义的,这样就调用这个类的函数.
f2()是虚函数.
调用m_j -> f2();会调用m_j中到底保存的对象中,对应的这个函数.这是由于new的B
对象.
f3()与f2()一样,只是在基类中不需要写函数现实.
今天做了一个这样的例子来测试了一下到底这个几种函数的
不同.
基类:
class A
... {
public:
A();
void f1();
virtual void f2();
virtual void f3()=0;
virtual ~A();
} ;
子类:
class B : public A
... {
public:
B();
void f1();
void f2();
void f3();
virtual ~B();
} ;
主函数:
int main( int argc, char * argv[])
... {
A *m_j=new B();
m_j->f1();
m_j->f2();
m_j->f3();
delete m_j;
return 0;
}
f1()是一个普通的重载.
调用m_j -> f1();会去调用A类中的f1(),它是在我们写好代码的时候就会定好的.
也就是根据它是由A类定义的,这样就调用这个类的函数.
f2()是虚函数.
调用m_j -> f2();会调用m_j中到底保存的对象中,对应的这个函数.这是由于new的B
对象.
f3()与f2()一样,只是在基类中不需要写函数现实.