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.
Related
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
Object-oriented C++ here.
I'm supposed to code a Microwave object that "heats" a FrozenMeal object.
One method of the Microwave object, called void heatMeal(FrozenMeal), is supposed to take an instance of a FrozenMeal object as a parameter and increase its temperature.
FrozenMeal.h
#include <string>
class FrozenMeal {
public:
FrozenMeal(std::string, int);
void setTemperature(double);
std::string getName() const;
int getVolume() const;
double getCoeffizient() const;
double getTemperature() const;
private:
std::string name;
int volume;
double temperature;
double coeffizient;
};
FrozenMeal.cpp
#include <string>
#include "FrozenMeal.h"
using namespace std;
FrozenMeal::FrozenMeal(string mealName, int mealVolu) {
name = mealName;
volume = mealVolu;
temperature = -18;
coeffizient = 0.24;
}
void FrozenMeal::setTemperature(double mealTemp) { temperature = mealTemp; }
string FrozenMeal::getName() const { return name; }
int FrozenMeal::getVolume() const { return volume; }
double FrozenMeal::getCoeffizient() const { return coeffizient; }
double FrozenMeal::getTemperature() const { return temperature; }
Microwave.h
#include "FrozenMeal.h"
class Microwave {
public:
Microwave();
void morePower();
void lessPower();
void setPeriod(double);
void heatMeal(FrozenMeal); // <----------------------------
int getPower() const;
double getPeriod() const;
private:
int power;
double period;
};
Microwave.cpp
#include "Microwave.h"
using namespace std;
Microwave::Microwave() {}
void Microwave::morePower() { if (power < 1000) power += 200; }
void Microwave::lessPower() { if (power > 200) power -= 200; }
void Microwave::setPeriod(double sessionPeri) { period = sessionPeri; }
void Microwave::heatMeal(FrozenMeal mealInst) {
mealInst.setTemperature(80); //example
}
int Microwave::getPower() const { return power; }
double Microwave::getPeriod() const { return period; }
Now, my problem is that my compiler says that the file FrozenMeal.h apparently redefines the object type of FrozenMeal, even though that should be the job of the FrozenMeal.cpp file, and compiling is unsuccessful.
I tried including FrozenMeal.h to Microwave.cpp but that resulted in even more compiler errors.
I feel like I'm doing something horribly wrong here.
Add include guards to your header files so its contents doesn't get included more than once:
FrozenMeal.h:
#ifndef FROZENMEAL_H_INCLUDED
#define FROZENMEAL_H_INCLUDED
// your code ...
#endif /* FROZENMEAL_H_INCLUDED */
Microwave.h:
#ifndef MICROWAVE_H_INCLUDED
#define MICROWAVE_H_INCLUDED
// your code ...
#endif /* MICROWAVE_H_INCLUDED */
Also, you never initialize int Microwave::power and double Microwave::period so you will read and write garbage values in Microwave::morePower() and Microwave::lessPower()
As suggested in the comments, you want to take the parameter of Microwave::heatMeal() by reference so the function can modify the passed object:
void Microwave::heatMeal(FrozenMeal &mealInst)
// ^
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...
my program basically depends on setters to initialize the data in my object instances but I want to remove them and have constructors in place of the setters, Is there a way I can do this or can anybody provide me a reference?
Instantiate object
//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <archer.hpp>
#include <ctime>
#include <ArmouredArcher.hpp>
#include <RNGI.hpp>
using namespace std; //Declaring use of namespace std
void instantiateMuskateer();
int main(int argc, char* argv[])
{
//init muskateer object
instantiateMuskateer();
system("pause");
return 0;
}
Instantiation, Activity and destruction
void instantiateMuskateer()
{
Archer* Muskateer = new Archer();
Muskateer->setName("Brett");
delete Muskateer;
}
.hpp file
#ifndef _Archer_
#define _Archer_
#include <string>
class Archer
{
public:
inline Archer() :
name(""),
healthpoints(0),
baseDamage(0),
range(0)
{ ; } //All Member varials are in a known state
inline Archer(std::string name, int healthpoints, int baseDamage, int range) :
name(name),
healthpoints(healthpoints),
baseDamage(baseDamage),
range(range) //All member variables are in a known state
{
;
}
inline ~Archer() { ; } // empty destructor
inline std::string getName() { return name; }
inline void setName(std::string name) { this->name = name; }
inline int getHealthPoints() { return healthpoints; }
inline void setHealthPoints(int healthpoints) { this->healthpoints = healthpoints; }
inline int getBaseDamage() { return baseDamage; }
inline void setBaseDamage(int baseDamage) { this->baseDamage = baseDamage; }
inline int getRange() { return range; }
inline void setRange(int range) { this->range = range; }
/*std::string getName(); //getter for name
void setName(std::string name); //Set the name
int getHealthPoints();
void setHealthPoints(int healthpoints);
int getBaseDamage();
void setBaseDamage(int baseDamage);
int getRange();
void setRange(int range); */
protected:
private:
// copy constructor
Archer(const Archer& other) = delete;
// overload assignment operator
Archer& operator=(const Archer& other) = delete;
std::string name;
int healthpoints;
int baseDamage;
int range;
};
#endif
In your example, it is really simple, you just have to take the parameters you need in your constructor:
Archer(std::string n) :
name(n),
healthpoints(0),
baseDamage(0),
range(0)
{} //All Member varials are in a known state
And then you can simply do that:
void instantiateMuskateer()
{
Archer* Muskateer = new Archer("Brett");
delete Muskateer;
}
A few comments not related, but to improve your code. Writing inline is useless when you declare and implement your functions inside your class, the inline is implied. Also, if your destructor does nothing, you should not define it or use = default, that way you can enable some optimizations from the compiler.
Also, in your previous function i see no need to allocate the object on the heap, it is again a loss of performance and a source of error (such as forgetting to delete the object), allocate it on the stack:
void instantiateMuskateer()
{
Archer Muskateer("Brett");
// do your things
}
Or use a unique_ptr.
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.