How to make an item database based off an item class

Hi guys,

This is my first post here, so if I'm doing anything wrong, please let me know.
So I need homework help. Right now, I'm taking one of the intro classes for C++, and the current assignment focuses on classes. Our assignment is to make some sort of grocery supermarket that allows the users to buy items and remove items, which will be evident from a .txt file.

The question: So I made my class for grocery items, and I want to make a database of some items based off of the class. I have made a .cpp file containing a whole list of items, and I did this by using inheritance. I tried to compile this, expecting errors here and there from all my other files. But my itemDatabase file gave me an incredible amount of errors, way more than I would expect (probably because I have a good amount of items) leading me to think I'm doing this wrong.

I don't think I really need help with looking over my code at the moment. I would just like some advice on how to create my item database. If you guys need to see parts of my code, I will post them. Basically in my itemDatabase, I put a whole list of items there by using inheritance, but I think I'm doing it wrong.

Hopefully this post isn't too long. And I understand we're not supposed to ask for help on explicit homework questions. I don't think this question is specific enough to answer all questions I have on this homework, but I think it'll be a great start for me.

Thank you.


edit: Okay, I think I might need to show you guys what I'm doing.

itemClass.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
#ifndef ITEMCLASS_H
#define ITEMCLASS_H

class groceryItem{
	protected:
		string itemName;
		float price;
		//string unitAmount;
		string itemType;
		bool origin;
		bool organic;
		bool edible;
			
	public:
	/*
		// include actual functions in a .cpp file.
		void chooseItem();
		void itemAmt();
	*/
	
	void set_name(string sName);
	void set_price(float sPrice);
	//void set
	void set_Type(string sType);
	void set_Ori(bool sOri);
	void set_Org(bool sOrg);
	void set_Edi(bool sEdi);
	
};
	
#endif 


itemClass.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
#include <iostream>
#include "itemClass.h"

// basic item info
void set_name(string sName){
	itemName = sName;	// sets string name for item
}

void set_price(float sPrice){
	price = sPrice;		// sets float price for item
}


// item categories
void set_Type(string sType){
	itemType = sType;	// determines item's type
}

void set_Ori(bool sOri){
	origin = sOri;		// T = local, F = imported
}

void set_Org(bool sOrg){
	organic = sOrg;		// T = organic, F = non-organic
}

void set_Edi(bool sEdi){
	edible = sEdi;		// T = food, F = ~food
}


itemDatabase.cpp (showing only one item)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include "itemClass.h"
#include "itemClass.cpp"
using namespace std;

class apple: public groceryItem{
	public:
		set_name("apple");
		set_price(1.09);	
		set_Type("fruits");	// fruit
		set_Ori(1);			// local
		set_Org(1);			// organic
		set_Edi(1);			// food
};




After reviewing my code, I realized I added a '#include "itemDatabase.cpp" ' in itself. That definitely cut a lot back on my error. But I still would like to know if I'm doing things right.

Thank you.


edit: I have included ' #include <string> ' in each of my files I have posted.
Last edited on
Hi,

Ok, some concepts ..... :+)

Name your files the same as the Class name. I use .hpp for header files, meaning a header file with cpp code in it.


I Put a leading C on the class names, a leading m_ on member variables and a leading p for pointers. This is purely a personal preference, but it works well for me.

So for you classes I would have these files: CGrocery.hpp , CGrocery.cpp, CApple.hpp, CApple.cpp and GroceryApp (has the main() function in it)

Don't include cpp files, only header files.

Investigate using initialiser lists - this means you will not need lots of trivial set functions (a bad idea). Call your base class constructors from this initialiser list, so you don't have object slicing. This means you need to provide constructors for your classes.

This leads to deciding what your interface is going to look like. What functions should you have? Think about what the object can do (verbs)

Don't have protected data members, I know it's tempting - instead make all data members private:

As it stands, you don't actually need you Apple class. All the data is stored in the base class, there is nothing new in the Apple class. Is there something you can add to your class? A fruit specialisation?

If you want to have a "Database" , you need to have some kind container which holds multiple objects. The simplest is probably a std::vector, but there are others that could come in handy - like std::map, std::unordered_set for example.

You could have a std::vector of pointers to CGrocery

There is a whole subject called Polymorphism which you could read about in the tutorials / Articles section at the top left of this page.

Have a read of this:

http://www.cplusplus.com/forum/beginner/144603/#msg762560


You could adapt this idea, so you could add up the sales for Fruit, Veges, Meat, Dairy etc

You could have a std::vector of pointers to CGrocery that way you can have a container which holds multiple types of objects. Then write functions which take pointers to CGrocery.

Hope this all helps, maybe quite a bit for you to think about - hope all goes well :+)

Hi IdeasMan,

I really appreciate your response. Thank you so much!

One thing I have learned today about programming classes: READ THE TEXTBOOK. Haha, the textbook is helping to set me straight on this topic, and your input definitely adds on to my understanding of this topic.

For now, I am going to stick with .h and .cpp files, since that's mainly what we've been taught/using in this class. But I like the idea of using a vector. Upon running my program though, would the "database" vector be created on every compile, or would it be stored in a fashion similar to calling out a .txt file?

And, should I use a vector or an array? From my understanding, a vector is good if a list size continues to change, whereas an array's size is set. I already know my list of items and the corresponding adjectives to attach to them, so would it be best to have an array in this case?
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
#ifndef CGROCERY_H
#define CGROCERY_H

class CGrocery {
	protected:
        private:
		std::string m_Name;
		 float   m_SalePrice;
 		//string unitAmount;
		std::string m_Type;
		 bool m_Origin; // investigate using an enum class for this
 		bool m_IsOrganic;
		 bool m_IsEdible;
			
	public:
	/*
		// include actual functions in a .cpp file.
		void chooseItem();
		void itemAmt();
	*/
	CGrocery(const std::string Name,  // mark all parameters const so we can't change them
                       const double SalePrice,
                       const   std::string Type,
                       const bool Origin,
                       const bool IsOrganic,
                       const bool IsEdible

                       ) :  // colon introduces initialiser list

                       m_Name(Name),
                       m_SalePrice(SalePrice),
                       m_Type(Type),
                       m_Origin(Origin),                 // do these
                       m_IsOrganic(IsOrganic),      // only apply
                       m_IsEdible(Edible) {}           // to food? if so, they belong in a class lower down in the tree

        void ShowAllInfo() const;  // std::cout all the member data variables, put definition in .cpp file

         // could have get functions here if there is a need to access members individually, like SalePrice
         inline const double getSalePrice() const {return m_SalePrice;}

	void set_name(string sName);
	void set_price(float sPrice);
	//void set
	void set_Type(string sType);
	void set_Ori(bool sOri);
	void set_Org(bool sOrg);
	void set_Edi(bool sEdi);
	
};
	
#endif  


Notice I mark functions that don't alter member variables const and it is quite often a good idea to return const values as well. If it is not a built in type (char, double, int etc), then return a reference.


Some more reading:

http://www.cplusplus.com/forum/beginner/152947/2/#msg795099



There is often a lot to think about when designing, there can be more classes than what you might have initially thought.
Upon running my program though, would the "database" vector be created on every compile, or would it be stored in a fashion similar to calling out a .txt file?

Every time you run the code, all the variables, containers etc are created. It is up to you whether you have file input/output.

And, should I use a vector or an array? From my understanding, a vector is good if a list size continues to change, whereas an array's size is set. I already know my list of items and the corresponding adjectives to attach to them, so would it be best to have an array in this case?


I would definitely go with a std::vector or some other resizeable container. Don't fence yourself in by restricting the size of some thing. It is possible to dynamically create memory, by creating the size of something at runtime, but it is easier to just push things into a resizeable container.

I imagine that with your supermarket you might start with various departments such as CFood, CCleaning, CClothing etc. Then within those you might have CFruit, CVege, CMeat, CBakery etc. We want to design it so that we can add new Sections or even new Departments without having to change things everywhere.

This is most easily done with Polymorphism, an Inheritance tree, and obeying the concept of generalising things as much as possible.

With generalising things, the idea is to push things as high up the tree as possible. For example, m_SalePrice applies to everything, so it would exist at the top of the tree, along with it's associated functions. More specialised things belong in the things they specialise.

Food is a bit tricky to come up with specialisations because they all have the same attributes (nutritional values etc). I would rather avoid having bool Meat, bool Vege etc

Though I have mentioned an inheritance tree here (it is essential for Polyorphism), it is not necessarily the answer for everything.

Hi,

Me again !

With the generalising of function & variable names, it is the naming that does the generalising. Some examples: ShowInfo() , Buy(), Sell() are generalised names, whereas BuyMeat(), SellVege() are not.

We generalise the names, so they can be pushed up the inheritance tree, and can be applied to various types of objects.

So I reckon you might have enough info to create some classes representing different Supermarket departments ,
along with types of products Meat, Vege etc. Create some objects of these types, push_back them into a std::vector, then add up the total value of them all. While you are at it, print out the details of all of them, using one for loop.

It's late at my end, so I look forward to seeing how you got on tmrw :+D ZZZZZZzzzzzz.....
IdeasMan, you the man. Really appreciate your effort in helping me.

Upon reading through my file, I apologize for having "dead" code in there. Hopefully some of the comments I had didn't confuse you.

My market is just going to sell food, and a few other things such as paper towels and utensils. Therefore, I had a string variable for that, categorizing items into things such as meat, veggies, non-food (hence, the bool isEdible, but maybe I actually don't need that if I already have a category for it.) My idea is to give users options to filter the list of items I have so they can find what they're looking for. I'm hoping string is a good idea for that.
So I'm making some progressing at least.

I can get the classes to work, as the compiler is giving me no errors regarding my use of it. Right now I am trying to create the vector. At the moment, each instance of my class has 5 inputs into it: string name, float price, string type, bool origin, and bool organic. Being something that has five values attached to it, how would I make a vector out of this? Or, would I go about managing five vectors?

I have tried
 
vector<itemClass> = dBase(23);

where itemClass is my class (but is also my desired type for the vector), dBase is my vector variable name, and 23 is my size of vector (since I have 23 items).

I have also tried creating an array, but with no luck.

IdeasMan, I definitely appreciate any advice you can give me on this, but anyone else, please feel free to help me out, as well! I'll keep this updated as I make progress.
Being something that has five values attached to it, how would I make a vector out of this? Or, would I go about managing five vectors?


You only need 1 vector, declare it like this:

std::vector<CGrocery> Inventory;

If you use the class I posted earlier, you can only access stuff through it's interface, which is at the moment the functions getSalePrice() and ShowAllInfo() . To access members of a vector, just use a subscript like an array, or use the member function at()

So once you have push_back some CGrocery objects into the vector, access the first one like this:

Inventory[0].ShowAllInfo();

To process them all, use a range based for loop.

Have a look at the reference material at the top left of this page for more info on how to do these things.

http://www.cplusplus.com/reference/vector/vector/


If you are having trouble with your code, then post it along with any compiler messages in full.

It might be alright to have just one class if you want (I am not keen on your naming though), but you will loose all the power from proper OOP.

See how you go with that :+)
I thought I made a post earlier, but I guess not. Oops!

I've resorted to using an array, which initializes a variable that now contains all my items. Hope I don't disappoint you there.
Now my next goal is to get the array, which was created in a void function, into a different void function. I'm not sure how I go about doing that.

Basically, I have a main function that, at the moment, calls upon a void function, a "display menu" function, if you will. Then, that display function goes to one of two functions, a "super market" function, or a "shopping cart" function (all void at this point). The shopping cart function is not the focus right now. Everything we have done so far is to create items for the super market, and now I would like for the super market function to display the items I have created in the item database.

I believe we'll need pointers for this, but not sure how to implement them.



Also, since I feel like we're starting to steer away from the original question, is it okay to continue this discussion, or should I stop and start a new discussion if necessary? (after looking up old forums first for answers)
I strongly urge you read the Tutorial, Articles, Reference & information sections at the top left of this page.

Keep this topic going - it's all about the same thing.
Will do. I'll keep you updated once I figure it out, or when it's due. ;)
[somewhat of a rant :+D]

So why do want to use an array?

I gave some pretty good hints on how to use a vector. I can't help but think that using an array will severely limit what you can do with it.

If you use an array and functions that deal with it, i can see your cpp code (OOP) degenerating into C code, thereby losing all of your OOP advantages. Not trying to Dis C code or programmers, but this is an ideal project for proper OOP, there are other valid reasons for using C for specific things.

If you are expected to use classes, then do that, don't ruin it by turning it into a mass of spaghetti code trying to make an array of data work. The purpose of OOP is to make things easy & organised & scalable with the minimum of fuss.

[end of rant ! :+)]

I suppose that I have presented given clues as to how I would do it, but have forgotten what situation you are in.

Having said all that, realise I am not trying to be harsh - I guess you have an underlying worry that you will be busted for getting too much help from forums, so you want to submit code that looks like it was all your idea :+) This means that you can't be seen to be doing anything "too advanced". So things like vectors, initialisation lists & polymorphism might be dead give a ways. Depends on how lenient your prof is - might look on it favourably if you can demonstrate what it all means & why.

So what exactly are you allowed to use? Classes & inheritance as a guess? Maybe you could post your actual assignment question?

If you are allowed to use c++11 standard, then you could have an std::array<CGrocery*> at least, rather than an ordinary array.
Haha, I appreciate the rant. My assignment is due soon (tonight, Pacific Time), and at this point, I am just trying to get as much done as possible, and one of the ways I am doing that is by using commands I am familiar with.

It's not that I don't believe you're right with using a vector. I definitely like the idea of having a "resizeable" container. And as simple as you might think it is to use a vector, I haven't touched on it much in the CS classes I've taken so far, which is really not that many (I'm taking my second CS class now, with the last one being over last summer, so my skills are slightly rusty).

In our class, having OOP is indeed our main focus, but again, this is just going back to getting things done as much as possible in a timely manner. I am not comfortable with using vectors at the moment, and I got my array to work, so I am running with that.


I think with our class being an online course, there won't be suspicions raised if I use "advanced" skills, as students online tend to come from varying backgrounds. In fact, we'll be covering polymorphism next week! (what the heck is that?) I'm not too afraid to use some advanced topic in assignments we haven't covered before, but at the same time, I don't want to blindly code things in without at least understanding what's going on.

Our assignment doesn't have one concrete question. It's a goal in which some of the constraints are left vague in order to give us more freedom for design, although I would still appreciate a little bit of a "holding my hand" walkthrough on some stuff.


Admittedly, I did indeed start this assignment kind of late. Each assignment in this class is given two weeks, and I usually start to really hammer away when there's about less than a week left. I understand that's a really bad approach to this, but I have a generous amount of other homework I had/have to take care of. As much as I want to be able to focus on CS, this just happens to be my minor, as I am majoring in Mechanical Eng. As interesting as CS is, I feel like I am at a disadvantage because I feel my knowledge in that field tends to lack a bit more than the actual CS majors, or just really smart people.

And I guess that was my rant, too. Not so much as to argue or anything, but I just wanted to let you know my background so you understand who you're working with: an almost clueless person in CS who is really interested in learning the stuff.


I'll really try to make an effort on starting assignments earlier, as I heard we were going to create our own simple game that would be very dependent on classes and such (hooray!). Hopefully that will REALLY get me into wanting to start it earlier. IdeasMan, you seem like a pretty reasonable person with lots to knowledge to share. If I got questions in the future, I'm looking forward to hearing from ya. :)
Topic archived. No new replies allowed.