新手程序员在这里试图完成他的作业。我正在尝试使用一组STL类,但编译器抱怨我的代码。
car.h
#include <string>
#include <iostream>
#include <time.h>
#include <set>
class Car
{
private:
std::string plateNumber;
std::string description;
std::string dateIn;
std::string timeIn;
public:
Car() {};
~Car() {};
Car(std::string plate, std::string desc)
{
plateNumber = plate;
description = desc;
};
void setPlateNumber(std::string plate) ;
std::string getPlateNumber() const;
void setDesc(std::string desc);
void setTimeDateIn() ;
std::string getTimeIn() const;
std::string getDateIn() const;
std::string getDesc() const;
friend std::ostream & operator<<(std::ostream & os, Car &c);
};
std::ostream & operator<<(std::ostream & os, Car& c)
{
os << "Plate Number: " << c.plateNumber << ", Date In: " << c.dateIn << ", " <<
`"Time in: " << c.timeIn << "Description: " << c.description << std::endl;
return os;
}
bool operator< ( const Car& lhs, const Car& rhs)
{
return ( lhs.getPlateNumber() < rhs.getPlateNumber() );
};
main.cpp
#include "stdafx.h"
#include <iostream>
#include <set>
#include <string>
#include "car.h"
void carEnters(std::set<Car> g);
void carLeaves(std::set<Car> g);
void displayContents(std::set<Car> g);
int main ()
{
char choice [80];
// initialize the sets and iterators
std::set<Car> garage;
do // Loop until user quits
{
std::cout <<
std::endl;
std::cout << "Menu:" << std::endl;
std::cout << "-----" << std::endl;
std::cout << "'1' to enter a new car, or " << std::endl;
std::cout << "'2' to exit the front car, or " << std::endl;
std::cout << "'3' to to list all the cars or." << std::endl;
std::cout << "'0' to close the garage: " << std::endl;
std::cin.getline( choice, 1, '\n');
switch ( choice[0] )
{
case '0' :
std::cout << std::endl << "Thanks for playing...\n";
break;
case '1' :
carEnters(garage);
break;
case '2' :
carLeaves(garage);
case '3' :
displayContents(garage);
break;
default:
std::cout << "I'm sorry, I didn't understand that.\n";
break;
}
} while ( choice[0] != '0' ); // Loop again if the user hasn't quit.
return 0;
}
void carEnters( std::set<Car> g)
{
// Car enters garage
std::cout << "Please enter the plate number:" << std::endl;
std::string plate;
std::cin >> plate;
std::cin.ignore();
std::set<Car>::iterator findPlate;
Car* lookup = new Car;
lookup->setPlateNumber(plate);
findPlate = g.find(*lookup);
if (findPlate != g.end()) // Add car to garage
{
Car *currentCar = new Car ;
// Set car parameters
std::cout << "Please type the entering car's description <Model, Color...
> : " << std::endl;
char desc[80];
std::cin.get(desc, 80 );
std::cin.ignore();
currentCar->setDesc(desc);
currentCar->setTimeDateIn();
currentCar->setPlateNumber(plate);
g.insert(currentCar);
}
else // Plate is already in garage set
{
std::cout << "Sorry, this car is already in the garage!" <<
std::endl;
}
}
void carLeaves( std::set<Car> g)
{
std::string plate;
std::cout << "Which plate is leaving?" << std::endl;
std::cin >> plate;
std::cin.ignore();
// Find car's plate number in the garage set
// for (findPlate=garageSet.begin(); findPlate !=garageSet.end(); findPlate++)
std::set<Car>::iterator findPlate;
Car lookup(plate,"");
findPlate = g.find(lookup);
if (findPlate != g.end())
{
// Display time in and then remove car from set of cars
std::cout << "Car out at " << (*findPlate).getDateIn() << ", " <<
(*findPlate).getTimeIn() << std::endl;
g.erase(findPlate);
}
else
{
std::cout << "Car was not found in set of Cars!" << std::endl;
}
}
// Car class function implementation
void Car::setPlateNumber(std::string p)
{
plateNumber = p;
}
std::string Car::getPlateNumber() const
{
return plateNumber;
}
void Car::setDesc(std::string d)
{
description = d;
}
void Car::setTimeDateIn()
{
char dat[9];
char tim[9];
_strdate_s(dat);
_strtime_s(tim);
dateIn=dat;
timeIn=tim;
}
std::string Car::getTimeIn() const
{
return timeIn;
}
std::string Car::getDateIn() const
{
return dateIn;
}
std::string Car::getDesc() const
{
return description;
}
// Display the car set
void displayContents(std::set <Car> garage)
{
// function displays current contents of the parking garage.
std::set <Car>::iterator carIndex;
std::cout << std::endl << "Here are all the cars parked: " << std::endl;
for (carIndex = garage.begin();
carIndex != garage.end();
++carIndex )
{
std::cout << " " << carIndex->getPlateNumber() << ", Date In: " <<
carIndex->getDateIn() << ", " << "Time In: " << carIndex->getTimeIn() << "Description:
" << carIndex->getDesc() << std::endl;
}
}
我从编译器得到的错误是这样的: xmemory(208):错误C2664:'Car :: Car(const Car&amp;)':无法将参数1从'Car *'转换为'const Car&amp;' 原因:无法从'Car *'转换为'const Car' 没有构造函数可以采用源类型,或者构造函数重载解析是不明确的
我不确定我哪里出错了,有人请指出我的过载是怎么回事吗?
由于
答案 0 :(得分:4)
错误可能是g.insert(currentCar)
方法中的carEnters
行,因为g
是std::set<Car>
,而不是std::set<Car*>
。传递对当前汽车的引用(*currentCar
)或使车库包含指向汽车的指针。
此外,您可能希望以... {/ p>的形式传递g
作为参考。
void carEnters(std::set<Car>& g) { }
void carLeaves(std::set<Car>& g) { }
否则正在复制该集,您可能无法获得所需的结果。
如果您需要解释任何这些的 why ,请添加评论。我过去常常做一些TAing。 :)
答案 1 :(得分:1)
我相信@James走在正确的轨道上,但是通过*CurrentCar
并不是正确答案(至少是IMO)。相反,你应该稍微备份一下:
Car *currentCar = new Car ;
也许您之前有使用Java(或类似的东西)的经验,这是一种常规的,正常的代码类型。但是,在C ++中,直接使用new
(或者至少应该是)非常不寻常。你几乎肯定想要的是:
Car currentCar;
然后你会填写以下字段:
currentCar.whatever = x;
然后,当您将currentCar
放入std::set
(或其他)时,您不必取消引用任何内容,因为您将从Car
对象开始,是预期的。顺便说一句,我注意到当你查看汽车时,你也在动态创建一个Car
对象 - 但你似乎永远不会删除任何一个,所以你的代码就是泄漏内存。 / p>
编辑:我应该补充说,有些替代方案可能更可取。现在,您基本上将Car
视为“哑数据”,并使用外部代码对该数据进行操作。如果您希望您的代码是“面向对象的”,那么将用于读取Car
的数据的代码移动到类本身几乎肯定会更好,因此外部代码只会调用该成员函数。
另一种可能性是使Car
成为不可变对象。我不是创建一个单元化的汽车,然后在该对象中设置适当的值,而是将正确的值传递给Car
的构造函数,并消除当前用于更改这些值的成员函数。至少就你的目的而言,你似乎并不需要实际更改汽车的车牌号码 - 它显然只有一个车牌号码,在这种情况下,你的代码更好地反映(并强制执行)直接
答案 2 :(得分:0)
您的问题是您的集合采用Car
类型的元素,但您要插入Car*
类型的元素:
void carEnters( std::set<Car> g)
{
...
Car *currentCar = new Car;
...
g.insert(currentCar);
在这种情况下,currentCar
是指向Car
的指针,g.insert
指的是Car
。有多种方法可以解决此问题 - 您可以将设置更改为使用Car*
,但重载的operator<
将不再有效(您必须创建一个传递给该集合的仿函数并且需要两个Car*
S)。您可以将currentCar
更改为Car
类型。然而,这导致了一堆复制。或者你可以完全抛弃currentCar
并创建一个构造函数来设置你需要设置的所有变量:
Car(const std::string &plate, const std::string &desc)
{
plateNumber = plate;
description = desc;
setTimeDateIn();
};
然后你可以这样做:
g.insert(Car(desc, plate));
这实际上比你现在所做的更好,因为有人可能会忘记拨打setTimeDateIn
。在Car
构建时调用它更有意义。