Instancing a Class via Constructor

Have a nice day! I found this community maybe 2 years ago, but recently I've decided to register.

This is my first topic here, and well... despite is a 'help request', I think you'll welcome me? hehe

Going to the point:

I'm making a little "game engine" for a Rogue-Like game series I'll develop beside a friend. This "game engine" was programmed originally in ms-dos batch 6 years ago by me, and was evolving since. It have a VB6 version, a VB .net version, and a Python version... lately a C++ version following the same method of the first stable release of ms-dos batch (isn't weird?). As you can see, is a mere hobby.

Well, I have 1 headers for my C++ version of the engine, in that *.h file I have 2 classes (for now). The first class, and maybe the most important one, contains the code of the map handling (drawing, verification, creation, modification etc.) and the second one is the Object class, which code the "actors" or "npc" basic functions as movement, coloring, instancing etc...

The second class depends of the first class to function, because the first class is the responsible of displaying all inside the map.

The problem is that the class Object needs an instance of the class Map where the Object will be, but... that's the problem, the code seems right, but when is about to run it crash reporting a "No matching function for call to 'Map::Map()'" in the line 91 of AGE.h (that's the Object class constructor)... and its all.

So, this is the code of the main header that contains these classes:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <stdlib.h>
#include <conio.h>

#define Up 0
#define Down 1
#define Left 2
#define Right 3
#define UpLeft 4
#define UpRight 5
#define DownLeft 6
#define DownRight 7

class Map {
      public:
             Map(int MaxX_, int MaxY_, char* Background_, int FGColor_, int BGColor_);
             int MaxX, MaxY, BackgroundColor, ForegroundColor;
             char* Background;
             void DrawMap(int MinX, int MinY, int MaxX_, int MaxY_, int ConPosX, int ConPosY);
             void Point(int X, int Y, char* Graphic, int FGColor_, int BGColor_);
             bool IsFree(int X, int Y);
             char* XY[100][100];
             int BGColor[100][100];
             int FGColor[100][100];
};

Map::Map(int MaxX_, int MaxY_, char* Background_, int FGColor_, int BGColor_) {
             Background = Background_;
             BackgroundColor = BGColor_;
             ForegroundColor = FGColor_;
             MaxX = MaxX_;
             MaxY = MaxY_;
             for(int x=0; x<MaxX_; x++) {
                     for(int y=0; y<MaxY_; y++) {
                             XY[x][y] = Background_;
                             BGColor[x][y] = BGColor_;
                             FGColor[x][y] = FGColor_;
                     }
             }
}

void Map::DrawMap(int MinX, int MinY, int MaxX_, int MaxY_, int ConPosX, int ConPosY) {
     int yf = 0;
     for(int x=MinX; x<MaxX_; x++) {
             gotoxy(ConPosX, ConPosY + yf);
   		     for(int y=MinY; y<MaxY_; y++) {
                     textcolor(FGColor[x][y]);
                     textbackground(BGColor[x][y]);
                     cputs(XY[x][y]);
             }
             yf += 1;
     }
}

void Map::Point(int X, int Y, char* Graphic, int FGColor_, int BGColor_) {
     if ( X < MaxX && Y < MaxY && X > 0 && Y > 0) {
          XY[X][Y] = Graphic;
          BGColor[X][Y] = BGColor_;
          FGColor[X][Y] = FGColor_;
     }
}

bool Map::IsFree(int X, int Y) {
     if ( X < MaxX && Y < MaxY && X > 0 && Y > 0) {
          if ( XY[X][Y] == Background && BGColor[X][Y] == BackgroundColor && FGColor[X][Y] == ForegroundColor ) {
               return true;
          } else {
               return false;          
          }
     } else {
          return false;
     }
}

class Object {
      public:
             Object(Map M, int X_, int Y_, char* Graphic_, int ForegroundColor_, int BackgroundColor_);
             ~Object();
             int X, Y, BackgroundColor, ForegroundColor;
             char* Graphic;
             bool Move(int Xto, int Yto);
             bool StepMove(int Direction, int Steps);
             Map OMap;
      private:
              char* LastGraphic;
              int LastFG, LastBG, LastDR;
};

Object::~Object() {}

Object::Object(Map M, int X_, int Y_, char* Graphic_, int ForegroundColor_, int BackgroundColor_) {
                OMap = M;
                X = X_;
                Y = Y_;
                Graphic = Graphic_;
                ForegroundColor = ForegroundColor_;
                BackgroundColor = BackgroundColor_;
}

bool Object::Move(int Xto, int Yto) {
     
}

bool Object::StepMove(int Direction, int Steps) {
     switch ( Direction ) {
            case Up:
                 return Move(X, Y - Steps);
            case Down:
				 return Move(X, Y + Steps);
            case Left:
				 return Move(X - Steps, Y);
            case Right:
				 return Move(X + Steps, Y);
            case UpLeft:
				 return Move(X - Steps, Y - Steps);
            case UpRight:
				 return Move(X + Steps, Y - Steps);
            case DownLeft:
				 return Move(X - Steps, Y + Steps);
            case DownRight:
				 return Move(X + Steps, Y + Steps);
     }
}


Its called AGE.h.

This is the code of the main file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <stdlib.h>
#include "conio.h"
#include "AGE.h"

using namespace std;

int main(int argc, char *argv[]) {
    Map m(10, 10, "+", LIGHTGREEN, BLACK);
    clrscr();
    m.Point(1, 1, "0", LIGHTCYAN, BLACK);
    m.DrawMap(0, 0, 10, 10, 2, 2);
    char kp = getch();
    return 0;
}


A simple code that uses "AGE.h" for test purposes...

I hope you can help me with this, I'm not a professional C++ programmer or else.

Thanks!
Last edited on
See `initialization list'
Thanks for the response. I was modifying the code to avoid this error for using "initialization list" was a bit difficult for me, and when I catch what is "initialization list" I realize that these methods where not needed, and a way easier exists....

But now, when I successfully compile the header and the program, I began to make a static library for the "engine" but when I put the source header and all the code of the functions in a source file like this:

AscIIGameEngine.h
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <string>
#include <conio.h>

#define Up 0
#define Down 1
#define Left 2
#define Right 3
#define UpLeft 4
#define UpRight 5
#define DownLeft 6
#define DownRight 7

#define Color_Black 0
#define Color_Blue 1
#define Color_Green 2
#define Color_Cyan 3
#define Color_Red 4
#define Color_Magenta 5
#define Color_Yellow 6
#define Color_Gray 8

// Lit Color Values ...
//
// Blue = 9
// Green = 10
// Cyan = 11
// Red = 12
// Magenta = 13
// Yellow = 14
// White = 15
struct Position {
       int FGColor, BGColor, X, Y;
       char* Graphic;
       bool Lit;
};

struct Object {
       int X, Y, FGColor, BGColor, ID;
       char* Graphic;
       bool Visible, Collision;
       std::string Name;
       Position LastPosition;
       Position Collision_Pos;
};

struct Light {
       int X, Y, Intensity, ID, Color;
       bool Visible;
};

class Map {
      public:
             // Constructor & Misc Functions
             Map(int MaxX_, int MaxY_, char* Background_, int FGColor_, int BGColor_);
             void AGEInfo();
             // Variable Declarations
             int MaxX, MaxY, BackgroundColor, ForegroundColor;
             char* Background;
             Position XY[100][100];
             Object Objects[100];
             Light Lights[100];
             // Map Draw Functions
             void DrawMap(int MinX, int MinY, int MaxX_, int MaxY_, int ConPosX, int ConPosY);
             void DrawAllMap(int ConPosX, int ConPosY);
             void DrawFollowing(int ObjectID, int ConPosX, int ConPosY, int Radius);
             // Map Painting Functions
             void Point(int X, int Y, char* Graphic, int FGColor_, int BGColor_, bool Lit);
             void Square(int X, int Y, char* Graphic, char* Fill, int FGColor_, int BGColor_, int Width, int Height, bool Lit);
             void Line(int X, int Y, char* Graphic, int FGColor_, int BGColor_, int Direction, int Lenght, bool Lit);
             // Map Properties Functions
             bool IsFree(int X, int Y);
             bool IsObject(int X, int Y);
             // Object Functions
             int Object_Create(int X, int Y, char* Graphic, int FGColor_, int BGColor_, std::string Name);
             void Object_Hide(int ObjID);
             void Object_Show(int ObjID);
             bool Object_StepMove(int Direction, int Steps, int ObjID);
             bool Object_Move(int Xto, int Yto, int ObjID);
             // Light Functions
             int Light_Create(int X, int Y, int Intensity);
             void Light_Show(int LightID);
             void Light_Hide(int LightID);
             void Light_Move(int LightID, int Xto, int Yto);
             void Light_StepMove(int LightID, int Direction, int Steps);
             void Light_Intensity(int LightID, int Intensity);
       private:
             int ObjC, LgtC;
             bool IsLit(int Color);
             bool IsInvalid(int X, int Y);
             int ToLight(int Color);
             int ToDark(int Color);
};


AscIIGameEngine.cpp
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <string>
#include <conio.h>
#include "AscIIGameEngine.h"

// Constructor & Misc Functions
Map::Map(int MaxX_, int MaxY_, char* Background_, int FGColor_, int BGColor_) {
            ...
}

void Map::AGEInfo() {
     ...
}

// Map Draw Functions

void Map::DrawAllMap(int ConPosX, int ConPosY) {
    ...
}

void Map::DrawMap(int MinX, int MinY, int MaxX_, int MaxY_, int ConPosX, int ConPosY) {
     ...
}

void Map::DrawFollowing(int ObjectID, int ConPosX, int ConPosY, int Radius) {
    ...
}

// Map Painting Functions

void Map::Line(int X, int Y, char* Graphic, int FGColor_, int BGColor_, int Direction, int Lenght, bool Lit) {
     ...
}
void Map::Point(int X, int Y, char* Graphic, int FGColor_, int BGColor_, bool Lit) {
    ...
}

void Map::Square(int X, int Y, char* Graphic, char* Fill, int FGColor_, int BGColor_, int Width, int Height, bool Lit) {
    ...
}

// Map Properties Functions

bool Map::IsFree(int X, int Y) {
     ...
}

bool Map::IsObject(int X, int Y) {
     ...
}

// Private Map Functions

int Map::ToLight(int Color) {
    ...
}

int Map::ToDark(int Color) {
    ...
}

bool Map::IsInvalid(int X, int Y) {
     ...
}

// Object Functions

int Map::Object_Create(int X, int Y, char* Graphic, int FGColor_, int BGColor_, std::string Name) {
    ...
}

bool Map::Object_Move(int Xto, int Yto, int ObjID) {
    ...
}

bool Map::Object_StepMove(int Direction, int Steps, int ObjID) {
     ...
}

void Map::Object_Hide(int ObjID) {
     ...
}
void Map::Object_Show(int ObjID) {
     ...
}

// Light Functions

int Map::Light_Create(int X, int Y, int Intensity) {
   ...
}

void Map::Light_Show(int LightID) {
    ...
}

void Map::Light_Hide(int LightID) {
     ...
}

void Map::Light_Move(int LightID, int Xto, int Yto) {
     ...
}

void Map::Light_StepMove(int LightID, int Direction, int Steps) {
     ...
}

void Map::Light_Intensity(int LightID, int Intensity) {
     ...
}


All the "..." is to abbreviate all the lines of code because there's no error in code, it compiles without any kind of mistakes fortunately, the compiler makes an AscIIGameEngine.o & AscIIGameEngine.a, all right ... but when I try to use the static library and try to compile this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdlib>
#include <iostream>
#include <conio.h>
#include "AscIIGameEngine.h"

using namespace std;

int main(int argc, char *argv[])
{
    Map m(5, 5, "p", Color_Cyan, Color_Black);
    m.DrawAllMap(2, 2);
    system("PAUSE");
    return EXIT_SUCCESS;
}


The compiler output is:

[Linker error] undefined reference to `Map::Map(int, int, char*, int, int)'
[Linker error] undefined reference to `Map::DrawAllMap(int, int)'
ld returned 1 exit status
C:\Dev-Cpp\Projects\AGE Test\Makefile.win [Build Error] ["AGE] Error 1

What I'm doing wrong?

Thanks in advance.
Last edited on
You need to link them.

By the way, Dev-Cpp is deprecated http://www.cplusplus.com/articles/36vU7k9E/
Really thanks :) I'll search how to link them, if I've some problems can I ask?
I fail then... I was searching how to link them, but I can't find (or I can't understand) how to. I change to Orwell Dev-C++ too :) thanks for the advice. How can I link the header with the source here in Orwell Dev-C++ in order to use the final static library in any other of my software developed in C++ without having the trouble of "undefined reference to..."?
Uninteresting stuff:
Suppose that `c++' is a command that will build your program. (it can compile and link)
Now, you've got a program in a single source file, so you do
$ c++ main.cpp -o program.bin

It would check for syntax errors in the source, and if all goes good, it would generate an executable (program.bin)

However, in your case you've got several source files, each one has different functions
If you simply do
$ c++ main.cpp -o program.bin

it generates error `undefined reference'
You'll need to
$ c++ main.cpp func.cpp -o program.bin

in order to work (so you provide all the function definitions)

That has some issues. The process is quite lengthy, and at each build it would re-analyze `func.cpp' (that may not have changed).
As an alternative you could use an intermediate state (no longer text), that has only the function definitions so there is no work to be done
$ c++ -c func.cpp -o func.o #just compile
$ c++ main.cpp func.o -o program.bin #compile main.cpp and link against func.o


Now you can use `func.o' in any of your works, by simply linking to it.
As a suggestion organize your libraries. By instance, put all the includes in `$HOME/usr/include/' and the object files (.o, .so, .a) in `$HOME/usr/lib/'
$ c++ -I$HOME/usr/include/ main.cpp -L$HOME/usr/lib/ -lfunc


As to how to relate the header with the source, that's compiler specific.
By instance #pragma comment(lib, "xxx.lib") for mscv
or use `pkg-config'


tl, dr:
I've got no idea how your IDE works.
But you may be able to create a project and insert all the cpp in it.
Last edited on
Thanks a lot! I finally understand this... hehe that's because I prefer C++! is well done for anything.
Topic archived. No new replies allowed.