Zombie.h has some static member variables. Read.cpp, which includes Zombie.h, knows the values that need to go in those variables. I want read.cpp to set those variables with something along the lines of
int Zombie::myStaticInt = 4;
or
Zombie::setStaticVar(4);
I've tried everything I can think of, including using a public static accessor function and even making the static variables themselves public, but I've been getting a lot of "undefined reference" or "invalid use of qualified-name" errors. By looking into those I found out how to set Zombie.h's private static member variables from Zombie.cpp, but I don't have a Zombie.cpp file, just read.cpp. Can I set them from Read.cpp instead, and if so, how?
// In Zombie.h
class Zombie {
public:
static void setMax(int a_in, int b_in, int c_in) {
a = a_in;
b = b_in;
c = c_in;
}
private:
static int a, b, c;
}
// In read.cpp
#include "Zombie.h"
...
main() {
int Zombie::a; // SOLUTION: Put this outside the scope of main and other functions
int Zombie::b; // SOLUTION: Put this outside the scope of main and other functions
int Zombie::c; // SOLUTION: Put this outside the scope of main and other functions
int first = rand() * 10 // Just an example
int second = rand() * 10 // Just an example
int third = rand() * 10 // Just an example
Zombie::setMax(first, second, third);
return 0;
}
This yields (Updated)
(Move first three lines of main outside of main() to solve this)
invalid use of qualified-name 'Zombie::a'
invalid use of qualified-name 'Zombie::b'
invalid use of qualified-name 'Zombie::c'
You have to define a,b,c somewhere. So far you've only declared them to exist. In some .cpp file, at the outer scope, you need to add:
int Zombie::a;
int Zombie::b;
int Zombie::c;
EDIT Re your edit, you can't put them inside a method. You have to put this at the outermost scope of the .cpp file.
Unlike non-static variables that get storage allocated in every object, static variables must have their storage outside of the class. You do this by creating definitions for the variables in a .cpp file. It doesn't matter which file they go in, although for convenience they should go with the code for the class.
int Zombie::a;
int Zombie::b;
int Zombie::c;
The linker error you're getting is telling you that these lines are missing.
Your problem is you haven't implemented Zombie class yet.
Your code here:
zombie.h
#ifndef ZBE_H
#define ZBE_H
class Zombie
{
public:
static int myStaticInt;
Zombie();
};
#endif
read.cpp
#include <stdio.h>
#include <iostream>
#include "zombie.h"
int Zombie::myStaticInt = 1;
Zombie::Zombie()
{
}
int main()
{
cout << "OOOK: " << Zombie::myStaticInt << endl;
Zombie::myStaticInt = 100;
cout << "OOOK: " << Zombie::myStaticInt << endl;
return 0;
}
Related
I am new to C++, and was wondering what I am doing wrong.
I am trying to create a text-based adventure game that keeps track of player stats using an add or remove function. Currently, my function does not add five points to trust and I am trying to get it to.
#include "function.h"
using namespace std;
int main() {
double trust=100;
editPlayer user(100);
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust);
cout << trust;
Here is my function.cpp only using trust as an example:
#include "function.h"
editPlayer::editPlayer(double trust) {
}
void editPlayer::addTrust(double trust){
trust +=5;
}
void editPlayer::removeTrust(double trust){
trust -=5;
}
And here is my function.h:
#include<iostream>
#include<string>
using namespace std;
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
Lets take your addTrust function:
void editPlayer::addTrust(double trust) {
trust += 5;
}
This will modify the local variable trust, and then the function will end. When the function ends, the life-time of the local variable trust also ends, and the modifications you made to it will be lost.
If you truly want to modify the argument, you need to either pass it by reference:
void editPlayer::addTrust(double& trust) {
trust += 5;
}
Or return the new value:
double editPlayer::addTrust(double trust) {
return trust + 5;
}
If you return the new value, you need to assign to it when calling the function:
trust = user.addTrust(trust);
With the above said, the code and the editPlayer class doesn't make much sense. There's just no need for a class editUser really. Possibly addTrust could be a non-member function, or maybe not a function at all.
The class name doesn't make sense, since it doesn't "edit" anything. And passing an argument to the constructor also doesn't make sense since the objects doesn't have any internal state (the value passed to the constructor is just discarded).
Currently you're not storing anything specific on behalf of user object (an object of the editPlayer class.
The cout << trust; statement just prints a value of the trust local variable which you declared at the beginning: double trust=100;. Because this variable hasn't been changed anyhow since that initialization it is still equal to 100 and this is what you see.
In order to track any editPlayer-specific information the best idea is to store that information as a data member of the class editPlayer. You can declare a data member representing the trust of an object like this:
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const; // add also this one, will be useful
private:
double m_trust {0}; // <---- here - a data member, aka. a class field
};
Now you must refine you constructor to let it utilize the parameter which it takes and assign its value to this new data member (because currently the constructor does nothing):
editPlayer::editPlayer(double trust) {
m_trust = trust;
}
Now in the member functions that you already have just rename the variable so that it reflects the trust data member (and not the parameter) which effectively will allow to update its value:
void editPlayer::addTrust(double trust) {
m_trust += 5;
}
void editPlayer::removeTrust(double trust) {
m_trust -= 5;
}
double editPlayer::getTrust() const { // add definition of our "getter"
return m_trust;
}
Finally you can replace that cout << trust; which we already discussed (still prints the local variable's value) with an invokation of the getter which yields m_trust's value:
cout << user.getTrust();
and see the actual effect of performing the addTrust() operation as well as get delighted with your legitimate object-oriented program.
In general the code you are asking can be covered by classes, member declarations and also a pinch of object oriented programming.
The internet has lots of good (and less than good) tutorials if you search for it.
I would try my luck with some of the following searches
CPP + classes
CPP + member declarations
CPP + dynamic vs. static memory allocation (pointers and stuff)
object oriented programming (OOP)
The examples on this site provide good (and short :D) examples of alot of basic concepts imho.
https://www.tutorialspoint.com/cplusplus/cpp_classes_objects.htm
Some of the topics also apply to other languages.
The first block with my comments:
#include "function.h"
using namespace std; // dont get into the habbit of using namespace std;
// the above can potentially open up for bugs
int main()
{
double trust=100; // This variable is declared in this scope({ ... })
// and will get deallocated once the scope ends with the character '}'
editPlayer user(100); // instance of editPlayer named 'user' is constructed
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust); // calling function on user object
cout << trust;
}
Now looking at the .h file i would advocate against including headers that you dont use in the header.
For small projects it does not matter at all - but for big projects of thousands lines of code removing unused includes can speed up things.
Some would prefer forward declarations - which you can look into once you are more comfortable with the basics of cpp.
#include<iostream> // not used here
#include<string> // not used
using namespace std; // disaster waiting to happen
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
The .cpp file
#include "function.h"
editPlayer::editPlayer(double trust) {}
// function implementation with argument - but argument is not used - change to void fun(double) -> fun(void) OR fun()
void editPlayer::addTrust(double trust) { trust +=5; }
void editPlayer::removeTrust(double trust) { trust -=5; }
I did an example with class declaration and member variables.
#include <iostream>
#include <string>
// this is a class declaration
class Player
{
protected: // protected member variables
double _trust;
public: // public interface
Player(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const;
};
// Implementation of public interface
// notice _trust is the member defined in the class
Player::Player(double trust) : _trust(trust) {} // constructor
// example of default parameters (do note that only definition or declaration can have them)
// This means that calling the function without arguments will become 5
void Player::addTrust(double trust = 5) { _trust += trust; }
void Player::removeTrust(double trust = 5) { _trust -= trust; }
double Player::getTrust() const {return _trust; }
int main()
{
Player player(100); // this will invoke the constructor - and the player object will get initialised with the given state
std::cout << player.getTrust() << std::endl;
// variable to buffer input data into - assuming type int wrt. following if
int firstChoice;
//asks user choice
std::cin >> firstChoice;
if (firstChoice == 1)
{
player.addTrust(25);
player.addTrust();
}
std::cout << player.getTrust();
}
Happy coding !
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<::x; // should print 10;
}
return 0;
}
Is there any way to print x=10 without changing variable names, variable values and position of cout?
I assume this is an academic question (puzzle) because nobody should write code like that. In the same spirit, here's a way to make it print 10 instead of 15 without changing variable names, variable values and the position of cout:
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
#define x x-5
cout<<::x; // should print 10;
}
return 0;
}
Normally you should parenthesize such expressions in macros, like (x-5). In this case, that would be counterproductive :)
No you can't
An inner block, because it is a different block, can re-utilize a name existing in an outer scope to refer to a different entity; in this case, the name will refer to a different entity only within the inner block, hiding the entity it names outside.
Further information here: http://www.cplusplus.com/doc/tutorial/namespaces/
You cannot access x=10 in the inner block where you defined x=5. It can only see x=5 as x=10 is hidden at that point.
Ref: 3.3.7/1
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).
If you don't mind some horrible undefined behaviour, we could make assumptions about where local variables are stored on the stack. This works on my machineā¢ using g++ without any additional flags (although even -O1 breaks it):
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<*((&x) + 1); // should print 10;
}
return 0;
}
This is based on the assumption that local variables are placed on the call stack (or some other place) consecutively in main memory, in reverse order of declaration. It breaks in many cases, such as having a different order, having x=10 be placed in a register, or x=10 being optimized away entirely because it's unused.
#include <iostream>
using namespace std;
int x = 15;
int main()
{
int x = 10;
{
int x = 5;
}
cout << x; // should print 10;
return 0;
}
you should probably put cout<< to outside
In principle, a variable defined outside any function (that is, global, namespace, and class static variables) is initialized before main() is invoked. Such nonlocal variables in a translation unit are initialized in their declaration order
Above are the lines from the class notes given by my lecturer.
#include <iostream>
using namespace std;
int a=99;
int main(int argc, char *argv[])
{
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
int b=100;
There is an error while I run this. Isn't it true that b assigned to 100 before main() is called?
The problem here is not initialisation order: b is indeed initialised before main starts running.
The problem is the "visibility" of b. At the point where main is being compiled, there is no b.
You can fix it by either moving the definition/initialisation of b to before main:
#include <iostream>
using namespace std;
int a = 99;
int b = 100;
int main (int argc, char *argv[]) {
cout << a << '\n';
cout << b << '\n';
return 0;
}
or simply indicate that b exists:
#include <iostream>
using namespace std;
int a = 99;
extern int b;
int main (int argc, char *argv[]) {
cout << a << '\n';
cout << b << '\n';
return 0;
}
int b = 100;
Neither of those two solutions change when b is created or initialised at run-time, they simply make b available within main.
Your lecturer is wrong; global variables are initialised in order of definition, not declaration.
For example,
#include <iostream>
struct S { S(const char *s) { std::cout << s << '\n'; } };
extern S a; // declaration
extern S b; // declaration
int main() { }
S b("b"); // definition
S a("a"); // definition
will print
b
a
The code you posted doesn't work because b is not even declared at the point of use. A declaration (for example, extern int b), is required because C++ (like C) was originally designed as a one-pass compiler.
The problem is here: cout<<b<<endl;
You can't access the variable before it's declaration.
Read carefully.
A variable defined outside any function (B) is initialized before main is invoked (not compiled).
To be compiled correctly B should be defined(and declared) before it's first use (and that's your error: B is used before been declared anywhere).
The problem is the statement b=100;: you can't place a statement in a global scope (except for variable initialization).
If this line remains as is, the code won't compile regardless of b declarations/definitions or the use of b within main or anywhere.
Without this line, the code is correct and works, with b value equals 0, since uninitialized global variables are initialized to 0 (or the line b=100; could be moved into any function scope).
I can't figure out why I get this error: "the function was not declared". I am still a newbie at programming, but I am trying my best to learn it!
so here is my code, I would be realy greatful if you could help me:
main:
#include <iostream>
#include <vector>
#include "szovegkezelo.h"
using namespace std;
int main()
{
string sz;
beolvas(sz);
kiir(sz);
return 0;
}
header:
#ifndef SZOVEGKEZELO_H_INCLUDED
#define SZOVEGKEZELO_H_INCLUDED
#include <iostream>
using namespace std;
class szovegkezelo {
protected:
string sz;
public:szovegkezelo
void beolvas(string &sz);
void kiir(string t);
};
#endif // SZOVEGKEZELO_H_INCLUDED
cpp:
#include "szovegkezelo.h"
#include <iostream>
void szovegkezelo::beolvas(string &sz)
{
getline(cin, sz);
}
void szovegkezelo::kiir(string t)
{
cout << "a beadott szoveg: " << t << endl;
cout << "a string hossza: " << t.size() << endl;
}
From what it looks like, you are trying to call a classes function (method) called 'beolvas' from 'main' but because it belongs to a class, you can't call it like that, you need to create an instance of that class and call the method on that instance, or make the function static and call it from the class.
Your first option is to create an instance of the class and then call the methods on the class like so:
int main()
{
string sz;
szovegkezelo szov;
szov.beolvas(sz);
svoz.kiir(sz);
return 0;
}
Your second option is to make the functions in your class static, this way they will not need an instance of the class to be called:
int main()
{
string sz;
szov::beolvas(sz);
svoz::kiir(sz);
return 0;
}
static void szovegkezelo::beolvas(string &sz)
{
getline(cin, sz);
}
static void szovegkezelo::kiir(string t)
{
cout << "a beadott szoveg: " << t << endl;
cout << "a string hossza: " << t.size() << endl;
}
Been a while since I've done anything static in c++ so please correct me if I've done something wrong in the second option.
Your two or more data types... error comes from a misuse of...something...after that public access specifier.
Change this:
public:szovegkezelo
to this:
public:
If you're trying to make a constructor, it needs to be declared like any other function, minus the return type.
Your other error occurs because this function was declared improperly.
Other than that, you need to create an object before you can call the class's functions. Each object has it's own set of variables that the functions work on. I would seriously recommend reading a good beginner C++ OOP book.
Somewhere in main, you need to create an object:
szovegkezelo myObject;
Then, use it to call functions:
myObject.kiir (sz);
Finally, note that your data members should typically be declared with the private access specifier. protected has nothing to do with normal classes that are not inherited from.
couple of things :
1) In main you have not instantiated an object of szovegkezelo and you are trying to call beolvas . Compiler is looking for a free function beolvas whereas you have declared beolvas as member function
2) public:szovegkezelo is not right if you are looking for a default constrcutor that does nothing don't have that line else if you need to do something specific with default construct declare it as szovegkezelo() in header.
3) as mentioned in comments it is not a good practice to put
using namespace std in header files or any using namespace
I've developed a 'custom' cout, so that I can display text to console and also print it to a log file. This cout class is passed a different integer on initialization, with the integer representing the verbosity level of the message. If the current verbosity level is greater then or equal to the verbosity level of the message, the message should print.
The problem is, I have messages printing even when the current verbosity level is too low. I went ahead and debugged it, expecting to find the problem. Instead, I found multiple scenarios where my if statements are not working as expected.
The statement if(ilralevel_passed <= ilralevel_set) will sometimes proceed even if ilralevel_set is LESS then ilralevel_passed. You can see this behavior in the following picture (my apologizes for using Twitpic) http://twitpic.com/1xtx4g/full. Notice how ilralevel_set is equal to zero, and ilralevel_passed is equal to one. Yet, the if statement has returned true and is now moving forward to pass the line to cout.
I've never seen this type of behavior before and I'm not exactly sure how to proceed debugging it. I'm not able to isolate the behavior either -- it only occurs in certain parts of my program. Any suggestions are appreciated as always.
// Here is an example use of the function:
// ilra_status << setfill('0') << setw(2) << dispatchtime.tm_sec << endl;
// ilra_warning << "Dispatch time (seconds): " << mktime(&dispatchtime) << endl;
// Here is the 'custom' cout function:
#ifndef ILRA_H_
#define ILRA_H_
// System libraries
#include <iostream>
#include <ostream>
#include <sstream>
#include <iomanip>
// Definitions
#define ilra_talk ilra(__FUNCTION__,0)
#define ilra_update ilra(__FUNCTION__,0)
#define ilra_error ilra(__FUNCTION__,1)
#define ilra_warning ilra(__FUNCTION__,2)
#define ilra_status ilra(__FUNCTION__,3)
// Statics
static int ilralevel_set = 0;
static int ilralevel_passed;
// Classes
class ilra
{
public:
// constructor / destructor
ilra(const std::string &funcName, int toset)
{
ilralevel_passed = toset;
}
~ilra(){};
// enable / disable irla functions
static void ilra_verbose_level(int toset){
ilralevel_set = toset;
}
// output
template <class T>
ilra &operator<<(const T &v)
{
if(ilralevel_passed <= ilralevel_set)
std::cout << v;
return *this;
}
ilra &operator<<(std::ostream&(*f)(std::ostream&))
{
if(ilralevel_passed <= ilralevel_set)
std::cout << *f;
return *this;
}
}; // end of the class
#endif /* ILRA_H_ */
When you define a static variable outside a class, you're defining a separate variable for each source file into which you include the header -- changing the value in one doesn't affect the value of the variable with the same name in another file.
What you almost certainly want is to have
int ilralevel_set = 0;
int ilralevel_passed;
In one file where you're defining your object, and:
extern int ilralevel_set;
extern int ilralevel_passed;
in the header. Alternatively, it looks like you could move it all inside the class:
class ilra {
int passed_level;
int set_level;
public:
ilra(int toset) : passed_level(toset), set_level(0) {}
verbose_level(int toset) { set_level = toset; }
// ...
};
You should not be defining static variables in a header file like this:
static int ilralevel_set = 0;
static int ilralevel_passed;
I don't know what you think those definitions do, but they probably don't do what you want.
To declare in the class:
struct A {
static int ilralevel;
};
You then need to define in one .cpp source file:
int A::ilralevel = 0;
Just a guess .. you're getting different copies of your static globals in different compilation units. fx, route.cpp has it's own copy of ilralevel_passed and ilralevel_set, plus an inlined copy of irla::operator<<. Move ilralevel_passed to a member variable of irla, and ilralevel_set to a static const, and see if that helps.