C ++ STL类的集合 - 编译器错误错误C2664

时间:2011-01-24 18:22:57

标签: c++ class stl set

新手程序员在这里试图完成他的作业。我正在尝试使用一组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'           没有构造函数可以采用源类型,或者构造函数重载解析是不明确的

我不确定我哪里出错了,有人请指出我的过载是怎么回事吗?

由于

3 个答案:

答案 0 :(得分:4)

错误可能是g.insert(currentCar)方法中的carEnters行,因为gstd::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构建时调用它更有意义。