Having trouble initiating an array in a structure - c++
class CRA_Account {
int tax[4];
double refund[4];
int SIN;
public:
CRA_Account();
}
CRA_Account::CRA_Account() {
SIN = 0;
tax[4] = { 0 };
refund[4] = { 0 };
}
When I create a object in main it'll set the SIN to 0 but won't do the same to the arrays. Can someone help why?
tax[4] = { 0 }; is wrong at many levels..
One way to initlizie your class:
CRA_Account::CRA_Account():
tax{0,0,0,0},
refund{0,0,0,0},
SIN{0}{
}
Online
Try to have a look at std::array
Related
Use initializer list to initialize new vector
So I have this big map of vectors, you can see I use an initializer list to initialize the vectors. However, although this works it really doesn't seem like it should, if you create an empty vector and try to use the = operator and then assign it to an initializer list you get the error "too many values in initializer list" but for some reason when you try to do the same with a map of vectors it just... works. However the issue is of course these are allocated on the stack and quickly causes a stack overflow so the goal would be to find a way to use initializer list (or something of similar brevity) to initialize these vectors on the heap. Example code causing stack over flow below #include <map> #include <vector> #include <string> struct IVector2 { int x; int y; }; struct animation_frame_t { IVector2 position; IVector2 size; }; std::map<std::string, std::vector<animation_frame_t>> animations; void initAnimations() { animations["boss_andromeda_attack_"] = { {{303,101},{100,100}}, {{606,101},{100,100}}, {{606,0},{100,100}}, {{505,909},{100,100}}, {{505,808},{100,100}}, {{505,707},{100,100}}, {{505,606},{100,100}}, {{505,505},{100,100}}, {{505,404},{100,100}}, {{505,303},{100,100}}, {{505,202},{100,100}}, {{505,101},{100,100}}, {{505,0},{100,100}}, {{404,909},{100,100}}, {{404,808},{100,100}}, {{404,707},{100,100}}, {{404,606},{100,100}}, {{404,505},{100,100}}, {{404,404},{100,100}}, {{404,303},{100,100}}, {{404,202},{100,100}}, {{404,101},{100,100}}, {{404,0},{100,100}} }; animations["boss_andromeda_breathing_"] = { {{303,909},{100,100}}, {{303,808},{100,100}}, {{303,707},{100,100}}, {{303,606},{100,100}}, {{303,505},{100,100}}, {{303,505},{100,100}}, {{303,404},{100,100}}, {{303,303},{100,100}}, {{303,202},{100,100}}, {{606,202},{100,100}} }; animations["boss_andromeda_death_"] = { {{303,0},{100,100}}, {{202,909},{100,100}}, {{202,808},{100,100}}, {{202,707},{100,100}}, {{202,606},{100,100}}, {{202,505},{100,100}}, {{202,404},{100,100}}, {{202,303},{100,100}}, {{202,202},{100,100}}, {{202,101},{100,100}}, {{202,0},{100,100}}, {{101,909},{100,100}}, {{101,808},{100,100}} }; animations["boss_andromeda_hit_"] = { {{303,0},{100,100}}, {{202,909},{100,100}}, {{202,808},{100,100}} }; animations["boss_andromeda_idle_"] = { {{101,707},{100,100}}, {{101,606},{100,100}}, {{101,505},{100,100}}, {{101,404},{100,100}}, {{101,303},{100,100}}, {{101,202},{100,100}}, {{101,101},{100,100}}, {{101,0},{100,100}}, {{0,909},{100,100}}, {{0,808},{100,100}} }; animations["boss_andromeda_run_"] = { {{0,707},{100,100}}, {{0,606},{100,100}}, {{0,505},{100,100}}, {{0,404},{100,100}}, {{0,303},{100,100}}, {{0,202},{100,100}}, {{0,101},{100,100}}, {{0,0},{100,100}} }; animations["boss_antiswarm_attack_"] = { {{393,1310},{130,130}}, {{917,655},{130,130}}, {{917,524},{130,130}}, {{917,393},{130,130}}, {{917,262},{130,130}}, {{917,131},{130,130}}, {{917,0},{130,130}}, {{786,1834},{130,130}}, {{786,1703},{130,130}}, {{786,1572},{130,130}}, {{786,1441},{130,130}}, {{786,1310},{130,130}}, {{786,1179},{130,130}}, {{786,1048},{130,130}}, {{786,917},{130,130}}, {{786,786},{130,130}}, {{786,655},{130,130}}, {{786,524},{130,130}}, {{786,393},{130,130}}, {{786,262},{130,130}}, {{786,131},{130,130}}, {{786,0},{130,130}}, {{655,1834},{130,130}}, {{655,1703},{130,130}}, {{655,1572},{130,130}}, {{655,1441},{130,130}}, {{655,1310},{130,130}}, {{655,1179},{130,130}}, {{655,1048},{130,130}}, {{655,917},{130,130}}, {{655,786},{130,130}}, {{655,655},{130,130}}, {{655,524},{130,130}}, {{655,393},{130,130}}, {{655,262},{130,130}}, {{655,131},{130,130}}, {{655,0},{130,130}}, {{524,1834},{130,130}}, {{524,1703},{130,130}}, {{524,1572},{130,130}}, {{524,1441},{130,130}}, {{524,1310},{130,130}}, {{524,1179},{130,130}} }; animations["boss_antiswarm_breathing_"] = { {{524,1048},{130,130}}, {{524,917},{130,130}}, {{524,786},{130,130}}, {{524,655},{130,130}}, {{524,524},{130,130}}, {{524,393},{130,130}}, {{524,262},{130,130}}, {{524,131},{130,130}}, {{524,0},{130,130}}, {{393,1834},{130,130}}, {{393,1703},{130,130}}, {{393,1572},{130,130}}, {{393,1441},{130,130}}, {{917,786},{130,130}} }; animations["boss_antiswarm_death_"] = { {{393,1179},{130,130}}, {{393,1048},{130,130}}, {{393,917},{130,130}}, {{393,786},{130,130}}, {{393,655},{130,130}}, {{393,524},{130,130}}, {{393,393},{130,130}}, {{393,262},{130,130}}, {{393,131},{130,130}}, {{393,0},{130,130}}, {{262,1834},{130,130}}, {{262,1703},{130,130}}, {{262,1572},{130,130}}, {{262,1441},{130,130}}, {{262,1310},{130,130}}, {{262,1179},{130,130}}, {{262,1048},{130,130}}, {{262,917},{130,130}}, {{262,786},{130,130}}, {{262,655},{130,130}}, {{262,524},{130,130}}, {{262,393},{130,130}}, {{262,262},{130,130}}, {{262,131},{130,130}}, {{262,0},{130,130}}, {{131,1834},{130,130}}, {{131,1703},{130,130}} }; animations["boss_antiswarm_hit_"] = { {{131,1572},{130,130}}, {{131,1441},{130,130}}, {{131,1310},{130,130}} }; //40k more lines of code
cppcheck complains about unreadVariable when used in template
Can someone explain to me why the following code for a unit test gives the error unreadVariable for n and k in cppcheck? Combinations is a template class that calculates all combinations of n choose k but this should not matter here. TEST(Combinations, ChooseOne) { const UINT8 n = 3; const UINT8 k = 1; Combinations<n, k> comb; comb.calc(); std::vector< std::vector<UINT8> > _vui8Expect = { { 2 }, { 1 }, { 0 } }; EXPECT_THAT(comb.result, ::testing::ContainerEq(_vui8Expect)); } I can change the code to the following and not get a cppcheck error anymore. But I do not like this, because it make the code less verbose. n, k are well defined quantities in statistics and they make it more clear in the call what is going on. TEST(Combinations, ChooseOne) { Combinations<3, 1> comb; comb.calc(); std::vector< std::vector<UINT8> > _vui8Expect = { { 2 }, { 1 }, { 0 } }; EXPECT_THAT(comb.result, ::testing::ContainerEq(_vui8Expect)); }
This is a known issue: http://trac.cppcheck.net/ticket/7542 So unless it will be fixed, the cppcheck will report this false positive.
I tried to put this in a comment, but here is a thought. As far as I remember Google Tests is using TEST clause in a following manner: TEST(test_case_name, test_name) { ... test body ... } I haven't personally encountered something similar, but in your case you have the very same name for the test case name, and the actual class you test. To me it seems like some sort of name collision. Have you tried renaming TEST(Combinations, ChooseOne) { const UINT8 n = 3; const UINT8 k = 1; Combinations<n, k> comb; comb.calc(); std::vector< std::vector<UINT8> > _vui8Expect = { { 2 }, { 1 }, { 0 } }; EXPECT_THAT(comb.result, ::testing::ContainerEq(_vui8Expect)); } to a: TEST(CombinationsTest, ChooseOne) { const UINT8 n = 3; const UINT8 k = 1; Combinations<n, k> comb; comb.calc(); std::vector< std::vector<UINT8> > _vui8Expect = { { 2 }, { 1 }, { 0 } }; EXPECT_THAT(comb.result, ::testing::ContainerEq(_vui8Expect)); }
What to use for initial values? Struct, enum or class, #defines c++
It's kind of a shame to ask this question and probably will fit better in the Code Review site, so sorry in advance. My question is the following (can be extensible for other languages since is more OOP): I have a class: class Unit { public: Unit(Type); Type type; private: int weaponry; int shielding; int hull; int rapid_fire; } with an enum to differenciate between different types of units. enum Type{ Cruiser, Missile }; All the units will be initialize with a default value (plus a factor, depending in external variable). Unit::Unit(Type type) { this->type = type; int weaponry, shielding, hull,rapid_fire; switch(type){ case Cruiser: weaponry = 2700; shielding = 50; hull = 400; rapid_fire = 5; break; case Missile: weaponry = 200; shielding = 20; hull = 80; rapid_fire = 0; break; } this->weaponry = weaponry ; //+ whatever this->shielding = shielding; //+ whatever this->hull = hull; //+ whatever this->rapid_fire = rapid_fire; } I will also have a method that will change the values of the object, such as the typical setHull(int newHull){this->hull = newHull} In one of these methods, i want to revert one of the private variables to its default value, in the example case, if is Cruiser this->shielding = 50, if its a missile = 20. My questions are the following. Am i doing something wrong? I have several options to keep the defaults values, either with (the one I would "noobly" will choose) #define initial_cruiser_shielding 50 either with enum: enum shielding_init{ cruiser_i = 50, missile_i = 20 }; to have default instances of the basic objects, and then just copy them and create as many new objects I need. Thanks in advance!
My recommendation will be to create private static member functions that can return default values. class Unit { public: Unit(Type); Type type; int set_default_weaponry() { weaponry = get_default_weaponry(); } int set_default_shielding() { shielding = get_default_shielding(); } int set_default_hull() { hull = get_default_hull(); } int set_default_rapid_fire() { rapid_fire = get_default_rapid_fire(); } private: int weaponry; int shielding; int hull; int rapid_fire; static int get_default_weaponry(); static int get_default_shielding(); static int get_default_hull(); static int get_default_rapid_fire(); }
c++ set value of a class with a pointer of another class
I am trying to implement the game Deal or no deal, i have two classes, Box & Player. in box is stored the vector game_box and in Player I want to store the box and the money that the player has to keep till the end of the game. I have tried to implement it in this way. it runs correctly, without no errors, but when i try to verify if the values were stored into the setter, it just give me that the setter is empty. I really dont understand why! does anybody knows why? class Box { vector<Box> game_box; float pound_contained; int box_number; public: Box(int box_number, float pound_contained); Box(); int getbox_number(); float getpound_contained(); }; class Player :public Box { int player_box; float player_money; public: Player(); ~Player(); float getplayer_money(); int getplayer_box(); void setplayer_money(float); void setplayer_box(int); }; void Player::setplayer_money(float) { player_money = player_money; } void Player::setplayer_box(int) { player_box = player_box; } float Player::getplayer_money() { return this->player_money; } int Player::getplayer_box() { return this->player_box; } int main() { vector<Box> game_box; srand(time(0)); int n; Player money; Box oper; float myArray [22][2] = { { 0.01, 0 }, { 0.10, 0 }, { 0.50, 0 }, { 1, 0 }, { 5, 0 }, { 10, 0 }, { 50, 0 }, { 100, 0 }, { 250, 0 }, { 500, 0 }, { 750, 0 }, { 1000, 0 }, { 3000, 0 }, { 5000, 0 }, { 10000, 0 }, { 15000, 0 }, { 20000, 0 }, { 35000, 0 }, { 50000, 0 }, { 75000, 0 }, { 100000, 0 }, { 250000, 0 } }; //random assignation of pound value to the 22 boxes for (int e = 1; e <22; e++) { int pos; bool op = true; while (op) { pos = rand() % 22 + 1; if (myArray[pos][1] == 0) { myArray[pos][1] = 1; op = false; } } Box b(e, myArray[pos][0]); //creating the class game game_box.push_back(b); //function of the vector to insert a data in it } // random assignment of a box to the player int i = rand() % 22 + 1; Box* boxes = &game_box[i]; cout << "Your box is going to be the box number: "<< boxes->getbox_number()<<endl; ////////////////////////////////////////////////////////////////////setter not working money.setplayer_money(boxes->getpound_contained()); money.setplayer_box(oper.getbox_number()); cout << money.getplayer_box() << " " << money.getplayer_money() << endl << endl; game_box.erase(game_box.begin()+i); return 0; }
There are not "setters" or "getters" in C++ that are distinct from other method calls. So you write them just as you would any other method. To elaborate on the problem pointed out by #maniek, you wrote: void Player::setplayer_money(float) { player_money = player_money; } C and C++ have the ability to specify method and function arguments without names--just types. This might seem a little strange as there is no way to access that parameter (at least not a way that is guaranteed to work in all compilers or optimization levels, you can possibly do it by messing with the stack). So what you are doing here is just setting the member player_money to itself. (Note: If you are wondering why it allows you to specify a method argument without a name, it has a few uses...one is that not naming it suppresses warning messages that you aren't using that parameter. So it is a way of marking something as not being used at the current time, yet still required--perhaps for legacy reasons or perhaps because you might use it in the future.) You can give a new name to the parameter that doesn't overlap with the name of the member variable: void Player::setplayer_money(float new_player_money) { player_money = new_player_money; } That's one way of avoiding ambiguity. Because in terms of what value is in scope, the parameter will win over the member variable. So this would be another do-nothing operation, that would assign the parameter value to itself: void Player::setplayer_money(float player_money) { player_money = player_money; } (Note: Since player_money is passed by value and not by reference, that wouldn't change the parameter's value at the calling site. In particular, how could it change the value, if you passed in a constant like 10.20.) What #maniek suggested is that a way to disambiguate in that case is to use this->player_money when you mean the member variable and player_money when you mean the argument to the method. Another thing some people do is name their member variables specially--like start them with m_ as in m_player_money: void Player::setplayer_money(float player_money) { m_player_money = player_money; } (Note: You can also just use an underscore prefix with no m as long as the next character is lowercase, but some people consider that too dangerous as underscores followed by capital letters are reserved for compiler internal usages.) As a final thought--if the class name is Player then it's already implicit whose money you are setting (the player's) so you could just call it set_money. Furthermore, I'm not a fan of underscores in names (more common in C than C++) so I'd probably call it setMoney.
How about: void Player::setplayer_money(float player_money) { this->player_money = player_money; } ?
Inherited variables are not reading correctly when using bitwise comparisons
I have a few classes set up for a game, with XMapObject as the base, and XEntity, XEnviron, and XItem inheriting it. MapObjects have a number of flags, one of them being MAPOBJECT_SOLID. My problem is that XEntity is the only class that correctly detects MAPOBJECT_SOLID. Both Items are Environs are always considered solid by the game, regardless of the flag's state. What is important is that Environs and Item should almost never be solid. Each class has a very basic preliminary constructor, just initializing all varibles to zero or NULL. During the CreateX() phase, Objects are linked into the map, set into a linked linked list. Both XItem and XEnviron are a tad sloppy. They are both new, and in the middle or my debugging attempts. Here are the relevent code samples: XMapObject: #define MAPOBJECT_ACTIVE 1 #define MAPOBJECT_RENDER 2 #define MAPOBJECT_SOLID 4 class XMapObject : public XObject { public: Uint8 MapObjectType,Location[2],MapObjectFlags; XMapObject *NextMapObject,*PrevMapObject; XMapObject(); void CreateMapObject(Uint8 MapObjectType); void SpawnMapObject(Uint8 MapObjectLocation[2]); void RemoveMapObject(); void DeleteMapObject(); void MapObjectSetLocation(Uint8 Y,Uint8 X); void MapObjectMapLink(); void MapObjectMapUnlink(); }; XMapObject::XMapObject() { MapObjectType = 0; Location[0] = 0; Location[1] = 1; NextMapObject = NULL; PrevMapObject = NULL; } void XMapObject::CreateMapObject(Uint8 Type) { MapObjectType = Type; } void XMapObject::SpawnMapObject(Uint8 MapObjectLocation[2]) { if(!(MapObjectFlags & MAPOBJECT_ACTIVE)) { MapObjectFlags += MAPOBJECT_ACTIVE; } Location[0] = MapObjectLocation[0]; Location[1] = MapObjectLocation[1]; MapObjectMapLink(); } XEntity: XEntity *StartEntity = NULL,*EndEntity = NULL; class XEntity : public XMapObject { public: Uint8 Health,EntityFlags; float Speed,Time; XEntity *NextEntity,*PrevEntity; XItem *IventoryList; XEntity(); void CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2]); void DeleteEntity(); void EntityLink(); void EntityUnlink(); Uint8 MoveEntity(Uint8 YOffset,Uint8 XOffset); }; XEntity::XEntity() { Health = 0; Speed = 0; Time = 1.0; EntityFlags = 0; NextEntity = NULL; PrevEntity = NULL; IventoryList = NULL; } void XEntity::CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2]) { CreateMapObject(EntityType); SpawnMapObject(EntityLocation); if(!(MapObjectFlags & MAPOBJECT_SOLID) { MapObjectFlags += MAPOBJECT_SOLID; } EntityFlags = ENTITY_CLIPPING; Time = 1.0; Speed = 1.0; EntityLink(); } void XEntity::EntityLink() { if(StartEntity == NULL) { StartEntity = this; PrevEntity = NULL; NextEntity = NULL; } else { EndEntity->NextEntity = this; } EndEntity = this; } XEnviron: class XEnviron : public XMapObject { public: Uint8 Effect,TimeOut; void CreateEnviron(Uint8 Type,Uint8 Y,Uint8 X,Uint8 TimeOut); }; void XEnviron::CreateEnviron(Uint8 EnvironType,Uint8 Y,Uint8 X,Uint8 TimeOut) { CreateMapObject(EnvironType); Location[0] = Y; Location[1] = X; SpawnMapObject(Location); XTile *Tile = GetTile(Y,X); Tile->Environ = this; MapObjectFlags = MAPOBJECT_ACTIVE + MAPOBJECT_SOLID; printf("%i\n",MapObjectFlags); } XItem: class XItem : public XMapObject { public: void CreateItem(Uint8 Type,Uint8 Y,Uint8 X); }; void XItem::CreateItem(Uint8 Type,Uint8 Y,Uint8 X) { CreateMapObject(Type); Location[0] = Y; Location[1] = X; SpawnMapObject(Location); } And lastly, the entity move code. Only entities are capable of moving themselves. Uint8 XEntity::MoveEntity(Uint8 YOffset,Uint8 XOffset) { Uint8 NewY = Location[0] + YOffset, NewX = Location[1] + XOffset; if((NewY >= 0 && NewY < MAPY) && (NewX >= 0 && NewX < MAPX)) { XTile *Tile = GetTile(NewY,NewX); if(Tile->MapList != NULL) { XMapObject *MapObject = Tile->MapList; while(MapObject != NULL) { if(MapObject->MapObjectFlags & MAPOBJECT_SOLID) { printf("solid\n"); return 0; } MapObject = MapObject->NextMapObject; } } if(Tile->Flags & TILE_SOLID && EntityFlags & ENTITY_CLIPPING) { return 0; } this->MapObjectSetLocation(NewY,NewX); return 1; } return 0; } What is wierd, is that the bitwise operator always returns true when the MapObject is an Environ or an Item, but it works correctly for Entities. For debug I am using the printf "Solid", and also a printf containing the value of the flag for both Environs and Items. Any help is greatly appreciated, as this is a major bug for the small game I am working on. I am also very new at Object Oriented programming, anything tips, suggestions and/or criticism are also welcome.
Your problem appears to be that you never initialize MapObjectFlags in any classes other than XEnviron so, as a basic type, it will have an unspecified value in XItem, XEntity and other XMapObject derived objects. I suggest that, as a member of XMapObject you explicitly initialize it to a known value. As a rule, it is generally a good idea to ensure that all members of basic type are explicitly initialized in the initializer list of every constructor that you define. e.g. XMapObject() : MapObjectFlags(0) , // ... other initializers { // Other initializations }
You can't (legally) be calling XEntity::MoveEntity on a MapObject or Environ because they don't have such a method. If you're using static_cast to change your object pointer into an XEntity so you can call MoveEntity on it, then you really have no guarantees about how the bit operation will work. In some implementations, things may appear to work in MoveEntity, but what's actually happening is it's interpreting the other object's memory as an XEntity. When it tries to access the offset where it believes MapObjectFlags exists, it's not actually there and always has that bit set to 1.
I figured out the problem earlier today - It didn't have any relation to OO programming, inheritance, or bitwise; it was a simple scope error. The problem was in the fact that during my quick test to get an Environ in game, I declared the new variable inside of the control switch sequence, so the next time any control was used, the Environ would act in unpredictable ways. switch(Event.key.keysym.sym) { ... case SDLK_c: { XEnviron Environ; Environ.InitEnviron(...); } ... }