刚刚学习使用c++,遇到一个类的对象和类的指针的问题。自己先的理解是对应一般的类型,比如int a与int* b;在这里b其实可以理解成一串a的集合,相当于一个不定的数组。而对应类这种理解是错误的。(这里指针其实只是个入口而已,其也只对应一个。)
首先:在类没有创建完成时,就可以定义类的指针,这表明类的指针不会是指向一系列完整的东西,否则这个定义就不成立;
其次:类本身就是一个抽象的定义,用int这种实例化的例子等同是不对的。这里int、double等数据类型才能形成一个类,而int、double等都是类的对象而已;
最后:类的指针真正的用途主要是实现类的多态性:
以下转自:http://book.51cto.com/art/201001/176424.htm
9.6.2 使用指向类对象的指针
使用指针处理基类和派生类的对象是一项重要的技术。指向基类对象的指针不仅可以包含基类对象的地址,还可以包含派生类对象的地址。因此,我们可以根据被指向的对象种类,使用类型为"基类指针"的指针获得虚函数的不同行为。通过看一个示例,我们可以更清楚地了解实际的工作过程。
试一试:指向基类和派生类的指针
本示例将使用与上一个示例相同的类,但对main()函数作了少量修改,从而使该函数使用指向基类对象的指针。创建Ex9_08项目,其中Box.h和GlassBox.h头文件与上一个示例中的相同。我们可以将Box.h和GlassBox.h文件从Ex9_07项目复制到本项目的文件夹中。将现有的文件添加到某个项目非常容易,我们只需右击Solution Explorer选项卡中的Ex9_08,从弹出的菜单中选择Add | Existing Item,然后选择要添加到该项目的头文件即可。在添加头文件之后,将Ex9_08.cpp修改成如下形式:
- // Ex9_08.cpp
- // Using a base class pointer to call a virtual function
- #include <iostream>
- #include "GlassBox.h" // For CBox and CGlassBox
- using std::cout;
- using std::endl;
- int main()
- {
- CBox myBox(2.0, 3.0, 4.0); // Declare a base box
- CGlassBox myGlassBox(2.0, 3.0, 4.0);// Declare
derived box of same size- CBox* pBox = 0; // Declare a pointer to base class objects
- pBox = &myBox; // Set pointer to address of base object
- pBox->ShowVolume(); // Display volume of base box
- pBox = &myGlassBox; // Set pointer to derived class object
- pBox->ShowVolume(); // Display volume of derived box
- cout << endl;
- return 0;
- }
示例说明
这两个类与示例Ex9_07.cpp中的类相同,但main()函数已经被修改成使用指针来调用ShowVolume()函数。因为使用的是指针,所以要使用间接成员选择运算符->来调用函数。ShowVolume()函数被调用了两次,两次调用都使用相同的基类对象指针pBox。在第一次调用时,该指针包含基类对象myBox的地址。在第二次调用时,该指针包含派生类对象myGlassBox的地址。
产生的输出如下所示:
- CBox usable volume is 24
- CBox usable volume is 20.4
输出与上一个示例的输出完全相同,在上一个示例中,我们在函数调用中使用了显式的对象。
从本示例可以得出这样的结论:虚函数机制借助于指向基类的指针同样能够正常工作,实际调用的函数是基于被指向的对象类型而选择的。该过程如图9-5所示。
(点击查看大图)图 9-5 |
这意味着即使我们不知道程序中某个基类指针所指对象的准确类型(比如某个指针作为实参传递给函数时),虚函数机制也能确保调用正确的函数。这是一种特别强大的功能,因此务必充分理解。多态性是一种我们将多次使用的基本C++机制。
因此,在类比时要注意类比的前提是否成立,这是后面研究的关键。