0

it said that it was an illegal use of this type as an expression.

Perhaps you meant shoes = new Shoe[50];

Edited by Moschops

0

Sure:

Shoes.h:

#include <iostream>
#include <fstream>
#include <string>

#ifndef Shoes_Shoes_h
#define Shoes_Shoes_h

using namespace std;

class Shoe
{
public:

    //Constructors
    Shoe();
    Shoe(string Name_, double ShoeSize_, int Number_);

    //Destructor
    ~Shoe();

    //getters
    string getName() const;
    double getShoeSize() const;
    int getNumber() const;

    //setters
    void setName(const string Name_);
    void setShoeSize(const double ShoeSize_);
    void setNumber(const int Number_);

    string Name;
    double ShoeSize;
    int Number;

};

class Shoe_List
{
public:

    Shoe_List();

    void load();

    void view();

private:
    int length;
    Shoe * shoes;
};

#endif

Shoes.cpp:

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

//Shoe Constructors
Shoe::Shoe()
{
    Name = "";
    ShoeSize = 0;
    Number = 0;
}

Shoe::Shoe(string Name_, double ShoeSize_, int Number_)
{
    Name = Name_;
    ShoeSize = ShoeSize_;
    Number = Number_;
}

//Shoe Destructor
Shoe::~Shoe()
{

}

//Shoe Getters
string Shoe::getName() const
{
    return Name;
}

double Shoe::getShoeSize() const
{
    return ShoeSize;
}

int Shoe::getNumber() const
{
    return Number;
}

//Shoe Setters
void Shoe::setName(const string Name_)
{
    Name = Name_;
}

void Shoe::setShoeSize(const double ShoeSize_)
{
    ShoeSize = ShoeSize_;
}

void Shoe::setNumber(const int Number_)
{
    Number = Number_;
}

//Shoe_List Constructor
Shoe_List::Shoe_List()
{
    shoes = NULL;
    int length = 0;
}

void Shoe_List::load()
{

    fstream fin; 

    fin.open("shoe_list.txt");

    if(fin.good()) 
    {
        fin >> length;

        shoes = new Shoe[10];

        for (int i=0; i<length; i++) 
        {
            fin >> shoes[i].Name;
            fin >> shoes[i].ShoeSize;
            fin >> shoes[i].Number;
        }
    }

    fin.close();

}

void Shoe_List::view()
{

    for (int i=0; i<length; i++)
    {
        cout << shoes[i].Name << endl;
        cout << shoes[i].ShoeSize << endl;
        cout << shoes[i].Number << endl;
        cout << endl;
    }
}

main.cpp:

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

int main()
{
    Shoe_List shoes;

    char input;

    while (1) 
    {

        cout << endl;
        cout << "Menu" << endl;
        cout << "1. Load" << endl;
        cout << "2. View" << endl;
        cout << "3. Exit" << endl;

        cout << "Enter option: ";
        cin >> input;
        cout << endl;
        // act on the user's input
        switch(input) 
        {
            case '1':
                shoes.load();
                break;

            case '2':
                shoes.view();
                break;

            case '3':
                return 0;
                break;

            default:
                cout << "Incorrect entry" << endl << endl;
                break;
        }
    }
}

shoe_list.txt:

6

Nike
2
7.5

Puma
4
6

Nike
4
8.5

Addidas
1
9

Puma
2
10

Reebok
1
11.5

Output:

Nike
2
0

.5
0
0

0
0

0
0

0
0

0
0

0

Lines 85 and 86 need to switched in Shoes.cpp. Your txt file goes name, number, size and you are reading in name size, number.

0

Didnt see that for the life of me! Thank you all for your help I have learnt a lot!
One last thing. If I am adding functions such as save would it be better code practice to pass the shoes array as const and also the length as call by value for the functions save and view since they shouldn't change for these functions? And then the opposite for functions that do want to change the shoes array and length? So:

//Functions that do not intend to change shoes and length
void Shoe_List::save(const Shoe * shoes, int length);
void Shoe_List::view(const Shoe * shoes, int length);

//Functions that do intend to change shoes and length
void Shoe_List::load(Shoe * shoes, int & length);
void Shoe_List::add(Shoe & shoes, int & length);
0

Yes you should always declare a parameter as const if you are not going to modify it and it is not being passed by value. Also you dont really need to pass the variables to the functions since they exist in your class. Any function in you class can access the member data of the class.

Edited by NathanOliver

0

Sorry for the late reply but thanks for the help. Not sure if I should be posting on this thread again since it is quite old? But a question about the class Shoe that was initial posted on page 1. If the variables are private in Shoe how can I display shoes? If they are private and I do:

for (int i=0; i<length; i++)
    {
        cout << shoes[i].Name << endl;
        cout << shoes[i].Number << endl;
        cout << shoes[i].ShoeSize << endl;
        cout << endl;
    }

Then these members won't be accessible..

Edited by Hey90

0

Create an overloaded operator<< to do the output:

ostream& operator<<(ostream& out, const Shoe& obj)
{
    out << shoes[i].Shoe << '\n';
        << shoes[i].Number << '\n';
        << shoes[i].ShoeSize << endl;

    return out;
}

Don't forget to make it a friend of the Shoe class, because those members are private.

0

That's right. You've hit up against one of the key points of classes. At risk of labouring the obvious, you make internal variables private when the user should not have direct access to them.

Accordingly, (assuming that you do want to keep the internal variable private) you have one of two principal choices. Firstly, what you see many inexperienced Java coders do as a nervous reflex without even realising it; you create a class function called a "getter" function whose job is to give you back the value of an internal variable. Like this, for example:

int Shoe::getShoeSize()
{
  return ShoeSize;
}

which you then call something like:
cout << shoes[i].getShoeSize();

The other method, which I personally consider a better option, is to make the shoe object itself responsible as far as possible for it's own functionality. If you want to be able to see information about a shoe on screen, you can give the shoe object a function for that. For example:

    void Shoe::displayInfo()
    {
      cout << Shoe << endl;
      cout << Number << endl;
      cout << ShoeSize << endl;
    }

and then you can simply offload that to each individual shoe:

for (int i=0; i<length; i++)
{
   shoes[i].displayInfo();
}

It's not so important in a simple case like this, but when classes get big and complicated, it makes life so much easier for yourself to have the class be responsible as far as possible for itself.

Edited by Moschops

0

Ok right I see what you mean Moschops. So if you see the whole code posted earlier is this the right direction to be going in having two classes, Shoe and Shoe_List? Are you saying I should do this for all my functions? I might be starting to confuse myself here

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.