Vectors and Classes

Currently in c/c++ programming 2 and trying to expand my knowledge of classes and vectors and how they interact with each other. I'm experimenting with using a header file and multiple .cpp files. This is my first project working with "object-oriented" programming so i have a few questions.

I am taking a .txt file, reading it, and inserting it into a vector so that I can access it inside of my c++ program (when called upon). The code below will build successfully. However, when run the program and I go and pick "a" it gives me a "vector subscript out of range error".

In my "FinalProjectHeader.h" file I declare function declarations and declare class theVector and class Menu. I am inheriting theVector into the class Menu class.

In my "FinalProject.cpp" file i just make an object for the respective classes and call for them.

What I find interesting is that if I copy and put the vector code in the menu class, it works (it accesses the list[2] element). However doing it how i did below does not work (builds successfully though).

My question is how do I best access the elements in the vector, using classes and object-oriented programming?

Thanks for the help.


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

void theVector::fileVector() 
{
	ifstream wordfile("FoodSelection.txt"); //if there is a wordfile
	
	while (wordfile >> word)
	{
		list.push_back(word); // adds new element to end of vector
	} // end while loop
};


int Menu::mainmenu()
{
	do
	{ // do statement
		cout << "Welcome, to Grab n' Dash" << endl;
		cout << "Enter A for bacon cheeseburger" << endl;
		cout << "Enter B for soft drink" << endl;
		cout << "Enter C for french fries" << endl;
		cout << "Enter D to exit" << endl;
		cout << "--------------------------------------------------" << endl;
		cin >> choice;
		switch (choice) //switch statement for menu
		{
		case 'A':
		case 'a': //lower and uppercase for safety
			cout << list[2] << endl;
			break;
		case 'B':
		case 'b':
			cout << list[5] << endl;
			break;
		case 'C':
		case 'c':
			cout << list[8] << endl;
			break;
		case 'D':
		case 'd':
			cout << "Goodbye" << endl;
			return 1; // end program if user is done.
			break;

		default:  cout << "I'm sorry, please try again!" << endl;

		}//end of menu(switch statement).
	}// do loop
	while (choice != 'A' || 'a' || 'B' || 'b' || 'C' || 'c' || 'D' || 'd'); //while any of these options
	{
	}
	return 0;
};
Last edited on
closed account (E0p9LyTq)
What little code you show makes it near impossible to say what the problem is.

Are you actually writing your own vector class instead of using std::vector?
Yes i'm writing my own vector class and making a vector.

Here is my "FinalProjectHeader.h" file and my "FinalProject.cpp" file. This, combined with what i have up above is all the code i have.

***FinalProjectHeader.h file****

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
// header ==> Function Declarations
#include <iostream>
#include <string> 
#include <fstream> //still need directives in header file
#include <vector>

using namespace std;

#ifndef FinalProjectHeader_h //needed for header files
#define FinalProjectHeader_h


class theVector
{
public:

	vector<string> list;
	string word;

	void fileVector();
};



class Menu : public theVector
{
public:

	char choice;

	int mainmenu();
};

#endif //also needed for header files. 


***FinalProject.cpp file***

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "FinalProjectHeader.h"


int main()
{
	theVector vectorOne;
	vectorOne.fileVector();
	
	Menu menuOne;
	menuOne.mainmenu();

	return 0;
}


Last edited on
closed account (E0p9LyTq)
Yes i'm writing my own vector class and making a vector.

By the look of your code you are not trying to write your own vector class.

What you are doing in your custom class is create a std::vector data member variable, creating a std:vector variable (list) that holds std::string. Using a vector instead of something plain old data (POD) like int.

Calling your class "theVector" is a bit confusing, your class is designed to read data from a file and store each word read.

With that said:

Look at your mainmenu() function. You have hard-coded what element to access for each choice. list[2] requires 3 items in your data file, list[5] requires 6 items, and list[8] requires 9 items. By the logic of the menu I would say your data file contains only 3 items to read. Not 6 or 9.

Vectors are zero-based arrays. In order,: list[0], list[1], list[2] and so on.
Last edited on
Sorry about the name confusion.

This is my .txt file:

Bacon Cheeseburger 5.49
Soft Drink 1.25
French Fries 2.00

As you can see it has 9 elements. Vectors are zero-based so that is why i'm trying to get the 2, 5, and 8 elements respectively (the prices of the food items).

The problem that I am running into is that even if I switch to list[0] in my menu to access that element, it does not work. I get a "vector subscript out of range". It does build successfully though.

If you were to take the vector code and put it in the same scope as the menu and just have one class (or main) it would run. The vector would be populated and I can access list[2], list[5], and list[8].

Something is wrong with the population of my vector. Perhaps it is getting lost in between the classes.

I'm trying to separate the vector from the main menu scope... I feel that would be better programming practice because i think a "vector class" would be a separate entity from a "main menu" class. This is my first object-oriented program so i'm open to any and all suggestions.
Last edited on
closed account (E0p9LyTq)
Trying to separate theVector and Menu into separate classes requires a lot of additional work. You have to include a function to access the individual elements in theVector., and rewrite your mainmenu to accept a reference to a theVector object.

Not something for a beginner.

Rewrite your class declarations in your header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class theVector
{
private:
   vector<string> list;
   string word;

public:
   void fileVector();

   std::string operator[](int);
};


class Menu
{
private:
   char choice;

public:
   int mainmenu(theVector&);
};

Add the following class function (also known as a method) to your class source file:
1
2
3
4
std::string theVector::operator[](int num)
{
   return list[num];
}

And modify your main source:
1
2
3
4
5
6
7
8
9
10
11
12
#include "FinalProjectHeader.h"

int main()
{
   theVector vectorOne;
   vectorOne.fileVector();

   Menu menuOne;
   menuOne.mainmenu(vectorOne);

   return 0;
}

Confusing, I bet.

closed account (E0p9LyTq)
I forgot to show the rewritten definition of your mainmenu function, ooops:

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
int Menu::mainmenu(theVector& list)
{
   do
   { // do statement
      cout << "Welcome, to Grab n' Dash" << endl;
      cout << "Enter A for bacon cheeseburger" << endl;
      cout << "Enter B for soft drink" << endl;
      cout << "Enter C for french fries" << endl;
      cout << "Enter D to exit" << endl;
      cout << "--------------------------------------------------" << endl;
      cin >> choice;
      
      switch (choice) //switch statement for menu
      {
      case 'A':
      case 'a': //lower and uppercase for safety
         cout << list[2] << "\n\n";
         break;

      case 'B':
      case 'b':
         cout << list[5] << "\n\n";
         break;

      case 'C':
      case 'c':
         cout << list[8] << "\n\n";
         break;

      case 'D':
      case 'd':
         cout << "Goodbye" << endl;
         return 1; // end program if user is done.
         break;

      default:  cout << "I'm sorry, please try again!\n\n";

      }//end of menu(switch statement).
   }// do loop

   // the following code will never be reached
   while (choice != 'A' || choice != 'a' || choice != 'B' || choice != 'b' || choice != 'C' || choice != 'c' || choice != 'D' || choice != 'd'); //while any of these options
   {
   }

   return 0;
}
Wow it works!

I've spent hours trying to find hints and advise. My question is kind of specific and challenging to explain so it's hard to find resources that are applicable. I'm also trying to challenge myself in a few ways which can increase the difficulty.

I think this is a challenging step because I don't feel like a beginner (I understand "address of" and that "using namespace std" is not considered a good practice). At the same time, I'm not "experienced". Mixing academic learning and web tutorials can sometimes lead to interesting results as well. C/C++ is a humbling language, to say the least.

I'm going to look into how "operator" works and try to understand it further. I just started working with classes a few weeks ago so I'll have to explore that more as well. Thank you for the help.
Last edited on
closed account (E0p9LyTq)
Start with understanding the concept of "function overloading."
http://www.cplusplus.com/doc/tutorial/functions2/

Then when you delve further into classes the idea of overloading class methods becomes easier to understand.

The fun of overloading the insertion (<<) and extraction (>>) operators to make it as easy to input/output a complex class structure as an int.
I hope you realize that classes are not required for everything, even in "OOP". For example, IMO, your Menu class is unnecessary, a simple free function would be a better solution.

Cool, I'll have to check out the function overloading.

jlb,

I'm sort of doing this to gain experience working with classes... but I'm sure in reality there are more applicable ways to implement what I have.

A menu is usually pretty specific, so it would make sense for it to not be an object (why would I need to use a "specific menu" many times?).

A free function is just a non-member function (outside of the class) right? I never even thought of mixing "OOP" with "functional programming" (or basic understanding of variables and functions in main).
Last edited on
Topic archived. No new replies allowed.