C++中的虚函数

本文深入探讨了C++中的多态性概念,包括非虚拟函数与虚拟函数的区别,以及如何通过指针和引用实现多态行为。文章通过具体代码示例解释了静态类型与动态类型之间的差异,并展示了如何正确使用虚拟函数。

缺省情况下 ,类的成员函数是非虚拟的 nonvirtual ,当一个成员函数为非虚拟的时候通过一个类对象(指针或引用)而被调用的该成员函数, 就是该类对象的静态类型中定义的成员函数 例如

      void Query::display( Query *pb )
{
set<short> *ps = pb->solutions();
// ...
display();
}
pb 的静态类型是 Query* 非虚拟的 solutions()调用的是 Query 的成员函数 而非虚拟函数display()通过隐式 this 指针被调用 this 指针的静态类型也是 Query* 所以被调用的函数是 Query 的成员函数
   要把对象声明为虚拟的 我们只需指定关键字 virtual
class Query {
public:
virtual ostream& print( ostream& = cout ) const;
// ...
};

当成员函数是虚拟的时候 通过一个类对象(指针或引用)而被调用的该成员函数 是在该类对象的动态类型中被定义的成员函数 。但是 ,正如所发生的, 一个类对象的静态和动态类型是相同的。 所以 虚拟函数机制只在使用指针和引用时才会如预期般地起作用,只有在通过基类指针或引用间接指向派生类子类型时, 多态性才会起作用 使用基类对象并不会保留派生类的类型身份 例如 考虑下列代码段
NameQuery nq( "lilacs" );
// ok: 但是 nq 被 "切割" 成一个 Query 子对象
Query qobject = nq;
用nq 初始化 qobject 是合法的: qobject 现在等于Query 基类子类型nq。 但是 ,qobject并不是一个 NameQuery 对象。 在初始化 qobject 之前 ,nq 的NameQuery 部分被切除。 在C++的面向对象程序设计中, 具有讽刺意味的是 ,我们必须使用指针以引用而不是对象来支持它(指面向对象程序设计 )例如 在下面的代码段中
void print( Query object,
const Query *pointer,
const Query &reference )
{
// 直到运行时刻才能确定
// 调用哪个 print() 实例
pointer->print();
reference.print();
// 总是调用 Query::print()
object.print();
}
int main()
{
NameQuery firebird( "firebird" );
print( firebird, &firebird, firebird );
}

通过 pointer 和 reference 的调用被解析为它们的动态类型 在这个例子中 它们都调用NameQuery::print() 而通过object 的调用则总是调用 Query::print()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值