main:
#include <iostream>
#include "common.h"
#include "squares.h"
#include "board.h"
using namespace std;
int Board::board_length=8;
int main()
{
Board *tabla=new Board();
tabla->printBoard();
}
board.h :
#ifndef BOARD_H
#define BOARD_H
#include "squares.h"
class Board
{
static int board_length;
Square boardSquares[board_length][board_length];
public:
Board();
void printBoard();
};
error line 8 in board.h
C:\c++ projects\CHESS-P3\board.h|8|error: array bound is not an integer constant before ']' token|
As the error message indicates, board_length is not a constant value. To fix that, change the line
static int board_length;
in board.h to
static const int board_length = 8;
and remove the line
int Board::board_length=8;
from your main file. This should compile, but I cannot tell for sure, since you did not provide a minimal, reproducible example.
Bonus: To avoid a memory leak you should also change
Board *tabla=new Board();
tabla->printBoard();
in main just to
Board tabla;
tabla.printBoard();
Since you do not seem to be passing the Board instance around, there is no need to use a pointer here.
As a general rule of thumb: Whenever there is a new somewhere, there also needs to be a corresponding delete. Otherwise your pogram may leak memory. While this is no big deal for a small, short-running example program, it can become a serious issue for a program that runs for a long time.
This is a nice use case for an int template:
board.h
template<int _board_length>
class Board
{
static const int board_length = _board_length;
int boardSquares[_board_length][_board_length];
public:
Board(){};
void printBoard(){};
};
main.cpp
...
constexpr int BL=8;
//odr declare the static member if it matters
template<>
const int Board<BL>::board_length;
int main() {
Board<BL> tabla;
tabla.printBoard();
}
That way, the actual dimensions of the array are defined in the main and not in the include file where the class is declared, and all the methods in Board can know the actual size.
Related
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.
I'm trying to create a class from within a class but I'm now very confused about how can that be done. I've tried for hours and hava had no luck, and my beginner level in c++ has limited me also a bit.
I've been using this link for reference with no success :/:
Creating instance in an another class of an object
This is my code:
Big class Sensor.h:
#ifndef SENSOR_H
#define SENSOR_H
#include "Dummy_Sensor.h"
#include "Lovato_DMG610.h"
class Sensor{
public:
double last10Vals [10];
char id[2];
Lovato_DMG610 dataSource(2);
Sensor(unsigned char dataSize){
}
int getSensorData ()
{
return 0;
}
private:
unsigned char dataSize;
};
#endif
My smaller class Lovato_DMG610.h:
#ifndef _KERN_LOVATO_DMG610
#define _KERN_LOVATO_DMG610
#include <Arduino.h>
//using namespace std;
class Lovato_DMG610{
public:
double variable = 0;
Lovato_DMG610(uint8_t pinToConnect)
{
_pinToConnect=pinToConnect;
}
private:
uint8_t _pinToConnect;
};
#endif
I've been getting an error related to the first file:
Sensor.h:10: error: 'Lovato_DMG610' does not name a type
Lovato_DMG610 dataSource(2);
My question for you guys would be:
How could i include the Lovato class in order to avoid this error?
How should the Lovato parameters should be set from Sensor class?
(this question is related to an error I'm also getting "Sensor.h:10: error: expected identifier before numeric constant
Lovato_DMG610 dataSource(2);")
I was using the code: using namespace std; before all class declarations and I get it is not a good practice (https://www.quora.com/What-does-using-namespace-std-mean-in-C++). Nevertheless, I would like to ask you if you could advise me whether this should be used in the scope of any of these headers.
Main program will keep an array of Sensor objects in which i want to make queries to different sensors. The only include in my Header.h is Sensors.h.
Thank you!
Update: After correcting the initialization as proposed by vll the constructor is ok (question 2 is resolved) but the same 'Lovato_DMG610' does not name a type' in Sensor.h error appears every time.
Parameters should be set in the constructor:
Lovato_DMG610 dataSource;
Sensor(unsigned char dataSize) : dataSource(2)
{}
I'm trying to make a program involving files assign2.cpp, Player.h, Player.cpp, Team.h, Team.cpp which reads data from a txt file on player info (like hits, atBat, position, name and number) and displays it out into assign2.cpp. assign2.cpp is what contains int main() and is suppose to contain very little code because relies on the other files to do the work.
The error:
request for member getName which is of non-class type ‘char’...
Please help, I've been trying to find the issue and can never do so. The compilation failure :
In file included from Team.cpp:1:0:
Team.h:34:11: warning: extra tokens at end of #endif directive [enabled by default]
Team.cpp: In constructor ‘Team::Team()’:
Team.cpp:15:5: warning: unused variable ‘numPlayers’ [-Wunused-variable]
Team.cpp: In member function ‘void Team::sortByName()’:
Team.cpp:49:56: error: request for member ‘getName’ in ‘((Team*)this
-> Team::playerObject[(j + -1)]’, which is of non-class type ‘char’
Team.cpp:49:74: error: request for member ‘getName’ in ‘bucket’, which is of non-class type ‘int’
Team.cpp: In member function ‘void Team::print()’:
Team.cpp:63:18: error: request for member ‘print’ in ‘((Team*)this)- >Team::playerObject[i]’, which is of non-class type ‘char’
make: *** [Team.o] Error 1
Team.h
#ifndef TEAM_H
#define TEAM_H
#include "Player.h"
class Team
{
private:
char playerObject[40];
int numPlayers; // specifies the number of Player objects
// actually stored in the array
void readPlayerData();
void sortByName();
public:
Team();
Team(char*);
void print();
};
#endif / *Team.h* /
Team.cpp
#include "Team.h"
#include <cstring>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <cstdlib>
using namespace std;
Team::Team()
{
strcpy (playerObject,"");
int numPlayers = 0;
}
Team::Team(char* newPlayerObject)
{
strncpy(playerObject, newPlayerObject, 40);
readPlayerData();
}
void Team::readPlayerData()
{
ifstream inFile;
inFile.open("gamestats.txt");
if (!inFile){
cout << "Error, couldn't open file";
exit(1);
}
inFile.read((char*) this, sizeof(Team));
inFile.close();
}
void Team::sortByName()
{
int i, j;
int bucket;
for (i = 1; i < numPlayers; i++)
{
bucket = playerObject[i];
for (j = i; (j > 0) && (strcmp(playerObject[j-1].getName(), bucket.getName()) > 0); j--)
playerObject[j] = playerObject[j-1];
playerObject[j] = bucket;
}
}
Player.h (incase anyone needs it)
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
// Data members and method prototypes for the Player class go here
private:
int number;
char name[26];
char position[3];
int hits;
int atBats;
double battingAverage;
public:
Player();
Player(int, char*, char*, int, int);
char* getName();
char* getPosition();
int getNumber();
int getHits();
int getAtBats();
double getBattingAverage();
void print();
void setAtBats(int);
void setHits(int);
};
#endif
I'm very stuck, Thanks in advance.
In the Team constructor on this line
playerObject = newPlayerObject;
you're trying to assign a value of type char* to a member of type char[40], which doesn't work, since they are two different types. In any case, you probably would need to copy the data from the input instead of just trying to hold the pointer internally. Something like
strncpy(playerObject, newPlayerObject, 40);
Generally, you will always be able to assign a char[N] to a char*, but not the other way around, but that's just because C++ will automatically convert the char[N] to a char*, they are still different types.
Your declaration is:
char playerObject[40];
And your constructor reads:
Team::Team(char* newPlayerObject)
{
playerObject = newPlayerObject;
The error message you referenced in the title of this question obviously comes from here, and it is self explanatory. An array and a pointer are two completely different, incompatible types, when it comes to this kind of an assignment.
What you need to do depends entirely on what you expect to happen, and what your specifications are.
A) You could be trying to initialize the array from the character pointer, in which case you'll probably want to use strcpy(). Of course, you have to make sure that the string, including the null byte terminator, does not exceed 40 bytes, otherwise this will be undefined behavior.
Incidently, this is what you did in your default constructor:
Team::Team()
{
strcpy (playerObject,"");
}
B) Or, your playerObject class member should, perhaps, be a char * instead, and should be either assigned, just like that, or perhaps strdup()ed. In which case your default constructor will probably need to do the same.
Whichever one is the right answer for you depends entirely on your requirements, that you will have to figure out yourself.
While trying to make a simple game, I've run in to a circular dependency problem.
I searched on the internet and found that forward declaring could fix it, but... Both of my classes depend on a static value.
Is there any easy way to fix, perhaps to forward declare the static values, or do I have to rewrite the core of my game?
2ND EDIT: Looks like I was wrong, the error's still there even after removing almost everything:
main.cpp:
#include "App.h"
//Start the app
int main(int argc, char* args[]){
App App;
return App.on_execute();
}
App.h:
#ifndef APP_H
#define APP_H
#include "Object.h"
class App
{
public:
//Runs when the program starts
int on_execute();
};
#endif // APP_H
App.cpp:
#include "App.h"
int App::on_execute(){
return 0;
}
Object.h:
#ifndef OBJECT_H
#define OBJECT_H
#include <string>
#include <vector>
#include <stdio.h>
#include <SDL.h>
#include <math.h>
#include "Entity.h"
class Object
{
public:
Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks);
//Object vector
static std::vector<Object*> objects;
};
#endif // OBJECT_H
Object.cpp:
#include "Object.h"
std::vector<Object*> Object::objects;
Object::Object(int character, int x, int y, std::string name, SDL_Color color, bool blocks){
}
Entity.h:
#ifndef ENTITY_H
#define ENTITY_H
#include "Object.h"
#include <sdl.h>
class Entity : public Object
{
public:
Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense);
};
#endif // ENTITY_H
Entity.cpp:
#include "Entity.h"
Entity::Entity(int character, int x, int y, std::string name, SDL_Color color, bool blocks, int hp, int power, int defense) : Object(character, x, y, name, color, blocks){
}
I think the design of your code may need to be reworked.
First of all, I'd really discourage you from using non-primitive, non-trivial class statics where possible, whether class static or global static. Non-trivial static classes will have an explicit constructor call before main, and will need to register a destruction to be called after main. The relative ordering of these things is undefined. Worse, if you have a library structure later such that the assembly from the same .cpp file shows up twice, weird things can happen where two copies of the object get constructed, but the same one is destroyed twice.
Second, some of the information is unclear. For example, you claim that the Map class has a static member of type Map. I really don't think this is possible; the static Map member will also have an object of type map, and so on. Similarly with the vector of Objects declared inside Object. Maybe in both these cases you mean inside the file Map.cpp or Object.cpp, as opposed to literally inside the class?
Third, be clear on what forward declaration gives you. It makes the compile aware that something exists, nothing more. It lets you have pointers and references to that type. You cannot create an object or even declare a member variable of a forward declared type, because the compiler doesn't know the size of the forward declared object. You can't use its methods because the compiler doesn't know they exist.
Fourth, you didn't talk about your header files at all. It's only a circular dependency if Map.h requires Object.h, and vice versa. Two header files can't both include each other. On the other hand, the implementation is in Map.cpp and Object.cpp, both of these files can include both Map.h and Object.h. However, personally I prefer to avoid having mutually dependent classes.
What I'd probably suggest is that a Map should own the Objects present on that map. The pattern right now with Map accessing this global is not a good one. Instead of having objects be a global, make std::vector objects a member of the Map class. Notice that if you decide to have multiple Maps later, this works much better, each Map will own the Objects located on that map. The current design doesn't work well if there's more than one Map.
You can then implement move_to as a method not of Object, but rather of Map. Map::move_to(i, dx, dy) moves the ith Object.
and I struggle with function which should return vector of objects but for some reason it throws errors all the time, telling that my object is undeclared identifier and vector of this objects is not valid template and points me to .h file where I declare function.
I will appropriate any explanation what that mean and how to fix this. bellow I place code from my class and starting files.
#ifndef SETUPW_H
#define SETUPW_H
#include"Square.h"
#include <iostream>
#include<string>
#include<fstream>
#include<vector>
std::vector<std::ifstream> allText();
std::ifstream loadTxt(std::string txt);
void printByLine(std::ifstream& txt);
std::vector<square> allSquares();//compiler points me to this line and that one bellow
void whichSQ(int sqNum, std::vector<square> sq);
#endif
and my class:
#ifndef SQUARE_H
#define SQUARE_H
#include"player.h"
#include"setupW.h"
#include<iostream>
#include<string>
#include<fstream>
class square
{
public:
square(std::string name, int sqNumber, std::string description, int exits, int object);
void loadSQ(std::ifstream& inFile);
void printSQ();
private:
int mSqNumber;
std::string mName;
std::string mDescription;
int mExits;
int mObject;
};
#endif
The problem arises because you have a circular dependency here. In square.cpp you firstly include square.h. But square.h contains this line #include"setupW.h" (before your class declaration). Therefor the declarations of your functions will appear before the declaration of your square class. That causes the compiler to mutter that square is not declared (at that time) when he reads std::vector<square>.
The most easiest solution would be to simply remove the include, because it is, as far as I can tell, unneccessary.