0

I'm trying to make a data structure which contains all the monsters in the game. For some reason when I allocate new monster i get "cannot convert Monster** to p_monster {Aka monster*} in initialization. If you could help me out it would be much appreciated. Thanks in advance

struct Monster {
    int x;
    int y;
    int health;
    Monster *next;
};
typedef Monster* p_monster;
class gameUtils {
protected:
  p_monster monster};
public:
gameUtils(){
monster=NULL;
...}
function(){
monster = getMonster(monster)}  // so that I can assign whatever value I want to monster->last->next through the function itself

p_monster getMonster(p_monster monster){
  p_monster newMonster = new p_monster;
        if(monster==NULL){
            monster=newMonster;

        }else{
    ....   // find last monster then create new one and pass it to caller

        return monster;   // returns new monster without any value
    } 

7
  • Give yourself a break and use std::list<Monster>. The std::list has already been tested and works, so that you can move on and do other coding. Commented Jul 28, 2022 at 17:24
  • Don't use manual memory management in modern C++. Commented Jul 28, 2022 at 17:25
  • 6
    p_monster newMonster = new p_monster; should be p_monster newMonster = new Monster; I think you confused yourself with the unnecessary typedef Commented Jul 28, 2022 at 17:26
  • Fyi, p_monster {Aka monster*} - that you are compelled to mention that is an indication of what a terrible idea hiding pointer types in typedef aliases really is. And if you don't think so, look at @drescherjm ' s comment above. I suspect he's hyper-accurate in that assessment. Commented Jul 28, 2022 at 17:26
  • 4
    Type-aliasing pointers is one of those things that everyone discovers to be a great idea – for two or three weeks or so. And then the pain sets in... Commented Jul 28, 2022 at 17:33

1 Answer 1

3

Type aliases are slightly more clear with using.

//typedef Monster* p_monster;
using p_monster = Monster*;

p_monster is Monster*. Now when you call new T then an object of type T is created and as a result you get a pointer to that object, a T*.

When you write:

p_monster newMonster = new p_monster;

Then new dynamically allocates a p_monster, a Monster*, and you get a p_monster*, a Monster**. There is no conversion from Monster** to Monster*, hence the error.

I suggest a std::vector<Monster> to store your monsters. Your approach for the list is intrusive, a Monster in your design is aware of being in a linked list, it has a next member. When you use a std::vector<Monster> you can store Monsters in a vector, outside of the vector, or in a different container, the Monster needs not care. Also not using manual memory managment via raw pointers will make your code much simpler.

struct Monster {
    int x;
    int y;
    int health;
    Monster(int x,int y,int health) : x(x),y(y),health(health) {}
};

struct gameUtils {
    std::vector<Monster> monster;
    Monster& createMonster(int x,int y,int health) {
        monster.emplace_back(x,y,health);
        return monster.back();
    }
};

A linked list in C++ is std::list, though a vector profits a lot from its elements being stored in contiguous memory. It profits from that so much, that it is often superior to a std::list even though time complexity of some methods suggests otherwise.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.