I am in need of clarification. I am still a 'noob' when it comes too C++. I get a lot of the basic stuff except passing arguments.

I understand that you can pass by reference and by pointer and by copy. but things start getting really confusing from that point on. Probably not a new problem heard of before on the discussion forums. However if someone can help me out here.
Lets say I have a type

class SOME_TYPE{
private:
    string name;
    int value;
public:
    SOME_TYPE(){ //constructor
    }
    string GetName(){
        return name;
    }
    void SetName(string nname){
        name = nname;
    }
    int GetValue(){
        return value;
    }
    void SetValue(int amount){
        value = amount;
    }
};

lets say I have a list of pointers to that type

SOME_TYPE* list[5]; //I'm assuming this is how you write a list of pointers

Now I want to send that list over to another method to display their values.

void DisplayList(SOME_TYPE* list){
    for(int loop = 0; loop < 5; loop++){
        if(list[loop] != NULL){
           cout << list[loop]->GetName() << " - Value: " << list[loop]->GetValue() << endl;
        }
    }
}
int main(){
    SOME_TYPE* list[5];
    list[0]->SetName("one");
    list[0]->SetValue(1);
    list[1]->GetName("two");
    list[1]->SetValue(2);
    DisplayList(list);
    return;
}

Now here is where I am getting frustrated. Is the 'DisplayList" method asking for the correct argument? I am assuming it is asking for a pointer to the beginning of a list. Since 'list' declared in main is a list of pointers am I sending it the correct way? Can someone please correct my understanding and explain to me how pointers are handled?

Edited 6 Years Ago by drt_t1gg3r: imported what was missing in the SOME_TYPE class

I assume the error is something along the lines of error C2664: 'DisplayList' : cannot convert parameter 1 from 'SOME_TYPE * [5]' to 'SOME_TYPE *' You need to do one of two things.

First, in the declaration of DisplayList, change the parameter type. DisplayList(SOME_TYPE* list[]) . Note the extra brackets.

Second, and my personal favourite, again change the declaration of DisplayList to take an "array length" parameter DisplayList(SOME_TYPE* myList, double arrayLength) and cast your array in the call, passing the length of the array also. DisplayList((SOME_TYPE*)list, 5) I prefer the second method as it prevents me from going out of bounds whilst still being evident that I'll be working on an array.

The first method also indicates you're working with an array, but you will need to work out how large the array is to prevent out of bounds errors.

Edited 6 Years Ago by Ketsuekiame: n/a

int main(){
    SOME_TYPE* list[5];
    list[0]->SetName("one");
    list[0]->SetValue(1);
    list[1]->GetName("two");
    list[1]->SetValue(2);
    DisplayList(list);
    return;
}

This is okay, except that Line 5 should be a call to the SetName() method, not the GetName() method, also see note(s) below concerning DisplayList()...

void DisplayList(SOME_TYPE* list){
    for(int loop = 0; loop < 5; loop++){
        if(list[loop] != NULL){
           cout << list[loop]->GetName() << " - Value: " << list[loop]->GetValue() << endl;
        }
    }
}

This is your problem. This is not an issue of passing pointers, it is an issue of passing ARRAYS. When you pass an array, you must tell the function parameter that it needs to look for an array.

Read this, then add opening and closing square-brackets to the parameter name as well as a SIZE argument.

void DisplayList(SOME_TYPE* list[B][], int ARRAY_SIZE[/B]){
    for(int loop = 0; loop < [b]ARRAY_SIZE[/b]; loop++){
        if(list[loop] != NULL){
           cout << list[loop]->GetName() << " - Value: " << list[loop]->GetValue() << endl;
        }
    }
}

Edited 6 Years Ago by Fbody: n/a

@Ketsuekiame -- the error usually states that one type can not be converted to another type.

@fbody -- I see what you are saying. But can the method be generic enough to pass it a pointer to a single type and not an array of that type?

void DisplayList(SOME_TYPE* list, int count){
    if(count == 1){
       cout << list->GetName() << " -- Value: " << list->GetValue() << endl;
    }else if(count > 0){
       for(int loop = 0; loop < count; loop++){
            cout << list->GetName() << " -- Value: " << list->GetValue() << endl;
       }
    }else{
        cout << "There are no members in your list\n";
    }
}

I thought that SOME_TYPE* list[5]; meant that it was a pointer to the first element? Am I wrong there? I mean does 'list' know that it has 5 elements in it?

Yes, a similar way of writing what you have would be SOME_LIST** list = new (SOME_LIST*[5]); Please remember your memory clean up. Also, I noticed that you haven't initialised any of your contents. You should do that ;)

I prefer my option two because it does allow you to work on a single object. But, to conform to the standard you should use Fbody's method. My method is an excuse for less coding ;)

>>...can the method be generic enough to pass it a pointer to a single type and not an array of that type?
Due to how you originally wrote DisplayList(), simply attempting to pass a pointer to the first element is not sufficient. To do what you are thinking, you must actually pass a specific element, not the array.

The more-recent version is closer to what you are thinking, but it requires changes in main() and also requires something called "pointer arithmetic", which you have not implemented properly in this version. To prevent further confusion in the short term, I suspect you won't want to get involved in that at this point.

>>I thought that SOME_TYPE* list[5]; meant that it was a pointer to the first element? ... does 'list' know that it has 5 elements in it?
That is essentially what it means, but you can't rely on that when passing to a function. When you pass an array, you need to tell the function to expect an array; that's what the brackets are for. The array parameter's name "list" is just that, a name. Other than its dataType, it really knows nothing else about the incoming information. You need the additional SIZE parameter/argument to provide the necessary information.

Edited 6 Years Ago by Fbody: n/a

Yes, a similar way of writing what you have would be SOME_LIST** list = new (SOME_LIST*[5]); Please remember your memory clean up. Also, I noticed that you haven't initialised any of your contents. You should do that ;)

I prefer my option two because it does allow you to work on a single object. But, to conform to the standard you should use Fbody's method. My method is an excuse for less coding ;)

Alright let me show you a new class

class FOO{
private:
   string name;
   int value;
public:
   FOO(){ //constructor
   }
   string GetName(){
       return name;
   }
   void SetName(string nname){
      name = nname;
   }
   int GetValue(){
      return value;
   }
   void SetValue(int amount){
      value = amount;
   }
};
class SOME_TYPE{
private:
   string name;
   int value;
   FOO* list[5];
public:
   SOME_TYPE(){ //constructor
   }
   string GetName(){
       return name;
   }
   void SetName(string nname){
      name = nname;
   }
   int GetValue(){
      return value;
   }
   void SetValue(int amount){
      value = amount;
   }
   FOO** GetList(){
      return list;
   }
};

Would that meet the requirements of what you were talking about? if so when I call upon the GetList() method in the SOME_TYPE class what kind of pointer is it returning? just a standard pointer? a pointer to a pointer? is that pointer pointing to the first element of the list? If it's a pointer to a pointer, why?

sorry for all the questions but this passing pointers is confusing.

I assume the error is something along the lines of error C2664: 'DisplayList' : cannot convert parameter 1 from 'SOME_TYPE * [5]' to 'SOME_TYPE *'

The error I get is that in the DisplayList(NPC* list) method, NPC was not declared in that scope

Edited 6 Years Ago by drt_t1gg3r: n/a

I'm probably over-complicating things for you. As for your original question, Fbody's method is the way you should go.

To explain the question you just asked ** indicates a double pointer or a pointer to a pointer (or list of pointers).

When you declare your array, you are declaring an array of pointers. But each of those needs to be initialised or set to null.

If you did what you have there and then tried to do anything (like SetValue) then you will find that the function fails because there is no class there (You've just told it to make room for a pointer to your class)

EDIT: Include your NPC class header.

Edited 6 Years Ago by Ketsuekiame: n/a

it's a huge file full of get's and sets. I wrote the class after watching the Wrath Land videos on how to make a text adventure. But when it comes to creating the NPC classes in main and then passing them either as a pointer to an array or a pointer to a vector things start to get real hairy. I get errors like this argument can not be converted to this or that, and similar. My first game was successful as I built my classes and methods similar to the videos. But now that I want to make a different game with different logic I thought my knowledge of pointers, vectors, and arrays would be sufficient. But I digress.

mostly my problem comes when I create a FIGHTER, CLERIC, and MAGICUSER which are all children to the NPC class. I then create a pointer to a list(crew) all 3 of them. then I try to send that pointer to the DisplayList method with similar definitions to the above (I have tried both) but have problems because I am unsure what it is I am sending and what it is that the method wants. I assume they are not the same thing and that's why I get the errors.

bool GameStart(){
    FIGHTER fighter; //all 3 objects are children of the NPC class
    CLERIC cleric;
    MAGICUSER mu;
    NPC* crew[3];
    switch(ChooseClass()){
        case CT_FIGHTER:{
             crew[0] = &fighter;
             crew[1] = &cleric;
             crew[2] = &mu;
             break;}
        case CT_CLERIC:{
             crew[0] = &cleric;
             crew[1] = &fighter;
             crew[2] = &mu;
             break;}
        case CT_MAGICUSER:{
             crew[0] = &mu;
             crew[1] = &cleric;
             crew[2] = &fighter;
             break;}
        default:{
            crew[0] = &fighter;
            crew[1] = &mu;
            crew[2] = &cleric;
            break;}
    }    
    
    crew[0]->SetName("Dartania");
    crew[1]->SetName("Roland");
    crew[2]->SetName("Cyndy");
    DisplayList(crew); //here is where we send the crew to be displayed
}
void DisplayList(NPC* crew){
    for(int man = 0; man < 3; man++){
        crew[man]->DisplayStats(); //DisplayStats() is a method in the NPC class
    }
}

ERROR:
in method DisplayList(NPC* crew) NPC is not declared in this scope

Your code is correct, but it seems the DisplayList method may be in a different file that is compiled before your NPC class.

Include the headerfile of your NPC class in the header file that contains your DisplayList definition.

OMG!I was defining the DisplayList() function before the NPC class. Can you tell I'm a noob. sheeesh.

anyway I have one more question. Now from the GameStart() method I pass the list as a pointer right? so any method receiving the list needs to actually want a pointer, not a pointer to a pointer?

okay actually 2 questions
in the NPC class there is a datamember

SPELL* castableSpells[6];

I retrieve the list with from the NPC class

SPELL** GetSpellList(){
    return castableSpells;
}

NOW pertaining to the NPC, when I pass the pointer of the crew over to a method and I want to work with a certain NPC's spell list I would ...

SPELL** list = crew[0]->GetSpellList();

now 'list' holds a pointer to the first spell in that list right? so I can say

list[0]->Cast(enemy, count); //where Cast() is a method in the SPELL class

EDIT:: corrected coding

Edited 6 Years Ago by drt_t1gg3r: corrected coding

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