C++ RPG Error: data member initializer is not allowed - c++

this has already been posted several times, but none of the times have answered my case. Please help me with my 'error: data member initializer is not allowed' which appears under the equals signs. Here's the code with the problem in it.
//Player.cpp :Contains information about the player
#include <iostream>
#include <string>
#include "Main.cpp"
using namespace std;
void Player()
{
struct Player {
int Charma = 0;
unsigned int Hunger = 10;
unsigned int Energy = 50;
unsigned int Health = 100;
};
enum Race {
UNKNOWN,
DEAD,
HUMAN,
ORC,
GOBLIN,
ELF,
LIZARD,
CAT,
VAMPIRE,
WEREWOLF,
SNK
};
}

You are getting that error because you are initializing the variables when you are declaring a struct. This is not allowed. Instead, move the initialization into the constructor of the struct.
However that is not the only error in your code. You are defining the struct inside of the Player function (which should be the constructor). You need to switch those, so that you have the Player function inside of the Player struct. This way the struct will have a constructor where you can initialize the values. Another thing, don't #include .cpp files. It's a bad practice.
Your code should be something like this:
struct Player {
int Charma;
unsigned int Hunger;
unsigned int Energy;
unsigned int Health;
Player() : Charma(0), Hunger(10), Energy(50), Health(100)
{
// do other constructor stuff here
}
};

In another approach of idea, if you are planning on doing some mecanics inside Player, you may move the declaration inside a real class. You will then be able to scale your project a little more easily. Something like this:
Header
// #include "Item.h"
typedef enum RaceDef {
UNKNOWN,
DEAD,
HUMAN,
ORC,
GOBLIN,
ELF,
LIZARD,
CAT,
VAMPIRE,
WEREWOLF,
SNK
} PlayerRace;
class Player {
public:
Player(unsigned int Charma=0,
unsigned int Hunger=10,
unsigned int Energy=50,
unsigned int Health=100,
PlayerRace Race=HUMAN);
void attack(Player);
void slap(Player);
//void equipItem(Item);
void exercise(unsigned int duration);
void die();
void etc();
private:
unsigned int m_Charma;
unsigned int m_Hunger;
unsigned int m_Energy;
unsigned int m_Health;
unsigned PlayerRace m_Race;
Race m_Race;
};
CPP
Player::Player(unsigned int Charma,
unsigned int Hunger,
unsigned int Energy,
unsigned int Health,
PlayerRace Race):
m_Charma(Charma),
m_Hunger(Hunger),
m_Energy(Energy),
m_Health(Health),
m_Race(Race) {
//constructor code goes here
//e.g. if player starts with a random item :
// Item randomItem = ItemUtils.getRandomItem();
// equipItem(randomItem);
}
I hope this helps, and good luck :)

Related

How can I best decouple two classes, which one way dependencies

I am attempting to create a D&D combat encounter simulator using C++ and since it's D&D, all aspects of the simulation are going to depend heavily on the "Dice" Class and its methods.
I could instantiate a "Dice" object every time another class needs
to invoke its methods, however, that would leave everything heavily
coupled and make it very difficult to make changes or extensions later.
I don't have any practical knowledge about things such as Factories, dependency injections, and other such methods.
My question therefore in essence is:
What would be the best way to ensure that the "Dice" class remains as
decoupled as possible from all other classes?
While still enabling them to make use of the "Dice" objects, and its methods, when needed.
Dice.h
#ifndef dice_h_
#define dice_h_
#include <stdlib.h>
class Dice
{
private:
int maxValue;
public:
Dice(int maxValue);
~Dice();
int getMaxValue( void ){return maxValue;}
void setMaxValue(int newMaxValue){maxValue = newMaxValue;}
int rollDice();
int rollMultipleDice(int numberOfDiceRolls);
};
#endif
Dice.cpp
#ifndef dice_cpp_
#define dice_cpp_
#include "dice.h"
Dice::Dice(int maxValue){this->maxValue = maxValue;}
Dice::~Dice(){}
int Dice::rollDice()
{
return (rand() % maxValue) + 1;
}
int Dice::rollMultipleDice(int numberOfDiceRolls)
{
int i = numberOfDiceRolls, sum = 0;
while(i-- > 0)
{
sum += rollDice();
}
return sum;
}
#endif
Actor.h
#ifndef actor_h_
#define actor_h_
#include "dice.h"
class Actor
{
private:
unsigned int hp;
unsigned int ac; // Armor Class
unsigned int dmg;
public:
Actor(unsigned int hp, unsigned int ac, unsigned int dmg);
~Actor();
unsigned int getHP( void );
unsigned int getAC( void );
unsigned int getDmg( void );
void setHP( unsigned int newHP);
void setAC( unsigned int newAC);
void setDmg( unsigned int newDmg);
void attack(Actor* target);
bool isHit(Actor target);
};
#endif
Actor.cpp
#ifndef actor_cpp_
#define actor_cpp_
#include "actor.h"
Actor::Actor(unsigned int hp, unsigned int ac, unsigned int dmg)
{
this->hp = hp;
this->ac = ac;
this->dmg = dmg;
}
Actor::~Actor(){}
unsigned int Actor::getHP( void ){return hp;}
unsigned int Actor::getAC( void ){return ac;}
unsigned int Actor::getDmg( void ){return dmg;}
void Actor::setHP( unsigned int newHP ){this->hp = newHP;}
void Actor::setAC( unsigned int newAC ){this->ac = newAC;}
void Actor::setDmg( unsigned int newDmg ){this->dmg = newDmg;}
void Actor::attack(Actor* target)
{
Dice damageDice(8);
if (isHit(*target))
{
target->setHP(target->getHP() - damageDice.rollDice());
}
}
// helper function to attack function
// do not use elsewhere
bool Actor::isHit(Actor target)
{
Dice atkDice(20);
return atkDice.rollDice() >= target.getAC();
}
#endif
You talk about singletons and the like in the question so do you want ever class that needs to use the dice to use the same instance of the Dice class?
If so since the Dice class doesn't have any states to hold onto it can be a static class. I would then remove the MaxValue and add an input to the RollDice and RollMutiDice to take a Max Value (which I am guessing is suppose to the "sides" of the dice). So a call to Dice::RollDice(3) is to roll a 3 sided dice or Dice::RollMutiDice(6,3) would roll a 6 sided dice 3 times.
Also make sure you send the rand() class. I think is it srand(int). Usually you pass it time so it is fairly random

Linker errors for multiple defined symbols when defining a static class field

I have a class in which I defined a static integer that I hope will keep track of how many objects of that class get instantiated.
class mob {
public:
mob::mob();
mob::mob(std::string, std::string, int, int, int, int, int);
//some other stuff
private:
//some other stuff
static int mob_count;
};
int mob::mob_count = 0;
then I define the following constructor:
mob::mob(string name, string wName, int lowR, int highR, int health, int defense, int reward)
{
nName = name;
nWeapon.wName = wName;
nWeapon.wRange.Rlow = lowR;
nWeapon.wRange.RHigh = highR;
nHealth = health;
nArmor = defense;
xpReward = reward;
++mob_count;
}
So what am I missing? I think i'm doing everything my text book tells me.
I get this when compiling
I hope someone can point my mistakes, thank you very much.
EDIT: #linuxuser27 helped me solve my problem, so basically i just moved the
int mob::mob_count = 0;
from the class definition, to the class implementation, like so:
mob.h:
class mob {
public:
mob::mob();
mob::mob(std::string, std::string, int, int, int, int, int);
//some other stuff
private:
//some other stuff
static int mob_count;
};
mob.cpp
int mob::mob_count = 0;
constructor stays the same.
I assume you are declaring your class in a header file (e.g. mob.hpp) and then including the header file in multiple compilation units (i.e. cpp files). Basically this:
main.cpp
#include "mob.hpp"
...
mob.cpp
#include "mob.hpp"
...
Remove int mob::mob_count = 0; from the header file and put it in the mob.cpp.

cant get subclasses to work properly

I making a simple text based fighting game and i am having a lot of trouble getting my subclasses to work.
of the many errors im getting, the most persistant is "our of line definition "Dwarf" does not match any declaration of "Dwarf"
#include <iostream>
using namespace std;
class Poke{
protected:
string race;
int health, damage, shield;
public:
Poke();
Poke(int health, int damage, int shield);
virtual int attack(Poke*);
virtual int defend(Poke*);
virtual int getHealth();
};
this is one sublcasses of the different races, there are 2 more with different levels of attack/health/shield
// Dwarf: High health, Low attack, High defense
class Dwarf: public Poke {
public:
string race = "Dwarf";
int attack(Poke*);
int defend(Poke*);
int getHealth();
};
.cpp V
//DWARF
Dwarf::Dwarf(int health, int damage, int shield) {
this->health = 100;
this->damage = 50;
this->shield = 75;
};
//attack
int Poke:: attack(Poke*){
if (shield > (damage + rand() % 75)){
cout << "Direct Hit! you did" << (health - damage) << "points of damage";
}
else {std::cout << "MISS!"<<;
}
return 0;
};
int Poke:: attack(Poke*){
Enemy this->damage ;
};
i am using a player class for the person playing the game that will use "Poke"
class Player{
int wins, defeats, currentHealth;
string name;
Poke race;
bool subscribed;
public:
Player(int wins, int defeats, int currentHealth);
int addWins();
int addDefeats();
int getWins();
int getDefeats();
int getHealth();
};
.cpp V
//getHealth
int Player::getHealth(){
return this->currentHealth;
};
and and "enemy" class for the computer opponent:
class Enemy{
int eHealth;
Poke eRace;
public:
Enemy (int eHealth, Poke eRace);
int getEHealth;
};
.cpp V
int Enemy:: getEHealth(){
return this->eHealth;
};
any help would be much appreciated!!
Constructors are not inherited. You will have to declare a Dwarf constructor that matches your definition.
I think you'll also have trouble with this:
string race = "Dwarf";
You can't initialize class members that way. It will have to be initialized in a constructor.
Edit:
You don't seem to understand what I mean by a declaration. Change your Dwarf class declaration to look something like this:
// Dwarf: High health, Low attack, High defense
class Dwarf: public Poke {
public:
string race;
Dwarf(int health, int damage, int shield); // <-- constructor declaration
int attack(Poke*);
int defend(Poke*);
int getHealth();
};
Edit 2:
Your Dwarf constructor should also call the Poke constructor, like so:
Dwarf::Dwarf(int health, int damage, int shield) :
Poke(health, damage, shield),
race("Dwarf")
{
// Nothing needed here.
};

Type value mismatch error with vectors

I get the following error message when I try to run my program:
main.cpp|44|error: type/value mismatch at argument 1 in template
parameter list for 'template<class _Tp, class _Alloc> class
std::vector' main.cpp|44|error: expected a type, got '(render)3u'
main.cpp|44|error: template argument 2 is invalid main.cpp|44|error:
invalid type in declaration before ';' token
=== Build finished: 4 errors, 0 warnings (0 minutes, 0 seconds) ===
And here is my code for main leading up to the error causing line:
#include<stdlib.h>
#include<windows.h>
#include<GL/glut.h>
#include<GL/freeglut.h>
#include<iostream>
#include <vector>
#include "include/Block.h"
#include <string>
#include <sstream>
#include "include/TextBlock.h"
#include "include/Enemy.h"
string text;
stringstream ss;
enum render {Normal,SelectRangeText,SelectSText,Enemy,EnemyTypeSelection};
enum render state;
enum type { Foreground, Background, Midground };
enum type selected;
enum types { Blocks, Enemies, Text };
enum types special;
string names[4] = { "grass" , "smallGrassBlock" , "dirt" , "sand" };
void createEnemy(int,int);
void addEnemyWaypoint(int,int);
void addToList(vector<Block> &list,int x,int y);
void placeText(int x,int y);
void initTextures();
GLint GetTexture(string file);
void IdleFunction();
void removeBlock(int x,int y);
int xOffset,yOffset,multiuse = 0;
using namespace std;
string to_string(int number);
void placeBlock(int x,int y);
void drawBitmapText(char *string, float x, float y, float z);
void reshape(int w, int h);
void render(void);
void keyboard(unsigned char c,int x,int y);
void mouse(int button,int state, int x, int y);
void arrows(int key, int x, int y );
std::vector <Block> backBlockList;
std::vector <TextBlock> textBlockList;
std::vector <Block> midBlockList;
std::vector <Block> foreBlockList;
std::vector <Enemy> enemyList;//error occurs here
GLuint textures[1];
unsigned int screenXSize=800;
unsigned int screenYSize=800;
unsigned int selectedBlockType = 1;
int main(int argc, char ** argv)
{
The header for enemy:
#ifndef ENEMY_H
#define ENEMY_H
#include<GL/freeglut.h>
#include <vector>
class Enemy
{
public:
Enemy(int Type );
virtual ~Enemy();
void render(int,int,GLuint);
void addWaypoint(int,int);
protected:
private:
int type;
std::vector <int> X, Y;
int xsize,ysize;
};
#endif // ENEMY_H
And the constructor for enemy:
Enemy::Enemy(int Type)
{
xsize=30;
ysize=30;
type=Type;
}
However it will run corrrectly if I substitute the type of my vector to an int.
When the following line is commented out: std::vector enemyList; it compiles, however if it's there it doesn't
when declaring an Enemy like this
Enemy e(5);
it runs correctly
Updates:
If i change the enemy header, and cpp to something like the following:
CPP:
#include "../include/Enemy.h"
Enemy::Enemy( )
{
}
Enemy::~Enemy()
{
//dtor
}
Header
#ifndef ENEMY_H
#define ENEMY_H
class Enemy
{
public:
Enemy( );
~Enemy();
protected:
private:
};
#endif // ENEMY_H
It still crashes with the same error, this means it must be something in main
FIX:
For some reason when I declare it in the line above my enums it works, however if below it doesn't, I have no idea why. If someone could explain this please go ahead.
For some functions, std::vector<T> requires that T be default-constructible. Your Enemy class cannot be default-constructed, therefore the compiler issues an error. Either define a default constructor for Enemy, do not call vector functions that require default constructibility, or change the vector to be of a different type.
Given the virtual use in Enemy, and that std::vector<Enemy> could never accept a derived class, plus your use of disgusting global variables, C arrays and otherwise terrible code, I am going to posit that you have no idea what is going on.
A std::vector<Enemy> can only ever hold an Enemy. It cannot hold a derived class of Enemy or anything else. It can only hold Enemy. If you wish to have a vector of things that might be various derived classes, you must use a pointer of some degree of ownership. This means you must solve the problem of who owns the objects being pointed to, and further that you must understand the concept of ownership and what smart pointers are available. This is essential knowledge for C++ and you won't get far without it.
To have a vector of some value type, the type must have an available no-argument constructor, which yours doesn't (ie. that's what the error message is telling you). However, since I doubt you want to copy around Enemys, you should store them by pointer,ie.
vector<Enemy*> enemies;
for (int i = 0; i < NUM_ENEMIES; ++i)
enemies.push_back(new Enemy(type));
EDIT I just noticed you have the following declaration
class Enemy...
but you also declare an enum value
enum render {... ,Enemy, ....
I just compiled the following code and got a suspiciously similar error:
#inlcude <vector>
class A {};
enum type {A, B, C};
std::vector<A> As;
int main(int argc, char** argv)
{
return 0;
}
So there's your problem. When it comes time to resolve the template, the compiler sees an enum value (which can be a template parameter, just like any other integral type), and assumes that's the one you meant. However, since no vector template matches (they all have a class as the first template parameter), it doesn't compile. Hence, your error.

Access reading error when using class member variable

I have a class with private member variables declared in a header file. In my constructor, I pass in some filenames and create other objects using those names. This works fine. When I try to add another member variable, however, and initialize it in the constructor, I get an access reading violation. I sent the code to someone else and it works fine on his computer. Any idea what could be wrong?
Here is the offending code:
The .h file:
class QUERYMANAGER {
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
public:
QUERYMANAGER();
QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
~QUERYMANAGER();
This is the .cpp file:
#include "querymanagernew.h"
#include "snippet.h"
using namespace std;
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname){
cache = new INDEXCACHE(indexfname, btfname);
table = new URLTABLE(urltablefname);
snip = new SNIPPET(snippetfname, snippetbtfname);
//this is where the error occurs
qsize = 0;
}
I am totally at a loss as to what is causing this - any ideas?
Thanks, bsg
Suggestion, factor out the arrays:
class QUERYMANAGER
{
// Snip
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
// Snip
};
Looks like you should have another structure:
struct Info
{
int* iquery;
int* metapointers;
int blockpointers;
int docpositions;
int numberdocs;
int frequencies;
int docarrays[256];
};
And the QueryManager now looks like:
class QueryManager
{
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int qsize;
Info details[MAX_QUERY_LENGTH];
};
This may help encapsulate themes a little better.
Your dependencies are probably not right, and the necessary files aren't getting rebuilt. Try a "clean" rebuild.
As a note to style, use initializer lists.
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
char *snippetfname, char *snippetbtfname) :
cache(new INDEXCACHE(indexfname, btfname)),
table(new URLTABLE(urltablefname)),
snip(new SNIPPET(snippetfname, snippetbtfname)),
qsize(0)
{
}
and you may not need to make those items pointers:
class QUERYMANAGER {
INDEXCACHE cache;
URLTABLE table;
SNIPPET snip;
...
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
char *snippetfname, char *snippetbtfname) :
cache(indexfname, btfname),
table(urltablefname),
snip(snippetfname, snippetbtfname),
qsize(0)
{
}
Have you built clean? Since accessing the last member variable blows up, but assigning to earlier ones works OK, either you're not constructing/allocating the instance right when you do use it, or you have object files that refer to older versions of the header that didn't have qsize in the object yet, and thus aren't allocating enough space. Or something along those lines.
As expected, this runs just fine on my machine:
#include <cstdlib>
struct INDEXCACHE {};
struct URLTABLE {};
struct SNIPPET {};
const std::size_t MAX_QUERY_LENGTH = 256;
class QUERYMANAGER {
INDEXCACHE *cache;
URLTABLE *table;
SNIPPET *snip;
int* iquery[MAX_QUERY_LENGTH];
int* metapointers[MAX_QUERY_LENGTH];
int blockpointers[MAX_QUERY_LENGTH];
int docpositions[MAX_QUERY_LENGTH];
int numberdocs[MAX_QUERY_LENGTH];
int frequencies[MAX_QUERY_LENGTH];
int docarrays[MAX_QUERY_LENGTH][256];
int qsize;
public:
QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
};
QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname)
: cache(new INDEXCACHE(/*indexfname, btfname*/))
, table(new URLTABLE(/*urltablefname*/))
, snip(new SNIPPET(/*snippetfname, snippetbtfname*/))
, qsize(0)
{
}
int main()
{
QUERYMANAGER foo("blargl", "frxnl", "wrgxl", "brlgl", "srgl");
return 0;
}
So the error must be in the code you're not showing.
BTW, all upper-case names are boo except for macros. They're making your code harder to read and confuse everyone used to a more common coding style.