子类向量
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>>
,以便自动销毁所有对象向量并释放内存。
我需要做 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>>
,以便自动销毁所有对象向量并释放内存。