0

I am trying to write a little game in which there are bricks on a track.

My problem is that I would like to have a vector of bricks in the track class, but I would need to keep a pointer to the track in the brick class.

What I was trying to do is to have two header files track.h and brick.h and I wanted to include track.h in the brick.h file and vice-versa.

brick.h:

#pragma once

#include "track.h"

class brick
{
    public:
        brick (track &theTrack);
    private:
        track *mTrack;
};

brick::brick(track &theTrack)
{
    mTrack = &theTrack;
}

track.h:

#pragma once

#include "brick.h"

class track
{
    public:

    private:
        vector<brick> brickPositions;
};

However this results in compile errors.

I don’t use .cpp files for these classes, just a single .h file with #pragma once at the top.

Can you please explain what is the problem and how can I solve this?

caius
  • 3
  • 1

2 Answers2

3

You can do forward declaration:

 #pragma once

class brick;
class track
{
    public:

    private:
        vector<brick> brickPositions; //This might not compile, should be a pointer
};

However you need to have cpp file.

track.cpp:

    class brick
    {
        public:
            brick (track &theTrack);
        private:
            track *mTrack;
    };

    brick::brick(track &theTrack)
    {
        mTrack = &theTrack;
    }

Do the other way around (forward declare track before class brick), since you use only pointer to track in class brick.

P.S. Accept the answer below this :)

khajvah
  • 4,889
  • 9
  • 41
  • 63
  • Can brick really be forward declared for use in vector? Upvoted at least. – user2672165 Sep 17 '13 at 12:18
  • My first reaction was that you can't forward declare `brick` because `track` instantiates it. But it doesn't actually instantiate a `brick`. It instantiates a vector of `brick` and a vector is actually a fixed-sized object which contains a pointer to dynamically allocated memory. I tried it with VC++11 and it compiled without errors. Of course, that doesn't really mean much... – Ferruccio Sep 17 '13 at 12:29
  • The standard requires container element types to be complete. – Sebastian Redl Sep 17 '13 at 12:49
2

Since the brick class only has a pointer to the track class, you can use a forward declaration.

#pragma once

class track;

class brick
{
    public:
        brick (track &theTrack);
    private:
        track *mTrack;
};

brick::brick(track &theTrack)
{
    mTrack = &theTrack;
}

You don't need to change the track class.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • This is better answer. I didn't notice that track has variable to brick (just copied and pasted). – khajvah Sep 17 '13 at 12:12
  • Three things: Using an initializer list for the pointer would be a better idea; `#pragma once` is not 100% portable (yet), use an include guard (in addition to or instead of, it's your choice); and if you are going to use a forward declaration, you do not need the header include in the header file, push it to the definition file. – Casey Sep 17 '13 at 12:29
  • Thanks for your answer, @Ferruccio, but I still cannot solve it after many hours. My problem is that I cannot access anything in track from brick. Here is the skeleton code: http://pastebin.com/cgfz1zA1 – caius Sep 17 '13 at 23:38
  • @caius Drop the "include "track.h"", define the track class with implementation of brick class(before brick::brick(track &theTrack)). – khajvah Sep 18 '13 at 06:46