0

I've lurked and browsed for a while around here already, but this is my first time posting. Hope I've got the rules and format down pat.

I'm been coding for several months now, so still pretty new at this. Right now, I'm trying to implement a very basic parkingmeter class, with only 2 functions. One to insert quarters, and one to check remaining time. Member variables are maxTime, rate, and time.

I got some functionality up and running, but it kept giving me strange results with my checkTime function. I tested at almost every line, and I realize that after I exit the constructor, the values I entered disappear and are replaced with a really long number. I can't figure out why this is happening. It's not my first time using classes, constructors, instantiating objects, and such, and I don't see what I've done differently this time.

Could any of you experts let me know where I've messed up?

Here's my header file:

#ifndef PARKINGMETER_H_INCLUDED
#define PARKINGMETER_H_INCLUDED

#ifndef PARKINGMETER_H_INCLUDED
#define PARKINGMETER_H_INCLUDED

class ParkingMeter {
private:
    int maxTime;
    double time, rate;

public:
    ParkingMeter();
    ParkingMeter(int, double);
    ~ParkingMeter();
    void insertQtrs(int);
    double checkTime(double);
    double getTime();
    void setTime(double);

};

And here's my implementation:

#include <iostream>
#include <stdexcept>
#include <ctime>
#include "ParkingMeter.h"

using namespace std;

ParkingMeter::ParkingMeter() {       //default constructer
    maxTime = 120;
    rate = .25;
    time = 0;
}

ParkingMeter::ParkingMeter (int maxTime, double rate) {       //constructor
    maxTime = maxTime;
    rate = rate;
    cout<<"maxTime is "<<maxTime<<endl;
    cout<<"rate is "<<rate<<endl;
}

ParkingMeter::~ParkingMeter(){      //destructor
}

void ParkingMeter:: insertQtrs(int quarters){
    ParkingMeter test(this->maxTime, this->rate);
    cout<<"maxTime is "<<test.maxTime<<endl;
    cout<<"rate is "<<test.rate<<endl;
    cout<<"You have inserted: "<<quarters<<" quarters."<<endl;
    double time = quarters * (rate * 60);
    if ( time > 120)
        time = 120;
    this ->setTime(time);

}

double ParkingMeter:: checkTime (double startTime){
    ParkingMeter test(this->maxTime, this->rate);
    double elapsed = clock() - startTime;
 //   test.maxTime = this->maxTime;
    cout<<"test: "<<test.maxTime<<endl;
    cout<<"elapsed time: "<<elapsed<<endl;
    cout<<"meter time: "<<time<<endl;
    cout <<"Your remaining time is: "<< (time - (elapsed / ((double)CLOCKS_PER_SEC)));
}

/*double ParkingMeter:: getTime (){
    int time = this-> maxTime;
    cout<<"time: "<<time<<endl;
    return time;
}*/

void ParkingMeter:: setTime (double time){
    this ->time = time;
}

int main () {
    double maxTime, rate;
    int quarters;
    char y;

    cout<<"Please enter the max parking time and rate, separated by a space: "<<endl;
    cin>>maxTime>>rate;
    ParkingMeter meter(maxTime, rate);
    cout<<"Please enter the amount of quarters you wish to enter: "<<endl;
    cin>>quarters;
    clock_t start = clock();
    meter.insertQtrs(quarters);
    cout<<"Please enter Y to check remaining time: "<<endl;
    cin>>y;

    if (y == 'y'){
       double startTime = start;
        cout<<"starttime: "<<startTime<<endl;
        meter.checkTime (startTime);
    }



}
D_S_B
  • 208
  • 3
  • 9
  • The self-assignments are just another reason you should use constructor initializer lists. – chris Sep 15 '13 at 14:46
  • 1
    For starters, `checkTime` doesn't return anything even though its signature says it does. – jrok Sep 15 '13 at 14:47
  • 1
    Doubling include guards doesn't make them better! In fact, it should prevent the header from working... – Dietmar Kühl Sep 15 '13 at 14:47
  • You **always** need to check after reading that the operation was successful. That is, you want to use `if (std::cin >> quarters)` and likewise for other read operations. – Dietmar Kühl Sep 15 '13 at 14:48
  • @DietmarKühl, could you clarify what you mean by doubling include guards? – D_S_B Sep 15 '13 at 15:48
  • @D_S_B: The header posted starts of with `#ifndef PARKINGMETER_H_INCLUDED` and `#define PARKINGMETER_H_INCLUDED` - twice. – Dietmar Kühl Sep 15 '13 at 15:52
  • @DietmarKühl, I'm using CodeBlocks and it filled that in automatically for me. – D_S_B Sep 15 '13 at 16:16

1 Answers1

1

Here's your problem:

ParkingMeter::ParkingMeter (int maxTime, double rate) {       //constructor
   this->maxTime = maxTime;
   this->rate = rate;
// ^^^^^^ note this!

you might want to use an initializer list, in which case you can (and must) drop the this->. To avoid problems, I suggest you use different names for member variables, e.g., add _:

ParkingMeter::ParkingMeter (int maxTime, double rate)
    : maxTime_( maxTime ), rate_( rate )
{
    cout<<"maxTime is "<<maxTime_<<endl;
    cout<<"rate is "<<rate_<<endl;
}
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • K, I used the initializer list and that seemed to fix this issue. Could you clarify why it did, though? Was it because the variables had the same name? – D_S_B Sep 15 '13 at 15:46
  • Also, I don't know how to edit my original question, but my checkTime function is giving me the seconds elapsed, and I'm trying for the minutes. Could you see where I went wrong with that? – D_S_B Sep 15 '13 at 15:47
  • @D_S_B Yes, it was because of the same name in the function body. In the initializer list the rules are a bit different, as the variable that is initialized is *always* a member and only the expression which is used to initialize it looks up the parameter names. For the seconds vs. minutes problem: Just divide the value by 60? If that is not the solution, then I don't get the question. – Daniel Frey Sep 15 '13 at 20:16