每次将对象推入向量时数据丢失

时间:2018-05-20 18:38:33

标签: c++ class templates vector stl

我有一个学校项目,我应该在其中构建一个模板类Vanzare,意思是销售。我有2个STL矢量,一个用于有库存的汽车,一个用于销售的汽车,另外两个变量可以计算有多少汽车库存以及销售的汽车数量。

该类应该让-=运算符重载,并且它应该卖掉一辆汽车,意味着从库存矢量(名为stoc)中删除它并将其添加到已售出的矢量(命名为vandut)。

我还超载了+=运营商以添加汽车库存。

我拥有的汽车类型都来自基类Masina,其中一些还有额外的字段。

问题在于,无论何时我使用+=-=(或一般push_back())任何有额外字段的内容(与基类相比),都会破坏以前的元素从矢量。所以我不能在不丢失信息的情况下存储任何派生对象。

我还被告知,对整个班级进行专业化可能有所帮助,但事实并非如此。

模板类从第300行开始(我不知道如何突出显示对不起)。我很抱歉,如果我写的不清楚,我对所有这些面向对象的东西都是新手。提前谢谢!

编辑:我尽我所能尽量减少程序,但它仍然有250行代码。我还将(希望一切)改名为英语。当我向对象添加一个对象时,字段sh仍然会丢失。

#include <iostream>
#include <string.h>
#include <vector>
#include <ctime>

using namespace std;

class Car
{
int capacity;
float length;
int price;
int year;


public:

int getYear();
void setPrice(int);
int getPrice();
Car();
~Car();
Car(int , float , int , int);
Car(const Car&);

friend istream& operator>>(istream& , Car&);
friend ostream& operator<<(ostream& , Car&);
friend class VAN;
};

int Car::getYear()
{
return year;
}

int Car::getPrice()
{
return price;
}

void Car::setPrice(int p)
{
price = p;
}

ostream& operator<<(ostream& out , Car& m)
{
out<<"capacity: "<<m.capacity<<"\nlength: "<<m.length<<"\nprice: "<<m.price<<"\nYear: "<<m.year;
return out;
}

istream& operator>>(istream& in , Car& m)
{
cout<<"capacity: ";
in>>m.capacity;
cout<<"length: ";
in>>m.length;
cout<<"price: ";
in>>m.price;
cout<<"Year: ";
in>>m.year;

return in;
}

Car::Car()
{
capacity = 0;
length = 0;
year = 0;
price = 0;
}

Car::Car(int lit , float lun , int an , int pre)
{
capacity = lit;
length = lun;
year = an;
price = pre;
}

Car::Car(const Car& m)
{
capacity = m.capacity;
length = m.length;
year = m.year;
price = m.price;
}

Car::~Car()
{
capacity = 0;
year = 0;
length = 0;
price = 0;
}

class VAN:public Car
{

int sh;

public:
void setSH(int);
int isSH();
VAN();
~VAN();
VAN(int , float , int , int , int);
VAN(const VAN&);

friend istream& operator>>(istream& , VAN&);
friend ostream& operator<<(ostream& , VAN&);
};

void VAN::setSH(int s)
{
if(s)
    sh = 1;
else
    sh = 0;
}

int VAN::isSH()
{
return sh;
}

ostream& operator<<(ostream& out , VAN& m)
{
out<<(Car&)m;
out<<endl<<"Second hand: "<<m.sh;

return out;
}

istream& operator>>(istream& in , VAN& m)
{
in>>(Car&)m;
cout<<"Second Hand: ";
int x;
in>>x;
if(x)
    m.sh = 1;

return in;
}

VAN::VAN():Car()
{
;
}

VAN::~VAN()
{
;
}

VAN::VAN(int a , float b , int c, int d , int s):Car(a , b, c , d)
{
if(s)
sh = 1;
}

VAN::VAN(const VAN& m):Car(m)
{
;
}

template <class T>
class Sale
{
vector<T> stock;
vector<T> sold;

int nrSold;
int nrStock;

public:

Sale();
Sale<T>& operator += (T&);
template <class U>
friend ostream& operator<<(ostream& , Sale<U>& );
Sale<T>& operator -= (int);
};

template <class T> Sale<T>& Sale<T>::operator -= (int i)
{
nrStock--;
nrSold++;
sold.push_back(stock[i]);

stock.erase(stock.begin()+i);

time_t now = time(0);
tm *ltm = localtime(&now);

if(ltm->tm_mon == 5 || ltm->tm_mon == 6 || ltm->tm_mon == 7)
{
    (sold[nrSold-1]).setPret((sold[nrSold-1].getPret()/10)*9);
}

return *this;

}

template <class T> Sale<T>::Sale()
{
nrSold = 0;
nrStock = 0;
}

template <class T> ostream& operator<<(ostream& out, Sale<T>& v)
{
out<<"\nWhat we have in stock:\n\n";
for(int i = 0; i < v.nrStock ; i++)
{
    out<<v.stock[i]<<endl;
}

cout<<"\nWhat we sold:\n\n";
for(int i = 0; i < v.nrSold ; i++)
{
    out<<v.sold[i]<<endl;
}


return out;
}

template <class T> Sale<T>& Sale<T>::operator += (T& t)
{
nrStock ++;
stock.push_back(t);

return *this;
}

int main()
{
VAN x;
cin>>x;
cout<<x;

Sale<VAN> v;

v += x;
v += x;

cout<<v;
}

1 个答案:

答案 0 :(得分:0)

所有VAN构造函数都存在逻辑错误:

  1. 在默认构造函数中,sh成员根本没有被初始化,因此它的值是不确定的。

  2. 在转换构造函数中,如果sh参数为0,则s成员未被初始化,因此在这种情况下它的值是不确定的。您的operator>>具有类似的逻辑错误,如果输入为0,则不会更新m.sh成员。

  3. 复制构造函数中的
  4. sh成员根本没有从m复制,因此它的值是不确定的。

  5. 当您将VAN对象推送到vector时,会生成该对象的副本。如果向量需要重新分配其数组以增加其容量,则会生成现有元素的新副本。由于您的复制构造函数已损坏,因此您丢失了sh值。

    你的VAN构造函数需要看起来更像是 1

    VAN::VAN() : Car(), sh(0)
    {
    }
    
    VAN::VAN(int a , float b , int c, int d , int s) : Car(a , b, c , d)
    {
        sh = (s != 0);
    }
    
    VAN::VAN(const VAN& m) : Car(m), sh(m.sh)
    {
    }
    

    1:对于复制构造函数,您实际上可以完全省略它,并让编译器为您自动生成合适的复制构造函数。

    而你的operator>>需要看起来更像这样:

    istream& operator>>(istream& in , VAN& m)
    {
        in >> (Car&)m;
        cout << "Second Hand: ";
        int x;
        in >> x;
        m.sh = (x != 0);
        return in;
    }
    

    在几个旁注:

    • 您的sh成员被声明为int,但显然应该是bool

    • VAN不需要,也不应该被声明为friend Car。如果VAN需要直接访问Car个私人成员,则应将其声明为protected