【发布时间】:2018-05-20 18:38:32
【问题描述】:
我有一个学校项目,我应该在其中构建一个模板类Vanzare,意思是销售。我有 2 个 STL 向量,一个用于库存汽车,一个用于已售汽车,还有 2 个变量用于计算库存汽车数量和售出汽车数量。
该类应该有 -= 运算符重载,并且应该出售汽车,这意味着将其从库存向量中删除(名为 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;
}
【问题讨论】:
-
这是很多代码。请隔离问题,创建一个单独的程序并为我们重新创建它。我们在这里更喜欢一个最小的、可验证的例子。
-
如果要保留多态性并避免对象切片,请保留指针向量。
-
我认为这也值得一提:您通常应该更喜欢 emplace_back 而不是 push_back。 1.push_back vs emplace_back 2.Tip of the Week #112: emplace vs. push_back
-
通过做一个最小的例子,我们并不是要让你的程序尽可能短。我们的意思是分别测试每个部件并消除正常工作的部件。您还应该学习使用调试器来单步调试您的代码。
标签: c++ class templates vector stl