#include <iostream>
 #include <stdio.h>
 using namespace std;/*
 用C++如何实现内存的自动管理和用一个容器存放继承层次的任何类的对象
 */ class Vehicle
 {
 public:
     virtual double weight() const = 0;
     virtual void start() = 0;
     ///这个虚函数是复制对象的,执行的是copy构造函数,有这个函数的存在就复制了一个新的对象
     virtual Vehicle* copy() const = 0;
     virtual ~Vehicle(){}
 };class RoadVehicle : public Vehicle
 {
 public:
     RoadVehicle(){}    ///拷贝构造函数
     RoadVehicle(const RoadVehicle& road)
     {
         cout << "copy RoadVehicle obj...." << endl;
     }public:
     virtual double weight() const 
     {
         return 1.0;
     }
     virtual void start()
     {
         cout << "RoadVehicle start......" << endl;
     }     virtual Vehicle* copy() const         ///这个虚函数是复制对象的,执行的是copy构造函数,有这个函数的存在就复制了一个新的对象
     {
         ///调用的是RoadVehicle的copy构造函数
         ///RoadVehicle(const RoadVehicle& road)
         return new RoadVehicle(*this);
     }
     virtual ~RoadVehicle()
     {
         cout << "~RoadVehicle" << endl;
     }
 };class AutoVehicle : public RoadVehicle
 {
 public:
     AutoVehicle(){}    ///拷贝构造函数
     AutoVehicle(const AutoVehicle& ato)
     {
         cout << "AutoVehicle copy....." << endl;
     }public:
     virtual double weight() const 
     {
         return 2.0;
     }
     virtual void start()
     {
         cout << "AutoVehicle start..." << endl;
     }    ///拷贝构造函数
     virtual Vehicle* copy() const        ///这个虚函数是复制对象的,执行的是copy构造函数,有这个函数的存在就复制了一个新的对象
     { 
         return new AutoVehicle(*this);
     }
     virtual ~AutoVehicle()
     {
         cout << "~AutoVehicle" << endl;
     }
 };class Aircraft : public Vehicle
 {
 public:
     Aircraft(){}
     Aircraft(const Aircraft& air)
     {
         cout << "Aircraft copy ....." << endl;
     }public:
     virtual double weight() const
     {
         return 3.0;
     }
     virtual void start()
     {
         cout << "Aircraft start...." << endl;
     }
     virtual Vehicle* copy() const         ///这个虚函数是复制对象的,执行的是copy构造函数,有这个函数的存在就复制了一个新的对象
     {
         return new Aircraft(*this);
     }
     virtual ~Aircraft()
     {
         cout << "~Aircraft" << endl;
     }
 }; /*
     如何设计一个C++容器类,使它有能力包含类型不同而彼此相关的对象?容器通常只能包含一种类型的对象,所以很难在容器中存储对象本身,
     虽然可以存储对象的指针,但是增加了内存分配的额外负担,需要手动释放申请的内存。
     Vehicle* parking_lot[100];
     这个中间层存储指针,这样有2个问题:
     1.带来了动态内存管理的负担,需要手动调用delete/free
     2.如果parking_lot[q]和parking_lot[p]指向了同一个对象,当释放parking_lot这个数组时,程序就会崩溃     virtual Vehicle* copy() const = 0;
     当执行copy函数的时候就是调用了拷贝构造函数,重新创建了一个新的对象,就是说有2个对象了,    现在实现了copy对象,但是是动态申请了内存,该如何避免显示的处理内存分配管理,又能保持类Vehicle在运行时进行动态绑定?
    C++中最基本的设计原则就是用类来表示概念,写一个中间层的概念,它的行为和Vehicle相似,又潜在的表示了所有继承自Vehicle类的对象的东西
*/
 /*
 VehicelSurrogate是一个代理类,他的行为和Vehicle十分相似,Vehicle用的功能该类都有,
 该类是一个中间层有2个作用:
 1.它的存在实现了Vehicle对象族的内存实现了自动管理,不需要关心内存泄漏的问题
 2.能够进行代理的创建,销毁和复制的功能
 有一个缺点:每次都需要复制对象,增加了额外的开销
 */
 class VehicelSurrogate
 {
 public:
     VehicelSurrogate() : vp(0)
     {
         ///cout << "construct VehicelSurrogate " << endl;
     }    VehicelSurrogate(const Vehicle& v) : vp(v.copy()){}
    ~VehicelSurrogate()
     {
         ///cout << vp << endl;
         ///如果vp为空,delete vp程序竟然不会挂,我一直以为程序是会挂的
         delete vp;
     }    ///这里会复制一个新的Vehicle族的对象出来,会调用copy函数
     VehicelSurrogate(const VehicelSurrogate& v) :vp(v.vp ? v.vp->copy() : 0){}    ///等号操作符实现了对象的赋值
     VehicelSurrogate& operator=(const VehicelSurrogate& v)
     {
         if (this != &v)
         {
             delete vp;
             ///这里会复制一个新的Vehicle族的对象出来,会调用copy函数
             vp = (v.vp ? v.vp->copy() : 0);
         }
         return *this;
     }    ///实现Vehicle的功能
     double weight() const
     {
         if (vp == 0)
         {
             cout << "vp is empty......." << endl;
             return 0;
         }
         return vp->weight();
     }    ///实现Vehicle的功能
     void start()
     {
         if (vp == 0)
         {
             cout << "vp in start fun is empty....." << endl;
             return;
         }
         vp->start();
     }private:
     Vehicle* vp;
 };int main()
 {
     {
         int num = 0;
         VehicelSurrogate parking_lot[10];        AutoVehicle x;
        parking_lot[num++] = x;
        Aircraft air;
         parking_lot[num++] = air;        for (int i = 0; i < num; i++)
         {
             parking_lot[i].start();
         }         cout << "----------------------" << endl;
        ///离开这个作用域,会调用VehicelSurrogate的析构函数,释放Vehicle对象的内存
         ///C++不仅是更好用的C语言,而且在这个层面上面进行了2层优化:1.实现了内存的自动管理,2.抽象出相同的属性start和weight接口    }
    getchar();
    return 0;
 }