constructor

i have a question about a constructor

im trying to make a constructor ,but im confused when it comes to double pointer

1
2
3
4
5
6
7
8
9
  public:
    Player(std::string name, int gameCount) : mName(name), m_GameCount(gameCount), mGames(NULL)// i dont understand the double pointer or how i should define it
    {}


  private:
	std::string mName;
	unsigned int mGameCount;
	Game** mGames;
You can think of it just like any other pointer; that's all it is. The fact that the thing it's pointing to is a pointer doesn't make any difference.

That said, I certainly don't like to see a pointer to a pointer. Why do you need one? Can you do it without pointers at all?
Repeater wrote:
Why do you need one? Can you do it without pointers at all?

I’m looking forward for the day when someone explains me what’s bad in providing minimum compilable examples of the code we need help on ;-)

ghost1111, since this code compiles 0 errors 0 warnings...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>

class Game;

class Player{
public:
    // i dont understand the double pointer or how i should define it
    Player(std::string name, int gameCount) 
        : mName(name), m_GameCount(gameCount), mGames(nullptr)
    {}
private:
    std::string mName;
    unsigned int m_GameCount;
    Game** mGames;
};

int main()
{
    Player p("John Smith", 13);
    return 0;
}

...I assume you find pointers to pointer hard to deal with in general, not in particular with member initialiser lists. If so, you aren’t the only one, because I really hate them :)
A pointer needs to be instructed to point to a memory area you own before using it.
If it’s a pointer to pointers, you also need to tell the pointed pointers which memory area point to.

To my knowledge, pointers to pointers comes of handy in two situations:
1) when you need to represent data like a 2D array;
2) when you need to pass a pointer to a function that will relocate it.

To answer your question, we need to know which of the two above cases you are using pointers to pointers for. Since you are using one of them as a class member, I suppose we are talking about the first case.
First case is, in turn, divided into two situations: a) your class is in charge of allocating the pointed memory; and b) the pointer will be addressed to an already allocated memory.

Situation 1.a) can be solved by a code like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>

class Game {};  // this is no more a class declaration: it's the definition of
                // an empty class.

class Player{
public:
    Player(std::string name, int gameCount) 
        : mName(name), m_GameCount(gameCount)
    {
        // I'm going to allocate memory for a 3x4 Game array
        // Firstly, instruct the 'external' pointer what memory area it's going
        // to point to:
        mGames_rows = 3;
        mGames = new Game*[mGames_rows];
        // Secondly, insert into any pointed pointers the address of a freshly 
        // allocated memory:
        mGames_cols = 4;
        for(int i{}; i<mGames_rows; ++i) {
            mGames[i] = new Game[mGames_cols];
        }
    }
private:
    std::string mName;
    unsigned int m_GameCount;
    Game** mGames;
    int mGames_rows {},
        mGames_cols {};
};

int main()
{
    Player p("John Smith", 13);
    return 0;
}


While situation 1.b) could lead to a code more or less like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>

class Game {};  // this is no more a class declaration: it's the definition of
                // an empty class.

class Player{
public:
    Player(std::string name, int gameCount) 
        : mName(name), m_GameCount(gameCount), mGames {nullptr}
        {}
    void setGames(Game** games, int rows, int cols)
    {
        mGames = games;
        mGames_rows = rows;
        mGames_cols = cols;
    }
private:
    std::string mName;
    unsigned int m_GameCount;
    Game** mGames;
    int mGames_rows {},
        mGames_cols {};
};

int main()
{
    Player p("John Smith", 13);
    Game mygames[3][4] {};
    p.setGames((Game**)mygames, 3, 4);
    return 0;
}


Having said that, my personal advice would be to try hard to avoid pointers to pointers and give a chance to std::vectors or std::arrays if possible. I think Repeater was also thinking about that.

Note: the above example are far to be optimised: are just meant as hints.
Topic archived. No new replies allowed.