How to properly return an array of objects in c++ and use it main?

Hi, first time here and I have a question after searching a lot of places including here. In my code I am trying to get a group of Critter objects to move every 2 seconds. Using an observer pattern and it works fine so far when I create one Critter but I am unable to successfully use an array of Critters.

The problem starts when I try to use the generateCritter(int) on Line 151 method and get a linker error. I have tried a lot of things with no luck.

The code is below or here to compile and run: http://ideone.com/t0Vho5

Thanks!


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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
 //CritterModel.h
 
#ifndef __CritterModelObserver__CritterModel__
#define __CritterModelObserver__CritterModel__
 
#include <stdio.h>
#include <iostream> 
#include <string>
#include <vector>
 
//IObserver.h
 
#ifndef CritterModelObserver_IObserver_h
#define CritterModelObserver_IObserver_h
 
class IObserver {
public:
    virtual void update() = 0;
};
 
#endif
 
//Observable.h
 
#ifndef __CritterModelObserver__Observable__
#define __CritterModelObserver__Observable__
 
#include <stdio.h>
 
class Observable {
public:
    Observable();
    virtual ~Observable();
    void addObserver(IObserver* ob);
    void removeObserver(IObserver* ob);
 
protected:
    void notify() const;
 
private:
    IObserver** observers;
    static const int maxObservers;
    int numObservers;
};
 
#endif /* defined(__CritterModelObserver__Observable__) */
 
class CritterModel : public Observable {
 
public:
    CritterModel();
    virtual ~CritterModel();
    CritterModel(int x, int y);
 
    // Getters
    inline int getReward() const { return reward; }
    inline int getHitPoint() const { return hitPoint; }
    inline int getStrength() const { return strength; }
    inline int getSpeeed() const { return speed; }
    inline int getLevel() const { return level; }
    inline int getXCoord() const { return x; }
    inline int getYCoord() const { return y; }
    inline int getDuration() const { return duration; }
    // Setters
    void setLevel(int l) {
        level = l;
    }
 
    void setStrength(int s) {
        strength = s;
    }
 
    void setHitPoint(int h) {
        hitPoint = h;
    }
    /**
    void setCellType(int c) {
        cellType = c;
    }
    */
    void setSpeed(int s) {
        speed = s;
    }
 
    void setReward(int r) {
        reward = r;
    }
 
    void setXCoord(int xC) {
        x = xC;
    }
 
    void setYCoord(int yC) {
        y = yC;
    }
 
    void setDuration(int d) {
        duration = d;
    }
 
    // Other methods
    int generateCritters(int);
    std::string getCell();
    void printCritters();
    void moveCritter(int, int); // Undefined at the moment.
    void shoot();
    void timer();
 
private:
    int reward;
    int hitPoint;
    int strength;
    int speed;
    int level;
    int duration;
    //int cellType;
    int x,y;
    //Cell cell;
 
 
};
 
#endif /* defined(__CritterModelObserver__CritterModel__) */
 
 
//CritterModel.cpp
#include <iostream> 
#include <time.h>
#include <vector>
 
using namespace std;
 
CritterModel::CritterModel() : Observable() {
    reward = 0;
    hitPoint = 0;
    strength = 0;
    speed = 0;
    level = 0;
    y = 0;
    x = 0;
}
 
CritterModel::~CritterModel() {
 
}
 
 
 
 
// Generate Critters
CritterModel* generateCritters(int numCritters) {
    CritterModel* critters = new CritterModel[numCritters];
 
    for (int i=0; i < numCritters; i++) {
        critters[i] = CritterModel();
    }
    return critters;
}
 
 
// Move those critters
void CritterModel::moveCritter(int xCoord, int yCoord) {
    bool flag = false;
    if (this->x != xCoord) {
        x = xCoord;
        flag = true;
    }
 
    if (this->y != yCoord) {
        y = yCoord;
        flag = true;
    }
 
    if (flag) {
        notify();
    }
}
 
 
//Observable.cpp
#include <iostream>
 
const int Observable::maxObservers = 5;
 
Observable::Observable() {
    observers = new IObserver* [maxObservers];
    for (int i=0; i < maxObservers; i++) {
        observers[i] = NULL;
        numObservers = 0;
    }
}
    // Destructor
    Observable::~Observable() {
        delete[] observers;
    }
 
    // Add observer method
    void Observable::addObserver(IObserver* ob) {
        // Check if full
        if (numObservers == maxObservers) {
            return;
        }
         // Check if observer exists
        for (int i=0; i < maxObservers; i++) {
            if (observers[i] == ob) {
                return;
            }
        }
 
        // Otherwise add the observer
        observers[numObservers] = ob;
        ++numObservers;
    }
 
void Observable::removeObserver(IObserver* ob) {
    // ommitted
}
 
void Observable::notify() const {
    for (int i=0; i < numObservers; i++) {
        observers[i]->update();
    }
}
 
//CritterDisplay.h
 
#ifndef __CritterModelObserver__CritterDisplay__
#define __CritterModelObserver__CritterDisplay__
 
#include <stdio.h>
 
class CritterDisplay: public IObserver {
 
public:
    CritterDisplay(CritterModel* critterModel);
    virtual ~CritterDisplay();
    void update();
 
private:
    CritterModel* critterModel;
};
 
#endif /* defined(__CritterModelObserver__CritterDisplay__) */
 
//CritterDisplay.cpp
#include <iostream> 
 
using namespace std;
 
CritterDisplay::CritterDisplay(CritterModel* critterModel) {
    this->critterModel = critterModel;
}
 
CritterDisplay::~CritterDisplay() {}
 
void CritterDisplay::update() {
 
    cout <<
    "================" << endl <<
    "Position: " << "(" << critterModel->getXCoord() << ", " << critterModel->getYCoord() << ")" << endl <<
    "Speed: " << critterModel->getSpeeed() << endl <<
    "Strength: " << critterModel->getStrength() << endl <<
    "Level: " << critterModel->getLevel() << endl <<
    "Hit Points: " << critterModel->getHitPoint() << endl <<
    "Reward: " << critterModel->getReward() << endl << "\n";
 
 
} 
 
 
//Driver.cpp
 
 
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <limits>
 
using namespace std;
 
void PressEnterToBegin()
{
    std::cout << "Press ENTER to begin..."; //<< &fflush;
    std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );
}
 
int main(int argc, const char * argv[]) {
 
    double dif = 0.0;
    bool flag = true;
    int x,y = 0;
 
    // Initialize players coin
    int pCoin = 100;
 
    // Initialize coin steal
    int stealCoin = 0;
 
    // Initialize reward
    int reward = 0;
 
    //CritterModel* critters;
    CritterModel* critterModel = new CritterModel();
 
    //CritterModel* critters = CritterModel::generateCritters(5);
    //critters->generateCritters(5);
 
    CritterDisplay* display = new CritterDisplay(critterModel);
 
    critterModel->addObserver(display);
    critterModel->setSpeed(2);
    critterModel->setStrength(10);
    critterModel->setLevel(1);
    critterModel->setHitPoint(100);
    critterModel->setReward(300);
 
    // Welcome message
    std::cout << "Welcome to the Critter game!\n" << "You have $100 in your bank to begin with. If a Critter happens to get to the exit, \nit steals coin from your bank proportional to the Critters strength.\n\n" << "Game play: \n1.) Game starts by a Critter wave being ready to enter the map.\n2.) Press ENTER to begin.\n3.) After the Critters enter, you will be notified that a timer will start.\n4.) Fire by pressing ENTER before time runs out and Critters exit the map.\n " << "---------------------------------------------------------------------------\n\n";
 
    PressEnterToBegin();
 
    // Start timed loop
    time_t start, end;
    time(&start);
    do  {
 
        // End simulation after dif > 2
        if (dif > 2) {
            flag = false;
        }
 
        // Otherwise move critter to next cell
        critterModel->moveCritter(x, y);
        ++x;
        ++y;
 
        time(&end);
        dif = difftime(end, start);
        cout << dif << endl;
 
        // Counter to simulate speed of critter. A critter moves every 2 seconds and the sleep method stops time which keeps dif < 2 in the above if-statment
        if (x > 1 || y > 1) {
            sleep(2);
        }
 
        // If critter coordinates are at the exit, steal coin from player
        if (critterModel->getXCoord() == 4 && critterModel->getYCoord() == 4) {
            stealCoin = stealCoin + critterModel->getStrength();
            pCoin = pCoin - stealCoin;
            std::cout << "A critter got through! You have $" << pCoin << " left in your bank.\n\n";
        }
 
    }while (flag);
 
 
 
    delete display;
    delete critterModel;
 
    return 0;
 
 
}
Last edited on
sorry couldn't read this big code. hope this will help..
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
#include <iostream>
#include <string>
using namespace std;

class dmy {
	private:
		int a;	
		string s;
		
	public:
		dmy() {	s = "a test";}
		dmy(int n) { for(int i=0; i<n; i++) s+='$'; };
		void show () 
		{	cout << s;	}
}ob1;

dmy* called(){
	dmy *obj = new dmy[10];
	return obj;
}


int main() {

	auto objects = called();
	objects[3].show(); //output: a test
	delete[] objects;

	return 0;
}
First, I have limited experience with object oriented design and programming. So, I have some comments and questions for you, but take them in the light of my limited experience. Hopefully, you can teach me something.

You asked:
How to properly return an array of objects in c++ and use it main?
In the normal case, why not create the objects in main and pass them as parameters to the methods which need to know about the objects.

You have a class named Observable. Observable is an adjective. I would expect the class name to be a noun. So looking at the other code, I would expect the class to be named Observers and objects of the class would be individual observers. What am I not seeing?

What can an Observe do? You show methods addObserver() and removeObserver(). Is not this the purpose of the constructor and destructor, respectively? What actions can an observer take or be subject to?

Similarly you have a class named CritterDisplay. I would expect that you would have a class named Critter which would include a method named Display. What am I not seeing?

You have a class named CritterModel. Would a better name be CritterGame?

Can an individual critter be displayed? Or does one display the entire CritterModel or CritterGame?

This program seems to be based on time. How are you going to model time? Should current time be a characteristic of an object from the class CritterModel or class CritterGame? How does time tick?

Does a CritterModel or CritterGame need to keep track of one or more Critters and Observers? Should the CritterModel or CritterGame be tracking the creation and removal of these.
Topic archived. No new replies allowed.