class objects as data members and header file includes - c++

I'm currently putting together what I've learned of C++ by writing a small text adventure - just trying to get the basic class interrelations down so I can have the player move through a few rooms at the moment. I'm getting an 'expected unqualified id before '}' error in my room.h file when I compile. I think it may have something to do with a Room class member which is a vector of Exit object pointers, but I'm not sure. I'd appreciate a quick scan of the code just to let me know If I'm missing something obvious but important. Sorry if this gets complicated. I'll try to be brief and to the point.
I'm not sure what you all may need to see (codewise) and I don't want to throw up the whole code so...Let me outline how I have things set up, to start off with.:
1) I have a cpp file, called from main(), which instantiates 21 new rooms on the heap
2) Followed by another cpp file which instantiates new Exit objects on the heap, pushes them onto a vector, and calls a Room.set() function to pass the vector of Exit pointers to the Room class as one of its data members. Each exit in The vector will also have a pointer to one of the new Rooms created on the Heap.
The file to instantiate new rooms looks like this:
#include "RoomsInit.h"
#include "Room.h"
void InstantiateRooms()
{
string roomName1 = "On a deserted beach";
string roomDescr1 = "You are standing on a deserted beach. To the east, a "
"crystal blue ocean\n dances in the morning sun. To the "
"west is a dense jungle, and somewhere\n far off, you can "
"hear the singing of a strange bird. The white, sandy \n"
"beach runs out of sight to the north and south.\n\n\n";
Room* p_deserted_beach = new Room(roomName1, roomDescr1);
* Only the roomName and roomDescr is passed to the constructor at this point...and there are 20 more rooms like this in the file.
The Exit instantiate file looks like this:
#include "exitsInit.h"
#include "exit.h"
#include "room.h"
#include "RoomsInit.h"
void InstantiateExits()
{
vector<Exit*> exitVec;
Exit* p_north1 = new Exit("north", p_on_the_beach_north, true, false);
Exit* p_south1 = new Exit("south", p_on_the_beach_south1, true, false);
Exit* p_east1 = new Exit("east", p_in_the_ocean, true, false);
Exit* p_west1 = new Exit("west", p_in_the_jungle, true, false);
exitVec.push_back(p_north1);
exitVec.push_back(p_south1);
exitVec.push_back(p_east1);
exitVec.push_back(p_west1);
(*p_deserted_beach).SetExitVec(exitVec);
exitVec.clear();
The exitVec is created and sent to the Room class via the set function to become one of it's data members...There are 20 more sets of these in this file)one for each room).
My Room class header file, where I'm getting the compiler error, at the moment, looks like this:
#ifndef ROOM_H_INCLUDED
#define ROOM_H_INCLUDED
#include <iostream>
#include <string>
#include <vector>
class Exit;
using namespace std;
class Room
{
private:
string m_roomName;
string m_roomDescr;
string m_specDescr;
bool m_isSpecDescr;
vector<Exit*> m_exitVec;
public:
Room(string roomName, string roomDescr, string specDescr = "",
bool isSpecDescr = false);
string GetRoomName(); const
string GetRoomDes(); const
bool GetRoomSpecBool(); const
string GetRoomSpec(); const
void SetExitVec(vector<Exit*> exitVec);
vector<Exit*> GetExitVec(); const
};
#endif // ROOM_H_INCLUDED
----------- with the corresponding cpp file: --------------
#include "room.h"
Room::Room(string roomName, string roomDescr,
string specDescr, bool isSpecDescr) :
m_roomName(roomName), m_roomDescr(roomDescr),
m_specDescr(specDescr), m_isSpecDescr(isSpecDescr) {}
string Room::GetRoomName() const
{
return m_roomName;
}
string Room::GetRoomDes() const
{
return m_roomDescr;
}
bool Room::GetRoomSpecBool() const
{
return m_isSpecDescr;
}
string Room::GetRoomSpec() const
{
return m_specDescr;
}
void Room::SetExitVec(vector<Exit*> exitVec)
{
m_exitVec = exitVec;
}
vector<Exit*> Room::GetExitVec() const
{
return m_exitVec;
}
---------The Exit class header is this:
#ifndef EXIT_H_INCLUDED
#define EXIT_H_INCLUDED
#include <iostream>
#include <string>
#include <vector>
class Room; // For using a class pointer as a data member
using namespace std;
class Exit
{
private:
string m_exitName; // east, west, etc
Room* mp_exitTo;
bool m_isExit;
bool m_isExitHidden;
bool m_isExitPhrase;
string m_exitPhrase;
public:
Exit();
Exit(string exitName, Room* pExit, bool isExit, bool isExitHidden,
bool isExitPhrase = false, string exitPhrase = "");
string GetExitName(); const
Room* GetExitTo(); const
void SetIsExitTrue();
void SetIsExitFalse();
bool GetIsExit(); const
void SetIsExitHiddenTrue();
void SetIsExitHiddenFalse();
bool GetIsExitHidden(); const
bool GetIsExitPhrase(); const
string GetExitPhrase(); const
};
#endif // EXIT_H_INCLUDED
-------------and its cpp file:
#include "room.h"
#include "exit.h"
#include "RoomsInit.h"
Exit::Exit() :
mp_exitTo(NULL), m_isExit(false), m_isExitHidden(false) {}
Exit::Exit(string exitName, Room* pExit, bool isExit, bool isExitHidden,
bool isExitPhrase, string exitPhrase) :
m_exitName(exitName), mp_exitTo(pExit), m_isExit(isExit),
m_isExitHidden(isExitHidden), m_isExitPhrase(isExitPhrase),
m_exitPhrase(exitPhrase) {}
string Exit::GetExitName() const
{
return m_exitName;
}
Room* Exit::GetExitTo() const
{
return mp_exitTo;
}
void Exit::SetIsExitTrue()
{
m_isExit = true;
}
void Exit::SetIsExitFalse()
{
m_isExit = false;
}
bool Exit::GetIsExit() const
{
return m_isExit;
}
void Exit::SetIsExitHiddenTrue();
{
m_isExitHidden = true;
}
void Exit::SetIsExitHiddenFalse();
{
m_isExitHidden = false;
}
bool Exit::GetIsExitHidden() const
{
return m_isExitHidden;
}
bool Exit::GetIsExitPhrase(); const
{
return m_isExitPhrase;
}
string Exit::GetExitPhrase() const
{
return m_exitPhrase;
}
I'm also getting 21 warnings stating that the rooms I've created on the Heap are unused variables - not sure what that means. I feel like I'm missing something about the #includes relationships that is crucial, but I just can't see what it is...I've only been programming for about 8 months and most of the examples I've come across in books or online are somewhat less complex than what I'm doing right now. And so, I'd really appreciate any advice or comments y'all who are more experienced might have. Thanks. - Mark

In room.h
string GetRoomName(); const
string GetRoomDes(); const
bool GetRoomSpecBool(); const
string GetRoomSpec(); const
void SetExitVec(vector<Exit*> exitVec);
vector<Exit*> GetExitVec(); const
should be
string GetRoomName() const;
string GetRoomDes() const;
bool GetRoomSpecBool() const;
string GetRoomSpec() const;
void SetExitVec(vector<Exit*> exitVec);
vector<Exit*> GetExitVec() const;
You got your semi-colons in the wrong place.

Related

No declaration matches in Codelite IDE

I have been looking in different threads with this error which is quite common but it feels like the IDE I am using messed with my workspace and I can't quite find the problem. I am setting up an extremely basic class called "Movie" that is specified below:
Movie.hpp :
#ifndef MOVIE_HPP
#define MOVIE_HPP
#include <iostream>
#include <string>
using std::string, std::cout,std::size_t;
class Movie
{
private:
std::string name;
std::string rating;
int watched_ctr;
public:
Movie(const string& name, const string& rating, int watched_ctr);
~Movie();
//getters
string get_name() const;
string get_rating() const;
int get_watched() const;
//setters
void set_name(string name);
void set_rating(string rating);
void set_watched(int watched_ctr);
};
#endif // MOVIE_HPP
Movie.cpp:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
Movie::Movie(const string& name, const string& rating, int watched_ctr)
: name(name) , rating(rating) , watched_ctr(watched_ctr) {
}
Movie::~Movie()
{
cout << "Destructor for Movies class called /n";
}
//Getters
string Movie::get_name(){return name;}
string Movie::get_rating(){return rating;}
string Movie::get_watched(){return watched_ctr;}
//Setters
void Movie::set_name(std::string n){this -> name = n;}
void Movie::set_rating(std::string rating){this -> rating = rating;}
void Movie::set_watched(int ctr){this -> watched_ctr = ctr;}
The main.cpp I am trying only consists in creating one Movie object:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
int main()
{
Movie StarTrek("Star Trek", "G", 20);
}
As you can see, I set all the attribute to private in order to exercise with the set/get methods but I keep stumbling upon the same error on each of them stating >"C:/Users/.../ProjectsAndTests/MoviesClass/Movie.cpp:18:8: error: no declaration matches 'std::__cxx11::string Movie::get_name()"
if you could give me a hint on what might cause this error I would greatly appreciate thank you!
I tried opening another workspace with classes implemented inside of them and the syntax I am using is very close from this test workspace I opened which compiled fine (no error regarding declaration match).
There are 2 problems with your code.
First while defining the member functions outside class you're not using the const. So to solve this problem we must use const when defining the member function outside the class.
Second, the member function Movie::get_watched() is declared with the return type of string but while defining that member function you're using the return type int. To solve this, change the return type while defining the member function to match the return type in the declaration.
//----------------------vvvvv--------->added const
string Movie::get_name()const
{
return name;
}
string Movie::get_rating()const
{
return rating;
}
vvv------------------------------>changed return type to int
int Movie::get_watched()const
{
return watched_ctr;
}
Working demo

Adding data inside unordered_map inside a class

I have a class Citydata, defined in .hh file
struct City_details {
string name;
int taxrate;
};
class Citydata {
public:
bool add_data(string id, string name, int taxrate)
//other member functions...
private:
unordered_map<id, City_details> info_map;
I have trouble implementing the add_data function in .cc file. Here is my try.
bool Citydata::add_data(string id, string name, int taxes) {
if ( info_map.find(id) == info_map.end()) {
City_details dataload;
dataload.name = name;
dataload.taxrate = taxes;
info_map[id] = dataload;
return true;
}
else return false;
}
When I test this, I cannot see any data added the way I wanted. Instead I see one completely empty entry (default empty values), and one entry with right id (the key) but no data added to the parameters. Each time I call add_data, it creates similar pair of one completely empty key-data member, then one with right id and otherwise empty data.
The original program is much longer than this, so problem might persist there too, but I wonder if my approach is flawed by design.
I have made some modifications that makes your program work.
First you should replace unordered_map<id, City_details> info_map; with unordered_map<std::string, City_details> info_map;
Second you had a missing semicolon ; for you add_data member function declaration inside the class which you might have missed while copy pasting the code here on Stackoverflow.
Third i have avoided the use of using namespace std;.
main.cpp
#include <iostream>
#include "file.h"
int main()
{
Citydata c1;
c1.add_data("id1","Georgia", 34);
c1.add_data("id2", "California", 32);
c1.add_data("id3","Texas", 23);
//lets print out the element of info_map
for(auto &it:c1.info_map)
std::cout << it.first <<" "<<it.second.name<<" "<<it.second.taxrate<<std::endl;
return 0;
}
file.h
#pragma once
#include <unordered_map>
#include <string>
struct City_details {
std::string name;
int taxrate;
};
class Citydata {
public:
bool add_data(std::string id, std::string name, int taxrate);
//other member functions...
//private:
std::unordered_map<std::string, City_details> info_map;//the first tempate argument should be int and not id
};
file.cpp
#include "file.h"
bool Citydata::add_data(std::string id, std::string name, int taxes) {
if ( info_map.find(id) == info_map.end()) {
City_details dataload;
dataload.name = name;
dataload.taxrate = taxes;
info_map[id] = dataload;
return true;
}
else return false;
}

Variable or field declared void C++

I am making a school assignment, but I am getting a strange error. I have tried to google it, but nothing helped.
So I have a file called main.cpp. Within this file I have some includes and code.
This:
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
#include "RentalAdministration.h"
#include "Limousine.h"
#include "Sedan.h"
void addTestDataToAdministration(RentalAdministration* administration)
{
string licencePlates[] = {"SD-001", "SD-002", "SD-003", "SD-004", "LM-001", "LM-002"};
for (int i = 0; i < 4; i++)
{
Car* sedan = new Sedan("BMW", "535d", 2012 + i, licencePlates[i], false);
administration->Add(sedan);
}
for (int i = 4; i < 6; i++)
{
Car* limousine = new Limousine("Rolls Roys", "Phantom Extended Wheelbase", 2015, licencePlates[i], true);
administration->Add(limousine);
}
}
int main( void )
{
RentalAdministration administration;
addTestDataToAdministration(&administration);
}
So the compiler tells me that the variable: "RentalAdministration administration" does not exist.
So if we have look in my rentaladministration header. We see this:
#ifndef RENTALADMINISTRATION_H
#define RENTALADMINISTRATION_H
#include <vector>
#include "car.h"
class RentalAdministration
{
private:
std::vector<Car*> Cars;
Car* FindCar(std::string licencePlate);
Car* FindCarWithException(std::string licencePlate);
public:
std::vector<Car*> GetCars() const {return Cars;}
bool Add(Car* car);
bool RentCar(std::string licencePlate);
double ReturnCar(std::string licencePlate, int kilometers);
void CleanCar(std::string licencePlate);
RentalAdministration();
~RentalAdministration();
};
#endif
This is the exact error:
src/main.cpp:18:34: error: variable or field ‘addTestDataToAdministration’ declared void
void addTestDataToAdministration(RentalAdministration* administration)
^
src/main.cpp:18:34: error: ‘RentalAdministration’ was not declared in this scope
src/main.cpp:18:56: error: ‘administration’ was not declared in this scope
void addTestDataToAdministration(RentalAdministration* administration)
Help will be appreciated!
Edit:
I am getting warnings in sublime for the Sedan and Limousine headers. Something that has to do with some static constants. I think it was called a GNU extension. Maybe it has something to do with it.
Even when I comment the call of that function out. I get the same error.
I am calling that function nowhere else.
Some people say that the cause might be in these headers:
#ifndef LIMOUSINE_H
#define LIMOUSINE_H
#include "Car.h"
//c
class Limousine : public Car
{
private:
bool needsCleaning;
bool hasMiniBar;
static const double priceperkm = 2.5;
public:
double Return(int kilometers);
void Clean();
bool GetHasMiniBar() const { return hasMiniBar;}
void SetHasMiniBar(bool value) {hasMiniBar = value;}
Limousine(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hasminiBar);
~Limousine();
};
#endif
2:
#ifndef SEDAN_H
#define SEDAN_H
#include "Car.h"
//c
class Sedan : public Car
{
private:
int lastCleanedAtKm;
bool hasTowBar;
bool needsCleaning;
static const double priceperKm = 0.29;
public:
void Clean();
int GetLastCleanedAtKm() const {return lastCleanedAtKm;}
void SetLastCleanedAtKm(bool value){ lastCleanedAtKm = value;}
bool GetHasTowBar() const {return hasTowBar;}
void SetHasTowBar(bool value) {hasTowBar = value;}
bool GetNeedsCleaning() const {return needsCleaning;}
void SetNeedsCleaning(bool value){needsCleaning = value;}
Sedan(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hastowBar);
~Sedan();
};
#endif
class Limousine : public Car
{
private:
static const double priceperkm = 2.5;
...
}
Remove the static and declare the member simply as const double, example:
class Limousine : public Car
{
private:
const double priceperkm = 2.5;
...
}
The error message ‘RentalAdministration’ was not declared in this scope indicates that the right header file for RentalAdministration was not included. Check the file names to make sure class declaration for RentalAdministration is in the right file.
Restarting the terminal has somehow solved this error. I got another error this time, which I solved already. I missed the destructor. It stood in the header file, but not in the cpp file.
Buggy terminals...

C++ Cannot use push_back on list containing custom structs

We are making a list that hold info on boardgames (name, year, score). We scan the info out of a .csv file, make a struct based on that info and then add the struct to a list. We keep doing this untill the document is done reading. Problem is that the push_back method of the list doesn't work. Here's the header of the list class:
NOTE BoardGame is the custom struct. BoardGame(wstring name, int year, float score).
#pragma once
#include "GameEngine.h"
#include "BoardGame.h"
#include <list>
class BoardGameList
{
public:
BoardGameList() {}
virtual ~BoardGameList() {}
// Methods
void Load(const tstring& fileName);
// Members
private:
std::list<BoardGame> m_Games;
};
The cpp file. Maybe I made the list the wrong way?
#include "BoardGameList.h"
#include <fstream>
void BoardGameList::Load(const tstring& fileName)
{
tifstream file(fileName);
tstring line;
if(!file)
{
GAME_ENGINE->MessageBox(_T("Error: The file could not be found!"));
}
else
{
tstring name;
tstring year;
tstring score;
while(!(file.eof()))
{
getline(file,line);
year = line.substr(0,4);
score = line.substr(5,5);
name = line.substr(11,line.find(_T("\n")));
float numberScore = std::stof(score);
int numberYear = std::stoi(year);
m_Games.push_back(BoardGame(name,numberYear,numberScore));
}
}
}
Running the program triggers an error (unhandled exception) that leads me to the following code in the "list" class itself I think.
_Unchecked_iterator _Unchecked_end()
{ // return unchecked iterator for end of mutable sequence
return (_Unchecked_iterator(this->_Myhead, this));
}
Any ideas why I can't add stuff to my list? I tried adding something in the constructor to check if it maybe needed an element before I could add more but even then, using a breakpoint showed me that the memory could not be read.
Many thanks in advance.
EDIT: Header of BoardGame
#pragma once
#include "GameEngine.h"
struct BoardGame
{
BoardGame(tstring name, int year, float score);
//Methods
tstring operator<<(BoardGame rhs);
//Members
tstring m_Name;
int m_Year;
float m_Score;
};
What exception is being thrown? This is vital to debugging your problem.
Without that information my best guess is this line:
name = line.substr(11,line.find(_T("\n")));
Will throw an exception on any line without a trailing newline, or any line less than 11 characters long.

initiating lists in the constructor's initialization list

I just moved from C to C++, and now work with lists.
I have a class called "message", and I need to have a class called "line",
which should have a list of messages in its properties. as I learned, the object's properties should be initialized in the constructor's initialization list, and i had the "urge" to initialize the messages list in addition to the rest of the properties (some strings and doubles). is that "urge" justified? does the list need to be initialized?
here is my code.
the purpose is to create an empty list of lines, and the constructor I'm talking about is the one in line.cpp
//-------------------
//Code for line.h:
//-------------------
#ifndef LINE_H_
#define LINE_H_
#include "message.h"
#include <string>
#include <list>
using namespace std;
namespace test
{
using std::string;
class Line
{
public:
// constractor with parameters
Line(const string& phoneStr, double callRate, double messageRate);
//function to get phone string
string getPhoneStr() const;
double getCallRate() const;
double getMessageRate() const;
double getLastBill() const;
void addMessage(const string& phoneStr);
private:
string mPhoneStr;
list<Message> mMessages;
double mMessageRate;
double mLastBill;
};
}
#endif /* LINE_H_ */
//-------------------
//Code for line.cpp:
//-------------------
#include "line.h"
namespace test
{
Line::Line(const string& phoneStr, double callRate, double messageRate)
: mPhoneStr(phoneStr), mCallRate(callRate), mMessageRate(messageRate),
mLastBill(0) {}
//getters:
string Line::getPhoneStr() const
{
return mPhoneStr;
}
double Line::getCallRate() const
{
return mCallRate;
}
double Line::getMessageRate() const
{
return mMessageRate;
}
double Line::getLastBill() const
{
return mLastBill;
}
}
//-------------------
//Code for message.h:
//-------------------
#ifndef MESSAGE_H_
#define MESSAGE_H_
#include <string>
namespace test
{
using std::string;
class Message
{
public:
// constractor with parameters
Message(const string& phoneStr);
//function to get phone string
string getPhoneStr() const;
//function to set new phone string
void setPhoneStr(const string& phoneStr);
private:
string mPhoneStr;
};
}
#endif /* MESSAGE_H_ */
//-----------------------------------------------------------------------
//---------------------
//code for message.cpp:
//---------------------
#include "message.h"
namespace test
{
Message::Message(const string& phoneStr) : mPhoneStr(phoneStr) {}
string Message::getPhoneStr() const
{
return mPhoneStr;
}
void Message::setPhoneStr(const string& phoneStr)
{
mPhoneStr = phoneStr;
}
}
The initialization list is for initializing any base classes and member variables. The body of the constructor is meant to run any other code that you need before the object can be considered initialized.
I'm having a hard time understanding your situation, but hopefully the above helps.
You don't have to do everything in the initialisation list. It's hard to tell without seeing some code, but it sounds like adding the messages would be better done in the body of the constructor.