this is my first post on SO, even though i've spent some time already here.
I've got here a problem with a function returning a 2d array. I have defined a private 2d int array property int board[6][7] in my Game class, but i don't know how to create a public getter for this property.
These are relevant parts of my game.h:
#ifndef GAME_H
#define GAME_H
class Game
{
public:
static int const m_rows = 6;
static int const m_cols = 7;
Game();
int **getBoard();
private:
int m_board[m_rows][m_cols];
};
#endif // GAME_H
Now what I would like is something like this in game.cpp (cause I thought array name without brackets is a pointer to first element, obviously it doesn't work with 2d arrays) :
int **Game::getBoard()
{
return m_board;
}
So that i can put this for example in my main.cpp:
Game *game = new Game;
int board[Game::m_rows][Game::m_cols] = game->getBoard();
Can anybody help me, what should i put in my game.cpp ?
Thanks!
You cannot pass arrays by value into and out of functions. But there's various options.
(1) Use a std::array<type, size>
#include <array>
typedef std::array<int, m_cols> row_type;
typedef std::array<row_type, m_rows> array_type;
array_type& getBoard() {return m_board;}
const array_type& getBoard() const {return m_board;}
private:
array_type m_board;
(2) Use the correct pointer type.
int *getBoard() {return m_board;}
const int *getBoard() const {return m_board;}
private:
int m_board[m_rows][m_cols];
An int[][] has no pointers involved. It isn't a pointer to an array of pointers to arrays of integers, it's an array of an array of integers.
//row 1 //row2
[[int][int][int][int]][[int][int][int][int]]
Which means one int* points to all of them. To get to a row offset, you'd do something like this:
int& array_offset(int* array, int numcols, int rowoffset, int coloffset)
{return array[numcols*rowoffset+coloffset];}
int& offset2_3 = array_offset(obj.getBoard(), obj.m_cols, 2, 3);
Related
I want to create a constant static int variable to specify the range of an array. I'm running into problems and getting errors saying that the variable is not a member of the class, but I can print out the variable in main using ClassName::staticVarName.
I cannot figure out how to properly set up a static variable that belongs to a class so that it can be used to initialize an array. The variable prints in main, but for some reason it will not compile when I try to use it to define a classes's array field's range.
error: class "RisingSunPuzzle" has no member "rows"
error: class "RisingSunPuzzle" has no member "cols"
header file for class:
#pragma once
#include<map>
#include<string>
#include<memory>
class RisingSunPuzzle
{
private:
bool board[RisingSunPuzzle::rows][RisingSunPuzzle::cols];
public:
RisingSunPuzzle();
~RisingSunPuzzle();
static const int cols;
static const int rows;
void solvePuzzle();
void clearboard();
};
cpp file for class:
#include "RisingSunPuzzle.h"
const int RisingSunPuzzle::cols = 5;
const int RisingSunPuzzle::rows = 4;
RisingSunPuzzle::RisingSunPuzzle()
{
}
RisingSunPuzzle::~RisingSunPuzzle()
{
}
void RisingSunPuzzle::solvePuzzle()
{
}
void RisingSunPuzzle::clearboard()
{
}
The names of data members that are referred to must be declared before the data members that refer them to.
Also the static constants have to be initializes.
You can reformat the class the following way
class RisingSunPuzzle
{
public:
static const int cols = 5;
static const int rows = 4;
private:
bool board[RisingSunPuzzle::rows][RisingSunPuzzle::cols];
public:
RisingSunPuzzle();
~RisingSunPuzzle();
void solvePuzzle();
void clearboard();
};
//...
There is no need to define the constants if they are not ODR used. Nevertheless you can define them (without initializers) like
const int RisingSunPuzzle::cols;
const int RisingSunPuzzle::rows;
im new in c++ (and not to old in programming...) and i have problem with handling vectors and strucs in class.
basically i have a vector and a array of pointers to struct members in the class and i want work on the in my methos but im doing something worng/
here is my movement.h
#pragma once
using namespace std;
class movement
{
private:
static const int MAX_ROW_PER_TRACKER = 100;
static const int MIN_TO_START_CALC = 30;
static const int MAX_TRACKERS = 20;
struct tracker
{
int id;
double a[MAX_ROW_PER_TRACKER];
double b[MAX_ROW_PER_TRACKER];
double c;
};
vector<int> trackersOrder[MAX_TRACKERS] = {};
tracker* trackersArr[MAX_TRACKERS];
public:
movement();
void addRow(int a, int b, int c);
~movement();
};
and my movement.cpp
#include "stdafx.h"
#include "movement.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
movement::movement()
{
}
void movement::addRow(int id, int a, int b)
{
int index;
vector<int>::iterator searchID = find(trackersOrder.begin(), trackersOrder.end(), ID);
if (searchID == trackersOrder.end())
{
vector<int>::iterator freeLocation = find(trackersOrder.begin(), trackersOrder.end(), 0);
index = freeLocation - trackersOrder.begin();
trackersOrder.insert(trackersOrder.begin + index, id);
structArr[index] = new tracker;
structArr[index]->id = id;
structArr[index]->a[0] = a;
structArr[index]->b[0] = b;
structArr[index]->c = 0;
}
}
movement::~movement()
{
}
so when i send to method "addRow" id, and b i want to first check if i allready have this id in my vector (the vector just give me the index for the structs array) and if not then if put the id in the first empty place in the vector and on the structs array/
but from some reasin its look to me that the methid dont reconized the vector and the structs. can you help me understand why?
p.s - i can bet that i have more mistakes in my code, its my firs try with pointers and ect. (im comming from the good life in Matlab) so i will be happy to learn on them also
thank you very much!
The main problem
The problem is that in your code, trackersOrder is not a vector but an array of vectors:
vector<int> trackersOrder[MAX_TRACKERS] = {}; // array of MAXTRACKERS vectors !!
The solution
If you define it as simple vector, it should work better:
vector<int> trackersOrder;
If you want to set its size do it in the movement constructor:
movement::movement() : trackersOrder(MAX_TRACKERS)
{
}
Other issues
There is a case typo with an ID that should be id.
auto searchID = find(trackersOrder.begin(), trackersOrder.end(), id); // by the way auto is easier + ID corrected
There are a missing () after a begin whicn transforms unfortunately your iterator arithmetic into function pointer arithmetic (sic!!):
trackersOrder.insert(trackersOrder.begin() + index, id); // corrected
Finally, there are a couple of structArr that should be replaced by trackersArr.
The result does finally compile (online demo)
I'm changing the class implementation of a large class for a company project that has several static variables declared as private members of the class. There are many arrays and structs declared in the class header that utilize these static variables. I now need to assign the static data members values from my main function somehow. I tried assigning the static variables through the constructor but the header is declared prior to the constructor call so that wasn't possible.
For example, if I have
class Data
{
private:
static unsigned int numReadings = 10;
static unsigned int numMeters = 4;
unsigned int array[numMeters];
}
I would want to change it such that I could set numReadings and numMeters from my main function somehow, so it will allow all of my arrays and structs that utilize numMeters and numReadings to be initialized properly.
Is there a way to do this in C++? Of course I could always change my class design and set these in the constructor somehow but I'd like to avoid that if I can as it will take quite a long time.
You cannot do it in the main function, but you can do it in the main.cpp file:
// Main.cpp
#include <iostream>
#include "T.h"
using namespace std;
int T::a = 0xff;
int main()
{
T t; // Prints 255
return 0;
}
// T.h
#pragma once
#include <iostream>
using namespace std;
class T {
public:
T() { cout << a << endl; }
private:
static int a;
};
Have you tried making them public and accessing them with Data::numReadings = 10?
UPDATE:
#include <cstdlib>
using namespace std;
/* * */
class Asdf
{
public:
static int a;
};
int Asdf::a = 0;
int main(int argc, char** argv) {
Asdf::a = 2;
return 0;
}
Regardless of the accessibility of these variables, you need to define and initialize the static members outside the class definition:
// header
class Data
{
private:
static unsigned int numReadings;
static unsigned int numMeters;
unsigned int array[numMeters]; //<=see edit
};
// class implementation file
unsigned int Data::numReadings = 10;
unsigned int Data::numMeters = 4;
This is part of the implementation of the class and shouldn't be in the header (ODR rule).
Of course, if you want to access these variables (which are shared among all instances of the class) from outside, you need to make them public, or better, foresee and accessor.
Edit:
As the question is formulated around the static issue, I didn't notice the variable length array : this is not standard c++, although some compilers might accept it as a non-standard extension.
To do this properly, you should define a vector and initialize it at construction:
class Data
{
public:
Data ();
private:
static unsigned int numReadings;
static unsigned int numMeters;
vector<unsigned int> mycontainer; //<=for dynamic size
};
Data::Data() : mycontainer(numMeters) { } // initialize object with right size
I'm trying to initialise static pointers as arrays inside a class definition, but getting runtime errors. I've seen examples where something similar is done, but I can't get it working, and not sure why. Some example code I've tried is:
class Header
{
private:
static int *pointer;
public:
int getVal(int val);
};
Class definition:
#include "Header.h"
int* Header::pointer = new int[] {0, 1, 2, 3, 4};
int Header::getVal(int val)
{
return pointer[val];
}
main:
#include "Header.h"
#include <iostream>
int main(int argc, char ** argv)
{
Header header;
for (int i = 0; i < 5; i++)
{
std::cout << header.getVal(i);
}
}
Running this causes an error while initialising the pointer. If I run through it in the debugger, and ignore the error, I can see that the pointer is initisalised with 0 at the beginning. If I then continue to step through it I get another error saying the heap's been corrupted. Is it possible to intitialise a pointer in this way? If not, are there any suggestions on how one can initialise a member variable pointer into an array, and assign it values, inside the class definition without having to assign each element of the array individually.
You could probably get away with:
class Header
{
public:
int getVal(int valIndex);
};
and then
#include "Header.h"
static int s_vals[] = {0, 1, 2, 3, 4}; // could move this line to B
int Header::getVal(int valIndex)
{
// B
return s_vals[valIndex];
}
Considering that you know the size of the array at compile time and there is no need to advertise an implementation detail if you are providing accessors anyway.
it is possible that your compiler simply does not support braced-init-list.
If so you can rewrite your class the following way
class Header
{
private:
static int *pointer;
static int *init()
{
int *p = new int[5];
std::iota( p, p + 5, 0 );
return ( p );
}
public:
int getVal(int val);
};
And then pointer is defined the following way
int * Header::pointer = Header::init();
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.