Hi, I'm working on a linked list filled with class objects and I've encountered a weird problem that I cannot see how to resolve. I declare 2 self-referential pointers within my 2 classes and the error:

In file included from prog2.cpp:16:
employeedatalist.cpp: In function âvoid getData(std::fstream&)â:
employeedatalist.cpp:15: error: âheadâ was not declared in this scope
employeedatalist.cpp:19: error: ânextâ was not declared in this scope


Here is the code with the error:

#include <iostream>
#include "employeedatalist.h"
using namespace std;


	   
/**
This function creates an EmployeeDataList Object from a file. This is the linked list to be used!
*/
void getData(fstream& dataFile)
	  {
	  int IDnumber, yearsAge; //Placeholder vars for infor from file.
	  string nameFull, phNumber; // Placeholder vars.
	  dataFile << IDnumber << nameFull << phNumber << yearsAge;
	  head = new EmployeeData(IDnumber, nameFull, phNumber, yearsAge);
	  while (!dataFile.eof())
	     {
		 dataFile << IDnumber << nameFull << phNumber << yearsAge;
		 next = new EmployeeData(IDnumber, nameFull, phNumber, yearsAge);
		 }
		 
	  }

RELEVANT CODE

// Class for the linked list.
#include <iostream>
#include <fstream>
#include "employeedata.h"
#ifndef employeedatalist_h
#define employeedatalist_h
using namespace std;

class EmployeeDataList
{
   private:
      class EmployeeData; //Class data type for nodes. 
	  EmployeeData *head;

   public:
	  EmployeeDataList() //Default empty constructor function. 
	  {
	  head = NULL;
	  }
	  
      ~EmployeeDataList();  //Destructor.
	  void getData(fstream& dataFile); // Obtain records from file.
      void appendRecord(EmployeeData); //Add a record to the end.
	  void insertRecord(EmployeeData); //Add a record in the middle of the list.
	  void deleteRecord(EmployeeData); //Delete a record.
	  void updateRecord(EmployeeData); // Update a record.
	  void displayRecord(); //Display one user-defined record.
	  void displayAllRecords(); //Display all records.
	  void searchData (int);
	  
};	  
#endif


//Class used for database object. 
#ifndef employeedata_h
#define employeedata_h
#include <string>
using namespace std;

class EmployeeData
{
   private:
      friend class EmployeeDataList;
      int id;  // Holds ID number of employee.
	  string fullName; // Holds full name string of employee.
	  string pNumber; //Holds social security number string of employee.
	  int age;  //Hold employee's age.
	  EmployeeData *next;

   public:
      EmployeeData() //Default empty constructor function. 
	  {
	  }
	  
/**
This function creates an EmployeeData Object from user input.
*/
	  EmployeeData(int idNumber, string name, string phoneNumber, int years)
	  {
	  id = idNumber;
	  fullName = name;
	  pNumber = phoneNumber;
	  age = years;
	  next = NULL;
	  }
	 

};

#endif

The MAIN

#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "employeedatalist.cpp"

using namespace std;

//Function prototypes.



int main()
{
   EmployeeDataList *employeeList = NULL;
   
   fstream dataFile;
   dataFile.open("empdb.data", ios::in);
   if (dataFile.fail())
      cout << "The Neuvelle Database file is missing. Please call server management ASAP" << endl;
   employeeList->getData(dataFile);

   
return 0;   
}

Please any help on clearing up this issue? I've looked everywhere for solutions and can't figure it out...

You need to designate that getData is a method of EmployeeDataList, since it's not defined within the class declaration.

void [B]EmployeeDataList::[/B]getData(fstream& dataFile)

Then you still need to declare "next" as a member variable of EmployeeDataList to avoid the second error.

Edited 5 Years Ago by jonsca: n/a

Thank you for your quick reply! That did solve that issue and I think I know what was going on with that problem. However, I now receive a new error message relevant to the same lines.
I changed the getData declaration to the form you suggested.
I also included EmployeeData *next; in the EmployeeDataList class.

Error:

employeedatalist.cpp: In member function âvoid EmployeeDataList::getData(std::fstream&)â:
employeedatalist.cpp:15: error: invalid use of incomplete type âstruct EmployeeDataList::EmployeeDataâ
employeedatalist.h:12: error: forward declaration of âstruct EmployeeDataList::EmployeeDataâ
employeedatalist.cpp:19: error: invalid use of incomplete type âstruct EmployeeDataList::EmployeeDataâ
employeedatalist.h:12: error: forward declaration of âstruct EmployeeDataList::EmployeeDataâ

Is it something related to how I included the files? I checked on that and can't find a problem. I also looked at the way EmployeeData is declared in EmployeeDataList, and removed the ;, but that led to more errors... Any help on this issue?

Actually, I see what you were trying to do with the "next", so maybe that was in the right place in the EmployeeData. You just needed to qualify it as EmployeeData::next so that the compiler knows where to find it (since the two classes are friends).

As to the other problem, you included employeedata.h in employeedatalist.h, and then included employeedatalist.h in the first code box listing, so I'm not entirely sure what it's complaining about. Did you change the code from the first time you posted it, as there is no EmployeeData object on line 12 of the file?

Also, don't do #include "employeedatalist.cpp" . Compile the two files together or make them part of the same project in your IDE.

I believe the error in line 12 is referring the the class declaration. I don't understand what it points out as the problem since the files are included in logical order...

I'm using UNIX and its onboard compiler. Edited with notepad++.

Attachments
//Class used for database object. 
#ifndef employeedata_h
#define employeedata_h
#include <string>
using namespace std;

class EmployeeData
{
   private:
      friend class EmployeeDataList;
      int id;  // Holds ID number of employee.
	  string fullName; // Holds full name string of employee.
	  string pNumber; //Holds social security number string of employee.
	  int age;  //Hold employee's age.
	  EmployeeData *next;

   public:
      EmployeeData() //Default empty constructor function. 
	  {
	  }
	  
/**
This function creates an EmployeeData Object from user input.
*/
	  EmployeeData(int idNumber, string name, string phoneNumber, int years)
	  {
	  id = idNumber;
	  fullName = name;
	  pNumber = phoneNumber;
	  age = years;
	  next = NULL;
	  }
	 

};

#endif
#include <iostream>
#include "employeedatalist.h"
using namespace std;


	   
/**
This function creates an EmployeeDataList Object from a file. This is the linked list to be used!
*/
void EmployeeDataList::getData(fstream& dataFile)
	  {
	  int IDnumber, yearsAge; //Placeholder vars for infor from file.
	  string nameFull, phNumber; // Placeholder vars.
	  dataFile << IDnumber << nameFull << phNumber << yearsAge;
	  head = new EmployeeData(IDnumber, nameFull, phNumber, yearsAge);
	  while (!dataFile.eof())
	     {
		 dataFile << IDnumber << nameFull << phNumber << yearsAge;
		 EmployeeData::next = new EmployeeData(IDnumber, nameFull, phNumber, yearsAge);
		 }
		 
	  }
// Class for the linked list.
#include <iostream>
#include <fstream>
#ifndef employeedatalist_h
#define employeedatalist_h
#include "employeedata.h"
using namespace std;

class EmployeeDataList
{
   private:
      class EmployeeData; //Class data type for nodes. 
      EmployeeData *head;
	  
   public:
	  EmployeeDataList() //Default empty constructor function. 
	  {
	  head = NULL;
	  }
	  
	  ~EmployeeDataList();  //Destructor.
	  void getData(fstream& dataFile); // Obtain records from file.
	  void appendRecord(EmployeeData); //Add a record to the end.
	  void insertRecord(EmployeeData); //Add a record in the middle of the list.
	  void deleteRecord(EmployeeData); //Delete a record.
	  void updateRecord(EmployeeData); // Update a record.
	  void displayRecord(); //Display one user-defined record.
	  void displayAllRecords(); //Display all records.
	  void searchData (int);
	  
};	  
#endif
/**
 @file prog1.cpp
 @author Aquiles Parodi
 @date 2011-27-01
 Description: Manipulates a database in memory. //FLKJOSPAIUF FIX THIS
 Course: CS1254
 Logon ID: cs125421
 Programming Project #: 2
 Instructor: Guillot
 */

#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "employeedatalist.cpp"

using namespace std;

//Function prototypes.



int main()
{
   EmployeeDataList *employeeList = NULL;
   
   fstream dataFile;
   dataFile.open("empdb.data", ios::in);
   if (dataFile.fail())
      cout << "The Neuvelle Database file is missing. Please call server management ASAP" << endl;
   employeeList->getData(dataFile);

   
return 0;   
}
In file included from prog2.cpp:16:
employeedatalist.cpp: In member function void EmployeeDataList::getData(std::fstream&):
employeedatalist.cpp:15: error: invalid use of incomplete type struct EmployeeDataList::EmployeeData
employeedatalist.h:12: error: forward declaration of struct EmployeeDataList::EmployeeData
employeedatalist.cpp:19: error: incomplete type EmployeeDataList::EmployeeData used in nested name specifier
employeedatalist.cpp:19: error: invalid use of incomplete type struct EmployeeDataList::EmployeeData
employeedatalist.h:12: error: forward declaration of struct EmployeeDataList::EmployeeData
employeedatalist.cpp: In member function void EmployeeDataList::getData(std::fstream&):
employeedatalist.cpp:15: error: invalid use of incomplete type struct EmployeeDataList::EmployeeData
employeedatalist.h:12: error: forward declaration of struct EmployeeDataList::EmployeeData
employeedatalist.cpp:19: error: incomplete type EmployeeDataList::EmployeeData used in nested name specifier
employeedatalist.cpp:19: error: invalid use of incomplete type struct EmployeeDataList::EmployeeData
employeedatalist.h:12: error: forward declaration of struct EmployeeDataList::EmployeeData

It has to mainly do with the way you have declared the class EmployeeData in EmployeeDataList.

class EmployeeDataList
{
   private:
      class EmployeeData; //Class data type for nodes. 
	  EmployeeData *head;
//-------

Since you have declared EmployeeData inside EmployeeDataList
you should be defining the class like this

class EmployeeDataList::EmployeeData
{
   private:
      friend class EmployeeDataList;
      int id;  // Holds ID number of employee.
	  string fullName; // Holds full name string of employee.
	  string pNumber; //Holds social security number string of employee.
	  int age;  //Hold employee's age.
	  EmployeeData *next;

   public:
      EmployeeData() //Default empty constructor function. 
	  {
	  }
	  
/**
This function creates an EmployeeData Object from user input.
*/
	  EmployeeData(int idNumber, string name, string phoneNumber, int years)
	  {
	  id = idNumber;
	  fullName = name;
	  pNumber = phoneNumber;
	  age = years;
	  next = NULL;
	  }
	 

};

Notice that the above definition of the class has EmployeeDataList:: added to EmployeeData

class EmployeeDataList::EmployeeData{

Great catch. I suspect all that the OP really needed to do was to put "friend" in front of line 4 of your top listing. I don't know if the OP wanted to make it a subclass or not.

That sounds ok, but how does the compiler threw me another error:

In file included from employeedatalist.h:6,
                 from employeedatalist.cpp:2,
                 from prog2.cpp:16:
employeedata.h:7: error: âEmployeeDataListâ has not been declared
employeedata.h:8: error: expected unqualified-id before â{â token

That one reallly baffled me. And EmployeeData is meant to be a subclass of EmpDataList. I really appreciate the help so far though. I don't see a way out of this one.

Edited 3 Years Ago by pyTony: fixed formatting

And EmployeeData is meant to be a subclass of EmpDataList.

My bad for assuming. SkyDiploma's solution should work then. If you want to keep things a bit more organized, put your declarations for EmployeeData wirhin the other class.

class EmployeeDataList
{
    private:
    class EmployeeData
    {
         private:
         
         public:

    };

};

That way you don't have to play around with the extra header file and the compiler is happy.

Thank you Jonsca, I guess the OP's decision to place the class as a sub-class would be rather healthy in the basis of OOPs as it brings down the scope of the 'the data' only across the class.

However, On other thoughts he must consider defining it as a class outside the scope of the List-Class so that it would allow more flexibility for other implementations to use 'The-Data'

Assuming that the program is only meant to store,search and display Employee records. I would prefer it being a sub-class itself.

What would you say?

I think it's fine to do as a subclass, but that's just my opinion. If you are treating EmployeeData objects as "nodes" on an EmployeeDataList then that is a common style.

I realize that the syntax described in the previous posts works. However, in our course we are required to use a file for our subclasses. I'll talk to my professor about my issue and see what she says.

This article has been dead for over six months. Start a new discussion instead.