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.
Related
I've began making a program in linux with c++ and I'm trying to make it work on windows. It compiles fine, but when run I get this error: "1 [main] Trails of Cold Steel Simulator 8748 cygwin_exception::open_stackdumpfile: Dumping stack trace to Trails of Cold Steel Simulator.exe.stackdump". In the stack trace this exception occurs: "Exception: STATUS_ACCESS_VIOLATION". Here's some code;
#include "Tachi.h"
#include "AutumnLeafCutter.h"
#include <iostream>
#include "Weapon.h"
#include "Armour.h"
#include "Shoes.h"
int main() {
int stats[12] = {15,110,10,4,2,1,2,4,4,3,7,1};
Tachi* Tachi1 = new Tachi(stats, "Tachi");
Tachi1->addEquipment(new PracticeSword());
Tachi1->addEquipment(new LeatherJacket());
Tachi1->addEquipment(new WorkBoots());
Tachi1->addMasterQuartz(new Forcelvl1());
std::string input;
std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
while(input != "q") {
std::cout << "Your current stats are:" << std::endl;
std::cout << "\n";
std::cout << "HP EP STR DEF ATS ADF SPD DEX AGL MOV RNG" << std::endl;
for(int i = 0; i < 12; i += 1) {
std::cout << Tachi1->getBaseStats()[i] << " ";
}
std::cout << "\n\n";
std::cout << "Select a Craft by typing its name:" << std::endl;
std::cout << std::endl;
for(int i = 0; i < Tachi1->getCrafts().size(); i++) {
std::cout << Tachi1->getCrafts()[i]->getName() << std::endl;
}
std::cout << std::endl;
getline(std::cin, input);
if(Tachi1->findCraft(input) != NULL) {
Tachi1->useCraft(input);
} else {
std::cout << "You do not have this craft." << std::endl;
}
std::cout << "\n\n\n";
}
}
Im extremely sorry for any formatting, I've never posted here. The error comes from lines 14,15,16 and 18. When I replaced all the "new xxx()" with NULL and comment out the body of the function with them, the program works. It does this for both addEquipment() and addMasterQuartz(). This is the functions;
void Character::addEquipment(Equipment* e) {
equipment.push_back(e);
std::cin.get();
for(int i = 0; i < 12; i++) {
baseStats[i] += equipment[equipment.size()]->getStatsModifier()[i];
}
}
and
void Character::addMasterQuartz(MasterQuartz* mq) {
masterQuartz = mq;
for(int i = 0; i < 12; i++) {
baseStats[i] += masterQuartz->getStatsModifier()[i];
}
}
Im guessing its a problem with the baseStats[i] += xxx stuff as its the only thing that occurs in both, but I have no idea how to fix that. It could also occur when the stuff is made using new xxx().
I can provide whatever else is needed. Thanks!!!!
EDIT:
I kept testing and the problem seems to lie in the creating of the objects. It worked on linux. Here is one of the object codes, they are all similiar and all crash the program;
#include "Armour.h"
Armour::Armour(int* sm, std::string n):Equipment(sm, n) {}
LeatherJacket::LeatherJacket():Armour(stats, armourName) {}
with header file;
#ifndef ARMOUR_H
#define ARMOUR_H
#include "Equipment.h"
class Armour:public Equipment {
public:
Armour(int* sm, std::string n);
};
class LeatherJacket:public Armour {
int stats[12] = {0,0,0,5,0,0,0,0,0,0,0,0};
std::string armourName = "Leather Jacket";
public:
LeatherJacket();
};
#endif
As soon as I remembered I did this I tried compiling (I think) with -std=c++11, it didnt help.
This is your error
baseStats[i] += equipment[equipment.size()]->getStatsModifier()[i];
By definition this is an out of bounds access on your vector, if a vector has a certain size, then the valid indexes are 0 to size - 1, not 0 to size.
It's fairly obvious that you wanted to access the last item in the vector. You can do that like this
baseStats[i] += equipment[equipment.size() - 1]->getStatsModifier()[i];
but even clearer is to use the back method.
baseStats[i] += equipment.back()->getStatsModifier()[i];
Another way would be to use the e variable you've just pushed onto the vector.
baseStats[i] += e->getStatsModifier()[i];
Adding some detail to the problem spotted by Useless, this code is incorrect.
class LeatherJacket : public Armour {
int stats[12] = {0,0,0,5,0,0,0,0,0,0,0,0};
std::string armourName = "Leather Jacket";
public:
LeatherJacket();
};
LeatherJacket::LeatherJacket() : Armour(stats, armourName) {}
The problem is the order in which things happen. First the Armour constructor is called, then the stats and armourName variables are initialised. So the call to the Armour constructor is using uninitiialised variables and will likely crash.
Several solutions possible, the best is probably to use virtual functions.
Making a couple of assumptions about Equipment (which isn't specified the question) it seems you should do something like this.
// header file
class Equipment
{
public:
virtual ~Equipment() {}
virtual std::string getName() const = 0;
virtual const int* getStatsModifier() const = 0;
};
class Armour : public Equipment
{
};
class LeatherJacket : public Armour
{
static const int stats[12];
public:
virtual std::string getName() const { return "Leather Jacket"; }
virtual const int* getStatsModifier() const { return stats; }
};
// source file
const int LeatherJacket::stats[12] = {0,0,0,5,0,0,0,0,0,0,0,0};
This answer adds pure virtual functions to the base class Equipment (which has become an interface), and implements those functions in LeatherJacket. Because the functions are virtual the appropriate function will always be called and there no need to pass the information down to Equipment. Also since it seems to be per-class constant data, stats has been made static const. Until you get to C++17 static const arrays must be defined in a source file, not the header file, as shown above.
Firstly, I'm going to replace the int[12] arrays with a proper type. Partly so the magic number 12 isn't littered all over the code and hard to change later, and partly because it will behave better (ie, not decay to a pointer in some contexts). This needs C++11.
#include <array>
using Stats = std::array<int, 12>;
To me it looks like Armour should have stats and a name, initialized from the arguments passed to its constructor (which you currently ignore).
Like so:
class Armour: public Equipment {
public:
Stats m_stats;
std::string m_name;
Armour(Stats const& s, std::string const &n) : m_stats(s), m_name(n) {}
};
You were already passing those two arguments to the constructor - you just weren't doing anything with them. Now you are.
This means that when we later have leather, scale, chain and plate subclasses, I can have a pointer of type Armour* and not need to worry about which subclass I'm looking at: the stats are available right there in the base class.
I made the members public, which is generally bad style, to save space. It might not matter for your use. I named the members with the m_ prefix so they can't accidentally get confused with similarly-named non-members. It's broadly good style but not essential.
LeatherArmour doesn't need an additional copy per instance, it just needs one of each for the whole class - so they should be const static members.
class LeatherJacket: public Armour {
static const Stats stats {0,0,0,5,0,0,0,0,0,0,0,0};
static const std::string name{"Leather Jacket"};
public:
LeatherJacket() : Armour(stats, name) {}
};
I made the LeatherJacket-specific stat values static const by writing static const in front of them.
The static means that every LeatherJacket has the same base stats, so you don't need a copy per instance, just one copy for the whole class. It's const because the base stats for leather jackets never change over time. You still have the base class member Armour::m_stats which can change as your individual leather jacket gets damaged, repaired, buffed or whatever.
Again, the LeatherJacket constructor was already passing (the equivalent of) these members to the base class constructor, but now they already exist (see the link above about static storage duration). The original instance variables didn't exist when you used them, because the derived (LeatherJacket) object and its data members aren't really constructed until after the base class subobject.
My IDE is Microsoft Visual Studio 2017.
This is primitive example code:
main.cpp
#include <iostream>
#include "Klasa_00.h"
using namespace std;
int main() {
int const Number_0 = 234;
float const Number_1 = 34.76;
double const Number_2 = 98.78;
cout << "Number_0 is:" << Number_0 << endl;
cout << "Number_1 is:" << Number_0 << endl;
cout << "Number_2 is:" << Number_0 << endl;
system("Pause");
return 0;
}
Klasa_0.cpp
#include "Klasa_00.h"
Klasa_00::Klasa_00()
{
}
Klasa_00::~Klasa_00()
{
}
Klasa_0.h file
#pragma once
class Klasa_00
{
public:
Klasa_00();
~Klasa_00();
};
I am new in C++ programing so I need a help about making code. For example, in Fortran programing language all variables with parameter attribute can be declared in separate module which can be easily used in main program.
What I want to learn here is possibility of using that principle of coding in C++ or something similar.
So, in my case a have a three variables which i want to move into class Klasa_00.
Is there way or ways for doing that?
As others have said, you might want to avoid using classes to store your constants in other files, and you might simply wish to store them in a header (possibly with a namespace, more on that later). Having said that, I do understand that you might want a constant that belongs to a class, so I'll cover that case as well later in the answer.
The simplest way is to declare and define the constant in a header on its own as such:
// YourHeader.h
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
[...]
const int aConstNumber = 1;
static const int anotherConstNumber = 2;
constexpr int aConstExprNumber = 3;
static constexpr int anotherConstExprNumber = 4;
[...]
#endif
// main.cpp
#include <iostream>
#include "YourHeader.h"
int main()
{
// You can simply access the variables by name as so:
std::cout << aConstNumber << "\n"; // 1
std::cout << anotherConstNumber << "\n"; // 2
std::cout << aConstExprNumber << "\n"; // 3
std::cout << anotherConstExprNumber << std::endl; // 4
}
These variables all behave the same logically, but they work in different ways. A variable declared with the const keyword is defined at runtime, and guaranties it won't change. A variable declared with the constexpr keyword, however, is defined at compile time.
So, while this means that if you had multiple classes with something like an ID (which shouldn't change, but should be unique), you'd prefer const over constexpr (since the latter wouldn't work in that context).
Let's talk about static as well. static means that there is a single shared instance of that variable across your classes. So if the Bar class has a static int ID value, all instances of Bar share the same ID value. Changing it once changes it for all instances. Though if it's a constant, you won't be able to change it.
In your case, if it's to define constants that are pre-defined and won't change, I'd strongly recommend using constexpr, since you can use those variables to do things you couldn't use a const variable for (like defining the size of an array).
Before you go ahead and do that, however, consider the following class.
class Foo
{
public:
const int a = 5; // Valid use of const.
constexpr int b = 7; // Invalid use of constexpr, won't even compile!
static constexpr int c = 10; // Valid use of constexpr.
int arrA[a]; // ERROR: 'a' is defined at runtime, so you can't use it to define a size.
int arrB[b]; // ERROR: You couldn't even define 'b', so this is not going to work...
int arrC[c]; // VALID: 'c' is known by the compiler, and is guaranteed to only ever be 10!
}
It is worth noting that if you wanted to access a or c (the only two valid variables declared and defined in your class), you'd have to use the following syntax, rather than just their names:
// "Foo" is their class' name, and represents their parent namespace.
std::cout << Foo::a << "\n"; // 5
std::cout << Foo::c << std::endl; // 10
As you can see, constexpr int b = 7; is invalid. Why though? Shouldn't it be seen by the compiler and work just fine? Well, no. You see, the issue is that maybe you'll never instantiate that class, right? const variables are fine, because they're defined at runtime, this means they don't have to exist, they just can't change once you've given them a value. constexpr on the other hand needs to be sure it'll exist, because it has to exist and be valid at compile time!
While declaring a constexpr variable is perfectly fine in a header file, it doesn't work unless you use the static keyword with it if you want to declare one in a class! Because the static keyword will let the compiler know that, regardless of how you instantiate this class, the variable's value will never change and it will be known at compile time thanks to constexpr!
I strongly recommend you read this post to understand just what static and constexpr do when combined.
If you have "constants" that are only constant once instantiated, go with const.
If you have constants that will never change and will always represent the same value (think of mathematical values like PI) go with constexpr.
If all instances of a class should share a constant value, I'd recommend against using static const, since it would be defined at runtime, but it will always have the same value, right? Just use static constexpr instead.
Finally, I mentioned namespaces at the start of this answer. Sometimes, you might want a group of associated constants that don't necessarily belong to a class. For instance, while PI is used in circles, it doesn't necessarily mean that I want to include the circle class' header every time I want PI. But I don't want to have a "raw" PI variable name in my project's namespace! That's just asking for trouble. Instead, consider surrounding your constants in a namespace block to emulate the syntax used to call a class' member!
// YourHeader.h
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
namespace MyConstants
{
constexpr int a = 1;
constexpr int b = 2;
}
#endif
// main.cpp
#include <iostream>
#include "YourHeader.h"
int main()
{
std::cout << MyConstants::a << "\n"; // 1
std::cout << MyConstants::b << "\n"; // 2
}
Note that we didn't use static with a namespace, we don't need to since we're not using a class or struct, we're simply wrapping them in the namespace to avoid naming conflicts. static would do something else here. See this post for more info on that.
Extra Note: While it is possible to declare a variable as a constexpr const, I wouldn't recommend it as it does the same as simply declaring it constexpr. Do note that constexpr when combined with pointers will turn the pointer into a constant pointer to a constant value! See this post for more details on that.
Why do you feel that you need a class for this? That doesn't seem appropriate. FORTRAN comparisons are also not likely to bear much fruit as C++ is a different language with different idioms and concepts.
To me, it seems like you should simply put those constants in a header file. Be sure to make them static const constexpr to avoid linker clashes.
// Constants.hpp
#ifndef MYLIB_CONSTANTS_HPP
#define MYLIB_CONSTANTS_HPP
#pragma once
static constexpr const int Number_0 = 234;
static constexpr const float Number_1 = 34.76;
static constexpr const double Number_2 = 98.78;
#endif
Now you just #include "Constants.hpp" in any translation unit that requires access to these values.
For the record, the old-school C approach to do the same thing would be to use #defines.
Don't forget to give these constants meaningful names.
I am wondering what the validity range is for a friend function.
In my case I want to grant access to private members. But what if in another program there is also a function FF()?
h-file:
#ifndef LIB_FRIEND_H
#define LIB_FRIEND_H
class Lib_Friend{
friend int FF(Lib_Friend *vFF);
private:
int TestFF();
int Test;
public:
Lib_Friend();
};
#endif // LIB_FRIEND_H
c-file:
#include "lib_friend.h"
int FF(Lib_Friend *vFF){
vFF->Test = 1;
return vFF->Test;
}
Lib_Friend::Lib_Friend(){
}
int Lib_Friend::TestFF(){
return FF(this);
}
Prog:
#include <iostream>
#include "lib_friend.h"
int FF(Lib_Friend *vFF){
vFF->Test = 1;
std::cout << "TEST A = " << vFF->Test << "\0";
// This works...
return vFF->Test;
}
int main(){
Lib_Friend mLib_Friend;
std::cout << "TEST B = " << mLib_Friend.Test << "\0";
// This causes error...
FF(&mLib_Friend);
return 0;
}
The question is:
Does a friend function grant access only by its name, or are there other parameters too? I hope, I have properly shown, what I mean and you can understand it.
(BTW: I've tried that above and it works. I really have access on a private member only because I have in another programm a function named FF (in this example).)
The other question naturally is: Is this avoidable for a friend function?
If a program defines its own version of FF different from the one in your library, it's violating the One Definition Rule because it has two different definitions for the function int FF(class_A*). Therefore, it is not a well-formed C++ program.
Normally, this should result in a linker error. Even if it does not, the program will not have any defined behaviour, so for all intents and purposes, it is buggy. And buggy programs can do anything.
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;
}
I declared a global function in a .cpp file void functionA(). I would like functionA() to be called exactly once before the start-up ( not inside main()). The thing I realize is if the function is int functionB(), I could call it using static int A = functionB(). But for return value of void, how could I do that?
Thanks
You put it into the constructor of a global object:
void functionA();
namespace {
struct global_initializer {
global_initializer() {functionA();}
} the_global_initializer;
}
Note that this has the common drawbacks of global initialization: While globals within the same translation unit are initialized in the order of their definition, the order of initialization of globals across translation units is undefined.
Also, linkers might choose to eliminate unreferenced objects (the_global_initializer), which would prevent functionA() from being called.
static int a = functionA(), 42;
There are few places where comma expressions are useful, but this may be one of them.
You could use a static struct, it's constructor will get called before main.
#include <iostream>
void functionA(void)
{
std::cout << "Hello, ";
}
static struct BeforeMain
{
BeforeMain(void)
{
// stuff in this constructor is executed before "main" function
functionA();
}
} g_beforeMain; // shouldn't get used though
int main(void)
{
std::cout << "world!" << std::endl;
return 0;
}
This will print Hello, world!, although I'm new to C++, so this may not be the best approach.
Solution 1: Make that void function to have a return type (say int) and return a dummy return value
If you can't do Solution 1,
Solution 2: Write a wrapper function as shown. Make sure to write code so that wrapper can be called only once (unless it is fine to do so multiple times)
Wrap it up! (and document extensively).
void fA(){}
int wrapper(){
// Have checks here to ensure it is not called more than once
fA();
return 0;
}
// Extensively document such as `'x' is a bogus dummy variable.`
static int x = wrapper();
int main(){
}