Issue nesting enum within a struct - c++

I am trying to nest some of my enums within structs so that I can use them in functions involving the other struct variables further down the line. I keep getting an error in the new code for loop:
name followed by a :: must be a class or namespace
However, that's not an issue in the old code for loop, which doesn't use classes or namespaces.
Why is the new code throwing up this error? How can I fix it without converting my structs to classes?
oldcode.h
const int LONGBUTTON_HEIGHT = 128;
const int LONGBUTTON_WIDTH = 256;
enum CreateForestButtonState { CREATE_DEFAULT, CREATE_HOVER, CREATE_INACTIVE, CREATE_PRESSED, CREATE_TOTAL };
oldcode.cpp
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "oldcode.h"
SDL_Rect create_clips[CreateForestButtonState::CREATE_TOTAL];
for (int i = 0; i < CreateForestButtonState::CREATE_TOTAL; i++)
{
create_clips[i].x = i * LONGBUTTON_WIDTH;
create_clips[i].y = 0;
create_clips[i].w = LONGBUTTON_WIDTH;
create_clips[i].h = LONGBUTTON_HEIGHT;
}
int useCreate_Clip = CREATE_DEFAULT;
newcode.h
const int LONGBUTTON_HEIGHT = 128;
const int LONGBUTTON_WIDTH = 256;
struct Graphic
{
enum state {DEFAULT, HOVER, INACTIVE, PRESSED, TOTAL};
int use_clip;
int x;
int y;
int h;
int w;
};
newcode.cpp
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "newcode.h"
Graphic create_plain;
create_plain.type = "long button";
create_plain.state::DEFAULT;
create_plain.use_clip;
SDL_Rect clips[create_plain.state::TOTAL];
for (int i = 0; i < create_plain.state::TOTAL; i++)
{
clips[i].x = i * LONGBUTTON_WIDTH;
clips[i].y = 0;
clips[i].w = LONGBUTTON_WIDTH;
clips[i].h = LONGBUTTON_HEIGHT;
}
create_plain.use_clip = create_plain.DEFAULT;

Don't name the enum :
struct Graphic
{
enum {DEFAULT, HOVER, INACTIVE, PRESSED, TOTAL};
int use_clip;
int x;
int y;
int h;
int w;
};
and
SDL_Rect clips[Graphic::TOTAL];

Use
for (int i = 0; i < Graphic::state::TOTAL; i++)
You should use the scope, not an object.

This arrangement works. I don't know why.
for (int i = 0; i < create_plain.TOTAL; i++)

Related

How to pass a 2D arrays of pointers to 3D arrays of pointers (function and class) and return 3d arrays of values in C++?

I am currently working on C++, creating a program of the analysis of matrices.
As far as i saw those can be created using an arrays of arrays like this array2D[3][3]={{1,2,3},{4,5,6},{7,8,9}}.
Therefore, what i did was to generate a function in a class, such a function must return a 2D array. Then i created another class in order to generate the other array of array of arrays, but this 3D arrays need the data obtained by the previous class, remember the previous class holds the values of the matrix in a variable called int **degreesOfFreedom. Here is where the problem arises this second class needs the values of the double pointer and the problem like this appears.
error: cannot convert ‘int***’ to ‘int**’ in assignment
As far as i can see the error comes when trying to pass the 2D pointers arrays into the 3D pointers function.
By the way i already checked several ways and i saw that one of them is replacing the double pointer ** in the declaration of the variable inside of the function, and replace it by [][]. I already tried that, it didn't solve the problem, also i would not like to do that way because in the future i will have matrices of millions per millions elements.
This is my code
#include <iostream>
#include <string>
#include <fstream>
class MatrixOfDegreesOfFreedom
{
public:
int X, Y;
int M = 0;
public:
int **matrixOfDegreesOfFreedom(int rows, int cols)
{
X = rows;
Y = cols;
int** matrix = new int*[X];
for (int i = 0; i < X; ++i)
{
matrix[i] = new int[Y];
for (int j = 0; j < Y; ++j)
{
matrix[i][j] = M;
M = M + 1;
}
}
return matrix;
}
//constructor
MatrixOfDegreesOfFreedom()
{
}
//destructor
~MatrixOfDegreesOfFreedom()
{
}
};
class MatrixOfIndexes
{
public:
int X, Y, Z;
int M = 0;
public:
int ***matrixOfIndexes(int rows, int cols, int colsTwo, int conect[][2], int **DoF)
{
X = rows;
Y = cols;
Z = colsTwo;
int*** matrix = new int**[X];
for (int i = 0; i < X; ++i)
{
M = 0;
matrix[i] = new int*[Y];
for (int j = 0; j < Y; ++j)
{
matrix[i][j] = new int [Z];
for (int t = 0; t < Z; ++t)
{
matrix[i][j][t] = DoF[conect[i][j]][t];
}
M = M + 1;
}
}
return matrix;
}
//constructor
MatrixOfIndexes()
{
}
//destructor
~MatrixOfIndexes()
{
}
};
int main(int argc, char const *argv[])
{
#ifndef OUTPUT
freopen("output.txt", "w", stdout); // file to store the output data.
#endif
int numberOfNodes = 3; // number of nodes
int numberOfDegreesOfFreedomPerNode = 2; //Number of Degrees of Freedom per node
int **degreesOfFreedom = {}; //number of degree of freedom
int numberOfDegreesOfFreedomPerElement = 4; //Number of Degrees of Freedom per element
int numberOfElements = 3;
int connectivity[numberOfElements][2] = {{0,1},{2,1},{0,2}}; // Conectivity matrix along with the property
int **indexes = {};
MatrixOfDegreesOfFreedom tableOfDegreesOfFreedom;
degreesOfFreedom = tableOfDegreesOfFreedom.matrixOfDegreesOfFreedom(numberOfNodes, numberOfDegreesOfFreedomPerNode);
MatrixOfIndexes tableOfIndexes;
indexes = tableOfIndexes.matrixOfIndexes(numberOfElements, numberOfDegreesOfFreedomPerElement, numberOfDegreesOfFreedomPerNode, connectivity, degreesOfFreedom);
std::cout<< "finishing" << std::endl;
return 0;
}
The problem is that the function matrixOfIndexes returns a 3-dimensional pointer (int***) but the array you're assigning that return value to is a two-dimensional one (int**). The types have to match.
To fix it just add an extra * to the declaration of indexes:
int*** indexes = {};

Initialize C++ struct that contains a fixed size array

Suppose I have a POD C struct as so:
struct Example {
int x;
int y[10];
int yLen;
}
With the following code, the program doesn't compile:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example{ 0, y, yLen };
}
However, doing return {0, {}, 0}; does seem to compile. Problem is, I can't know the size of y until doing some sort of logic ahead of time. Initializing int y[10]{} in test doesn't seem to make a difference. I know this seems like a pretty simple question, but I can't seem to find anything that works.
Declare the structure as a whole instead of its parts and then initialize it:
Example test() {
Example result;
auto len = this->getSomethingLength();
for (result.yLen = 0; result.yLen < len; result.yLen++) {
result.y[result.yLen] = this->getSomething(result.yLen);
}
return result;
}
Declaring y as an int* and allocating memory with new, when the size is known, would be an even better solution.
Declare constructor in Example:
struct Example {
int x;
int y[10];
int yLen;
Example(int xNew, int *yNew, int yLenNew)
{
x = xNew;
yLen = yLenNew;
for (int i = 0; i < yLenNew; i++)
{
y[i] = yNew[i];
}
}
};
And use it like this:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example( 0, y, yLen );
}

multidimensional array of objects in c++

I'm writing assignment (creating virtual world) and I've encountered one thing I can't go over. I have class Organism which is an abstract for all the future inheriting ones (animals etc.) and class World which represents the world of these objects. In the latter I can't create an array of Organisms though - to store position of every existing organism.
It throws:
"syntax error : missing 'token1' before 'token2'
I was thinking that maybe it has something to do with that it refers to each other (organism has reference to certain world and certain world wants to create array of organisms) but default constructor is solving that thing imo.
Could you tell what have I overseen? Thanks in advance.
World.h
#pragma once
class World
{
private:
int sizeX;
int sizeY;
Organism * worldMesh;
public:
World(int sizeX, int sizeY);
void nextTurn();
void drawWorld();
int getWorldX();
int getWorldY();
~World();
};
World.cpp
#include "stdafx.h"
#include "World.h"
#include <iostream>
using namespace std;
World::World(int sizeX, int sizeY)
{
this->sizeX = sizeX;
this->sizeY = sizeY;
worldMesh = new Organism[sizeX][sizeY];
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
worldMesh[i][j] = NULL;
}
}
} ....
Organism.h
#pragma once
#include "World.h"
#include "Position.h"
class Organism
{
protected:
int strength;
int initiative;
Position * position;
static World * world;
public:
Organism();
Organism(World * world);
int randValue();
virtual void spawn();
virtual void action();
virtual void collision();
void kill();
virtual ~Organism();
};
There is no such new Type[size1][size2] construction in C++, but you can do something like this:
int** mesh = new int*[size1];
for( int i = 0; i < size1; i++ ) {
mesh[i] = new int[size2];
for( int j = 0; j < size2; j++ ) {
mesh[i][j] = 0;
}
}
or just use std::vector
std::vector< std::vector<Type> > mesh;
or use single std::vector with size size1 * size2 and calculate index fromi and j: index = i * size1 + j

POSIX pthread_create scrambles the values of variables in a struct, how to avoid that?

So I have my program here:
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
int const size = 3;
struct Arguments{
int array[];
float result1[];
float result2[];
};
//void calc(int arr[], float rarr1[], float rarr2[], int size);
void* calc(void *param);
int main(int argc, char *argv[]){
time_t t;
srand((unsigned) time(&t));
int arr[size][size] = {};
float rarr1[size][size-1] = {};
float rarr2[size][size-1] = {};
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
int number = rand()%10;
arr[x][y] = number;
}
}
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
cout << arr[x][y] << " ";
}
cout << endl;
}
cout << endl;
/////////////////////////////////////////
pthread_t child;
struct Arguments input;
for(int i = 0; i < size; i++){
input.array[i] = arr[0][i];
}
pthread_create(&child, NULL, calc, (void*)&input);
pthread_join(child, NULL);
//calc(&input);
for(int i = 0; i < size-1; i++){
rarr1[0][i] = input.result1[i];
cout << "Test: " << rarr1[0][i] << endl;
}
//////////////////////////////////
return 0;
}
//void calc(int arr[], float rarr1[], float rarr2[], int size){
void* calc(void *param){
struct Arguments *input = (struct Arguments*)param;
int arr1[] = {};
float rarr1[] = {};
float rarr2[] = {};
for(int i = 0; i < size; i++){
arr1[i] = input->array[i];
}
for(int i = 0; i < size; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float euc = 1 + pow(difference, 2);
euc = sqrt(euc);
rarr1[i] = euc;
}
for(int i = 0; i <size-1; i++){
input->result1[i] = rarr1[i];
}
for(int i = 0; i <size-1; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float apar = (difference/rarr1[i]);
float result = asin(apar);
result = result*(180/3.14);
rarr2[i] = result;
}
return NULL;
}
The important part that causes the trouble is between ////// lines but I left the rest of the code for the context, since it might be useful.
So I have the function calc(param); that does the important calculation in the program.
It is working just fine as long as I call it myself (by actually including the function call in the code) and the test loop right after it gives the correct results.
However, when I try to use pthread_create(); to create a new thread that will take care of executing that function, the test loop spits out nonsense and some random huge numbers different each time.
It's kinda weird because the code compiles either way, and literally the only thing that I change is these 2 lines.
What am I doing wrong and why the function spits out garbage when started by the Pthread? Is there a way to fix it?
Ok so if anyone's having a similar problem:
Declare the size of arrays no matter what. It turns out that my program didn't work properly because I initialized my result arrays as float result1[]; instead of float result1[size];

Segfault error when calling a method through pointer

I have a baseclass called gridObject
Here's the header file:
#ifndef ITEM_H
#define ITEM_H
class gridObject
{
public:
gridObject();
virtual ~gridObject();
virtual int get_GridID() = 0;
virtual int get_x() = 0;
virtual int get_y() = 0;
virtual int get_direction() = 0;
void set_x(int x);
void set_y(int y);
void set_direction(unsigned int direction);
protected:
private:
int _x;
int _y;
unsigned int _direction;
};
#endif // ITEM_H
I have a subclass called player
Here's the get_GridID() method in the class file:
int player::get_GridID() { return 2; }
There's also a grid class that keeps track of all the objects on it via a 2d vector. In the header file, there's that vector:
private:
vector<vector<gridObject*> > _position;
Here are the methods for setting and getting an object at a specific position, respectively:
void grid::setGridPosition(int x, int y, gridObject* obj) { _position[y][x] = obj; }
gridObject* grid::getGridPosition(int x, int y) { return _position[y][x]; }
The problem I'm having is here:
int main()
{
grid * gr = new grid(10, 10);
player p(0, 0, 100);
gridObject * go = &p;
gr->setGridPosition(0, 0, go);
cout << gr->getGridPosition(0, 0)->get_GridID();
return 0;
}
It crashes at: cout << gr->getGridPosition(0, 0)->get_GridID();
I have included all of the appropriate header files.
EDIT: Here is the constructor for grid and the initialization of _position:
grid::grid(int width, int length)
{
setSize(width, length);
}
void grid::setSize(int width, int length)
{
setLength(length);
setWidth(width);
}
void grid::setLength(int val) { _position.resize(val); }
void grid::setWidth(int val)
{
for(unsigned int i = 0; i < _position.size() - 1; i++)
for(unsigned int j = 0; j < _position.at(i).size() - 1; j++)
_position.at(i).resize(val);
}
You're working with vector of vectors:
vector<vector<gridObject*> > _position;
but the way you initialize _position is following:
_position.resize(length);
for(unsigned int i = 0; i < _position.size() - 1; i++)
for(unsigned int j = 0; j < _position.at(i).size() - 1; j++)
_position.at(i).resize(width);
Note that the first resize constructs length objects of type vector<gridObject*>. Then you are iterating not through these newly-constructed vectors, but rather their elements (second nested loop), which in this case causes that the line _position.at(i).resize(width); is never executed and thus _position[y][x] = obj tries to access the invalid memory resulting in undefined behavior that you observe as segmentation fault.
Try this instead (in grid::setSize):
_position.resize(length);
for(unsigned int i = 0; i < _position.size() - 1; ++i)
_position[i].resize(width);
and also consider using typedef for creating an alias for std::vector<gridObject*> :)