setter in class won't set variable - c++

I'm currently trying to make a game in C++. In my code I'm trying to nest my variables so that my main doesn't have a lot of includes. My problem right now though is that the value of my variables in my class aren't changing. Stepping through the code it shows it setting the value, but it doesn't work. Anyone know what's going on? Thank you in advance.
This is what I have so far:
Location.h
#ifndef LOCATION_H
#define LOCATION_H
#include <string>
class Location
{
public:
Location(void);
Location(std::string name);
~Location(void);
std::string GetName();
void SetName(std::string value);
private:
std::string m_Name
};
#endif
Location.cpp
#include "Location.h"
Location::Location(void): m_Name("") {}
Location::Location(std::string name): m_Name(name) {}
Location::~Location(void)
{
}
std::string Location::GetName()
{return m_Name;}
void Location::SetName(std::string value){m_Name = value;}
PlayerStats.h
#ifndef PLAYERSTATS_H
#define PLAYERSTATS_H
#include "Location.h"
class PlayerStats
{
public:
PlayerStats(void);
~PlayerStats(void);
Location GetLocation();
void SetLocation(Location location);
private:
Location m_Location;
};
#endif
PlayerStats.cpp
#include "PlayerStats.h"
PlayerStats::PlayerStats(void): m_Location(Location()) {}
PlayerStats::~PlayerStats(void)
{
}
Location PlayerStats::GetLocation(){return m_Location;}
void PlayerStats::SetLocation(Location location){m_Location = location;}
main.cpp
#include <iostream>
#include "PlayerStats.h"
using namespace std;
PlayerStats playerStats = PlayerStats();
int main()
{
playerStats.GetLocation().SetName("Test");
cout<< playerStats.GetLocation().GetName()<<endl;
return 0;
}

Your immediate issue is that
Location GetLocation();
returns a copy of the location, so when you call SetName here:
playerStats.GetLocation().SetName("Test");
You're changing the name of the temporary copy, and the change is lost as soon as the semicolon is hit.
More broadly, this kind of design (nesting classes and nesting includes so that main doesn't have a lot of includes, and using a.b.c() style code to access nested members) isn't great C++ style:
Having a bunch of source files that (transitively) include a bunch of header files means that changing a single header file will trigger recompilations of a bunch of source files. Compile times can be a significant issue in larger C++ projects, so reducing compile times by controlling #include's is important. Read up on "forward declarations" for more information.
Writing code like a.b.c() is considered bad object-oriented design, because it reduces encapsulation: not only does the caller have to know about a's details, it has to know about b's also. Sometimes this is the most expedient way to write code, but it's not something to be blindly done just to reduce #include's. Read up on "Law of Demeter" for more information.

If you want to set the result of playerStats.GetLocation(), you could make GetLocation() pass-by-reference (use ampersand, &, on the return argument). Otherwise you are just setting values in a temporary copy of PlayerStats::m_Location.
Alternatively, you could use the SetLocation() function.

Related

'Cashier' was not declared in this scope

I have this piece of code
#ifndef STATION_H
#define STATION_H
#include <vector>
#include "Dispenser.h"
#include "Cashier.h"
//class Cashier;
class Station
{
private:
int price;
int dispenser_count;
int cashier_count;
std::vector<Dispenser> dispensers;
std::vector<Cashier> cashiers;
public:
Station(int, int, int);
int GetPrice() const { return price; }
Dispenser *LookForUnoccupiedDispenser(int &id);
Dispenser *GetDispenserByID(int id);
Cashier *LookForUnoccupiedCashier();
};
#endif // STATION_H
When I have the class Cashier line commented, the compiler fails with a 'Cashier' was not declared in this scope error even though Cashier.h was included. Uncommenting it makes it possible to compile but I'm concerned that it shouldn't be happening.
Cashier.h
#ifndef CASHIER_H
#define CASHIER_H
#include "Station.h"
class Station;
class Cashier
{
private:
bool busy;
Station *at_station;
public:
Cashier(Station *employer);
bool IsBusy() const { return busy; }
};
#endif // CASHIER_H
How is it possible? It's clearly declared in the header file and as far as I know, #include does nothing more than pasting the content of a file into another one.
Thank you for the answers in advance!
Your station.h includes cachier.h. This is an example of cyclic dependency. Given that you only have a pointer to Station in Cachier I'd suggest removing the dependency of station.h and forward declare it.
An #include is literally nothing more than verbatim copy and paste of that file into the current compilation unit. The guards protect you from the effect of an infinite include cycle, but due to the guards one of the #includes does nothing, i.e. does NOT suck in the declaration (nor definition) of the respective class. This results in the error you get. In station.h the compiler has never seen any mention of the Cachier type when it sees the Station type.

C++ Beginner : calling default vs custom constructor

Beginner here - but i was uncertain what exactly to search for this (presumably common) question.
I am working on a program where I have a given class (Dictionary). I am supposed to make a concrete class (Word) which implements Dictionary. I should mention that I am not to change anything in Dictionary.
After making a header file for Word, I define everything in word.cpp.
I am unsure if I am doing this correctly, but I make the constructor read from a given file, and store the information in a public member of Word.
(I understand that the vectors should be private, but I made it public to get to the root of this current issue)
dictionary.h
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
class Dictionary
{
public:
Dictionary(istream&);
virtual int search(string keyword, size_t prefix_length)=0;
};
#endif /* __DICTIONARY_H__ */
word.h
#ifndef __WORD_H__
#define __WORD_H__
#include "dictionary.h"
class Word : public Dictionary{
public:
vector<string> dictionary_words;
vector<string> source_file_words;
Word(istream &file);
int search(string keyword, size_t prefix_length);
void permutation_search(string keyword, string& prefix, ofstream& fout, int& prefix_length);
};
#endif /* __WORD_H__*/
word.cpp
#include "word.h"
Word(istream& file) : Dictionary(istream& file)
{
string temp;
while (file >> temp)
{
getline(file,temp);
dictionary_words.push_back(temp);
}
}
In word.cpp, on the line "Word::Word(istream& file)", I get this error :' [Error] no matching function for call to 'Dictionary::Dictionary()'.
I've been told this is error is due to "Word's constructor invoking Dictionary's ", but I still don't quite grasp the idea well. I am not trying to use Dictionary's constructor, but Word's.
If anyone has an idea for a solution, I would also appreciate any terms related to what is causing this issue that I could look up - I wasn't even sure how to title the problem.
Your child class should invoke parent constructor, because parent object are constructed before child. So you should write something like:
Word::Word(isteam& file) : Dictionary(file)
{
...
}
Seems its better described here What are the rules for calling the superclass constructor?

Classes included within main() method

If I have some code like
main(int argc, char *argv[])
{
...
#include "Class1.H"
#include "Class2.H"
...
}
Generally the main() method is the starting point of every application and the content within main() is to be executed. Am I right in the assumption that the content of all classes included into main() will be executed when main() is started?
greetings
Streight
No, no, NO.
First of all, you don't #include a file within a function. You #include a file at the beginning of a file, before other declarations. OK, you can use #include anywhere, but you really just shouldn't.
Second, #include doesn't execute anything. It's basically just a copy-paste operation. The contents of the #included file are (effectively) inserted exactly where you put the #include.
Third, if you're going to learn to program in C++, please consider picking up one of our recommended texts.
You commented:
I am working with the multiphaseEulerFoam Solver in OpenFoam and
inside the main() of multiphaseEulerFoam.C are classes included. I
assume that the classes have the right structure to be called in
main()
That may be the case, and I don't doubt that the classes have the right structure to be called from main. The problem is main will be malformed after the #includes because you'll have local class definitions and who knows what else within main.
Consider this. If you have a header:
foo.h
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo (const std::string& val)
:
mVal (val)
{
}
private:
std::string mVal;
};
#endif
And you try to include this in main:
main.cpp
int main()
{
#include "foo.h"
}
After preprocessing the #include directive, the resulting file that the compiler will try to compile will look like this:
preprocessed main.cpp
int main()
{
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo (const std::string& val)
:
mVal (val)
{
}
private:
std::string mVal;
};
#endif
}
This is all kinds of wrong. One, you can't declare local classes like this. Two, Foo won't be "executed", as you seem to assume.
main.cpp should look like this instead:
#include "foo.h"
int main()
{
}
#define and #include are just textual operations that take place during the 'preprocessing' phase of compilation, which is technically an optional phase. So you can mix and match them in all sorts of ways and as long as your preprocessor syntax is correct it will work.
However if you do redefine macros with #undef your code will be hard to follow because the same text could have different meanings in different places in the code.
For custom types typedef is much preferred where possible because you can still benefit from the type checking mechanism of the compiler and it is less error-prone because it is much less likely than #define macros to have unexpected side-effects on surrounding code.
Jim Blacklers Answer # #include inside the main () function
Try to avoid code like this. #include directive inserts contents of the file in its place.
You can simulate the result of your code by copy-pasting file content from Class1.H and Class2.H inside the main function.
Includes do not belong into any function or class method body, this is not a good idea to do.
No code will be executed unless you instantiate one of your classes in your header files.
Code is executed when:
Class is instantiated, then it's constructor method is called and the code inside the method is executed.
If there are variables of a class type inside your instantiated class, they will too run their constructors.
When you call a class method.
Try this example:
#include <iostream>
using namespace std;
int main()
{
class A
{ public:
A() { cout << "A constructor called" << endl; }
};
// A has no instances
class B
{ public:
B() { cout << "B constructor called" << endl; }
void test() { cout << "B test called" << endl; }
} bbb;
// bbb will be new class instance of B
bbb.test(); // example call of test method of bbb instance
B ccc; // another class instance of B
ccc.test(); // another call, this time of ccc instance
}
When you run it, you'll observe that:
there will be no instance of class A created. Nothing will be run from class A.
if you intantiate bbb and ccc, their constructors will be run. To run any other code you must first make a method, for example test and then call it.
This is an openFoam syntax he is correct in saying that open Foam treats #include like calling a function. In OpenFoam using #include Foo.H would run through the code not the class declaration that is done in a different hierarchy level. I would recommend all openFoam related question not be asked in a C++ forum because there is so much stuff built onto C++ in openFoam a lot the rules need to be broken to produce a working code.
You're only including declarations of classes. To execute their code, you need to create class instances (objects).
Also, you shouldn't write #include inside a function or a class method. More often than not it won't compile.

c++ headers keeping sane

The biggest problem I seem to run into when coding in c++ is the fact that you must declare a class before you can reference it. Say I have two header file like this...
Header1.h
#include "Header2.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage;
class Hello
{
public:
string Message;
HelloPackage * Package;
Hello():Message("")
{
}
Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Execute()
{
cout << Message << endl;
//HelloPackage->NothingReally doesn't exist.
//this is the issue essentially
Package->NothingReally(8);
}
};
Header2.h
#include "Header1.h"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage
{
public:
deque<Hello> Hellos;
HelloPackage()
{
Hellos = deque<Hello>();
}
int AddHello(string Message)
{
Hellos.push_back(Hello(Message,this));
}
void ExecuteAll()
{
for each(Hello h in Hellos)
h.Execute();
}
int NothingReally(int y)
{
int a = 0;
a += 1;
return a + y;
}
}
What I'm wondering is, is there any elegant solution for dealing with these issues? In say c#, and java, you're not restricted by this "linear" compiling.
Use header include guards, either "#ifndef / #define / #endif", or "#pragma once"
Put your code in a .cpp, not inline in the header
???
Profit
The reason this will work for you is because you can then use forward declarations of the class you want to reference without including the file if you so wish.
You are missing include guards
why define methods in the header?
Besides these problems with your code, to answer your question : normal way is to forward declare classes - not to include headers in headers (unless you have to).
If you follow a few basic rules, it is not awkward at all. But in comparison to e.g. Java or C#, you have to follow these rules by yourself, the compiler and/or language spec does not enforce it.
Other answers already noted that, but I will recap here so you have it in one place:
Use include guards. They make sure that your header (and thus your class definition) is only included once.
Normally, you will want to separate the declaration and implementation of your methods. This makes the header files more reusable and will reduce compilation time, because the header requires normally fewer #includes than the CPP (i.e. implementation) file.
In the header, use forward declarations instead of includes. This is possible only if you just use the name of the respective type, but don't need to know any "internals". The reason for this is that the forward declaration just tells the compiler that a certain name exists, but not what it contains.
This is a forward declaration of class Bar:
class Bar;
class Foo {
void foooh(Bar * b);
};
Here, the compiler will know that there is a Bar somewhere, but it does not know what members it has.
Use "using namespace xyz" only in CPP files, not in headers.
Allright, here comes your example code, modified to meet these rules. I only show the Hello class, the HelloPackage is to be separated into header and CPP file accordingly.
Hello.h (was Header1.h in your example)
#include <string>
class HelloPackage;
class Hello
{
public:
Hello();
Hello(std::string message, HelloPackage * pack);
void Execute();
private:
string Message;
HelloPackage * Package;
};
Hello.cpp
#include "Hello.h"
#include "HelloPackage.h"
using namespace std;
Hello::Hello() : Message("")
{}
Hello::Hello(string message, HelloPackage * pack)
{
Message = message;
Package = pack;
}
void Hello::Execute()
{
cout << Message << endl;
// Now accessing NothingReally works!
Package->NothingReally(8);
}
One question that may arise is why is the include for string is needed. Couldn't you just forward declare the string class, too?
The difference is that you use the string as embedded member, you don't use a pointer to string. This is ok, but it forces you to use #include, because the compiler must know how much space a string instance needs inside your Hello class.

Another 'x was not declared in this scope'

this is my first question here.
Writing some code, i receive this error from g++: "Entity was not declared in this scope", in this context:
#ifndef Psyco2D_GameManager_
#define Psyco2D_GameManager_
#include <vector>
#include "Entity.h"
namespace Psyco2D{
class GameManager{J
private:
std::vector<Entity> entities;
};
}
#endif
This is the content of Entity.h:
#ifndef Psyco2D_Entity_
#define Psyco2D_Entity_
#include <string>
#include "GameManager.h"
#include "EntityComponent.h"
namespace Psyco2D{
class Entity{
friend class GameManager;
private:
/* Identificatore */
std::string _name;
/* Components list */
std::map<const std::string, EntityComponent*> components;
protected:
Entity(const std::string name);
public:
inline const std::string getName() const{
return this->_name;
}
void addComponent(EntityComponent* component, const std::string name);
EntityComponent* lookupComponent(const std::string name) const;
void deleteComponent(const std::string name);
};
}
#endif
If i use std::vector<class Entity> instead of std::vector<Entity> it works.
Why?
Thanks to all =)
The problem is you have a cyclic dependency. Take out #include "GameManager.h" in Entity.h, since you don't actually need it in that header. (Up-vote this answer, which first pointed it out.)
Note the guards are actually the problem; but don't take them out! You just need to minimize the includes you have, and declare (and not define) types when possible. Consider what happens when you include Entity.h: As some point it includes GameManager.h, which in turn includes Entity.h. At this point, Entity.h already has its header guard defined, so it skips the contents. Then the parsing of GameManager.h continues, where upon it runs into Entity, and rightfully complains it is not defined. (Indeed, this is still the process of including GameManager.h in the first inclusion of Entity.h, far before Entity is defined!)
Note your numerous edits demonstrate why it's important to post real code, not re-synthesized code. You need real details to get real answers.
Old:
Entity is in the Psyco2D namespace. You need to specify that:
class GameManager{
private:
std::vector<Psyco2D::Entity> entities;
};
Assuming the first snippet is part of GameManager.h you have a circular header dependency. I believe you can fix this by changing the GameManager.h include in Entity.h to class GameManager; instead.
Additionally as GMan noted, Entity is in a namespace and you need to qualify Entity with the namespace name.
Remove the Psyco2D-namespace and it will work without declaring "class Entity".