C++ setting array values in a class - c++

I am having trouble with what seems like a very simple concept. I have a class like such:
class Projectile
{
public:
int count;
int projectiles[1][3];
Projectile();
void newProjectile();
};
Projectile::Projectile()
{
count = 0;
}
void Projectile::newProjectile()
{
projectiles[0][0] = { 1, 2, 3 };
}
I am trying to set the values inside the projectiles array, and I must be doing this incorrectly. How can I go about dynamically adding a set of values into this property?

projectiles[0][0] refers to a specific location in a two-dimensional array, its type is int
If you want to dynamically add items, then you can use std::vector<int> (see here)

projectiles[0][0] = { 1, 2, 3 };
This isn't correct. Initializer lists can only given at the point of declaration. You have to assign values independently to each location of the array elements. std::vector<std::vector> twoDimArray; is what you want.
struct foo{
std::vector<std::vector<int> > twoDimArray;
void create(int size){
std::vector<int> oneDimArray(size);
// vector as of now can just accommodate size number of elements. They aren't
// assigned any values yet.
twoDimArray.push_back(oneDimArray); // Copy it to the twoDimArray
// Now if you wish to increase the size of each row, just push_back element to
// that row.
twoDimArray[0].push_back(8);
}
};

try this
void Projectile::newProjectile()
{
projectiles[0][0] = 1;
projectiles[0][1]=2;
projectiles[0][2]=3;
}

Related

Struggling with the declaration of class attributes inside the C++ header file?

As a C++ beginner, I oftentimes find myself struggling with the declaration of class attributes inside the header file that need more information than just a name, like arrays and objects of other classes with constructors.
Here's an example
SomeClass.h :
#include "OtherClass.h"
class SomeClass {
int num; // works fine
float arr[]; // produces an error because size is not declared
OtherClass obj; // produces an error because the constructor parameters are not passed in
public:
void setup();
void update();
};
SomeClass.cpp:
#include "SomeClass.h"
void SomeClass::setup() {
num = 10; // easy peasy, works!
arr = float some_arr[5 * num]; // error
// Fill in the array
for (int i = 0; i < 5 * num; i += num) {
ass[i] = 12;
}
// Fill in the class attributes
obj = {120, 40}; // error
}
void SomeClass::update() {
// Update stuff
}
In case of the array arr, how can I declare an array, if I don't know it's size at the moment of the declaration in the header file?
How can class objects with constructors be declared in the header file, without passing in unknown parameters at that moment?
Thanks.
In case of the array arr, how can I declare an array, if I don't know
it's size at the moment of the declaration in the header file?
You can't! C++ does not support variable length arrays, although some compilers (such as GCC) add support for them as an extension.
Instead, you should consider using the std::vector container type, from the Standard Template Library.
In your header/declaration:
class SomeClass {
int num; // works fine
// float arr[]; // produces an error because size is not declared
std::vector<float> arr;
//...
};
And, for your setup() function:
void SomeClass::setup() {
num = 10; // easy peasy, works!
// arr = float some_arr[5 * num]; // error
arr.resize(5 * num); // Sets the size of the container
// Fill in the array...
for (int i = 0; i < 5 * num; i += num) {
arr[i] = 12; // You can access (valid) elements just like a normal array!
}
//...
}
In case you don't know the array size before hand you can use dynamic allocation feature in C++.
First declare your array variable as follow
float *arr;
Then you can allocate required size as follows
arr=new float[10];
To deallocate memory
delete[] arr;
If want to dynamically allocate objects then,Declare class as
ClassName *obj;
Then to allocate use
obj=new ClassName(your_parameters);
Then you can delete it using
delete obj;
TIP:
It is always a good practice make pointer variable NULL after you have de-allocated memory.
Do arr=NULL; and obj=NULL; after de-allocating

Error adding n enum namespace inside structure

I have an error when I add a parameter of class inside the structure. I don't know why, but inserting a simple variable of type namespace::enum variable with a static_cast doesn't make an error. What I try to do, is to insert all my enums in a vector of structure
namespace code
namespace plazza {
enum Ingredients {
Doe,
Tomato,
Gruyere,
Ham
};
}
Structure
typedef struct s_stock {
plazza::Ingredients ingredient;
int quantity;
} t_stock;
Class
class Kitchen {
public:
Kitchen(int multiplier, int numCooks, int cookingTime);
~Kitchen();
private:
int _multiplier;
int _numCooks;
int _cookingTime;
std::vector<t_stock> _stock;
plazza::Ingredients ginger;
};
Code
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime) {
_multiplier = multiplier;
_numCooks = numCooks;
_cookingTime = cookingTime;
// How I think it should be
_stock[0].ingredient = plazza::Doe;
// No error
ingre = static_cast<plazza::Ingredients>(plazza::Ingredients::Doe);
// what I try but error
_stock[0].ingredient = static_cast<plazza::Ingredients>(plazza::Ingredients::Doe);
}
Error adding into the vector of structure
==7692== Invalid write of size 4
==7692== at 0x110A7E: Kitchen::Kitchen(int, int, int) (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== by 0x10CE96: Reception::time_to_work() (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== by 0x10C16B: main (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== Address 0x0 is not stack'd, malloc'd or (recently) free'd
You are assigning a value to _stocks[0] but you aren't sizing your vector first to contain at least one element. Either use push_back or use an initialization list to initialize your vector at construction.
To assign something to a t_stock you can use
t_stock dummy = { plazza::Doe /* first argument in struct is the ingredient */, 1 /*second argument in the struct is the quantity */ }
Combined, to assign everything properly in your Kitchen constructor, you could use:
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime)
: _multiplier(multiplier),
_numCooks(numCooks),
_cookingTime(cookingTime),
_stock({ {plazza::Doe, 1} }) // Initialize vector with one element
{
}
To add multiple elements at creation you can do:
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime)
: _multiplier(multiplier),
_numCooks(numCooks),
_cookingTime(cookingTime),
_stock({ {plazza::Doe, 1}, {plazza::Tomato, 4} }) // Initialize vector with two elements
{
}
To add new stock elements after creation, always use push_back
_stock.push_back({plazzo::Gruyere, 16}); // Add lots of 'em

Retrieve array name

I have written a function in c++ which receives a struct as a input. The struct object received has two arrays. I need to use both the arrays for different purposes. The array names have been created in a certain format. How to retrieve array names in a string.
struct INFO
{
float fADataLHS[3] = {1,2,3};
float fADataRHS[3] = {4,5,6};
Struct INFO has been defined where two arrays have been defined an initialized. The function useStruct uses both the function for different purposes.
void useStruct(struct *INFO)
{
--------;
--------;
}
int main()
{
struct INFO info;
useStruct(info);
}
I want a method in which I can retrieve the name of the array as for ex. fAdataLHS and store it to a string. The idea is to find the sub-string LHS and RHS from the string names and process then accordingly.
PS: I am quite new to c++.
I will go simple as you're a begginer to C++.
If you want to use both of arrays for different purposes, just doit. For instance:
void use_array_for_different_purposes(INFO *info)
{
// Purpose one, printing values using fADataLHS.
for (int i = 0; i < 3; i++) {cout << info->fADataLHS[i] << endl;}
// Purpose two, computing total sum using fADataRHS.
int acum;
for (int i = 0; i < 3; i++) {acum += info->fADataRHS[i];}
}
As you can see, you don't need to get the arrays names as strings values.
If I understand corectly, your use case is this: you have two (or more) names and each has a float array associated with it. You want to get the array by name and process the data.
Consider this code:
class INFO
{
std::map<std::string, std::vector<float>> vectors;
public:
INFO() : vectors{}
{
vectors["fADataLHS"] = { 1, 2, 3 };
vectors["fADataRHS"] = { 4, 5, 6 };
}
const std::vector<float>& operator[](const std::string& key) const // access vector by key
{
return vectors.at(key);
}
};
void useStruct(const INFO& info) // pass instance by const reference
{
std::cout << info["fADataLHS"][0] << "\n"; // access element 0 from the fADataLHS array
// get the entire array:
const auto& arr = info["fADataRHS"];
// this will throw a std::out_of_bounds
const auto& arr = info["non-existent-key"];
}
EDIT: A few other notes:
in C++ try not to use float - use double instead
if you need to alter the vector contents from client code, add a non-const version of the operator[]

Using global variable for array size in class

I want to define dynamic array h of size size and later in other functions, modify and use it as here:
class definition:
static int size=10;
class hash{
public:
string h[size];
hash();
void resize();
void operations();
void print();
};
hash::hash()
{
h[size-1]="nikhil"; //size=10 now.
}
/*Defining `h` as `string* h=new string[size];` is not working.
My compiler (MinGW on Windows 7) show error: dynamic allocation is not allowed by default*/
// resizing the array
void hash::resize( )
{
string temp[2*size];
for(int i=0;i<=size;i=i+1)
{
temp[i]=h[i];
}
size=2*size;
h=temp;
}
void hash::print()
{
for(int i=0;i<size;i=i+1)
{if(!h[i].empty())
{cout<<"h["<<i<<"]="<<h[i]<<endl;}
}
}
int main()
{
hash p;
p.resize();//now size should change to 20.
p.print();
}
Where is the problem is it defining the size variable or in resizing the array?
Use std::vector if you need arrays of dynamic size.
class hash {
public:
std::vector<std::string> h;
hash();
void resize();
void operations();
void print();
};
hash::hash() : h(10) {
h[9] = "nikhil";
}
void hash::resize() {
h.resize(2 * h.size());
}
Though note that std::vector does resizing for you automatically if you add new elements using push_back. Also note that the standard library has hash table data types already (std::unordered_set and std::unordered_map), so you don’t have to write them yourself.
I do not know C++ but you haven't exactly told what is going on.
But the way your resize() method is working is the for loop goes through 2*the size of H which will cause a problem.
When you loop through 2*size it is trying to loop through more items than what you actually have in the original array. you have to loop through the original array size.
for(int i = 0; i < h.size(); i++)
{
temp[i] = h[i];
}
I can barely see the comments in your code they are too light for me so I didn't see them.
But to explain a little better i guess, lets say original array is size 5 your new one is size 10 when you loop through 10 items you dont have 10 items in the original array so you'll get errors when trying to access them.

Values from vector differ from the original value

I am confused with C++ vector and ask for help.
I declare a class CBoundaryPoint:
class CBoundaryPoint:
{
public:
double m_param;
int m_index;
}
And then I define a vector:
vector<CBoundaryPoint> vBoundPoints;
CBoundaryPoint bp;
double param;
// other codes
bp.m_param = param;
vBoundPoints.push_back( bp );
It surprises me that for every element in vBoundPoints, the value of m_param is totally different from the given value param. I just don't know why.
For Example:
param = 0.3356;
bp.m_param = param; // so bp.param equals to 0.3356;
vBoundPoints.push_back( bp ); // while (*(vBoundPoints.end()-1)).m_param = -6.22774385622041925e+066; same case to other elements
So what happened and why? I'm using VS2010.
You probably get garbage when you resize the vector or create a vector of a certain size using the size_type constructor. You get default-constructed objects in your vector, and these contain primmitive types. Since you have no user defined default constructor, the values are essentially random, or "garbage".
You can fix this by adding a default constructor to your class:
class CBoundaryPoint:
{
public:
CBoundaryPoint : m_param(), m_index() {} // initializes members to 0. and 0
double m_param;
int m_index;
}