Thread: Error: no member named 'whatever'

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    78

    Error: no member named 'whatever'

    Hello there. Thank you for taking the time to help me! I am working on a program that keeps information about staff members of three types (volunteer, full time, or hourly), and has header files for each of these types. There is also a staffMemberParser file which reads an string that the user inputs and tokenizes the string into fields like firstName, lastName, and memberId. Right now, I have all of the subsidiary files written, and am working on the main function, called Assignment7.cpp. For this function, we are supposed to add code to what is given, and that is what I am having a problem with. I get these errors:

    54 Assignment7.cpp 'class std::vector<StaffMember*, std::allocator<StaffMember*> >' has no member named 'computePay'
    79 Assignment7.cpp 'class std::vector<StaffMember*, std::allocator<StaffMember*> >' has no member named 'printInfo'

    Now, I would assume that they are telling me the functions computePay and printInfo are not defined, but they ARE! I have written computePay and printInfo in all of the subsidiary files, which includes StaffMember.h, Volunteer.h, FullTimeEmployee.h, and HourlyEmployee.h, so there is certainly a definition for both of these functions. What is going on here? How can I fix this?

    Thank you for any help you can provide! Here is my main function for your reference, and below that, just for kicks, is one of my other functions, just so you can see that the functions are defined:

    Code:
    // Assignment #: 7
    //         Name: 
    // EmailAddress:
    //  Description: It displays a menu of choices
    //               (add volunteers, full time employees, or hourly employees,
    //               compute their pay, search a member, list members,
    //               quit, display menu) to a user.
    //               Then it performs the chosen task. It will keep asking a user 
    //               to enter the next choice until the choice of 'Q' (Quit) is
    //               entered.
    
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <vector>
    #include "StaffMember.h"
    #include "StaffMemberParser.h"
    
    using namespace std;
    
    void printMenu();
    
    int main()
    {
    	char input1;
    	string inputInfo;
    	bool operation;
    
    	vector<StaffMember *> memberList;
    
    
    	printMenu();     // print out menu
    
    
    	do
    	{
    		cout << "What action would you like to perform?" << endl;
    		cin >> input1;
    
    		switch (input1)
    		{
    		case 'A':   //Add Member
    			cout << "Please enter a member information to add:\n";
    			cin >> inputInfo;
      /***********************************************************************************
      ADD your code here to create a pointer to an object of one of child classes of 
      StaffMember class and add it to the memberList
      ***********************************************************************************/
    			break;
    		case 'C':   //Compute Pay
      /***********************************************************************************
      ***  ADD your code here to compute the pay for all members the memberList.
      ***********************************************************************************/
    			memberList.computePay();
                cout << "pay computed\n";
    			break;
    		case 'D':   //Search for Member
    			cout << "Please enter a memberID to search:\n";
    			cin >> inputInfo;
    			operation = false;
      /***********************************************************************************
      ***  ADD your code here to search a given memberID. If found, set "found" true,
      ***  and set "found" false otherwise.
      ***********************************************************************************/
    			if (operation == true)
    				cout << "member found\n";
    			else
    				cout << "member not found\n";
    			break;
    		case 'L':   //List Members
                if (sizeof(memberList) == 0)
                {
                     cout << "no member\n" << endl;
                }
                else 
                {
                     for (int j=0; j < memberList.size(); j++)
    			     {
    				     memberList.printInfo;
    		         }   
                } 
    			break;
    		case 'Q':   //Quit
    			for (int j=0; j < memberList.size(); j++)
    			{
    				delete memberList.at(j);
    			}
    			break;
    		case '?':   //Display Menu
    			printMenu();
    			break;
    		default:
    			cout << "Unknown action\n";
    			break;
    		}
    
    	} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read
    
    }
    
    /** The method printMenu displays the menu to a user **/
    void printMenu()
    {
    	cout << "Choice\t\tAction\n"; 
    	cout << "------\t\t------\n"; 
    	cout << "A\t\tAdd Member\n"; 
    	cout << "C\t\tCompute Pay\n"; 
    	cout << "D\t\tSearch for Member\n"; 
    	cout << "L\t\tList Members\n"; 
    	cout << "Q\t\tQuit\n"; 
    	cout << "?\t\tDisplay Help\n\n";
    }
    Code:
    // HourlyEmployee.h
    
    // protections 
    #ifndef HourlyEmployee_H
    #define HourlyEmployee_H
    
    using namespace std;
    
    class HourlyEmployee: public StaffMember
    {
          // private variables
          private:
            double rate;
            int hoursWorked;
                    
          // public functions
          public: 
            HourlyEmployee(string1, string2, string3, double1, int1)
            {
                   StaffMember(string1, string2, string3)
                   rate = double1;
                   hoursWorked = int1;
            }
            
            virtual void computePay()
            {
                   pay = rate*hoursWorked; 
            }
            
            virtual void printInfo()
            {       cout << "\nHourly Employee:" << StaffMember::printInfo() << endl;     }
    
    };
    
    #endif

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You're trying to call the functions on the memberList, which is a vector. The computePay and printInfo functions only apply to individual StaffMember objects.

    You need to figure out how to obtain the information you need from the list of StaffMembers. Note that the instructions tell you what to do:
    Code:
    ***  ADD your code here to compute the pay for all members the memberList.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Okay, that makes sense...I don't really know how to do it, though. Do I use a for loop to go through every member of the memberList? Something like this:

    Code:
    for (int j=0; j < memberList.size(); j++)
    {
    	memberList.at(j);
    }
    I am guessing? But I don't know where to put the function (like printInfo or whatever) in there.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That code is a good start. Now, you have to decide how to combine the results of the function calls. For example, for computePay, would you just call that over and over for each member? Or would you have to do something with the result?

    As for how to call the function, you have to think about what the return value of memberList.at(j) is. Basically, what type does memberList.at(j) represent? (Hint: It gets one item from the vector, so it is probably whatever type the vector holds.) Once you figure out the type, you can call the function properly. A trick to make it clearer is to create a variable of that type and assign the value of memberList.at(j) to it. Then use that variable inside the rest of the loop.

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Okay, I think I understand the basic idea. The problem I am having right now is how I tell the code which type of member is being dealt with. What I mean is that since I will have various types of members, such as volunteers and employees, won't the calls to the function be different depending on what type I am dealing with? I am thinking this because each .h file has its own version of printInfo and computePay, so it would make sense that I have to differentiate to the code which type is being dealt with. How do I do this? I have a StaffMemberParser.h file, which might be useful, and looks like this:

    Code:
    // StaffMemberParser.h
    
    #include <stdio.h>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <stdexcept>
    
    // protections 
    #ifndef StaffMemberParser_H
    #define StaffMemberParser_H
    
    using namespace std;
    
    class BadConversion : public std::runtime_error 
    {
     public:
       BadConversion(const std::string& s)
         : std::runtime_error(s)
         { }
    };
     
    inline double convertToDouble(const std::string& s)
    {
       std::istringstream i(s);
       double x;
       if (!(i >> x))
         throw BadConversion("convertToDouble(\"" + s + "\")");
       return x;
    } 
    
    inline int convertToInt(const std::string& s)
    {
       std::istringstream i(s);
       int x;
       if (!(i >> x))
         throw BadConversion("convertToInt(\"" + s + "\")");
       return x;
    } 
    
    class StaffMemberParser
    {
          static StaffMember * parseStringToMember(string lineToParse)
          {
                 const char *ptr = lineToParse.c_str();
                 char field [100];
                 int n, i = 0, hoursWorked;
                 string type, firstName, lastName, employeeId;
                 double rate, bonus;
                 
                 while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
                 {
                      switch (i++)
                      {
                             case 0: type = field; break;
                             case 1: firstName = field; break;
                             case 2: lastName = field; break;
                             case 3: employeeId = field; break;
                             case 4:
                                  if ( type == "Volunteer" )
                                  {
                                       // nothing to do
                                  }
                                  else if ( type == "HourlyEmployee" )
                                  {
                                       rate = convertToDouble(field);
                                  }
                                  else if ( type == "FullTimeEmployee" )
                                  {
                                       rate = convertToDouble(field);
                                  }
                                  break;
                             case 5:
                                  if ( type == "Volunteer" )
                                  {
                                       // nothing to do
                                  }
                                  else if ( type == "HourlyEmployee" )
                                  {
                                       hoursWorked = convertToInt(field);
                                  }
                                  else if ( type == "FullTimeEmployee" )
                                  {
                                       bonus = convertToDouble(field);
                                  }
                                  break;
                             default: break;
                      }
                      ptr += n;
                      if ( *ptr != '/' )
                      {
                           break;  // didn't find an expected delimiter
                      }
                      while ( *ptr == '/' )      
                      { 
                           ++ptr;  // skip the delimiter     
                      }
                 }  
          }
    };
    
    #endif
    So I am thinking I need to use the type variable from this function, but I am unsure how to do that.

    Thank you so much for all of your help, Daved.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The whole point of member functions is that you do not need to (or want to) know what the type is. Just do .computePay on your object (or ->computePay on a pointer to your object) and you're done.

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Okay. So, one of the places we are to add code is the case the prints all the members of the list. Right now, I have this:

    Code:
    	case 'L':   //List Members
                 StaffMember * member = new StaffMember;
            		
                 if (sizeof(memberList) == 0)
                 {
                     cout << "no member\n" << endl;
                 }
                 else 
                 {
                     for (int j=0; j < memberList.size(); j++)
    		{
    			member = memberList.at(j);
    			member.printInfo();
    		 }   
                  }
    	break;
    But I am getting some errors, so I am not thinking that is correct. I don't think I declared the new object correctly, and I don't know if I used the function printInfo() right either. I have also tried doing member->printInfo(); but that didn't work either. Is this even close to correct?

    Thank you guys for the help!!

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you're not going to tell us what the errors are, why are we here?

    In any event, this:
    Code:
    StaffMember * member = new StaffMember; //red is oh so wrong
    could use some work.

  9. #9
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Well I just figured it was so wrong that the errors were irrelevant, as they were probably caused solely by my lack of skill. I just didn't think they were important here, because I thought all my code would be scrapped as just being wrong wrong wrong.

    Here are the errors I am getting:

    83 Assignment7.cpp cannot allocate an object of type `StaffMember'
    83 Assignment7.cpp because the following virtual functions are abstract:
    34 StaffMember.h virtual void StaffMember::computePay()

    and then this error three times:

    98 Assignment7.cpp jump to case label
    83 Assignment7.cpp crosses initialization of `StaffMember*member'

    My code is posted below. Is there a way to put line numbers into the code so that other people can know which lines the errors reference?


    Yeah, I didn't think that was right, but I don't know how else to declare the object of type StaffMember...how do I do it, if not like that? I just copied an example my teacher gave us, but obviously this application doesn't work. What do I put on the right side of the instantiation?

    Thank you for all the help, tabstop! :-)


    Code:
    // Assignment #: 7
    //         Name: 
    // EmailAddress:
    //  Description: It displays a menu of choices
    //               (add volunteers, full time employees, or hourly employees,
    //               compute their pay, search a member, list members,
    //               quit, display menu) to a user.
    //               Then it performs the chosen task. It will keep asking a user 
    //               to enter the next choice until the choice of 'Q' (Quit) is
    //               entered.
    
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <vector>
    #include "StaffMember.h"
    #include "StaffMemberParser.h"
    
    using namespace std;
    
    void printMenu();
    
    int main()
    {
    	char input1;
    	string inputInfo;
    	bool operation;
    
    	vector<StaffMember *> memberList;
    
    
    	printMenu();     // print out menu
    
    
    	do
    	{
    		cout << "What action would you like to perform?" << endl;
    		cin >> input1;
    
    		switch (input1)
    		{
    		case 'A':   //Add Member
    			cout << "Please enter a member information to add:\n";
    			cin >> inputInfo;
    			StaffMemberParser.parseStringToMember(inputInfo);
                if ( inputInfo.type == "Volunteer" )
                {
                    StaffMember * volunteer1 = new Volunteer;
                }
                else if ( type == "HourlyEmployee" )
                {
                    HourlyEmployee * hourly1 = new HourlyEmployee;
                }
                else if ( type == "FullTimeEmployee" )
                {
                    FullTimeEmployee * fulltime1 = new FullTimeEmployee;
                }
      /*****************************************************************************
      ADD your code here to create a pointer to an object of one of child classes of 
      StaffMember class and add it to the memberList
      *****************************************************************************/
    			break;
    		case 'C':   //Compute Pay
      /*****************************************************************************
      ***  ADD your code here to compute the pay for all members the memberList.
      *****************************************************************************/
                cout << "pay computed\n";
    			break;
    		case 'D':   //Search for Member
    			cout << "Please enter a memberID to search:\n";
    			cin >> inputInfo;
    			operation = false;
      /*****************************************************************************
      ***  ADD your code here to search a given memberID. If found, set "found" true,
      ***  and set "found" false otherwise.
      *****************************************************************************/
    			if (operation == true)
    				cout << "member found\n";
    			else
    				cout << "member not found\n";
    			break;
    		case 'L':   //List Members
                 StaffMember * member = new StaffMember;
            		
                 if (sizeof(memberList) == 0)
                 {
                     cout << "no member\n" << endl;
                 }
                 else 
                 {
                     for (int j=0; j < memberList.size(); j++)
    			     {
    				     member = memberList.at(j);
    				     member->printInfo();
    		         }   
                 }
    			 break;
    		case 'Q':   //Quit
    			for (int j=0; j < memberList.size(); j++)
    			{
    				delete memberList.at(j);
    			}
    			break;
    		case '?':   //Display Menu
    			printMenu();
    			break;
    		default:
    			cout << "Unknown action\n";
    			break;
    		}
    
    	} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read
    
    }
    
    /** The method printMenu displays the menu to a user **/
    void printMenu()
    {
    	cout << "Choice\t\tAction\n"; 
    	cout << "------\t\t------\n"; 
    	cout << "A\t\tAdd Member\n"; 
    	cout << "C\t\tCompute Pay\n"; 
    	cout << "D\t\tSearch for Member\n"; 
    	cout << "L\t\tList Members\n"; 
    	cout << "Q\t\tQuit\n"; 
    	cout << "?\t\tDisplay Help\n\n";
    }

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Generally, people do
    Code:
    //this is line 45
    You don't want to initialize the pointer, was my point. Just let it be there.

    But even then, my original point was that you don't even want the pointer. Just call the function from the (pointer to the) object:
    Code:
    memberList.at(j)->printInfo();
    and be done with it.

    Oh, and as to the errors: So the first one I was hoping to see -- since your base class is pure virtual, there's no way to actually hold such an object; all you can hold is a pointer to a derived class via the base class.
    Last edited by tabstop; 10-08-2009 at 09:21 PM.

  11. #11
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Oh, okay...I see what you are saying. So, applying those concepts to another of the parts we are supposed to complete, which is supposed to search the list for a given memberId, here is what I came up with:

    Code:
    case 'D':   //Search for Member
    	cout << "Please enter a memberID to search:\n";
    	cin >> inputInfo;
    	operation = false;
    			
    	string id;
            for (int j=0; j < memberList.size(); j++)
    	{
                  id = memberList.at(j);
    	      if (inputInfo == id)
    	     {
                          operation = true;
                  }
                  else
                  {
                          operation = false;
                  }
    	}
    	if (operation == true)
    	     cout << "member found\n";
    	else
    	     cout << "member not found\n";
    	break;
    But it obviously isn't right, because the line id = memberList.at(j) doesn't do what I actually need to do. What I am trying to do in that line is to pull out the memberId of each member, so I can compare it to the input value. How can I do this?

    Also, what do I do about that second error? It now says this:

    94 Assignment7.cpp jump to case label
    76 Assignment7.cpp crosses initialization of `std::string id'

    and repeats that three times. What does that mean, and how do I fix it?

    Thank you very very much for your help, tabstop!!

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by vileoxidation View Post
    94 Assignment7.cpp jump to case label
    76 Assignment7.cpp crosses initialization of `std::string id'

    and repeats that three times. What does that mean, and how do I fix it?

    Thank you very very much for your help, tabstop!!
    What that means is that you can't define variables inside cases, or if you must, you need to enclose the case inside an extra set of braces so that the variable is not in scope for the other cases.

    I have no idea where your id is stored, but you would do the same thing here as before.
    Code:
    if (id_typed_in == memberList.at(j)->getID())

  13. #13
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Alright, that makes sense. I got rid of the variable that was throwing those errors, and fixed my call to getMemberId, and that part is compiling just fine now!

    I still have one question about this program. I have one more part to complete, and it is the most important part, because it is where the members are actually added to the list. Here is what I have so far:

    Code:
    case 'A':   //Add Member
    	cout << "Please enter a member information to add:\n";
    	cin >> inputInfo;
    	StaffMemberParser.parseStringToMember(inputInfo);
                if ( inputInfo.type == "Volunteer" )
                {
                    
                }
                else if ( type == "HourlyEmployee" )
                {
                    
                }
                else if ( type == "FullTimeEmployee" )
                {
                    FullTimeEmployee * fulltime1 = new FullTimeEmployee;
                }
    	break;
    As you can see, I have my if and else's in there, but I am just unsure about what to put in the body of those statements. As you can also see in the FullTimeEmployee case, I tried declaring new objects in the same way I tried before, which is obviously not correct. I understand how to declare a new object of type StaffMember, but how do I declare a new object of type Volunteer, which is a child of class StaffMember?

    I think this is my last question, so I'll be out of your hair soon! Thank you again for all of your help.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I understand how to declare a new object of type StaffMember, but how do I declare a new object of type Volunteer, which is a child of class StaffMember?
    You understand no such thing. It is completely impossible to declare a new object of type StaffMember. Remember when you tried up above? Remember how StaffMember was a pure virtual class and how no such objects can be created?

    Anyway, I don't know about your English skills, but constructor is not a made-up word and you should consider its actual English meaning.

  15. #15
    Registered User
    Join Date
    Sep 2009
    Posts
    78
    Quote Originally Posted by tabstop View Post
    You understand no such thing. It is completely impossible to declare a new object of type StaffMember. Remember when you tried up above? Remember how StaffMember was a pure virtual class and how no such objects can be created?

    Anyway, I don't know about your English skills, but constructor is not a made-up word and you should consider its actual English meaning.
    Okay, I (maybe) get that constructors create objects, so I see now that I should have used the constructor. But that still leaves me with a problem. What do I pass to the constructor? It takes five arguments, which have to be parsed from the StaffMemberParser file, so how do I access those variables from the StaffMemberParser file within the main function.

    Acerbic responses aside, I appreciate your help. Thank you for it. :-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem defining structure
    By MTK in forum C Programming
    Replies: 12
    Last Post: 09-08-2009, 03:26 PM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. Replies: 2
    Last Post: 04-22-2008, 12:07 PM
  4. Replies: 2
    Last Post: 04-19-2008, 12:06 AM
  5. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM