[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Problem with 2 classes and implementation

Posted on 2008-02-02
13
Medium Priority
?
172 Views
Last Modified: 2010-04-21
Hi guys, I am getting some strange errors when trying to compile my project. The project consists (at the moment) of a car class and a parking meter class.

Building target ParkingProgram of project ParkingProgram with configuration Release  (2 errors)
          cd /Users/***/ParkingProgram
    /Developer/usr/bin/g++-4.0 -o /Users/***/ParkingProgram/build/ParkingProgram.build/Release/ParkingProgram.build/Objects-normal/ppc/ParkingProgram -L/Users/***/ParkingProgram/build/Release -F/Users/***/ParkingProgram/build/Release -filelist /Users/***/ParkingProgram/build/ParkingProgram.build/Release/ParkingProgram.build/Objects-normal/ppc/ParkingProgram.LinkFileList -arch ppc -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk
Undefined symbols:
  "ParkedCar::ParkedCar()", referenced from:
      _main in program2.o
  "ParkingMeter::ParkingMeter()", referenced from:
      _main in program2.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
              "ParkedCar::ParkedCar()", referenced from:
                  _main in program2.o
              "ParkingMeter::ParkingMeter()", referenced from:
                  _main in program2.o
            ld: symbol(s) not found
            collect2: ld returned 1 exit status
Build failed (2 errors)

Thanks for the help. Here are my implementations.
parkingmeter.cpp
 
#include <iostream>
#include "ParkingMeter.h"
 
 
 
int ParkingMeter::getTime()
{
        return timePurchased;
}
 
void ParkingMeter::setTime(int time)
{
        timePurchased = time;
}
 
parkedcar.h
 
#ifndef PARKEDCAR_H
#define PARKEDCAR_H
 
class ParkedCar
{
        private:
                char make[30];
                char model[30];
                char color[30];
                int licenceNumber;
                int minutesParked;
        public:
                ParkedCar();
                ParkedCar(const char* make1, const char* model1, const 
                char* color1, int licenceNumber1, int minutesParked1);
                const char* getMake();
                const char* getModel();
                const char* getColor();
                int getLicenceNumber();
                int getMinutesParked();
                void setMake(const char * make1);
                void setModel(const char* model);
                void setColor(const char* color);
                void setLicence(int licenceNumber);
                void setMinutes(int minutesParked); 
};
#endif          
 
parkedcar.cpp
 
#include <iostream>
#include "ParkedCar.h"
 
const char* ParkedCar::getMake()
{
        return make;
}
 
const char* ParkedCar::getModel()
{
        return model;
}
 
const char* ParkedCar::getColor()
{
        return color;
}
 
int ParkedCar::getLicenceNumber()
{
        return licenceNumber;
}
 
int  ParkedCar::getMinutesParked()
{
        return minutesParked;
}
void ParkedCar::setMake(const char* make1)
{
        strcpy(make,make1);
}
void ParkedCar::setModel(const char* model1)
{
        strcpy(model,model1);
}
void ParkedCar::setColor(const char* color1)
{
        strcpy(color,color1);
}
void ParkedCar::setLicence(int licenceNumber1)
{
        licenceNumber = licenceNumber1;
}
void ParkedCar::setMinutes(int minutesParked1)
{
        minutesParked = minutesParked1;
}
        
parkingmeter.h
 
#ifndef PARKINGMETER_H
#define PARKINGMETER_H
 
class ParkingMeter
{
        private:
                int timePurchased;
        public:
                ParkingMeter();
                ParkingMeter(int timePurchased);
                void setTime(int time);
                int getTime();
                
};
#endif
 
 
program2.cpp
 
#include <iostream>
#include "ParkedCar.h"
#include "ParkingMeter.h"
 
using namespace std;
 
int main()
{
        ParkedCar car1;
        ParkingMeter meter1;
        meter1.setTime(100);
        cout << meter1.getTime() << endl;
        car1.setMake("Ford");
        car1.setModel("Taurus");
        car1.setColor("Maroon");
        car1.setLicence(1337);
        car1.setMinutes(25);
        cout << car1.getMake() << endl;
        cout << car1.getModel() << endl;
        cout << car1.getColor() << endl;
        cout << car1.getLicenceNumber() << endl;
        cout << car1.getMinutesParked() << endl;        
}

Open in new window

0
Comment
Question by:pacman32689
  • 7
  • 3
  • 2
  • +1
13 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 400 total points
ID: 20806017
Well, you are declaring both default constructors ( "ParkedCar::ParkedCar()" and  "ParkingMeter::ParkingMeter()") in both header files, yet you aren't providing an implementation in the respective .cpp files. Just add them:
ParkingMeter::ParkingMeter()
{
  // functionality goes here
}
 
ParkedCar::ParkedCar()
{
  // functionality goes here
}

Open in new window

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 1200 total points
ID: 20807402
Same for the other undefined constructors :

        ParkedCar::ParkedCar(const char* make1, const char* model1, const char* color1, int licenceNumber1, int minutesParked1)
        ParkingMeter::ParkingMeter(int timePurchased)

You need to implement those too ...
0
 

Author Comment

by:pacman32689
ID: 20808230
Sorry guys, have been sick all day, thanks for pointer! I will get to working on it.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 400 total points
ID: 20808307
To add to above information:

The constructor was used to initialize and/or set the member variables. You best do that by using an initializer list like that:


ParkedCar::ParkedCar()
    :  licenseNumber(0), minutesParked(0)
{
       make[0] = '\0';
       model[0] = '\0';
       color[0] = '\0';

Some remarks to that:

- if you would omit the constructor in the header, the compiler automatically would create one.
- however, the default constructor wouldn't set your C-type member variables to a well-defined initial value
- that's why you need a implementation for all constructors that explicitly sets all members
- setting the first byte of a char array to zero char makes the char array an empty string
- you better would use std::string instead of char arrays

#include <string>

....
class ParkedCar
{
        private:
                std::string make;
                std::string model;
                std::string color;

Then, the members were initialized automatically. You have no limitation for the length and you easily can assign values:

     model = "Firebird";
     color   = "silver";

- when turning the char arrays to std::string, the second constructor could be the same as you already have and the implementation was made by initializer list only:

ParkedCar::ParkedCar(const char* make1, const char* model1, const
                char* color1, int licenceNumber1, int minutesParked1)  
      : make(make1), model(model1), color(color1),
        licenceNumber(licenceNumber1), minutesParked(minutesParked1)
{
}

That works, cause std::string - like each string class - takes a const char* for one of its constructors.

With the above you would have

int main()
{
        ParkedCar car1("Ford", "Taurus", "Maroon", "1234", 100);
        ...

and could omit all the set functions.

Regards, Alex


0
 

Author Comment

by:pacman32689
ID: 20811622
I am getting some unfamiliar errors like assignment of read-only location. This is my first time using const char pointers, so maybe I am missing something obvious :)
#include <iostream>
#include "ParkedCar.h"
 
ParkedCar::ParkedCar()
{
	make[0] = '\0';
	model[0] = '\0';
	color[0] = '\0';
	licenceNumber = 0;
	minutesParked = 0;
}
ParkedCar::ParkedCar(const char* make1, const char* model1, const char* color1, int licenceNumber1, int minutesParked1)
{
	strcpy(make,make1);
	strcpy(model,model1);
	strcpy(color,color1);
	licenceNumber = licenceNumber1;
	minutesParked = minutesParked1;
}
const char* ParkedCar::getMake()
{
	return make;
}
 
const char* ParkedCar::getModel()
{
	return model;
}
 
const char* ParkedCar::getColor()
{
	return color;
}
 
int ParkedCar::getLicenceNumber()
{
	return licenceNumber;
}
 
int  ParkedCar::getMinutesParked()
{
	return minutesParked;
}
void ParkedCar::setMake(const char* make1)
{
	strcpy(make,make1);
}
void ParkedCar::setModel(const char* model1)
{
	strcpy(model,model1);
}
void ParkedCar::setColor(const char* color1)
{
	strcpy(color,color1);
}
void ParkedCar::setLicence(int licenceNumber1)
{
	licenceNumber = licenceNumber1;
}
void ParkedCar::setMinutes(int minutesParked1)
{
	minutesParked = minutesParked1;
}
	

Open in new window

0
 

Author Comment

by:pacman32689
ID: 20811623
above is ParkedCar.cpp
0
 

Author Comment

by:pacman32689
ID: 20811631
another error is unitialized member 'ParkedCar::make'

ect. with all my char arrays
0
 

Author Comment

by:pacman32689
ID: 20812117
Sorry to bump, but I can't understand what is going on. It is telling me my const char arrays are being uninitialized, which I don't quite understand.
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1200 total points
ID: 20812543
>> assignment of read-only location.

Did you make the class members const char* instead of char* ? const char* means that the string cannot be modified. For example, you can't do :

        strcpy(str1, str2);

if str1 is a const char*


>> unitialized member 'ParkedCar::make'

This is probably related to the previous error.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20819585
>>> class ParkedCar
>>> {
>>>         private:
>>>                 char make[30];
>>>                 char model[30];
>>>                 char color[30];

With that you wouldn't get the error 'assignment of read-only location' as the char aarays are not read-only but writeable.

>>> class ParkedCar
>>> {
>>>         private:
>>>                 const char* make;

But if you turned the member types to const char* these members were const and thus read-only. Then, statements like

     strcpy(make, make1);

would have two errors. First, you try to write to a const member. Second, the pointer wasn't initialized and the pointer was invalid (was not pointing to allocated memory).

 
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20819690

// .h

....
class ParkedCar
{
        private:
              char make[30];
              char model[30];
              char color[30];
....

// .cpp

ParkedCar::ParkedCar(const char* make1, const char* model1, const char* color1, int licenceNumber1, int minutesParked1)
    : licenceNumber(licenceNumber1)
    , minutesParked(minutesParked1)
{
       int len = sizeof(make) - 1;
       strncpy(make, make1, len);
       make[len] = '\0';
       len = sizeof(model) - 1;
       strncpy(model, model1, len);
       model[len] = '\0';
       len = sizeof(color) - 1;
       strncpy(color, color1, len);
       color[len] = '\0';
}

That looks rather bad, doesn't it? But actually it is the only way out to make fixed sized char arrays safe.

Using std::string for the text members it simply was:

ParkedCar::ParkedCar(const char* make1, const char* model1, const
                char* color1, int licenceNumber1, int minutesParked1)  
      : make(make1)
      , model(model1)
      , color(color1)
      , licenceNumber(licenceNumber1)
      , minutesParked(minutesParked1)
{
}


0
 

Author Comment

by:pacman32689
ID: 20819791
Thanks guys, fixed it a bit ago. Awarding points.
0
 

Author Closing Comment

by:pacman32689
ID: 31427521
thanks
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

607 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question