C++语言程序设计

下面我们通过一个例子说明基类指针如何访问对象的成员函数。假定我们在twoD类和threeD类分别增加一个成员函数getSum：

| 例11-16

class twoD
{
…
double getSum() const {return x+y;}
};

class threeD:public twoD
{
…
double getSum() const {return x+y+z;}
};
再采用如下方法调用getSum函数：
threeD three(20.0, 20.0, 30.0);
twoD *pTwo = &three;
double d = pTwo-> getSum();

d的值为为40.0，而不是70.0。虽然twoD类指针指向threeD类对象three，但是pTwo -> getSum()调用的是twoD类的成员函数，而不是threeD类的成员函数。可见，通过指针调用成员函数时，到底是调用基类的成员函数，还是调用派生类的成员函数，是由指针的类型决定的，而不是由对象决定的。
我们也可以对指针的类型进行强制转换，例如：
threeD three(20.0, 20.0, 30.0);
twoD *pTwo = &three;
threeD *pThree=(threeD *)pTwo;
double d = pThree->getSum();
上段代码的倒数第二行将twoD指针pTwo强制转换后赋给threeD指针pThree，若直接赋值会出现编译错误，因为twoD指针不能隐式转换成threeD指针。
如果指针pTwo确实指向threeD对象，pThree->getSum()正常调用threeD类的成员函数getSum，否则，可能出现难以预料的结果。
继承表示一种关系，即"新类是老类的一个类型"，这意味着在基类的所有函数在派生类中也是可用的，twoD里面的函数，在threeD里面也有。ThreeD对象不仅仅是threeD类型，同时也是twoD类型。例如：
threeD three(20.0, 20.0, 30.0);
twoD *pTwo;
pTwo = &three;
这种将派生类对象、指针或引用转变为基类的对象、指针或引用的过程称为向上映射。向上映射不需要作显式的说明，或强制的转换。因为向上映射是安全的，它是从特殊的类型转换为一般的类型，出现的最坏情况是失去类成员，而不会增加类成员。
由于向上映射是将特殊的类型转换成了一般的类型，对象的类型信息就损失掉了。比如，上面的对象three，编译器只把指针pTwo当成一个twoD类型指针处理，也就是说，不知道它现在指向的是一个threeD类型的对象。当调用getSum（）成员函数时：
pTwo->getSum()；
编译器会调用基类版本"twoD::getSum()"，而不是调用"threeD::getSum()"，如果想解决这个问题，需要利用下一节虚函数的知识。