-2

I have a class that has a 2D array of objects, but it throws an error when I call a function to set the object to a new one.

Here's my game class. It's simple and not very large.

#include <iostream>
#include <stdio.h>
#include "room.hpp"
class Game
{
private:
  Room map[50][50];
public:
  Game(std::string title);
  ~Game()=default;
  void add_room(int x, int y);
  void trace(std::string text);
};

And here's my game.cpp. The error happens in the add_room() function. I have the proper imports and everything. No idea what's wrong.

#include <iostream>
#include <stdio.h>
#include "game.hpp"
#include "room.hpp"

Game::Game(std::string name)
{
  trace(name);
}

void Game::add_room(int x, int y, Room r)
{
  map[x][y]=r;
}

void Game::trace(std::string text)
{
  printf("%s\n", text.c_str());
}

Here's my Room class

#ifndef Room_H
#define Room_H

class Room
{
private:
  std::string name;
  std::string desc;
public:
  Room(std::string n, std::string d);
  ~Room()=default;
};

#endif

And here's the cpp

#include <iostream>
#include <stdio.h>
#include "room.hpp"

Room::Room(std::string n, std::string d)
{
  name=n;
  desc=d;
}

Here's the error anyway:

    ../TAGE/game.cpp: In constructor 'Game::Game(std::string)':
../TAGE/game.cpp:6:28: error: no matching function for call to 'Room::Room()'
 Game::Game(std::string name)
                            ^
../TAGE/game.cpp:6:28: note: candidates are:
In file included from ../TAGE/game.hpp:6:0,
                 from ../TAGE/game.cpp:3:
../TAGE/room.hpp:11:3: note: Room::Room(std::string, std::string)
   Room(std::string n, std::string d);
   ^
../TAGE/room.hpp:11:3: note:   candidate expects 2 arguments, 0 provided
../TAGE/room.hpp:5:7: note: Room::Room(const Room&)
 class Room
       ^
../TAGE/room.hpp:5:7: note:   candidate expects 1 argument, 0 provided
../TAGE/game.cpp: In constructor 'Game::Game(std::string)':
../TAGE/game.cpp:6:28: error: no matching function for call to 'Room::Room()'
 Game::Game(std::string name)
                            ^
../TAGE/game.cpp:6:28: note: candidates are:
In file included from ../TAGE/game.hpp:6:0,
                 from ../TAGE/game.cpp:3:
../TAGE/room.hpp:11:3: note: Room::Room(std::string, std::string)
   Room(std::string n, std::string d);
   ^
../TAGE/room.hpp:11:3: note:   candidate expects 2 arguments, 0 provided
../TAGE/room.hpp:5:7: note: Room::Room(const Room&)
 class Room
       ^
../TAGE/room.hpp:5:7: note:   candidate expects 1 argument, 0 provided
Lumaio
  • 7
  • 4
  • What is the exact error message? Without it, it is hard to tell what's wrong. – anderas Jul 18 '14 at 13:15
  • 1
    There is an extra `Room` parameter in the cpp, not declared in the header file... Also, this parameter would require copy constructors that may or may not be declared for `Room` (code not shown). – François Moisan Jul 18 '14 at 13:16
  • Didn't see that. I added the Room parameter and it gave me the same error. Not sure what you mean by copy constructors. – Lumaio Jul 18 '14 at 13:19
  • 1
    Write default Constructor for Room class. `Room::Room() { // Do for default case } ` – Singh Jul 18 '14 at 13:19
  • You have a 2D array of `Room`. This needs to be initialized somehow. – chris Jul 18 '14 at 13:21
  • @Singh I've done that. Same error. – Lumaio Jul 18 '14 at 13:21
  • By the way, you can print strings directly: `std::cout << text;`. I can't believe that a default constructor for `Room` doesn't clear up the related errors, though. – chris Jul 18 '14 at 13:22
  • @chris I dislike using `std::cout`, I much prefer printf() and I'm not done with the trace function yet. It's going to be used to write to files. – Lumaio Jul 18 '14 at 13:26
  • @Lumaio `Room` is passed by value in `add_room` so your object must be [copy-constructible](http://stackoverflow.com/questions/2168201/what-is-a-copy-constructor-in-c) and assignable. – François Moisan Jul 18 '14 at 13:27
  • Is it worth noting that the Room constructor takes 2 strings as arguments? – Lumaio Jul 18 '14 at 13:28
  • @Lumaio Sure, declaring that constructor is fine, but your array must be able to get initialized by default, so you still need to provide a default and a copy constructor as well... – François Moisan Jul 18 '14 at 13:29

2 Answers2

0

You are missing a default constructor for the class Room (Room() {}). Add this to the room class or specify how the room class should be initialized in the Game class. Your function definition in the game class is also missing the Room parameter.

On a side note, unless you want to copy the strings you pass to the functions/constructor you might want to pass by const reference (the following assumes you have a compiler which supports C++11, if it does not change cstdio to stdio.h):

#include <iostream>
#include <cstdio>

#include "room.hpp"

class Game
{
public:
    Game(const std::string& title);
    void add_room(int x, int y, const Room& r);
    void trace(const std::string& text);

private:
    Room map[50][50];

};

With the .cpp file looking like:

#include "game.hpp"

Game::Game(const std::string& name)
{
    trace(name);
}

void Game::add_room(int x, int y, const Room& r)
{
    map[x][y] = r;
}

void Game::trace(const std::string& text)
{
    //Consider std::cout << text << std::endl;
    printf("%s\n", text.c_str());
}

Regarding Edit

You did not define a constructor. You defined a destructor. Define it like this:

Room() {}

or seeing as you can use default:

Room() = default;

instead of:

~Room() = default;

Explanation

You did define a constructor but that constructor expects two strings. Now when you declare the array in the game class with Room it will initialize these objects the moment your Game constructor is called.

At this point it notices that there is no specification about the way the objects should be initialized (no strings or anything being passed). So it will start looking for a constructor that does not take any parameters. Here is where the error comes in, it tells you the room class does not have a constructor without parameters.

So you add the empty constructor without parameters so it can construct the objects according to that.

Floris Velleman
  • 4,848
  • 4
  • 29
  • 46
  • This, again, didn't work. I'm guessing it's a problem with my room class. I'll update my post with my room class. – Lumaio Jul 18 '14 at 13:38
  • @Lumaio Seems like you defined a default destructor instead of a default constructor (see the last part of my answer). – Floris Velleman Jul 18 '14 at 13:42
  • I thouht `Room(std::string n, std::string d);` WAS the constructor, It seems I was wrong? I added `Room()=default;` to the Room class and it worked. – Lumaio Jul 18 '14 at 13:46
  • @Lumaio I will add a small explanation regarding what is going on! – Floris Velleman Jul 18 '14 at 13:48
  • And I saw that, It just doesn't make sense to me. – Lumaio Jul 18 '14 at 13:54
  • 1
    @Lumaio You are not *totally* wrong ;). `Room(std::string n, std::string d)` is *a* constructor (you can have many). Declaring this one though, prevents the compiler from generating others for you, such as the default and copy constructors. Those are required with your current code. Floris' answer explains how add them back. I hope it clears some things for you ? – François Moisan Jul 18 '14 at 13:54
0

You are doing:

map[x][y]=r;

You should do something like this:

CRoom* map[50][50];

for(int i = 0; i < 50; ++i)
    for(int j = 0; j < 50; ++j)
        map[i][j] = nullptr;

map[0][0] = new CRoom("Hola", "Hello");

map[0][0]->PrintOut();
butterbox
  • 442
  • 1
  • 4
  • 14