子类向量

Vector of subclasses

我需要做 4 次 classes。 Superclass机器人,两个subclasses r1和r2以及class线。 Classes robot, r1 和 r2 有一个静态成员 l_obiektow 用于显示对象的数量和两个虚拟方法 praca 用于显示对象的类型和 clone 用于复制一个对象。 Class行用于管理对象r1和r2的vector。我的方法克隆有问题,我不确定我应该 return 什么类型以及它应该做什么。

#include <vector>
using namespace std;
class robot;
//typedef  robot* wsk;
using wsk = robot*;

class robot{
  protected:
  static int l_ob;
  public:
  static int l_obiektow(){return l_ob;}
  virtual ~robot(){ cout << "~robot()" << endl;}
  virtual void praca()const=0;
  virtual wsk clone()const=0;
};

class r1 : public robot {
  public:
  r1(){l_ob++;}
  r1(const r1& r){l_ob++;}
  void praca()const{
        cout<<"r1"<<endl;
  }
  virtual wsk clone()const{
        r1 tmp=r1(*this);
        return &tmp;
  }
  ~r1(){cout << "~r1()" << endl; l_ob--;}
};

class r2 : public robot {
    public:
  r2(){l_ob++;}
  r2(const r2& r){l_ob++;}
  void praca()const{
        cout<<"r2"<<endl;
  }
 virtual wsk clone()const{
        r2 tmp=r2(*this);
        return &tmp;
  }
  ~r2(){cout << "~r2()" << endl; l_ob--;}
};

class line{
  vector <wsk> ve;

  public:
  line(){}
  line(int r):ve(r){
    for(size_t i=0; i<ve.size(); ++i )
      cout << ve[i] << ", " ;
    cout << endl;
  }

  line(const wsk* b, const wsk* e){
        size_t roz=e-b;
        for(size_t i=0;i<roz;i++){
            ve.push_back(b[i]->clone());
        }
    }
  line(const line& arg){
        for(size_t i=0;i<arg.ve.size();i++){
            ve.push_back(arg.ve[i]->clone());
        }
  }
  line& operator = (const line& a){
        if(this!=&a){
            ve.clear();
            for(size_t i=0;i<a.ve.size();i++){
                ve.push_back(a.ve[i]->clone());
            }
        }
        return *this;
  }

  void add( const wsk& arg){
    ve.push_back(arg);
  }
  void del(int i){
    delete ve[i-1];
    ve.erase(ve.begin()+i-1);
  }
  void delet(){
    delete ve[ve.size()-1];
    ve.pop_back();
  }

  void work(){
     for(size_t i=0;i<ve.size();i++){
        ve[i]->praca();
     }
  }
  ~line(){
        for(size_t i=0;i<ve.size();i++){
            delete ve[i];
        }
        ve.clear();
        cout<<"~line()"<<endl;
  }

};

int robot::l_ob=0;
void numberofobj(){
  cout << robot::l_obiektow() << endl;
}
int main()
{
    {
    { line l1 ;    }
    { line l2(5) ; }
    cout << "--==**1**==--" << endl;
    line lp1, lp2;
    lp1.add(new r1);
    lp1.add(new r1);
    lp1.add(new r2);
    lp1.add(new r2);
    lp2=lp1;
    {
      line lp3;
      lp3.add(new r1);
      lp3.add(new r2);
      lp3.add(new r1);
      lp3.add(new r2);
      lp3.delet();
      cout << "--==**2**==--" << endl;
      lp3.work();
      lp1 = lp3;
      cout << "--==**2a**==--" << endl;
    }

    cout << "--==**3**==--" << endl;
    lp1.work();
    cout << "--==**4**==--" << endl;

    wsk TabAdrRob[] = {new r2, new r2};
    line lp4(TabAdrRob, TabAdrRob+2 );
    lp4.work();
    cout << "--==**5**==--" << endl;
    lp4 = lp2;
    lp4.work();
    cout << "--==**6**==--" << endl;
    line lp6(lp1);
    lp6.del(1);
    lp6.work();
    cout << "--==**7**==--" << endl;

    delete TabAdrRob[0];
    delete TabAdrRob[1];}

  numberofobj();
  return 0;
}

这是一个严重的错误:

virtual wsk clone()const{
        r1 tmp=r1(*this);
        return &tmp;      // returning pointer to a local object
  }

您正在返回指向堆栈上本地对象的指针。 clone()returns后,tmp会被销毁

不要使用原始拥有指针。改用智能指针,例如。 unique_ptr .

在子类中使用 override 也是一个好习惯,因此如果您覆盖了错误的方法,编译器会发出错误。你不需要在子类中使用 virtual,如果子类不打算派生自(这是在 C++-11 之前的时代标记虚方法的旧方法)。

所以方法变成:

unique_ptr<robot> clone() const override
{
   return make_unique<robot>(new r1(*this));
}

对于机器人列表,您可以使用智能指针向量 vector<unique_ptr<robot>>,以便自动销毁所有对象向量并释放内存。