Register to reply

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

by John O' Meara
Tags: access, class, nested, pointer
Share this thread:
John O' Meara
#1
Mar16-12, 04:35 PM
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.
Phys.Org News Partner Science news on Phys.org
Suddenly, the sun is eerily quiet: Where did the sunspots go?
'Moral victories' might spare you from losing again
Mammoth and mastodon behavior was less roam, more stay at home
Chopin
#2
Mar18-12, 01:28 AM
P: 351
I'm not sure I completely understand what you're being asked to do here. You said you added the getAllGrades() function, so does that mean everything else was given to you? And the goal is to implement the addGrade() function, or something else?

If so, then is addGrade() allowed to put the new grade at the beginning of the list, or does it have to be at the end? If it's allowed to be at the beginning, then you ought to be able to just create a new pairList whose 'next' member points to allGrades, and then replace allGrades with your new pairList. You don't need a special accessor for that member, since you're accessing it from within the class.

Once that's done, you should be able to implement readForwardList() by simply calling addGrade() repeatedly.
rcgldr
#3
Mar18-12, 01:44 AM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
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

Chopin
#4
Mar18-12, 01:49 AM
P: 351
How do you access a pointer of a class nested in another class

Quote Quote by rcgldr View Post
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.
rcgldr
#5
Mar18-12, 03:25 AM
HW Helper
P: 7,030
Getting back to the original question:
Quote Quote by John O' Meara View Post
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 Quote by rcgldr View Post
     access->getAllGrades()->getNextEntry() =
       new pairList(studentID, grade, NULL);
Quote Quote by Chopin View Post
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));
John O' Meara
#6
Mar18-12, 11:51 AM
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.
rcgldr
#7
Mar18-12, 01:28 PM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
... addGrade() ...
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){
    allGrades = new pairList(studentID, grade, allGrades);
}
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 Quote by John O' Meara View Post
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 Quote by John O' Meara View Post
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.
John O' Meara
#8
Mar18-12, 02:30 PM
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.
rcgldr
#9
Mar18-12, 02:41 PM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
In the grades constructor: grades() { } // start with empty lists, that is all he says.
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 Quote by John O' Meara View Post
meanValue
This could use a better name, like validValues.
John O' Meara
#10
Mar19-12, 06:23 PM
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.
rcgldr
#11
Mar19-12, 06:59 PM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
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()?

Also shouldn't the name of readForwardList() be something like inputGrades()?
John O' Meara
#12
Mar19-12, 07:05 PM
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.
rcgldr
#13
Mar19-12, 08:52 PM
HW Helper
P: 7,030
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;
    }
}
John O' Meara
#14
Mar19-12, 09:01 PM
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.
John O' Meara
#15
Mar19-12, 09:06 PM
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.
rcgldr
#16
Mar19-12, 09:49 PM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
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()
{
// ...
    theSubject = new grades;
// ...
    theSubject->addGrade(...);
// ...
}
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()
{
// ...
    theSubject.addGrade(...);
// ...
}
Quote Quote by rcgldr View Post
Are you sure you didn't use grades(){allGrades == NULL; meanValue = false;} (== instead of =)? This is working for me.
Quote Quote by John O' Meara View Post
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;
John O' Meara
#17
Mar20-12, 08:46 AM
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.
rcgldr
#18
Mar20-12, 02:38 PM
HW Helper
P: 7,030
Quote Quote by John O' Meara View Post
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.


Register to reply

Related Discussions
Waitlists to get into class at junior college math class ? Academic Guidance 16
How could I call a base class virtual function from the derived class ? (C++) Programming & Computer Science 2
Why does Chern class belong to INTEGER cohomology class? Differential Geometry 41
How does a Physics class differ from an Engineering class? Academic Guidance 38
Access members of another class? Programming & Computer Science 1