2011-01-24 3 views
0

ここでは初心者のプログラマが宿題を解決しようとしています。私はクラスのSTLのセットを使用しようとしているが、コンパイラは自分のコードについて不平を言う。クラスのC++ STLセット - コンパイラエラーエラーC2664

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: 'カー::車(constの車&)':CONST」に '車*' からパラメータ1を変換することはできませんカー& " 理由:から変換できません『『のconstカー』に』車* ませコンストラクタは、ソースタイプを取らない、またはコンストラクタのオーバーロードの解決ができたあいまいな

私は私が間違っているつもりだ場所がわからないんだけど、ういくつか私の過負荷が間違っている方法を指摘してください?

おかげ

+3

このコードを問題を示す小さな例に結晶化できますか?これは私たちを助けるだけでなく、あなたが間違っていることを突然理解するかもしれません。 –

+1

このエラーの原因となっている行を指摘できますか? –

答えて

4

エラーgstd::set<Car>、ないstd::set<Car*>あるとして、おそらくcarEnters方法でg.insert(currentCar)ラインです。現在の車(*currentCar)への参照を渡すか、ガレージに自動車へのポインタが含まれているようにしてください。また

、あなたはそれ以外のセットがコピーされていると思うような結果が得られない可能性があります

void carEnters(std::set<Car>& g) { } 

void carLeaves(std::set<Car>& g) { } 

...の形で、参考としてgに渡すこともできます。

なぜについて説明が必要な場合は、にコメントを追加してください。私はその日にいくつかのTAingをやっていました。 :)

+0

あなたは勝ちました。私はそれを投稿しようとしていた。しかし、私の投稿をキャンセルしました。 – Nawaz

+0

@Nawaz:常に競合する回答の部屋。 :) – James

+0

私のポストはあなたよりも良くありませんでした。私はあなたの投稿が十分だと思います。 +1。 – Nawaz

0

あなたの問題はあなたのセットはタイプCarの要素を取りますが、あなたはタイプCar*の要素を挿入することである。この場合、

void carEnters(std::set<Car> g) 
{ 
... 
Car *currentCar = new Car; 
... 
g.insert(currentCar); 

currentCarCarへのポインタであり、g.insertCarを期待しています。これを修正するには複数の方法があります - operator<のオーバーロードが機能しなくなりましたが、Car*を使用するように設定を変更することができます(ファンクタを作成してセットに渡して、2つのCar*を取ります)。 currentCarCarに変更できます。しかし、この結果、たくさんのコピーが作成されます。それとも、currentCarを完全に捨て、あなたが設定する必要がすべての変数を設定しますコンストラクタを行うことができます。その後、

Car(const std::string &plate, const std::string &desc)  
{ 
    plateNumber = plate; 
    description = desc; 
    setTimeDateIn(); 
}; 

あなただけのこの操作を行うことができます:

あなたは何をしているかに実際に望ましい
g.insert(Car(desc, plate)); 

誰かがsetTimeDateInに電話するのを忘れるかもしれないので、今、 Carが構築されたときにそれが呼び出されるのがより理にかなっています。

1

私は@Jamesが正しい軌道にあると信じていますが、*CurrentCarを渡すことは本当に正しい答え(少なくともIMO)ではありません。代わりに、あなたが少しをバックアップする必要があります。

Car *currentCar = new Car ;    

おそらくあなたは、これは書くためのコードのルーチン、通常のタイプであるJavaの(または類似したもの)との経験を持っています。しかし、C++では、newを直接使っている(あるいは、少なくともそうでなければならない)のはかなり珍しいはずです。 「あなたは勝ったあなたがstd::set(または何でも)にあなたのcurrentCarを入れたときに、その後

currentCar.whatever = x; 

Car currentCar; 

、その後、次のようなフィールドに記入します:あなたはほぼ確実に代わりたいのです何かを逆参照する必要があります。なぜなら、あなたはCarオブジェクトで始まるからです。これは予想どおりです。さて、私はあなたが車を見上げると、Carオブジェクトも動的に作成していることに気付きましたが、どちらか一方を削除するようなことはないので、コードがメモリをリークしています。

編集:私には、他の選択肢があると付け加えるべきです。現在、あなたは基本的にCarを「ダムデータ」として扱い、そのデータを操作する外部コードを使用しています。あなたのコードを "オブジェクト指向"にするには、Carのデータを読み込むためのコードをクラス自体に移して、外部コードがそのメンバ関数を呼び出すほうがよいでしょう。

もう1つの可能性は、Carを不変オブジェクトにすることです。ユニット化された車を作成し、そのオブジェクトに適切な値を設定する代わりに、私はCarのコンストラクタに正しい値を渡し、それらの値を変更するために現在持っているメンバ関数を削除します。少なくともあなたの目的のために、車のプレート番号を実際に変更する必要はないと思われます。プレート番号が1つしかないはずです。その場合は、コードでそのプレート番号を反映させて直接。

+0

コードを次のように変更しました。 std :: set garage; ケース '1':carEnters(&garage); \t \t \t \t break; – strasser