Solved

CLASS vector functions

Posted on 2003-11-02
21
458 Views
Last Modified: 2013-12-14
I am trying to access my functions of a class vector... without exposing my private variables.  I will narrow this down two functions that work together.  These functions worked fine, when they were pure class functions, but I need some help reworking them for the class vector.  I have tried to include enough code for you to attempt to run this on your compiler.

FYI... the code comes from 3 places (as per my professor's instructions).  I have included my search function (that is working) in case you see a need for it.
Any ideas?


#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;

THE CLASS:
#ifndef APARTMENT_H
#define APARTMENT_H
//Class for an Apartment:
class Apartment
{
public:
    Apartment(int buildNum, int aptNum, int BA_Num, int aptType, bool view, bool highFloor, bool rentalStatus, string cust_name, bool rent_paid);

    void newMonth( );
    double setPastDue (double rentDue);
    friend searchFor(vector<Apartment> &record);
    int the_BA_Num;            //building & apartment number combined

private:
    int the_buildNum;          //building number
    int the_aptNum;            //apartment number
    int the_aptType;           //apartment type (# of bedrooms)
    bool the_view;             //lake view (T or F)
    bool the_highFloor;        //high floor (T or F)
    bool the_rentalStatus;     //rental status (T or F)
    string the_cust_name;      //customer's name
    bool PastDue;              //past due status (T or F)
    bool the_rent_paid;        //rent paid status (T or F)
    double rentDue;            //amount of rent due
    double rent;               //amount of base rent
};                                      
#endif

THE FUNCTIONS:
    int search(vector<Apartment> record)
   {
        int BNum, ANum;
        cout << "What building number: ";
        cin >> BNum;
        cout << "What apartment number: ";
        cin >> ANum;
        int BA_temp = (BNum * 1000) + ANum;
   for (int i=0; i < SIZE; i++)
        {
     if(record[i].the_BA_Num == BA_temp)
           return i;
        }
        return SIZE;
    }


    void Apartment::newMonth( )
      //Precondition: Apartment object is set up.  Test for an outstanding balance.
      //Postcondition: Rent for new month is added to "rentDue".
      //      If there was an outstanding balance "PastDue" function was called.
    {
        for (int i = 0; i < SIZE; i++)
        {
        the_rent_paid = false;               //sets all rents to False
        if (rentDue >= 0.01)                 //checks for an outstanding balance
  //              setPastDue(record, rentDue);               //if so, calls "setPastDue" function
        rentDue = (rentDue + rent);        
     }
     }

    double Apartment::setPastDue(double rentDue)
      //Precondition: "newMonth" indicates that there is a dollar amount due.
      //Postcondition: Adds $50.00 to the "rentDue".
    {
        return (rentDue + 50.0);                     //adds $50.00 to "rentDue"
    }

THE FUNCTION CALL:
           //ADD ONE MONTH RENT TO ALL APARTMENTS
        {
        for (int i=0; i < SIZE; i++)
         {
         record[i].newMonth();
         }
         cout << "ALL RENTS HAVE BEEN UPDATED.\n" << endl;
                    }
0
Comment
Question by:puckerhoop
  • 9
  • 6
  • 4
  • +1
21 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 9667882
What you need is a copy constructor and an assignment operator for your class:

class Apartment
{
public:
   Apartment(int buildNum, int aptNum, int BA_Num, int aptType, bool view, bool highFloor, bool rentalStatus, string cust_name, bool rent_paid);

  Apartment ( const Apartment& r) {
      the_buildNum = r.the_buildNum;
      the_aptNum = r.the_aptNum;
      the_aptType = r.the_aptType;
      the_view = r.the_view;          
      the_highFloor = r.the_highFloor;
      the_rentalStatus = r.the_rentalStatus;
      the_cust_name = r.the_cust_name;
      PastDue = r.PastDue;    
      the_rent_paid = r.the_rent_paid;
      rentDue = r.rentDue;  
      rent = r.rent;
  }

  Apartment& operator ( const Apartment& r)  {
      the_buildNum = r.the_buildNum;
      the_aptNum = r.the_aptNum;
      the_aptType = r.the_aptType;
      the_view = r.the_view;          
      the_highFloor = r.the_highFloor;
      the_rentalStatus = r.the_rentalStatus;
      the_cust_name = r.the_cust_name;
      PastDue = r.PastDue;    
      the_rent_paid = r.the_rent_paid;
      rentDue = r.rentDue;  
      rent = r.rent;

         return *this;
  }

//...
};
0
 
LVL 86

Expert Comment

by:jkr
ID: 9667886
Ooops, that should read

 Apartment& operator = ( const Apartment& r)  {
0
 

Author Comment

by:puckerhoop
ID: 9668017
The header file (with the class declaration) and functions need to be in separate files.
I have declared, as suggested... but it can't access the class variable:

errors:
'operator =(const Apartment&)' must be a member function
Undefined symbol 'the_buildNum'
'Apartment::the_buildNum' is not accessible
0
 
LVL 86

Expert Comment

by:jkr
ID: 9668069
>>in separate files.

Then, have you made sure that the implemetation reads

Apartment::Apartment ( const Apartment& r) {
    the_buildNum = r.the_buildNum;
    the_aptNum = r.the_aptNum;
    the_aptType = r.the_aptType;
    the_view = r.the_view;          
    the_highFloor = r.the_highFloor;
    the_rentalStatus = r.the_rentalStatus;
    the_cust_name = r.the_cust_name;
    PastDue = r.PastDue;    
    the_rent_paid = r.the_rent_paid;
    rentDue = r.rentDue;  
    rent = r.rent;
}

Apartment& Apartment::operator = ( const Apartment& r)  {
    the_buildNum = r.the_buildNum;
    the_aptNum = r.the_aptNum;
    the_aptType = r.the_aptType;
    the_view = r.the_view;          
    the_highFloor = r.the_highFloor;
    the_rentalStatus = r.the_rentalStatus;
    the_cust_name = r.the_cust_name;
    PastDue = r.PastDue;    
    the_rent_paid = r.the_rent_paid;
    rentDue = r.rentDue;  
    rent = r.rent;

         return *this;
}

?
0
 

Author Comment

by:puckerhoop
ID: 9668133
error:
'Apartment::=(const Apartment)' is not a member of 'Apartment'

I have tried to add the 'operator=' into the header file, but this doesn't help.
0
 
LVL 15

Assisted Solution

by:efn
efn earned 250 total points
ID: 9668171
A few more hints:

You have a loop that goes through the vector and calls newMonth for each Apartment in the vector.  So each time newMonth is called, it is called with a specific Apartment object.  An Apartment has only one rentDue member, so all newMonth has to do is deal with one object's rentDue.  Therefore, you don't need a loop inside newMonth.

setPastDue doesn't do what the comments say.  It calculates the value of rentDue + 50.0 and returns this value.  It doesn't do anything to rentDue.

Just as the vector doesn't have to know about Apartments, the Apartments don't have to know they are in a vector.  You can use an expression like "record[i]" to select a specific Apartment from the vector, then do things with that Apartment (like newMonth) just the same as if it were standing alone.

--efn
0
 
LVL 86

Expert Comment

by:jkr
ID: 9668269
Hu, I am at my wits end - are you sure it reads

//header file

class Apartment
{
public:
  Apartment(int buildNum, int aptNum, int BA_Num, int aptType, bool view, bool highFloor, bool rentalStatus, string cust_name, bool rent_paid);

 Apartment ( const Apartment& r);
 Apartment& operator = ( const Apartment& r);
//...
};

//implementation file

Apartment::Apartment ( const Apartment& r) {
   the_buildNum = r.the_buildNum;
   the_aptNum = r.the_aptNum;
   the_aptType = r.the_aptType;
   the_view = r.the_view;          
   the_highFloor = r.the_highFloor;
   the_rentalStatus = r.the_rentalStatus;
   the_cust_name = r.the_cust_name;
   PastDue = r.PastDue;    
   the_rent_paid = r.the_rent_paid;
   rentDue = r.rentDue;  
   rent = r.rent;
}

Apartment& Apartment::operator = ( const Apartment& r)  {
   the_buildNum = r.the_buildNum;
   the_aptNum = r.the_aptNum;
   the_aptType = r.the_aptType;
   the_view = r.the_view;          
   the_highFloor = r.the_highFloor;
   the_rentalStatus = r.the_rentalStatus;
   the_cust_name = r.the_cust_name;
   PastDue = r.PastDue;    
   the_rent_paid = r.the_rent_paid;
   rentDue = r.rentDue;  
   rent = r.rent;

         return *this;
}
0
 

Author Comment

by:puckerhoop
ID: 9668449
To make sure that nothing else is interfering, I just started a new project with just the header file (class) and one file with the functions and main (limited down to the functions we are discussing).
I am getting a fatal error.  That compiles, but freezes on  a blank screen.
 (I am using Borland 5.0).
I am rebooting and going to attempt in MS Visual C++
0
 

Author Comment

by:puckerhoop
ID: 9668658
files compile fin, but link in Visual C++ has a fatal:

LINK : fatal error LNK1168: cannot open Debug/desperate.exe for writing
Error executing link.exe.

0
 

Author Comment

by:puckerhoop
ID: 9668947
If you are still out there... I have found the fatal (it had to do with something else).
Once I have this functionality... how do I use it?

error:
Undefined symbol 'r'

???
   for (int i=0; i < SIZE; i++)
        {
     if(r[i].BA_Num == BA_temp)
           return i;
        }
        return SIZE;
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 15

Expert Comment

by:efn
ID: 9669024
You don't need necessarily need to use it directly--you need it to make the vector work.  When you put an Apartment into the vector, the vector code needs to be able to make a copy of the object.

If your vector is named "record" as you showed before, you should still refer to it by that name.  r is something defined in the copy constructor and the assignment operator, but not in the search function.

--efn
0
 

Author Comment

by:puckerhoop
ID: 9669121
Are class vectors really this hard, or am I just a fool?
Just when I think I understand them, I can't get them to work!

The only way my Search functionality is working is if the class variables are made private (which causes other problems and isn't proper code).

I have put in the code and it is compiling, but it does not help my functionality.

I still can not recognize a variable within my vector!
error:
'the_build_num' is not a member of 'Apartment'

I have also tried to write code for a function to 'get' the variable, but this doesn't seem to work.

    int search(vector<Apartment> record)
   {
        int BNum, ANum;
        cout << "What building number: ";
        cin >> BNum;
        cout << "What apartment number: ";
        cin >> ANum;
        int BA_temp = (BNum * 1000) + ANum;
   for (int i=0; i < SIZE; i++)
        {
     if(record[i].the_build_num  ==  BNum)
           return i;
        }
        return SIZE;
    }

0
 
LVL 15

Expert Comment

by:efn
ID: 9669150
> Are class vectors really this hard, or am I just a fool?

They're not really hard if you understand classes and vectors.  It seems to me that you are just missing some basic information.

> The only way my Search functionality is working is if the class variables are made private (which causes other problems and isn't proper code).

Did you mean "public"?  Many experts recommend against having public data members.

> 'the_build_num' is not a member of 'Apartment'

Check the spelling.  You spelled it differently in the class declaration.

--efn
0
 

Author Comment

by:puckerhoop
ID: 9669173
I have worked with classes and had no problems with them.
Our instructor wizzed through vectors and our book has very little on them.  I have been primarily trying to treat them like an array (which seems to work for int vectors, but not class vectors).

I do think my entire problem is just a basic misunderstanding of class vectors.  Do you know any good places that I could garner this information?  I have tried web searches... but to no avail... they all deal with int or char vectors.

Yes, I did mean "public"... I really don't want them in public, I want to keep them in private.

I corrected the spelling, but it still didn't work!
It will work to pull a class function, but not a variable within the class and in therefore in the vector.
0
 
LVL 15

Expert Comment

by:efn
ID: 9669272
I always recommend the book "The C++ Standard Library" by Nicolai M. Josuttis, but it's may be overkill for your current need.

You should be able to treat a vector like an array that knows how big it is and automatically grows.  There are fancier things you can do with one, but that should be adequate for a start.  All a vector requires of a class is that it be assignable and copyable, which is why jkr advised you to add those functions.

If you provide more information about what's not working, I or somebody else can probably help you.

--efn
0
 

Author Comment

by:puckerhoop
ID: 9669295
the biggest issue is that my compiler thinks that there is code in the header... this happens whenever I try to access the variables in the class vector.
ie.
     if(record[i].the_buildNum == BNum && record[i].the_aptNum == ANum)

how do I access the private variables?
0
 
LVL 15

Expert Comment

by:efn
ID: 9669427
I think this "code in the header" bit is Borland-specific.

http://www.sirma.bg/Jogy/Reisdorph/OWL.htm

suggests that all your STL includes should be after the #pragma hdrstop directive.  Maybe that will help.

You can make accessor functions for the private variables.  For example:

class Apartment
{
public:
  int numberOfResidents() { return m_residents; }
private:
  int m_residents;
}

if (record[i].numberOfResidents() == 0)
  cout << "Nobody home";

You don't necessarily have to access the private data for the search function.  I suggested this in your previous question as a simple and basic approach.  Alternately, you could provide a way to show an Apartment a pair of building and apartment numbers and ask it "Is this you?"  This could be a member function something like this:

bool matches(int building, int apt);

Then you would use it like this:

if (record[i].matches(BNum, ANum))

--efn
0
 

Author Comment

by:puckerhoop
ID: 9669625
efn,
it  wants to turn my class vector to be an int vector for this formatting!
why oh why won't it take my class vector?
0
 
LVL 15

Expert Comment

by:efn
ID: 9672235
Beats  me.  I can't advise you without more information.  Show some code and quote some error messages.
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10242441
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Split: jkr {http:#9667882} & efn {http:#9668171}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

746 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now