I have a public class in which I create an array, this array takes its size from the constructor and needs to be used in other functions (including int main). Therefore the variable must be public. my code looks something along these lines:
class myclass {
public:
int parameter1;
int parameter2;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
}
void makeArray() {
int array[parameter1][parameter2]; //I want this array to be public as the next method needs access to it
}
void otherFunction() {
array[1][2] = 5; //just an example of what i need to do
}
}
Look up how to use pointers and dynamic memory..
To do what you want would be something like:
class myclass {
public:
int parameter1;
int parameter2;
int **a;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
a = nullptr;
}
~myclass() {
// TODO: delete "a"
}
void makeArray() {
// TODO: delete "a" if it has already been allocated
a = new *int[parameter1];
for (int i = 0; i < parameter1; ++i) {
a[i] = new int[parameter2];
}
}
void otherFunction() {
// TODO: check that "a" has already been allocated
a[1][2] = 5; //just an example of what i need to do
}
}
You could also allocate the array in the constructor since you have the necessary information being passed in already.
This is more optimized way to do the same thing:
class myclass {
public:
int parameter1;
int parameter2;
int *array;
myclass(int p1, int p2) {
parameter1 = p1;
parameter2 = p2;
}
void makeArray() {
array = new int[parameter1*parameter2];
}
void otherFunction() {
// ary[i][j] is then rewritten as ary[i*sizeY+j]
array[1*parameter2+2] = 5;
}
};
int main()
{
int sizeX = 5;
int sizeY = 5;
myclass m1(sizeX,sizeY);
m1.makeArray();
m1.otherFunction();
cout << m1.array[1*sizeY+2] << endl;
return 0;
}
Related
I have an array in my MainProcessor
float waveforms[2][1080] = { {0}, {0} };
And I pass it to a SynthVoice like this:
osc1Voice->setWavetable(waveforms, 0); //[1]
osc2Voice->setWavetable(waveforms, 1);
There I read it like this in SynthVoice.h:
typedef float array_of_wavetable[1080];
void setWavetable(array_of_wavetable* waveform, int number)
{
wavetable = waveform;
id = number;
}
so i can use it like this in my SynthVoice class:
wavetable[id][first_sample + int(phase_0)]
Now I have moved [1] in a new class (OscilatorProcessor.h) and I want to set a pointer from MainProcessor -> OscillatorProcessor -> SynthVoice in a way that I can use it as wavetable[id][phase].
Now I don't know how to pass it from my MainProcessor to my OscillatorProcessor in the middle. So I can read it in the same way in the SynthVoice class.
I hope this made sense. Thank you for your time
edit: minimal reproducible example
#include <iostream>
typedef float array_of_wavetable[1080];
class SynthVoice
{
public:
void setWavetable(array_of_wavetable* waveform, int number)
{
wavetable = waveform;
id = number;
}
void outputWavetable()
{
for(int i = 0; i < 1080; i++)
{
std::cout << wavetable[id][i];
}
}
private:
array_of_wavetable * wavetable;
int id;
};
class OscillatorProcessor
{
public:
void setWavetable(array_of_wavetable * waveform, int number)
{
wavetable = waveform;
id = number;
}
void sendWaveToVoice()
{
SynthVoice voice;
voice.setWavetable(wavetable, id);
voice.outputWavetable();
}
private:
array_of_wavetable * wavetable;
int id;
};
int main() {
float waveform_templates[4][1080] = { {0}, {0}, {0}, {0} };
OscillatorProcessor oscillator;
oscillator.setWavetable(waveform_templates, 2);
return 0;
}
I'd like to access to a double pointer which is located in another class "Board".
class Board
{
public:
Board(void);
Board(unsigned int xSize, unsigned int ySize);
~Board(void);
void SetObjectManager(ObjectManager* pObm);
void SetBlock(Block* block);
void LoadBoard(void);
void InitBoard(void);
//Other Functions...
private:
ObjectManager* m_obm;
Block* m_block;
//pointer to pointer to a int. (for 2 dimensional-array)
int **m_board;
};
First, the Board class. at the last line of class, you can see m_board.
I want to change this value in outside of this class.
Like this,
void Block::InitBlock(void)
{
int randPiece = Random::GIRand().RandInt(0, 1);
int randPos = Random::GIRand().RandInt(0, 10);
switch (randPiece)
{
case 0:
m_piece[2][1] = 1;
m_piece[2][2] = 1;
m_piece[2][3] = 1;
m_piece[3][3] = 1;
break;
//Other cases are here...
}
std::cout << "RandPos : " << randPos << std::endl;
std::cout << "RandPiece : " << randPiece << std::endl;
for (int y = 0; y < m_ySize; ++y)
{
for (int x = 0, pX = randPos; x < m_xSize; ++x, ++randPos)
{
if (m_piece[x][y] != 0)
m_board->SetBoardStatus(randPos, y, 1);
}
}
}
But, When I run this program, It blows up at SetBoardStatus(int, int, int)
SetBoardStatus looks like this,
void Board::SetBoardStatus(int x, int y, int value)
{
m_board[x][y] = value; //Visual Studio breaks the program here.
}
I allocate the double pointer properly.
And I set the board at the outside of this classes.
void Block::SetBoard(Board* board)
{
m_board = board;
}
And this is my block class.
class Block
{
public:
Block(void);
~Block(void);
void SetObjectManager(ObjectManager* pObm);
void LoadBlock (void);
void InitBlock (void);
void UpdateBlock (void);
void ReleaseBlock (void);
void SetBoard(Board* board);
private:
ObjectManager* m_obm;
Board* m_board;
int **m_piece;
int m_xSize;
int m_ySize;
};
Consider inheriting Block in Board; This will eliminate any possible de-referencing errors or bugs, as you can access the pointer right away.
I wish to
create an array of class/struct items (c1)
then create an array of pointer to the original array (*cp1), which can be sorted
then access members of the class from within a function.
However I'm getting stuck at the initial function call.
Here's my basic code:
struct Car
{
int speed;
};
Car c1[5];
Car *cp1[5];
int main() {
for (int i=0;i<5;i++) {
c1[i].speed = i;
cp1[i] = &c1[i];
}
garage(cp1, 5);
}
void garage(Car **ar, int n) {
int p = (*ar[n / 2])->speed;
}
First of all, your garage function is not known to the compiler at the place where you call it, since it is defined below main. To fix it, either place the function definition above main, or introduce it with a prototype.
Second, at the line int p = (*ar[n / 2])->speed;, *ar[n/2] is not a pointer, so you should use . instead of ->, as in int p = (*ar[n / 2]).speed;
Funcion garage must be declared before you can refer it.
void garage(Car **ar, int n);
int main()
{
//...
}
void garage(Car **ar, int n) {
//...
}
Function main in C++ shall have return type int
int main()
{
//...
}
And within the function the correct expression will look
void garage(Car **ar, int n) {
int p = (*ar )[n / 2]).speed;
}
Or
void garage(Car **ar, int n) {
int p = ar[n / 2]->speed;
}
Or
void garage(Car **ar, int n) {
int p = ( *ar[n / 2] ).speed;
}
struct Car
{
int speed;
};
Car c1[5];
Car *cp1[5];
void garage(Car **ar, int n); // forward declare garage
int main()
{
for (int i=0;i<5;i++) {
c1[i].speed = i;
cp1[i] = &c1[i];
}
garage(cp1, 5);
}
void garage(Car **ar, int n) {
int p = ar[n / 2]->speed; // -> dereferences the pointer, you don't need to
}
I have to do a program for college.
I have 3 classes already declared in the statement of the problem.
First class:
class piesa_a{
protected:
int id;
char *tip;
int pret;
};
Second class:
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
};
Third class:
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
};
In main I need to create an array in which to store items such piesa_a, piesa_b, piesa_c. Then I have to sort items by price.
I have this code so far: http://pastebin.com/nx2FGSfe
The program is incomplete because it does not displays each item in the array.
I got stuck here. But if you display the array's elements when they are outside of it, it works.
SHORT: I have an error on line 143 and I want to solve it.
main.cpp:143:18: error: request for member ‘afisare’ in ‘*(v + ((unsigned int)(((unsigned int)i) * 4u)))’, which is of non-class type ‘piesa_a*’
The code is here:
#include <cstdlib>
#include<iostream>
#include<string.h>
using namespace std;
class piesa_a{
protected:
int id;
char *tip;
int pret;
public:
piesa_a()
{
id = 0;
tip = new char[1];
pret = 0;
}
piesa_a(int aidi, char *typ, int pretz)
{
id = aidi;
tip = new char[strlen(typ)+1];
strcpy(tip,typ);
pret = pretz;
}
piesa_a&operator =(piesa_a alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
return *this;
}
virtual void afisare()
{
cout<<"\n Piesa A: "<<id<<" "<<tip<<" "<<pret;
}
};
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
public:
piesa_b():piesa_a(){lungime = 0;bw = 0;}
piesa_b(float lg,bool bl, int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
lungime = lg;
bw = bl;
}
piesa_b&operator =(piesa_b &c)
{
id = c.id;
tip = new char[strlen(c.tip)+1];
strcpy(tip,c.tip);
pret = c.pret;
lungime = c.lungime;
bw = c.bw;
return *this;
}
void afisare()
{
piesa_a::afisare();
cout<<"impreuna cu piesa B: "<<lungime<<" "<<bw<<"\n";
}
};
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
public:
piesa_c():piesa_a(){nr=0; buf = new piesa_b[nr];}
piesa_c(int n, piesa_b *bu,int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
nr = n;
buf = new piesa_b[nr];
for(int i=0;i<nr;i++)
buf[i]= bu[i];
}
piesa_c&operator =(piesa_c &alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
nr = alta.nr;
for(int i=0;i<alta.nr;i++)
buf[i] = alta.buf[i];
}
void afisare()
{
for(int i=0;i<nr;i++)
buf[i].afisare();
}
};
int main(int argc, char** argv) {
piesa_b *H;
H = new piesa_b[2];
piesa_a A(4,"TIPA",120);
piesa_b B(100,1,3,"TIPA",120);
H[0]=B;
H[1]=B;
piesa_c C(2, H,14,"TIPC",20);
piesa_a** v = new piesa_a*[3];
v[0] = &A;
v[1] = &B;
v[2] = &C;
for(int i=0;i<3;i++)
v[i].afisare();
return 0;
}
What's wrong?
In C++ (and current C), casts are almost always a sign that the programmer didn't know how to use the language as it is supposed to be used. If you need an array of 3 types of data, the cleanest solution is an array of objects of a class that is base to the 3. And if you want to display each item differently, you'll want to overload the << operator, so you just iterate over the array and go << on each item. Sorted by price means that the class includes a price field, and you use the sort from the standard template library, passing a comparison operation that just compares prices.
Given the following scenario where my data might be of different type based on some condition.
class myClass {
public:
myclass() {
if (condition1) {
bool boolValue = false;
data = boolValue;
} else if (condition2) {
int intValue = 0;
data = intValue;
} else if (condition3) {
unsigned int unsignedIntValue = 0;
data = unsignedIntValue;
} else if (condition4) {
long longValue = 0;
data = longValue;
} else if (condition5) {
double doubleValue = 0.0;
data = doubleValue;
} else if (condition6) {
float floatValue = 0.0;
data = floatValue;
} else if (condition7) {
char *buffer = new char[10];
data = buffer;
}
}
void* getData() const { return data; }
private:
void *data;
}
As it happens the value that my void pointer points to is strictly within each statement. Therefore what is returned with getData() might not be valid. If I do get the data it is simply because the memory location where I point to is not yet written over.
The solution I have come up with is this:
class myClass {
public:
myclass() {
if (condition1) {
boolValue = false;
data = boolValue;
} else if (condition2) {
intValue = 0;
data = intValue;
} else if (condition3) {
unsignedIntValue = 0;
data = unsignedIntValue;
} else if (condition4) {
longValue = 0;
data = longValue;
} else if (condition5) {
doubleValue = 0.0;
data = doubleValue;
} else if (condition6) {
floatValue = 0.0;
data = floatValue;
} else if (condition7) {
buffer = new char[10];
data = buffer;
}
}
void* getData() const { return data; }
private:
void *data;
bool boolValue;
int intValue;
unsigned int unsignedIntValue;
long longValue;
double doubleValue;
float floatValue;
char *buffer;
}
I was thinking there must be a more elegant way to do this. Any suggestions?
You could use a union to save a few bits in memory, and then use pointer casting to get the value from the union:
#include<iostream>
using namespace std;
class myClass {
public:
myClass(char *str){
data.str = str;
}
myClass(double d){
data.d = d;
}
myClass(float f){
data.f = f;
}
void *getData() { return (void*)&data; }
private:
union {
double d;
float f;
char *str;
} data;
};
int main(){
myClass c(2.0);
cout << *(double*)c.getData() << endl;
myClass f(3.0f);
cout << *(float*)f.getData() << endl;
myClass s("test");
cout << *(char**)s.getData() << endl;
system("pause");
}
/* prints
2
3
test
*/
If you don't need to change the type of the data after you create an object, then you could use a template class:
template <typename T>
class myBaseClass {
public:
// Declare common functions here.
T getData()
{ return data; }
protected:
T data;
protected:
// Disallow constructing instances of this class outside the child classes.
myBaseClass(T val) : data(val) { }
};
template <typename T>
class myClass: public myBaseClass<T> {
public:
myClass() : myBaseClass<T>(0) { }
};
You then specialize for char*:
template <>
class myClass<char*>: public myBaseClass<char*> {
public:
myClass() : myBaseClass(new char[10]) { }
};
You then create instances like this:
myClass<int> a;
myClass<float> b;
myClass<char*> c;
// etc.
int i = a.getData();
float f = b.getData();
char* str = c.getData();