Variables across classes problem

I am trying to port a smoke effect from Processing (based on the Processing sketch by Glen Murphy at http://processing.org/learning/topics/smoke.html) across to OF to play with and learn from, and have been caught out by something fundamental- the fact that one class declares variables needed by the other classes, which can’t be seen by these other classes. It’s not solved by #include and inheritance does not work either (making all the classes extend the central class). I seem to not quite understand how these classes interlink…

Just to outline the problem: I have a smoke.h and .cpp which is going to eventually be called by testapp. This smoke class uses a particle, vbuffer and vsquare class. These make use of variables declared in smoke.h and .cpp. Xcode throws out the following errors when I try to compile. There are still other parts to clean up from the Processing port (like pMouse etc) but you should be able to see where I might be going wrong?:

  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp: In constructor 'Smoke::Smoke()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp:12: error: no matching function for call to 'VSquare::VSquare()'  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.h:23: note: candidates are: VSquare::VSquare(int, int)  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.h:15: note:                 VSquare::VSquare(const VSquare&)  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp:12: error: no matching function for call to 'VBuffer::VBuffer()'  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.h:25: note: candidates are: VBuffer::VBuffer(int, int)  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.h:14: note:                 VBuffer::VBuffer(const VBuffer&)  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp:12: error: no matching function for call to 'Particle::Particle()'  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.h:21: note: candidates are: Particle::Particle(float, float)  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.h:12: note:                 Particle::Particle(const Particle&)  
  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp: In member function 'void Particle::reposition()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:18: error: 'WIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:18: error: 'random' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:19: error: 'HEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:19: error: 'ofRandom' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp: In member function 'void Particle::updatepos()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:26: error: 'RES' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:29: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:29: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:30: error: 'v' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:56: error: 'ofRandom' was not declared in this scope  
  
  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp: In member function 'void VBuffer::updatebuf(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:22: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:22: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:23: error: 'v' was not declared in this scope  
  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::addbuffer(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:17: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:17: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:18: error: 'vbuf' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::updatevels(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:44: error: 'randomGust' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:45: error: 'randomGustX' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:46: error: 'randomGustY' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:47: error: 'sqrt' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:48: error: 'randomGustSize' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:49: error: 'RES' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:51: error: 'randomGustMax' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:51: error: 'randomGustXvel' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:52: error: 'randomGustYvel' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::display(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:66: error: 'lwidth' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:66: error: 'lheight' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:79: error: 'v' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:88: error: 'fill' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:89: error: 'RES' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:89: error: 'rect' was not declared in this scope  
  
  

The actual code producing these are:

  
  
smoke.h  
  
#pragma once  
  
#ifndef SMOKE  
#define SMOKE  
  
#include "ofMain.h"  
#include "VSquare.h"  
#include "VBuffer.h"  
#include "Particle.h"  
  
#define LWIDTH 151  
#define LHEIGHT 11  
  
class Smoke {  
public:  
	int WIDTH;  
	int HEIGHT;  
	  
	int RES;  
	int PENSIZE;  
	  
  
	int PNUM;  
	  
	  
	VSquare v [LWIDTH] [LHEIGHT] ;  
	VBuffer vbuf [LHEIGHT][LHEIGHT] ;  
	  
	Particle p [30000];  
	  
	int pcount;  
	int mouseXvel;  
	int mouseYvel;  
	  
	int randomGust;  
	int randomGustMax;  
	float randomGustX;  
	float randomGustY;  
	float randomGustSize;  
	float randomGustXvel;  
	float randomGustYvel;  
	  
	Smoke();  
	  
	void init();  
	void draw();  
	  
	  
};  
#endif  
  
  

and for the smoke.cpp

  
  
smoke.cpp  
  
#include "Smoke.h"  
  
  
Smoke::Smoke(){  
	WIDTH = 300;  
	HEIGHT = 300;  
	  
	RES = 2;  
	PENSIZE = 30;  
	  
	  
	PNUM = 30000;  
	  
	pcount = 0;  
	mouseXvel = 0;  
	mouseYvel = 0;  
	  
	randomGust = 0;  
}  
  
void Smoke::init(){  
	  
		for(int i = 0; i < PNUM; i++) {  
			  
			p[i] = Particle(ofRandom(WIDTH/2-20,WIDTH/2+20),ofRandom(HEIGHT-20,HEIGHT));  
	}  
	for(int i = 0; i <= LWIDTH; i++) {  
		for(int u = 0; u <= LHEIGHT; u++) {  
			v[i][u] = VSquare(i*RES,u*RES);  
			vbuf[i][u] = VBuffer(i*RES,u*RES);  
		}  
	}  
	  
}  
  
  
  
void Smoke::draw() {  
	//int axvel = mouseX-pmouseX;  
	//int ayvel = mouseY-pmouseY;  
	  
	//mouseXvel = (axvel != mouseXvel) ? axvel : 0;  
	//mouseYvel = (ayvel != mouseYvel) ? ayvel : 0;  
	  
	if(randomGust <= 0) {  
		if(ofRandom(0,10)<1) {  
			randomGustMax = (int)ofRandom(5,12);  
			randomGust = randomGustMax;  
			randomGustX = ofRandom(0,WIDTH);  
			randomGustY = ofRandom(0,HEIGHT-10);  
			randomGustSize = ofRandom(0,50);  
			if(randomGustX > WIDTH/2) randomGustXvel = ofRandom(-8,0);  
			else randomGustXvel = ofRandom(0,8);  
			randomGustYvel = ofRandom(-2,1);  
		}  
		randomGust--;  
	}  
	  
	for(int i = 0; i < LWIDTH; i++) {  
		for(int u = 0; u < LHEIGHT; u++) {  
			vbuf[i][u].updatebuf(i,u);  
			v[i][u].col = 0;  
		}  
	}  
	for(int i = 0; i < PNUM-1; i++) {  
		p[i].updatepos();  
	}  
	for(int i = 0; i < LWIDTH; i++) {  
		for(int u = 0; u < LHEIGHT; u++) {  
			v[i][u].addbuffer(i, u);  
			v[i][u].updatevels(mouseXvel, mouseYvel);  
			v[i][u].display(i, u);  
		}  
	}  
	randomGust = 0;  
}  
  
  

and for a typical subclass that tries to use some of the variables and which xcode seems to be unhappy about:

  
  
particle.h  
  
#ifndef PARTICLE  
#define PARTICLE  
  
class Particle{  
public:  
	float x;  
	float y;  
	float xvel;  
	float yvel;  
	float temp;  
	int pos;  
	  
	Particle(float xIn, float yIn);  
	  
	void reposition();  
	void updatepos();  
	  
	  
	  
	};  
#endif  
  
particle.cpp  
  
#include "Particle.h"  
  
Particle::Particle(float xIn, float yIn){  
	x = xIn;  
	y = yIn;  
}  
  
void Particle::reposition() {  
	x = WIDTH/2+random(-20,20);  
	y = ofRandom(HEIGHT-10,HEIGHT);  
	  
	xvel = ofRandom(-1,1);  
	yvel = ofRandom(-1,1);  
}  
  
void Particle::updatepos() {  
	int vi = (int)(x/RES);  
	int vu = (int)(y/RES);  
	  
	if(vi > 0 && vi < LWIDTH && vu > 0 && vu < LHEIGHT) {  
		v[vi][vu].addcolour(2);  
		  
		float ax = (x%RES)/RES;  
		float ay = (y%RES)/RES;  
		  
		xvel += (1-ax)*v[vi][vu].xvel*0.05;  
		yvel += (1-ay)*v[vi][vu].yvel*0.05;  
		  
		xvel += ax*v[vi+1][vu].xvel*0.05;  
		yvel += ax*v[vi+1][vu].yvel*0.05;  
		  
		xvel += ay*v[vi][vu+1].xvel*0.05;  
		yvel += ay*v[vi][vu+1].yvel*0.05;  
		  
		v[vi][vu].yvel -= (1-ay)*0.003;  
		v[vi+1][vu].yvel -= ax*0.003;  
		//v[vi][vu+1].yvel -= ay*0.003;  
		  
		if(v[vi][vu].yvel < 0) v[vi][vu].yvel *= 1.00025;  
		  
		x += xvel;  
		y += yvel;  
	}  
	else {  
		reposition();  
	}  
	if(ofRandom(0,400) < 1) reposition();  
	  
	xvel *= 0.6;  
	yvel *= 0.6;  
}  
  

I have attempted to read around this on the web with little success- although I wonder whether there may be further problems or better ways to implement the code involving pointers and accessing the parts of the arrays better. Processing has this as all inline classes, which is where I have come unstuck a little in figuring out how to separate out into c++!
All help VERY gratefully received!
thanks!

I can see your problem I think (for others’ benefit, you sent me the code for the other files too). Here’s VSquare.h:

  
  
  
  
  
#ifndef VSQUARE  
#define VSQUARE  
  
  
  
class VSquare{  
public:  
	int x;  
	int y;  
	float xvel;  
	float yvel;  
	float col;  
	  
	VSquare(int xIn,int yIn);  
	  
	void addbuffer(int i, int u);  
	void updatevels(int mvelX, int mvelY);  
	void display(int i, int u);  
	void addcolour(int amt);  
	  
	  
	};  
  
#endif  
*/  
  

Your error message says

  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp: In constructor 'Smoke::Smoke()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Smoke.cpp:12: error: no matching function for call to 'VSquare::VSquare()'  
  

This means that there’s no VSquare() constructor - and you don’t have one in your code, just VSquare(int xIn,int yIn). When you create an array of objects (and not pointers to objects) e.g.

  
  
VSquare squares[32];  
  

The constructor is called automatically, but the compiler doesn’t know how to call it automatically unless you explicitly define a VSquare() with no parameters. That’s why it’s complaining. So you need to either

(a) provide a default constructor (i.e. one that takes no parameters)
(b) provide default values for the constructor that takes parameters.
© create an array of pointers rather than actual objects, then you can call your constructor safely.

I would choose (b) as it’s the quickest fix…

In your VSquare.h, just put in some default values e.g.
VSquare(int xIn = 0,int yIn = 0);
(don’t do this in the cpp file, just the header.)

That should fix it, because the compile will now be able to create VSquares without needing any parameters.

That’s super helpful, thanks so much Marek, you’re a star!!
Hope this helps others too, this is a really clear explanation of where I was going wrong…
cheers!

Having now implemented the changes, the problem with the errors relating to how to use the constructors with default values are now gone, which is great. There still seems to be the problem that the variables cannot used by the three classes (Particle.cpp, VBuffer.cpp and VSquare.cpp) which are declared and initialised in Smoke.h and .cpp. The 24 errors I am left with are all ‘not declared in this scope’ problems? I’m puzzled and also sure this is some fundamental difference between the way Processing operates and oF?

  
  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp: In member function 'void Particle::reposition()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:21: error: 'WIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:22: error: 'HEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp: In member function 'void Particle::updatepos()':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:29: error: 'RES' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:32: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:32: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/Particle.cpp:33: error: 'v' was not declared in this scope  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp: In member function 'void VBuffer::updatebuf(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:23: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:23: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VBuffer.cpp:24: error: 'v' was not declared in this scope  
  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::addbuffer(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:20: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:20: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:21: error: 'vbuf' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::updatevels(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:47: error: 'randomGust' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:48: error: 'randomGustX' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:49: error: 'randomGustY' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:51: error: 'randomGustSize' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:52: error: 'RES' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:54: error: 'randomGustMax' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:54: error: 'randomGustXvel' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:55: error: 'randomGustYvel' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp: In member function 'void VSquare::display(int, int)':  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:69: error: 'LWIDTH' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:69: error: 'LHEIGHT' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:82: error: 'v' was not declared in this scope  
/Users/will/Desktop/of-iphoneOS4/_apps/iPhoneAddonsExamples/Sobras1_9/src/VSquare.cpp:93: error: 'RES' was not declared in this scope