在编程过程中可能要把不同的对象(这些对象可能存在一些关系:继承)放到一个容器里边,我们都知道一个基类的指针可以指向子类的一个实例,我们就在这里有用一个基类的指针使其指向不同的实例,并把这些指针放到一个容器内。我把这一章内的讲解的例子整理了一下,并通过了测试。测试的环境是(VS2003)
class vehicle
{
public:
virtual ~vehicle(void) {}
virtual double weight(void) const = 0;
virtual void start(void) = 0;
virtual vehicle* copy(void) const = 0;
};//vehicle是一个抽象类,不可以实例化
class RoadVehicle : public vehicle
{
public:
RoadVehicle(void) {}
~RoadVehicle(void) {}
double weight(void) const { cout<<"RoadVehicle weight"<<endl; return 0; }
void start(void) { cout<<"RoadVehicle start"<<endl; }
vehicle* copy(void) const { return new RoadVehicle(*this); }
};
class AutoVehicle : public RoadVehicle
{
public:
AutoVehicle(void) {}
~AutoVehicle(void) {}
double weight(void) const { cout<<"AutoVehicle weight"<<endl; return 0;}
void start(void) { cout<<"AutoVehicle start"<<endl; }
vehicle* copy(void) const { return new AutoVehicle(*this); }
};
class AirCraft : public vehicle
{
public:
AirCraft(void) {}
~AirCraft(void) {}
double weight(void) const { cout<<"AirCraft weight"<<endl; return 0; }
void start(void) { cout<<"AirCraft start"<<endl; }
vehicle* copy(void) const { return new AirCraft(*this); }
};
class Helicopter : public AirCraft
{
public:
Helicopter(void) {}
~Helicopter(void) {}
double weight(void) const { cout<<"Helicopter weight"<<endl; return 0; }
void start(void) { cout<<"Helicopter start"<<endl; }
vehicle* copy(void) const { return new Helicopter(*this); }
};
///下面就是代理类了,通过这个类来访问不同对象的方法。
class VehicleSurrogate
{
public:
VehicleSurrogate(void) : vp(0) {}
VehicleSurrogate(const vehicle &v) : vp(v.copy()) {};//构造不同的实例,在程序的编译期间是不知道会是个什么样的对象
~VehicleSurrogate(void) { delete vp; }
VehicleSurrogate(const VehicleSurrogate &v) : vp(v.vp ? v.vp->copy() : 0) { }
VehicleSurrogate& operator=(const VehicleSurrogate &v)
{
if (this != &v)
{
delete vp;
vp = (v.vp ? v.vp->copy() : 0);
}
return *this;
}
double weight(void)
{
if (vp == 0)
{
cout<<"weight vp is NULL"<<endl;
}
return vp->weight();
}
void start(void)
{
if (vp == 0)
{
cout<<"start vp is NULL"<<endl;
}
return vp->start();
}
private:
vehicle *vp;
};
int _tmain(int argc, _TCHAR* argv[])
{
VehicleSurrogate parking_lot[2];
Helicopter x;
AirCraft y;
parking_lot[0] = x;
parking_lot[1] = y;
parking_lot[0].weight();
parking_lot[1].start();
return 0;
}
Output:
Helicopter weight
AirCraft start
在这个程序中,存储到容器中的对象都是原来对象的一个副本(即原对象的一个拷贝),一定要复制这些对象吗?答案是否定的,我们可以存储这些对象的句柄,使用句柄同样可以保持原来的对象的多态行为,却是我们减少了不必要的拷贝,何乐而不为呢?