Inheritance

This program reads in a text file with information and is suppose to print it out in its respective format. Then it will do the taxes. I am having troubles with having it print.

This is what the text file looks like:
Residential yes 5000000 no 129-Avatar-Lane
Commercial no 2995342 no 0 24-Secret-Tunnel-Turnpike
Commercial yes 24668832 yes 20 23-Metal-Bend
Residential no 7334211 no 85-Sparky-Sparky-Boom-Village
Residential no 345678 yes Banana-Onion-Road
Residential yes 200000 yes 42-Iris-Way
Commercial no 1234567 yes 20.5 350-Sea-Towers
Commercial yes 77299351 no 0 12-Spirit-Way

And this is how it should be printed:
All properties:
Address: 129-Avatar-Lane. Rental. Estimated value: 5000000.00. A Residential Property. NOT occupied.
Address: 24-Secret-Tunnel-Turnpike. NOT rental. Estimated value: 2995342.00. A Commercial Property. NOT in a discount zone.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include "Property.h"
#include "Residential.h"

using namespace std;

void GetFile(string fileName, vector<Property*>&allProperties){
    string line;
    string type;
    int ID = 0;
    
    cout << "Where should I read the data from: " << endl;
    cout << endl;
    cin >> fileName;
    ifstream input;
    input.open(fileName);
    
    while (getline(input, line)) {
        stringstream inLine(line);
        string propertyType;
        bool isRental;
        int value;
        bool isOccupied;
        //bool Getdiscount;
        //double discountRate;
        string address;
        inLine >> propertyType;
        
        if (inLine >> propertyType) {
            if (type == "Residential") {
                inLine >> isRental;
                inLine >> value;
                inLine >> isOccupied;
                inLine >>address;
                    Property* residential = new Residential(address, isRental, value, isOccupied);
                    allProperties.push_back(residential);
                    ID++;
                }
            }
    }
    input.close();
    return;
}
void Print(vector<Property*> allProperties) {
    cout << "All properties: "<< endl;
    for (int i = 0; i < allProperties.size(); i++){
        cout << allProperties[i]->ToString();
        cout << endl;
        return;
    }
}

int main() {
    vector<Property*> allProperties;
    string fileName;
    
    cout << "starting..." << endl;
    GetFile(fileName, allProperties);
    Print(allProperties);
    
    return 0;
}
What about adding the code of "Property" and "Residential" classes?
#include "Property.h"

using namespace std;

int Property::id = 0;
Property::Property(){

}

Property::Property(string address, bool isRental, int value){
this->address = address;
this->isRental = isRental;
this->value = value;
this->ID = id++;
}
bool Property::GetRental(){
return isRental;
}

string Property::GetAddress(){
return address;
}
int Property::GetValue() {
return value;
}
double Property::GetTax() {
return valueWithTax;
}
int Property::GetID() const{
return ID;
}
string Property::ToString(){
string rentalType;
if (isRental == 0) {
rentalType = "Rental";
}
else {
rentalType = "Not Rental";
}
stringstream ss;
ss << "Address: " << address << "Rental: " << isRental << "Estimated value: " << value << endl;
return ss.str();
}

#include "Residential.h"
#include "Property.h"

Residential::Residential() : Property("",false, 0){ //bool rental, int value, string address

}
Residential::Residential(string address, bool isRental, int value, bool isOccupied) : Property(address, isRental, value){
this->isOccupied = isOccupied;
}
bool Residential::GetOccupied(){
return isOccupied;
}
double Residential::GetTax() {
double taxRate;
if (isOccupied) {
taxRate= 0.006;
}
else {
taxRate = 0.009;
}
double tax = GetValue() * taxRate;
return tax;
}
string Residential::ToString() {
string rentalType;
if (GetRental() == 1)
{
rentalType = "Rental";
}
else
{
rentalType = "NOT Rental";
}

string occupiedStatus;
if (isOccupied == 1)
{
occupiedStatus = "occupied";
}
else
{
occupiedStatus = "NOT occupied";
}
stringstream ss;
ss << "Address:" << GetAddress() << " " << rentalType << " " << "Estimated Value: " << GetValue() << " " << isOccupied << endl;
return ss.str();
}
Are you working on a two-level inheritance project?
Because you gave us only information about the first level (class Residential)...
As a matter of fact, you kept your header files secret, as if it would be possible to compile a project without them; you gave us an example file without warning us that lines contain different quantities of data; you are likely be working on a two-level inheritance (how to justify the different numbers of data otherwise?), but you gave us information only on the first level...
I don't want to sound negative, but if you don't want people to help you, you should not ask for help.

Anyway, I tryed to work out missing information and improve the input file.
This code compiles and looks more or less like what you were asking (apart from precision of doubles and similar details), so I hope it can be useful at least for hints.
(It will take more than one post.)

Property.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef PROPERTY_H
#define PROPERTY_H

#include <string>

class Property
{
public:
   Property(std::string addressArg = "", bool isRentalArg = false,
            int valueArg = 0);

   bool getRental() const;
   std::string getAddress() const;
   int getValue() const;
   double getTax() const;
   int getID() const;
   virtual std::string toString();

protected:
   std::string address;
   bool isRental {false};
   int value {0}; // should be double
   int ID {0};
   virtual ~Property() {} // if you plan not to manage any resource
                          // in this class, you don't need to declare
                          // the destructor virtual

private:
   double value_with_tax {0.0};

   static int id;
};

#endif // PROPERTY_H 


Property.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "Property.h"

int Property::id = 0;

Property::Property(std::string addressArg, bool isRentalArg, int valueArg)
   : address {addressArg}, isRental {isRentalArg}, value {valueArg}
{
   ID = id++;
}

bool Property::getRental() const { return isRental; }

std::string Property::getAddress() const { return address; }

int Property::getValue() const { return value; }

double Property::getTax() const { return value_with_tax; }

int Property::getID() const { return ID; }

std::string Property::toString()
{
   std::string information;
   if (isRental) {
      information = "Rental";
   }
   else {
      information = "Not Rental";
   }

   information = "Address: " + address + "; Rental: " + information
                 + "Estimated value: " + std::to_string(value);

   return information;
}


Residential.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef RESIDENTIAL_H
#define RESIDENTIAL_H

#include <string> // already included in Property.h, anyway...
#include "Property.h"

class Residential : public Property
{
public:
   Residential();
   Residential(bool isOccupiedArg, std::string addressArg = 0,
               bool isRentalArg = false, int valueArg = 0);

   bool getOccupied() const;
   double getTax() const;
   virtual std::string toString() override;

protected:
   bool isOccupied {false};
   virtual ~Residential() {}
};

#endif // RESIDENTIAL_H 


Residential.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "Residential.h"

//bool rental, int value, string address
Residential::Residential() : Property()
{}

Residential::Residential(bool isOccupiedArg, std::string addressArg,
                         bool isRentalArg, int valueArg) :
                         Property(addressArg, isRentalArg, valueArg)
{
   isOccupied = isOccupiedArg;
}

bool Residential::getOccupied() const { return isOccupied; }

double Residential::getTax() const
{
   double taxRate;
   if (isOccupied) {
      taxRate = 0.006;
   }
   else {
      taxRate = 0.009;
   }
   double tax = getValue() * taxRate;
   return tax;
}

std::string Residential::toString()
{
   std::string information;
   if (isRental) { // or Property::isRental, if you want to improve readability
      information = "Rental";
   } else {
      information = "NOT Rental";
   }

   std::string occupiedStatus;
   if (isOccupied) {
      occupiedStatus = "occupied";
   } else {
      occupiedStatus = "NOT occupied";
   }

   information = "Address:" + address + "; " + information
                 + "; Estimated Value: " + std::to_string(value) + "; "
                 + occupiedStatus;

   return information;
}


Commercial.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef COMMERCIAL_H
#define COMMERCIAL_H

#include <string>
#include "Residential.h"

class Commercial : public Residential
{
public:
   Commercial(double mysteryArg = 0.0, bool isOccupiedArg = false,
              std::string addressArg = "", bool isRentalArg = false,
              int valueArg = 0);
   std::string toString();

private:
   double mystery {0.0};
};

#endif // COMMERCIAL_H 


Commercial.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "Commercial.h"

Commercial::Commercial(double mysteryArg, bool isOccupiedArg,
                       std::string addressArg, bool isRentalArg,
                       int valueArg) :
   Residential(isOccupiedArg, addressArg, isRentalArg, valueArg)
{
   mystery = mysteryArg;
}

std::string Commercial::toString()
{
   std::string information;
   if (isRental) { // or Property::isRental, if you want to improve readability
      information = "Rental";
   } else {
      information = "NOT Rental";
   }

   std::string occupiedStatus;
   if (isOccupied) {
      occupiedStatus = "occupied";
   } else {
      occupiedStatus = "NOT occupied";
   }

   information = "Address:" + address + "; " + information
                 + "; Estimated Value: " + std::to_string(value) + "; "
                 + occupiedStatus + "; mystery: " + std::to_string(mystery);

   return information;
}

Last edited on
main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include "Residential.h"
#include "Commercial.h"

void getFile(std::vector<Property*>& allProperties);

// print: poor name. Also: std::print already defined in <locale>
void printEstate(std::vector<Property*>& allProperties);
void askForPropertiesFile(std::ifstream& estate);

int main()
{
   std::vector<Property*> allProperties;

   std::cout << "starting...\n";
   getFile(allProperties);
   printEstate(allProperties);

   return 0;
}

void getFile(std::vector<Property*>& allProperties)
{
   std::ifstream input;
   askForPropertiesFile(input);
   // File example:
   // Residential yes 5000000  no   0   129-Avatar-Lane
   // Commercial  no  2995342  no   0.0 24-Secret-Tunnel-Turnpike
   // Commercial  yes 24668832 yes 20.0 23-Metal-Bend
   // Residential no  7334211  no   0   85-Sparky-Sparky-Boom-Village
   // Residential no  345678   yes  0   Banana-Onion-Road
   // Residential yes 200000   yes  0   42-Iris-Way
   // Commercial  no  1234567  yes 20.5 350-Sea-Towers
   // Commercial  yes 77299351 no   0.0 12-Spirit-Way
   // structure could be:
   // std:string, bool, integer, bool, double, std::string
   struct FileData {
      std::string which_class;
      std::string is_rental;
      int value {0};
      std::string is_occupied;
      double mystery {0.0};
      std::string address;
   };

   FileData filedata;
   while(input >> filedata.which_class >> filedata.is_rental
               >> filedata.value >> filedata.is_occupied
               >> filedata.mystery >> filedata.address) {
      bool rental = false;
      if(filedata.is_rental == "yes") {
         rental = true;
      }
      bool occupied = false;
      if(filedata.is_occupied == "yes") {
         occupied = true;
      }
      if(filedata.which_class == "Commercial") {
         Commercial* comm = new Commercial(filedata.mystery,
                                           occupied,
                                           filedata.address,
                                           rental,
                                           filedata.value);
         allProperties.push_back(comm);
      } else if (filedata.which_class == "Residential") {
         Residential* res = new Residential(occupied,
                                            filedata.address,
                                            rental,
                                            filedata.value);
         allProperties.push_back(res);
      } else {
         std::cout << "Bad class name: row skipped\n";
      }
   }

   input.close();

   return;
}


void printEstate(std::vector<Property*>& allProperties)
{
   std::cout << "\nAll properties: \n";
   for(const auto prop : allProperties) {
      std::cout << prop->toString() << '\n';
   }

   return;
}

void askForPropertiesFile(std::ifstream& estate)
{
   bool is_file_opened = false;
   do {
      std::cout << "Where should I read the data from? ";
      std::string filename;
      std::cin >> filename;
      estate.open(filename);
      is_file_opened = estate.is_open();
      if(!is_file_opened) {
         std::cout << "Sorry, can't find or access " << filename
                   << ". Please, try again.\n";
      }
   } while(!is_file_opened);
}


rantiv_in.txt:
1
2
3
4
5
6
7
8
Residential yes 5000000  no   0   129-Avatar-Lane
Commercial  no  2995342  no   0.0 24-Secret-Tunnel-Turnpike
Commercial  yes 24668832 yes 20.0 23-Metal-Bend
Residential no  7334211  no   0   85-Sparky-Sparky-Boom-Village
Residential no  345678   yes  0   Banana-Onion-Road
Residential yes 200000   yes  0   42-Iris-Way
Commercial  no  1234567  yes 20.5 350-Sea-Towers
Commercial  yes 77299351 no   0.0 12-Spirit-Way


output:

starting...
Where should I read the data from? rantiv_in.txt

All properties:
Address:129-Avatar-Lane; Rental; Estimated Value: 5000000; NOT occupied
Address:24-Secret-Tunnel-Turnpike; NOT Rental; Estimated Value: 2995342; NOT occupied; mystery: 0.000000
Address:23-Metal-Bend; Rental; Estimated Value: 24668832; occupied; mystery: 20.000000
Address:85-Sparky-Sparky-Boom-Village; NOT Rental; Estimated Value: 7334211; NOT occupied
Address:Banana-Onion-Road; NOT Rental; Estimated Value: 345678; occupied
Address:42-Iris-Way; Rental; Estimated Value: 200000; occupied
Address:350-Sea-Towers; NOT Rental; Estimated Value: 1234567; occupied; mystery: 20.500000
Address:12-Spirit-Way; Rental; Estimated Value: 77299351; NOT occupied; mystery: 0.000000

Sorry I didnt include all the information. I thought i had put all the files in. This has helped greatly except when i print mine, it isnt printing the address number.
it isnt printing the address number

And… do you plane to share your output with us over the next few days? :-)
(Ok, just joking)

Please, consider that the loop inside my version of getFile() (BTW, perhaps getData() would be a better name) expects every line to have got the same number of ‘fields’; it later discards the unused one if it’s creating an instance of “Residential” (other note: name of classes usually are taken from nouns, not from adjectives, because it helps considering them as types, which is what they are).

You can see in my last post I’ve modified the input file forcing every line to have the same length (in terms of amount of fields).

If you decided to add a method for writing data into you classes, of course “Residential” could not add that extra field, since it can’t be aware of its ‘offspring’.
In that case it could make sense to change the mentioned reading loops to make it evaluate how many fields it should read according to the first one it meets (“Residential” versus “Commercial”).

If using my version of your data file doesn’t solve your issue, just post again – there are likely to be hundres of bugs on my code, I wrote it quickly, just to make it work. But try to put yourself in the reader’s shoes, if you can. The day you’re happy with your code, please consider ticking the post as solved.
@Enoizat sorry that I didnt post my code. It just is a lot so I only did the first part. This has completely helped me by the way. My class that I am taking hasnt been too helpful in learning and most of my learning comes from these forums so excuse my lack of knowledge and not the best naming of my functions and variables. I wish there was an easier way to do this. But i do appreciate your help and as soon as i get my code up to 100% i will check this as solved.
Topic archived. No new replies allowed.