-4

Hello I am new fairly newly to C++ and I am constructing a program that will simulate a colony of bunnies. I am a bit stuck on how to resolve this issue on how to get methods to recognize my global pointer variables. I get this error when I try to compile my program.

enter code here
main.cpp: In function ‘bool ageCheck(BunnyNode*)’:
main.cpp:133:5: error: ‘head’ was not declared in this scope
if(head){
   ^

I have several more errors that are similar to this one. I am under the impression that if I understand why this error is being given, I will be able to sort out the others. I chose an error from the ageCheck() method that is supposed to traverse the linked list of bunnies and check their ages. This is what I have

enter code here
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

//#include "listofbunny.h"

using std::cin;
using namespace std;

typedef struct BunnyNode {
    string* name;
    int age;
    bool gender;
    string* color;
    bool radioactive_bunny;
    BunnyNode *next;
    BunnyNode *head;
    BunnyNode *tail;
    BunnyNode *current;
}

char menu();
int randomGeneration(int x);
void generateFeatures(BunnyNode * newBunny);
void startCheck(int pass);
void sizeCheck(bool& terminate);
bool fatherCheck(BunnyNode * bunny, bool& fatherPresent);
bool motherCheck(BunnyNode * bunny);
bool ageCheck(BunnyNode * bunny);
void addBunnyAge();
void addBabyBunny();
void addBunny();
void addBunny(BunnyNode * mother);
int  mutantCount();
void mutantTransform();
void purge();
string getGender(BunnyNode * bunny);
string getName(BunnyNode * bunny);
int getColonySize();
void printColony();
void printFeature(BunnyNode * bunny);
void printSize();

bool ageCheck(BunnyNode * bunny){
    if(head){
        if(bunny->age >= MAX_AGE && bunny->radioactive_bunny == false){
            return 1;
        }
        else if(bunny->age >= MAX_MUTANT_AGE && bunny->radioactive_bunny){
            return 1;
        }
        else
            return 0;
    }
}
Eric Carr
  • 3
  • 1
  • There is no `head` but `BunnyNode::head`. If `ageCheck` was a member function of `BunnyNode` you might be rockin' and rollin' right now, but it's not. By the way, you don't have to do the `typedef struct` stuff in C++. – user4581301 Mar 18 '17 at 00:25
  • Addendum: You seem to be conflating the linked list with the node. This will lead you to problems in the future. – user4581301 Mar 18 '17 at 00:28
  • @user4581301 so I can just do `struct BunnyNode` ? – Eric Carr Mar 18 '17 at 00:28
  • `struct BunnyNode { guts of BunnyNode };` and after that you can just call it `BunnyNode` – user4581301 Mar 18 '17 at 00:29
  • @user4581301 `;` missing – 463035818_is_not_an_ai Mar 18 '17 at 00:30
  • @tobi303 thanks. Edited. – user4581301 Mar 18 '17 at 00:30
  • @user4581301 and instead of `BunnyNode *head;` I replace it with `BunnyNode::head;`? – Eric Carr Mar 18 '17 at 00:31
  • No. To use `BunnyNode::head` you need to have a `BunnyNode` object. You could go `bunny.head`, but this doesn't make any sense. This is what I meant by conflating the linked list with the node. You should have a `BunnyList` to contain the `BunnyNodes`. – user4581301 Mar 18 '17 at 00:34
  • @user4581301 so I would needs something like `class BunnyList {BunnyNode {everything else}}`? – Eric Carr Mar 18 '17 at 00:38
  • [Another `Bunny` question here.](http://stackoverflow.com/questions/42870748/error-function-is-private-void-error-within-this-context) This user is using a `std::vector` to contain their `Bunny`s. If you are allowed to use standard library containers instead of a roll-your-own linked list, use the container. Likely save you hours of coding. – user4581301 Mar 18 '17 at 05:26

1 Answers1

1

A typical linked list structure is made of three parts

The Data

class Bunny
{
    string name; // don't use pointers unless you really, really need them
    int age;
    bool gender;
    string color;
    bool radioactive_bunny;
public:
    string getGender(); // don't need to know which Bunny anymore because 
                        // these functions are bound to a particular Bunny
    string getName();
    ...
};

The Node

struct Node
{
    Bunny data; // we will ignore templates for now. But they are rilly kool!
    Node * next; // here is a good time to use a pointer: to point to the next node
    Node(): next(nullptr) // node constructor. This really helps. Trust me.
    {
    }
}

Nodes know nothing except their data and a link to the next Node. The dumber you can make a Node, the safer you are. Also note that the Node contains the Data. This allows you to easily swap out the Data without having to re-write the whole node and sets you up for easy templating of the Lined List structure later (though you're probably better off jumping to std::list).

And the Linked List:

class LinkedList
{
    Node *head;
    Node *tail;
    Node *current; // not as useful as you might think
public:
    LinkedList(): head(nullptr),tail(nullptr),current(nullptr)
    {
    }
    void add(Bunny & bunny);
    void remove(const string & bunnyname);
    Bunny & get(const string & bunnyname);
    Bunny & getNext(); // current may help here, but look into iterators
    ...
};

Note that we never let the caller at a Node. They could do something stupid like delete it or mangle Node::next.

Adding, removing and iterating through the list has been beaten to death on Stack Overflow, so you should be able to find tonnes of examples of how to do this. For example: Using pointers to remove item from singly-linked list. There is, in my opinion, a really important trick in that link well worth the time spent learning. Pointers are like fire: A handy servant, but a terrifying master.

The big trick to getting linked lists is use a pencil and paper to draw the list and the nodes. See how they are connected. Redraw the list step by step as you add, remove, etc... so you can see how it needs to be done. Then write code to match the drawings. I know. Easier said than done, but way easier than banging your head against a wall with no plan whatsoever.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • I think I am starting to understand a little bit better. I have a question. Would the other methods such as `ageCheck()`, `sizeCheck()` go in the LinkedList class? – Eric Carr Mar 18 '17 at 01:15
  • Where the function goes depends on what the function does. Classes represent some thing or concept. The functions that are members of that class should support that representation. Ask yourself, "Does this class need this capability in order to be useful?" If not, it's a function that uses the class. If `sizeCheck` looks for `Bunny`s over a particular size, then it doesn't sound like the linked list needs that ability. It can be written as a function that calls `getNext` until there are no more `Bunny`'s in the list, testing each `Bunny`'s size on the way by. – user4581301 Mar 18 '17 at 02:53