initialize array of structs - c++

I have a class like this:
class Wall
{
private :
Quad faces[6];
};
I have the constructor like this :
Wall::Wall(Quad f[], const float &mass, Vector3 center)
I want to initialize faces to be f(or copy f to faces),Quad is struct that doesn't have a default constructor.
Now I solved the problem by using faces{f[0],f[1],f[2],f[3],f[4],f[5]} in the initializer list but this requires c++11 which I'm afraid some of my friends don't have it, and I need to pass my code to them.
There are many similar questions but all of them seem to not have solutions other than switching to vector or using some complicated code which I don't want, as you can understand from the classes' name, a Wall doesn't need a vector(it only has 6 faces so why a vector).
Is this really hopeless ? isn't there any way ?
PS
Whether in the constructor body or in the initializer list, it doesn't matter.
changing to dynamic arrays(Quad *) doesn't matter either but keeping with static arrays is preferable.

Several options. The easiest is probably to subclass Quad with something that has a default constructor:
class Wall {
public:
Wall(Quad f[], ...) {
for (int i = 0; i < 6; ++i) faces[i] = f[i];
}
private:
class MyQuad : public Quad {
MyQuad() : Quad(...) {}
}
MyQuad faces[6];
};
Another option is to use placement new - note that the code below doesn't work out of the box since it is not doing proper alignment/padding and dealing with some aliasing issues, which are left as an exercise to the reader. It should give you a starting point though.
class Wall {
public:
Wall(Quad f[], ...) {
for (int i = 0; i < 6; i++) {
// TODO: take padding into account
new (&faces_data + sizeof(Quad) * i) Quad(f[i]);
}
}
~Wall() {
for (int i = 0; i < 6; i++) {
face(i).~Quad();
}
}
Quad& face(int idx) {
// TODO: take padding into account
return (reinterpret_cast<Quad*>(faces_data))[idx];
}
private:
// TODO: force proper alignment and take padding into account
char faces_data[sizeof(Quad) * 6];
};

Related

Alternatives to virtual get and set functions?

I'm running into a situation where I need to use virtual get and set functions to access members of derived classes. However, as pointed out in the answers of this topic (which is quite similar to my problem by the way), this is a bad practice and may mean that my classes need to be redesigned. The thing is... I'm new to C++ and OOP in general, so I'm not sure how exactly I can write my code in a different way.
If you have the patience, I'll explain my situation: I'm working on a code that can solve two different types of problem (say ProblemX and ProblemY). Depending on the user input, you can solve only problemX, only ProblemY, or both at the same time. If you want to solve only ProblemX, you need only a variable named "memberX". If you want to solve only ProblemY, you need only "memberY". If you want to solve both at the same time, you'll need both "memberX" and "memberY", but the problems will depend on each other, so you can't solve each problem individually. In short, the code would be something like this:
#include <vector>
class Problem
{
public:
double memberX;
double memberY;
};
class MainProblem
{
public:
std::vector<Problem*> problems;
};
int main()
{
bool solveProblemX = true; // This variable will depend on user input
bool solveProblemY = true; // This variable will depend on user input
MainProblem * mainProblem = new MainProblem();
for (int i = 0; i < 10000; i++)
{
Problem * problem = new Problem();
mainProblem->problems.push_back(*problem);
}
if (solveProblemX && solveProblemY)
{
// Solve interconnected problem, using "mainProblem->problem[i]->memberX" and "mainProblem->problem[i]->memberY";
}
else if (solveProblemX)
{
// Solve individual problem, using only "mainProblem->problem[i]->memberX";
}
else if (solveProblemY)
{
// Solve individual problem, using only "mainProblem->problem[i]->memberY";
}
else
{
// throw some exception
}
}
So far so good... the real problem is: although I gave only a small sample of the code, my real program is in fact very memory expensive (I actually have a large set of Problems, and each contains a large set of members). So, in order to reduce memory usage, I had to make some modifications. For example: If the user chooses to solve only problemX, the variable memberY will only be a dead weight, since the program won't need it. And vice versa.
Therefore, I thought in making derived classes for ProblemX and ProblemY individually, each containing their respectives data member. That way, I can assign to the vector of problems only a minor class containing specifically the data I need. And if I need both, I use another derived class named ProblemXandY, which containd both memberX and memberY. This is the code I thought:
#include <vector>
class Problem
{
public:
virtual double getMemberX(){ // Throw some exception};
virtual double getMemberY(){ // Throw some exception};
};
class ProblemX : public Problem
{
private:
double memberX;
public:
double getMemberX(){ return memberX; };
};
class ProblemY : public Problem
{
private:
double memberY;
public:
double getMemberY(){ return memberY; };
};
class ProblemXandY : public ProblemX, public ProblemY
{};
class MainProblem
{
public:
std::vector<Problem*> problems;
};
int main()
{
bool solveProblemX = true; // This variable will depend on user input
bool solveProblemY = true; // This variable will depend on user input
MainProblem * mainProblem = new MainProblem();
for (int i = 0; i < 10000; i++)
{
Problem * problem;
if (solveProblemX && solveProblemY)
problem = new ProblemXandY();
else if (solveProblemX)
problem = new ProblemX();
else if (solveProblemY)
problem = new ProblemY();
else
// throw some exception
mainProblem->problems.push_back(*problem);
}
if (solveProblemX && solveProblemY)
{
for (int i = 0; i < 10000; i++)
{
double memberX = mainProblem->problems[i]->getMemberX();
double memberY = mainProblem->problems[i]->getMemberY();
// Solve interconnected problem, using "memberX" and "memberY"
}
}
else if (solveProblemX)
{
for (int i = 0; i < 10000; i++)
{
double memberX = mainProblem->problems[i]->getMemberX();
// Solve individual problem, using only "memberX";
}
}
else if (solveProblemY)
{
for (int i = 0; i < 10000; i++)
{
double memberY = mainProblem->problems[i]->getMemberY();
// Solve individual problem, using only "memberY";
}
}
else
{
// throw some exception
}
}
My question is regarding the virtual get functions on the class Problem. It feels strange, I agree, since the variables memberX and memberY don't belong to the class Problem. However, without it I wouldn't be able to call mainProblem->problems[i]->getMemberX(), since mainProblem->problems[i] is an object of the base class Problem, instead of the derived classes. As I said, my program is memory expensive. That's why I chose to have a single vector of Problems in the class MainProblem, instead of multiple vectors, one for each derived class. Is there something wrong with my structure here? Should I really redesign it? If so, can you think of an alternative?

c++ error: array initializer must be an initializer list

I have really been struggling with a piece of code for a couple days. The error message i receive when i run my code is:
error: array initializer must be an initializer list
accountStore (int size = 0) : accts(size) { }
There seem to be others with similar problems here but unfortunately I am unable to apply their solutions (either don't work or not applicable).
What I am simply attempting to do is create a container class (array, can't use vectors) of a class 'prepaidAccount' but I am just unable to get the constructor portion of the container class 'storeAccount' to work. See code snippet below:
class prepaidAccount{
public:
//prepaidAccount ();
prepaidAccount(string newPhoneNum, float newAvailBal) : phoneNumber(newPhoneNum), availableBalance (newAvailBal){} //constructor
double addBalance(double howMuch) {
availableBalance = howMuch + availableBalance;
return availableBalance;
}
double payForCall(int callDuration, double tariff) {
callDuration = callDuration/60; //convert to minutes
double costOfCall = callDuration * tariff;
if (costOfCall > availableBalance) {
return -1;
}
else {
availableBalance = availableBalance - costOfCall;
return costOfCall;
}
}
void setAvailBal(int newAvailBal) {availableBalance = newAvailBal;}
float getAvailBal() {return availableBalance;}
void setPhoneNum(string newPhoneNum) {phoneNumber = newPhoneNum;}
string getPhoneNum() const {return phoneNumber;}
private:
string phoneNumber;
float availableBalance;
};
class accountStore { //made to store 100 prepaid accounts
public:
accountStore (int size = 0) : accts(size) { }
....
private:
prepaidAccount accts[100];
}
In main I simply call accountStore Account;
Any help is absolutely welcome. I very recently started learning c++ and about classes and constructors so please bear with me.
Thanks
You can't initialize an array with int like accountStore (int size = 0) : accts(size) {}.
prepaidAccount doesn't have a default constructor, you have to write member initialization list like,
accountStore (int size = 0) : accts{prepaidAccount(...), prepaidAccount(...), ...} { }
The array has 100 elements, it's not a practical solution here.
As a suggestion, think about std::vector, which has a constructor constructing with the spicified count of elements with specified value. Such as,
class accountStore {
public:
accountStore (int size = 0) : accts(size, prepaidAccount(...)) { }
....
private:
std::vector<prepaidAccount> accts;
};
Given that you have specified that you do not want to use a container such as std::vector but would like to specify the size at runtime, your only option would be to manually implement dynamic allocation yourself. Also given that you are wanting create 100 objects at a time, I would suggest making a function that can construct a temporary object according to your needs and then use this to initialise your dynamically allocated array. Consider the below code as a good starting point. (WARNING untested code.)
class prepaidAccount {
public:
// Constructor
prepaidAccount(string newPhoneNum, float newAvailBal)
: phoneNumber(newPhoneNum), availableBalance(newAvailBal) {}
// Default Constructor needed for dynamic allocation.
prepaidAccount() {}
/* your code*/
};
// Used to construct a tempoary prepaid account for copying to the array.
// Could use whatever constructor you see fit.
prepaidAccount MakePrepaidAccount(/*some parameters*/) {
/* Some code to generate account */
return some_var;
}
class accountStore {
public:
// Explicit constructor to avoid implicit type-casts.
explicit accountStore(const int &size = 0)
: accts(new prepaidAccount[size]) {
for (int i = 0; i < size; i++) {
// Will call defualt assignment function.
prepaidAccount[i] = MakePrepaidAccount(/*some parameters*/);
}
}
// Destructor
~accountStore() {
// Cleans up dynamically allocated memory.
delete[] prepaidAccount;
}
prepaidAccount *accts;
};
Edit: Amongst the c++ community it is often questionable when choosing to use dynamic allocation when there is such an excellent and comprehensive library of smart pointers. For example an std::vector would be perfect in this situation.

Consruct Member Class using Data computed in Composing Class

I have a class Itch that is a member of the class Scratch. I want to do some computations in the Scratch constructor and pass the result of these computations to instantiate the Itch object. My best guess in doing this is below, but this returns garbage:
#include <iostream>
class Itch {
public:
int N;
Itch(int n) {N = n;}
};
class Scratch {
private:
int N;
public:
Itch it;
Scratch(int n);
};
Scratch::Scratch(int n) : it(N) // here is where I want to use new data
{
// do some silly things
int temp = 5;
temp += n + 45;
N = temp - 1;
}
int main() {
int n = 1;
Scratch sc(n);
std::cout << sc.it.N << "\n";
}
Is there a standard way to do this?
The things in the initializer list happen before the things in the constructor code. Therefore, you cannot affect anything in the initializer list with the code in the constructor. You have a few options.
A reasonable approach would be to have an Itch * member rather than an Itch, and initialize it when it's ready, e.g.:
class Scratch {
...
Itch *it;
...
};
Scratch::Scratch(int n) : it(NULL)
{
// do some silly things
int temp = 5;
temp += n + 45;
N = temp - 1;
it = new Itch(N); // <- now you have enough info to instantiate an Itch
}
And you'll have to remember to clean up in the destructor unless you use an auto_ptr:
Scratch::~Scratch () {
delete it;
}
Another reasonable approach would be to pass n to the Itch constructor and have it do the calculations there instead of in Scratch, perhaps even allowing Itch to determine N, e.g.:
class Itch {
private:
int N;
public:
Itch (int n);
int getN () const { return N; }
}
Itch::Itch (int n) {
// do some silly things
int temp = 5;
temp += n + 45;
N = temp - 1;
}
Scratch::Scratch (int n) : it(n) {
// you can either remove Scratch::N altogether, or I suppose do:
N = it.getN();
// ... do whatever makes sense, try not to have redundant data.
// (also ask yourself if Scratch even *needs* to know N, or at
// least if it can just use it.getN() everywhere instead of
// keeping its own copy.)
}
Another approach, which IMO is a bit odd but it's still possible in some situations, is to have e.g. a static function (member or not) that computes N from n, which you can use in the initializer list, e.g.:
static int doSillyThings (int n) {
int temp = 5;
temp += n + 45;
return temp - 1;
}
Scratch::Scratch(int n) : N(doSillyThings(n)), it(N)
{
}
Choose whichever leads to the cleanest, most maintainable and easy-to-read code. Personally I'd prefer the first, Itch * option, since it makes logical sense and is very clear: You do the calculations necessary to initialize the Itch, then you initialize it.
You should think about your code a bit. If the Scratch's N is always equal to it.N, then do you really need both Ns?
There are other options too (including restructuring your code completely so you don't have to have an Itch member of Scratch, or so that you don't have to have it depend on extra calculations done on the Scratchs constructor parameters but that really depends on the situation), but hopefully that inspires you a little.
The reason your code returns garbage, by the way, is because N is garbage at the point you pass it to the Itch constructor. It's uninitialized until you initialize it, and at the point where it(N) is you haven't initialized N yet.

C++ Inheritance and how to pass and maintain subclass data through a superclass

Alright, wasn't quite sure how to word the question and couldn't find any duplicates that I think really address this situation.
Essentially I have a super class that gets extra data appended to it through a subclass. The container class for this data recognizes only the super class and adjust characteristics based on an id parameter in the super class.
I've actually never had to used inheritance in c++ till recently so forgive me if this is trivial. I'm under the impression that when I go to hard copy a bunch of data using the superclass, the subclass data is loss in translation so to speak. In order to bypass this limitation I'm trying to use a typecast-ed pointer however I now get a segmentation fault when trying to free the memory even when typecasting the pointer parameter in the free() function.
Here is the sample code...
Structs
// Super class
struct Vertex {
__declspec(align(4)) unsigned int vType; // Identifies the vertex type.
Vertex(const unsigned int _vType) : vType(_vType) { }
Vertex(const Vertex &_rV) : vType(_rV.vType) { } // Copy constructor
virtual ~Vertex() { }
unsigned int GetVType() const { return vType; }
};
// Subclass
// Id = 1
struct V_Pos : Vertex {
__declspec(align(4)) XMFLOAT3 position;
V_Pos(void) : Vertex(1) { }
V_Pos(XMFLOAT3 &_rPosition) : Vertex(1), position(_rPosition) { }
V_Pos(const V_Pos &_rV) : Vertex(_rV), position(_rV.GetPosition()) { } // Copy constructor
~V_Pos() { }
XMFLOAT3 GetPosition() const { return position; }
};
Here is how I'm currently copying the data.
// pBuffer is declared as a Vertex* data type
pBuffer = new V_Pos[_bufSize];
if (_pVBuffer->GetVType() == 1)
for (unsigned int i = 0; i < bufSize; ++i) {
V_Pos *_temp = (V_Pos*)&_pVBuffer[i];
pBuffer[i] = *_temp;
}
Here is how I am currently de-allocating the data.
if (pBuffer != 0) {
delete [] pBuffer;
pBuffer = 0;
}
What is the correct approach for this situation?
Edit 1 -
Updated the above code blocks to clarify the comment discussion under knulp's answer.
If you start mixing low level memory allocation with malloc()/free(), and C++ objects, you will run into a lot of troubles, while making your code almost unreadable.
You should create a new object with new on a proper constructor, which automatically 1) allocates memory and 2) initializes the struct. To properly free the memory you should use delete and the destructor.
You should copy using a copy constructor and an assignment operator. If you do not define them, the default ones are automatically defined by the compiler to perform a bitwise copy.
Why are you using a type field? C++ has a very strong typing features, so it makes very little sense to bypass all C++ mechanism to define a vType. Rather, define a base class, and two or more derived classes from there, and just eliminate the vtype field.
If you use clean OO programming, you will avoid all these problems from the start.
Your base class needs to have a virtual destructor. This will allow you to safely delete a derived class with a base class pointer.
Not that! Use a copy constructor.
// Super class
struct Vertex {
__declspec(align(4)) unsigned int vType; // Identifies the vertex type.
Vertex(const unsigned int _vType) : vType(_vType) { }
unsigned int GetVType() const { return vType; }
Vertex(const Vertex& v) : vType(v.vType) {}
};
// Subclass
// Id = 1
struct V_Pos : Vertex {
__declspec(align(4)) XMFLOAT3 position;
V_Pos(void) : Vertex(1) { }
V_Pos(XMFLOAT3 &_rPosition) : Vertex(1), position(_rPosition) { }
V_Pos(const V_Pos& v) : Vertex(v) {
position[0] = v.position[0];
position[1] = v.position[1];
position[2] = v.position[2];
}
};
Better yet, use a vecotr instead of XMFLOAT3;
Create a copy on the heap:
V_Pos original(...);
V_Pos * copyPtr = new V_Pos(original);

Handling Huge Multidimensional Arrays in C++

I'm designing a game in C++ similar to Minecraft that holds an enormous amount of terrain data in memory. In general, I want to store an array in memory that is [5][4][5][50][50][50]. This isn't bad since it amounts to about 100mb of virtual memory since my structure will only be about 8 bytes.
However, I'm having trouble figuring out the best way to handle this. I do want this to be in virtual memory, but obviously not on the stack. And I keep making the mistake some how of creating this array on the stack an causing a stack overflow. What I would like to do is below. This is just code that I threw together to give you an example of what I'm doing, I have code with correct syntax on my machine, I just didn't want to clutter the post.
typedef struct modelBlock
{
// Information about the blocks
} BLOCK;
typedef struct modelGrid
{
bool empty;
BLOCK blocksArray[50][50][50];
} GRID;
class Parent
{
Child* child;
Parent(void);
}
Parent::Parent()
{
Child c;
child = &c;
}
class Child
{
GRID grids[5][4][5];
}
However, every time I do this, I cause a stack overflow (appropriate web site choice right?). I played with using pointer based arrays, but I had a lot of trouble with data being lost outside of its scope.
If anyone could give me some insight on how to get my data to store on the heap instead of the stack, or if I should use some other way of creating my array, I'd really appreciate the help. I'd like to avoid using vectors because of overhead, though I'm not sure how substantial it is.
Use boost::multi_array
If you want to allocate something on the heap, use new.
#include <memory>
class Parent
{
std::auto_ptr<Child> child; // use auto_ptr for dynamically-allocated members
Parent(const Parent&); // You probably don't want to copy this giant thing
public:
Parent();
};
Parent::Parent()
: child(new Child) // initialize members with an initializer list
{
}
Also, avoid mixing C and C++ styles. There's no reason to do
typedef struct blah{ ... } BLAH;
in C++. A struct is just a class with all of the members public by default; just like a class, you can refer to the struct type's name without using the struct tag. There's also no need to specify void for a function that takes no parameters.
boost::multi_array (linked in PigBen's answer) is a good choice over raw arrays.
If you want the class created on the heap, create it with new:
Child * c = new Child;
and then of course delete it, or better still use a smart pointer.
In order to do exactly what you're trying to do you have to declare everything as pointers (and pointers to pointers to pointers to pointers) and then allocate each one individually.
Teh sux!
A better option is to simply allocate the ginormous block in one chunk and use multiple variable along with pointer arithmetic to arrive at the correct location.
Edit: Wasn't paying attention and didn't notice your constructor. That's not only not the way to get your Child allocated on the free-store, it's a great way to create situations eliciting undefined behavior. Your Child will be gone when the constructor is through and the pointer to it will then be invalid. I wonder if you shouldn't run through some basic tutorials before trying to write a game.
Here's something that works and can be built upon without the boost dependency. One downside is it removes use of [][][] style of referencing elements, but it's a small cost and can be added.
template<class T>
class Matrix {
unsigned char* _data;
const size_t _depth;
const size_t _cols;
const size_t _rows;
public:
Matrix(const size_t& depth, const size_t& rows, const size_t& cols):
_depth(depth),
_rows(rows),
_cols(cols) {
_data = new unsigned char [depth * rows * cols * sizeof(T)];
}
~Matrix() {
delete[] _data;
}
T& at(const size_t& depthIndex, const size_t& rowIndex, const size_t& colIndex) const {
return *reinterpret_cast<T*>(_data + ((((depthIndex * _cols + colIndex) * _rows) + rowIndex) * sizeof(T)));
}
const size_t& getDepth() const {
return _depth;
}
const size_t& getRows() const {
return _rows;
}
const size_t& getCols() const {
return _cols;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Matrix<int> block(50, 50, 50);
size_t d, r, c;
for (d = 0; d < block.getDepth(); d++) {
for (r = 0; r < block.getRows(); r++) {
for (c = 0; c < block.getCols(); c++) {
block.at(d, r, c) = d * 10000000 + r * 10000 + c;
}
}
}
for (d = 0; d < block.getDepth(); d++) {
for (r = 0; r < block.getRows(); r++) {
for (c = 0; c < block.getCols(); c++) {
assert(block.at(d, r, c) == d * 10000000 + r * 10000 + c);
}
}
}
return 0;
}
A smaller example (with changed names for all the structs, to make the general principle clearer). The 'Bloe' struct is the one you want to allocate on the heap, and this is accomplished using 'new'.
struct Bla {
int arr[4][4];
};
struct Bloe {
Bla bla[2][2];
};
int main()
{
Bloe* bloe = new Bloe();
bloe->bla[1][1].arr[1][1] = 1;
return 0;
}
I did this by putting all the data in a binary file. I calculated the offset of the data and used seek() and read() to get the data when needed. The open() call is very slow so you should leave the file open during the lifetime of the program.
Below is how I understood what you showed you were trying to do in your example. I tried to keep it straightforward. Each Array of [50][50][50] is allocated in one memory chunk on the heap, and only allocated when used. There is also an exemple of access code. No fancy boost or anything special, just basic C++.
#include <iostream>
class Block
{
public:
// Information about the blocks
int data;
};
class Grid
{
public:
bool empty;
Block (*blocks)[50][50];
Grid() : empty(true) {
}
void makeRoom(){
this->blocks = new Block[50][50][50];
this->empty = false;
}
~Grid(){
if (!this->empty){
delete [] this->blocks;
}
}
};
class Parent
{
public:
Grid (* child)[4][5];
Parent()
{
this->child = new Grid[5][4][5];
}
~Parent()
{
delete [] this->child;
}
};
main(){
Parent p;
p.child[0][0][0].makeRoom();
if (!p.child[0][0][0].empty){
Block (* grid)[50][50] = p.child[0][0][0].blocks;
grid[49][49][49].data = 17;
}
std::cout << "item = "
<< p.child[0][0][0].blocks[49][49][49].data
<< std::endl;
}
This could still be more simple and straightfoward and just use one bug array of [50][50][50][5][4][5] blocks in one memory chunk on the heap, but I'll let you figure out how if this is what you want.
Also, usind dynamic allocation in class Parent only has the sole purpose to use heap instaed of stack, but for such a small array (5*4*5 pointers), allocating it on stack should not be a problem, hence it could be written.
class Parent
{
public:
Grid child[5][4][5];
};
without changing anything in the way it is used.