AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > C++

C++程序设计中的多态技术研究

51自学网 http://www.wanshiok.com

  宏多态

  带变量的宏可以实现一种初级形式的静态多态:

// macro_poly.cpp

#include <iostream>
#include <string>

// 定义泛化记号:宏ADD
#define ADD(A, B) (A) + (B);

int main()
{
 int i1(1), i2(2);
 std::string s1("Hello, "), s2("world!");
 int i = ADD(i1, i2); // 两个整数相加
 std::string s = ADD(s1, s2); // 两个字符串“相加”
 std::cout << "i = " << i << "/n";
 std::cout << "s = " << s << "/n";
}

  当程序被编译时,表达式ADD(i1, i2)和ADD(s1, s2)分别被替换为两个整数相加和两个字符串相加的具体表达式。整数相加体现为求和,而字符串相加则体现为连接。程序的输出结果符合直觉:

1 + 2 = 3
Hello, + world! = Hello, world!

  动态多态

  这就是众所周知的的多态。现代面向对象语言对这个概念的定义是一致的。其技术基础在于继承机制和虚函数。例如,我们可以定义一个抽象基类Vehicle和两个派生于Vehicle的具体类Car和Airplane:

// dynamic_poly.h

#include <iostream>

// 公共抽象基类Vehicle
class Vehicle
{
 public:
  virtual void run() const = 0;
};

// 派生于Vehicle的具体类Car
class Car: public Vehicle
{
 public:
  virtual void run() const
  {
   std::cout << "run a car/n";
  }
};

// 派生于Vehicle的具体类Airplane
class Airplane: public Vehicle
{
 public:
  virtual void run() const
  {
   std::cout << "run a airplane/n";
  }
};

  客户程序可以通过指向基类Vehicle的指针(或引用)来操纵具体对象。通过指向基类对象的指针(或引用)来调用一个虚函数,会导致对被指向的具体对象之相应成员的调用:

// dynamic_poly_1.cpp

#include <iostream>
#include <vector>
#include "dynamic_poly.h"

// 通过指针run任何vehicle
void run_vehicle(const Vehicle* vehicle)
{
 vehicle->run(); // 根据vehicle的具体类型调用对应的run()
}

int main()
{
 Car car;
 Airplane airplane;
 run_vehicle(&car); // 调用Car::run()
 run_vehicle(&airplane); // 调用Airplane::run()
}

  此例中,关键的多态接口元素为虚函数run()。由于run_vehicle()的参数为指向基类Vehicle的指针,因而无法在编译期决定使用哪一个版本的run()。在运行期,为了分派函数调用,虚函数被调用的那个对象的完整动态类型将被访问。这样一来,对一个Car对象调用run_vehicle(),实际上将调用Car::run(),而对于Airplane对象而言将调用Airplane::run()。

  或许动态多态最吸引人之处在于处理异质对象集合的能力:

// dynamic_poly_2.cpp

#include <iostream>
#include <vector>
#include "dynamic_poly.h"

// run异质vehicles集合
void run_vehicles(const std::vector<Vehicle*>& vehicles)
{
 for (unsigned int i = 0; i < vehicles.size(); ++i)
 {
  vehicles[i]->run(); // 根据具体vehicle的类型调用对应的run()
 }
}

int main()
{
 Car car;
 Airplane airplane;
 std::vector<Vehicle*> v; // 异质vehicles集合
 v.push_back(&car);
 v.push_back(&airplane);
 run_vehicles(v); // run不同类型的vehicles
}

  在run_vehicles()中,vehicles[i]->run()依据正被迭代的元素的类型而调用不同的成员函数。这从一个侧面体现了面向对象编程风格的优雅。

 
 

上一篇:C++应用程序中创建持久对象  下一篇:STL泛型编程与设计新思维