# How do you access a pointer of a class nested in another class

by John O' Meara
Tags: access, class, nested, pointer
 P: 330 Given the following:  class pairList { private: int value1, value2; pairList *nextEntry pairList *reverseM(pairList *prev); public: pairList(int v1, int v2, pairList *next) : value1(v1), value2(v2), nextEntry(next) {} int getFirstValue() { return value1; } int fetSecondValue() { return vlaue2; } pairList *getNextEntry() { return nextEntry; } pairList *reverseM(); pairList *search(int val); }; class grades { private: pairList *allGrades; float mean, stdDev; bool meanValue; public: grades() {} // start with empty class void addGrade(int studentID, int grade); float average(); int getScore(int studenID); int getZScore(int studentID); pairList *getAllGrades() { return allGrades; } // I added this line }; My effort to access pairList within the grades class  void grades::addGrade(int studentID, int grade) { grades *access = this; if(access->getAllGrades()->getNextEntry() != NULL) access->addGrade(studentID, grade); else access->getAllGrades()-getNextEntry() = new pairList(studentID, grade, NULL); // I get an invallid lvalue in assignment here } pairList *readForwardList() { int inputval1, inputval2; pairList *front = NULL; cout << "enter ID no: " ; cin >> inputval1; cout << "\nEnter grade: "; cin >> inputval2; while(!cin.eof()) { front = new pairList(inputval1, inputval2, front); cout << "Enter ID no: "; cin >> inputval1; cout << "\nEnter grade: " cin >> inputval2; } cout '\n'; return front->reverseM(); } You cannot really create a local single linked pairList with readForwardList() and yet still be an automatic member of the outer class grades, I certainly don't think? That is, how do you do it, because the *allGrades pointer is private to the class grades. And any time you place it on the l.h.s. of an assignment you get an lvalue error, using getAllGrades().  int main() { grades *theGrades, *tmpGrades; int i, j; theGrades->gatAllGrades() = readFowardList(); // error here! how do you do it correctly? tmpGrades = theGrades; while(tmpGrades->getAllGrades() != NULL) { i = tmpGrades->getAllGrades()->getFirstValue(): j = tmpGrades->getAllGrades()->getSecondValue(); cout << i << ' ' << j << ' '; tmpGrades->getAllGrades() = tmpGrades->getAllGrades()->getNextEntry(); // error, lvalue } cout '\n'; // delete here return 0; } If you can see the problem I have, help is very welcome. Thanks in advance.
HW Helper
P: 6,903
 Quote by John O' Meara Given the following:  access->getAllGrades()-getNextEntry() = new pairList(studentID, grade, NULL); // I get an invallid lvalue in assignment here
Sometimes we all look for something complicated when it's just a simple bug. You used "-" instead of "->" for the pointer to getNextEntry(), it should be:

     access->getAllGrades()->getNextEntry() =
new pairList(studentID, grade, NULL);   // I get an invallid lvalue in assignment here

P: 341

## How do you access a pointer of a class nested in another class

 Quote by rcgldr Sometimes we all look for something complicated when it's just a simple bug. You used "-" instead of "->" for the pointer to getNextEntry(), it should be:  access->getAllGrades()->getNextEntry() = new pairList(studentID, grade, NULL); // I get an invallid lvalue in assignment here
That's still going to give an lvalue error--you can't assign to the return value of a function like that. This code has some more fundamental problems than just a few typos.
HW Helper
P: 6,903
Getting back to the original question:
 Quote by John O' Meara How do you access a pointer of a class nested in another class?
You either make the pointer public, or create a function to set the pointer.

 Quote by rcgldr  access->getAllGrades()->getNextEntry() = new pairList(studentID, grade, NULL);
 Quote by Chopin That's still going to give an lvalue error--you can't assign to the return value of a function like that.
I made the silly mistake this time. Wasn't paying attention to the fact that getNextEntry() was a function. Seems that adding an appendtoList() or setNextEntry() function in the intList class will be needed, or as already suggested, inserting new grades to the beginning of the list as was done with the other intList example programs. Example addList(), and example usage based on previous threads using class intList:

intList *intList::addList(intList * newList){
if(this == NULL){                   // if current list is empty
return(newList);                //   return newList
}
intList *tmpList = this;            // append newList to this list
while(tmpList->nextEntry != NULL)
tmpList = tmpList->nextEntry;
tmpList->nextEntry = newList;
return(this);
}

int main(){
using namespace std;
intList *theList = NULL;
int i;

for(i = 0; i < 8; i++)              // initialize list {0..7}
theList = theList->addList(new intList(i, NULL));
 P: 330 Hi, Thanks for the replies. The question is: Define a new class, pairList which is like intList except that each cell contains two integers instead of one. Its operations are the same as intList, except that getValue() is replaced with getFirstValue() and getSecondValue(), and its constructor is also changed approppriately. Define the operation pairList *search(int val), which looks for a cell that has val as its first and returns a pointer to that cell. Using 'pairList' define the class grades that keeps a grade list, consisting of student ID numbers (integres) and grades on one exam, and reports grades in terms of z-scores. 'mean' and 'stdDev' hold the mean and standard deviation of the scores but should not be computed each time a new grade is added. Instead, compute them only when one of the functions 'average', 'standardDeviation' or 'getZScores' is called. Set 'meanValid' to true when 'mean' and 'stdDev' are valid, and to false when they may not be. What I 'm asking is, for example, if I had the following :  struct addr { char name[30]; char street[40]; char state[3]; unsigned long int zip; } And I also have:  struct emp { struct addr address; // nested structre float wage; } worker; The following code assigns 12345 t0 the 'zip' element of "address" worker.address.zip = 12345; Can I not do something similar with pairList's elements given pairList *allGrades is a pointer of member of 'grades'. I don't think I can as no instance of pairList is defined in grades only a pointer to pairList, (as well as the member allGrades being private and not public; So I don't know where to start? I had tried making both nextEntry in pairList and allGrades public, but then I got a run time segmentation fault, and that is not the question anyway. The question assumes that it can be done the way itis setup.
HW Helper
P: 6,903
For addGrade() use Chopin's suggestion and insert new entries at the start of the list using the pairList constructor (which is public):

grades::addGrade((int studentID, int grade){
}
grades default constructor needs to initalize it's members:

class grades {
// ...
grades() {allGrades = NULL; mean = 0.; stdDev = 0.; meanValue = 0;}
// ...
I'm wondering why is meanValue a bool? What is meanValue used for?

 Quote by John O' Meara Define the operation pairList *search(int val), which looks for a cell that has val as its first and returns a pointer to that cell.
That will allow the grades class to implement a search by id function and return a pointer to that node in grade's pairList.

 Quote by John O' Meara If I had the following " ... struct ... ".
In the case of a struct, the default is all members are public unless declared private. I don't think you need to change this. The segmentation fault in your test code mostly likely happened to infinite recursion and stack overflow. I don't think you need to use that code for this book's example, but if you'd like to fix it, post that example here or create a new thread to get that issue solved.
 P: 330 Hi. Thanks for helping. In the grades constructor: grades() { } // start with empty lists, that is all he says. meanValue is set true when mean and stdDev are valid otherwise false. Because you are only to compute mean and stdDev each time average() , standardDeviation() and getZScore() is called They are not to be computed each time a new grade is added. No, I will not use the struct code example because I didn't even keep the code with the segmentation fault, I was just experimenting at the time. Thanks for the offer to look at it , though. I thought the question a bit open ended too.
HW Helper
P: 6,903
On my system, if my program (in debug mode) does a new, all members get set to 0xcdcdcdcd if the members aren't specifically initialized in the constructor, so they should be initialized in the constructor as I mentioned in my previous post, except meanValue could be set to false instead of 0.

 Quote by John O' Meara meanValue
This could use a better name, like validValues.
 P: 330 I replaced in the above readForwardList(): front = new pairList(inputval1, inputval2, front); with theGrade->addGrade(inputval1, inputval2); where theGrade is a pointer to grades, and where addGrade() is defined as in post #7. The program compiled fine, but when I ran it I got a segmentation fault on entering the first line of data.
HW Helper
P: 6,903
 Quote by John O' Meara got a segmentation fault on entering the first line of data.
I suspect an issue with how you're handling cin.eof(). It would help if you got access to a source level debugger. If you're running some version of windows, then I would recommend microsoft visual c++ express, which is free. Can you show the actual code for readForwardList()?

 P: 330 It is ok I got it working; I changed the initialization of the grades constructor from: grades() {allGrades = NULL; meanValue = false; } to, grades() : allGrades(NULL) { meanValue = false; }. Thanks, very much for helping all along.
 HW Helper P: 6,903 Are you sure you didn't use grades(){allGrades == NULL; meanValue = false;} (== instead of =)? This is working for me. Also I added a destructor to delete all the allocated pariLists in allGrades: class grades { private: pairList *allGrades; // list of grades float mean, stdDev; bool meanValue; public: grades(){allGrades = NULL; meanValue = false;} ~grades(); // destructor void addGrade(int studentID, int grade); void reverseM(){allGrades = allGrades->reverseM();} void showGrades(); }; grades::~grades(){ pairList *tmpList; while(allGrades != NULL){ tmpList = allGrades; allGrades = allGrades->getNextEntry(); delete tmpList; } }
 P: 330 OK, What I have done now is use a global pointer to grades (so that the average(), getZScore(), etc can access the input data) and now again, I am getting a segmentation fault. I have replaced readForwardList() with inputGrades().  grades *theSubject = NULL; // global scope .... void inputGrades() { int inputval1, inputval2; // grades theSubject; local scope cout << "Enter studentID no: "; cin >> inputval1; cout << "Enter grade: "; cin >> inputval2; while (!cin.eof()) { theSubject->addGrade(inputval1, inputval2); cout << "Enter studentID no: "; cin >> inputval1; cout << "Enter grade: "; cin >> inputval2; } cout << '\n'; } int main() { //grades *theSubject; local scope inputGrades(); // mean(); // deleteList(theSubject->getAllGrades()); return 0; } When the pointer 'theSubject' is local scope the program inputs the values fine. But not when 'theSubject' is global. Thanks.
 P: 330 No, I am sure of that. The book has not introduced us to destructors yet, infact another 10 pages has to go before before the book talks about delete. Thanks.
HW Helper
P: 6,903
 Quote by John O' Meara OK, What I have done now is use a global pointer to grades (so that the average(), getZScore(), etc can access the input data) and now again, I am getting a segmentation fault. I have replaced readForwardList() with inputGrades().
You need to allocate an instance of grades:

grades *theSubject = NULL;

int main()
{
// ...
// ...
// ...
}
or declare an actual instance of grades, but in this case it will be an instance of grades versus a pointer to grades:

grades theSubject;

int main()
{
// ...
// ...
}
 Quote by rcgldr Are you sure you didn't use grades(){allGrades == NULL; meanValue = false;} (== instead of =)? This is working for me.
 Quote by John O' Meara No, I am sure of that.
Since it's working for me, you could try this again. In C++, these two statements peform the same operation:

pariList * allGrades(NULL);
pairList * allGrades = NULL;
 P: 330 It is working fine now. The lack of an instance of grades was the problem,I guess. I thought I had allGrades initialized the way I said I had, I actually had the initialization of allGrades left out altogether. Thank you for your time and going to the trouble of typing the program into your own computer. Thanks again.
HW Helper
P: 6,903
 Quote by John O' Meara Thank you for your time.
No problem, as I said, I was learning from this as well, as I haven't done that much with classes or the "this" pointer.

 Related Discussions Academic Guidance 16 Programming & Computer Science 2 Differential Geometry 41 Academic Guidance 38 Programming & Computer Science 1