"request for member of non-class type" error

I’m trying to create a class for the first time in oF and am getting the “request for member of non-class type” error when trying to call its member functions. This makes me think the constructor is not being called correctly, which I tested by adding a cout line to the end of it.

The class is defined in separate files as a member of ofBaseApp. I tried at first having it as a member of testApp, but wasn’t sure how to access the mouseX and mouseY variables that way. Regardless, I get the same errors.

I’ve included my classes .h file in testApp.h and main.cpp and instantiated it in testApp.h in the form of “someClass *myClass;”. I call the constructor in testApp::setup() as follows: "someClass *myClass = new someClass(parameter A, parameter B, etc.).

Any idea what I’m doing wrong here? I couldn’t find an example of working with multiple classes in oF, which would be very useful to folks like me with little previous experience in C++.

Thanks,
Zach

here is a short tutorial about classes in openframeworks:

http://wiki.openframeworks.cc/index.php-…-2B-Classes

it won’t work to make an object inherit ofBaseApp, to get access to mouseX and mouseY. better is the following (in pseudo code):

  
class ball{  
public:   
   void setup();  
   float mouseX;  
   float mouseY;  
};  

in testApp.h:

  
ball myBall;  

in testApp.cpp, use the dot syntax to access the variables / functions in the ball object:

  
myBall.setup();  
myBall.mouseX = mouseX;  
myBall.mouseY = mouseY;  

does that help?

take care,
zach

I’m a little confused by the example because testApp.cpp never calls the constructor for the ball object. My class does most of the drawing in the constructor (which takes parameters for size, position, and color), then updates private variables and redraws them in response to mouse events. Therefore, I need access to testApp’s mouseX and mouseY inside the new class. In Java I would use parent.mouseX, but am not sure how to do this in C++.

Btw, I got into oF through your workshop at NY Resistor. Any NYC knitting circles coming up this fall?

Thanks,
Zach

You can either use the dot operator (for objects on the stack) or the arrow operator -> (for objects on the heap). But both ways will call the constuctor.

In your header file you have defined a pointer to SomeClass (to be created on the heap). Then you create a new instance with:

  
myObject = new SomeClass();  

And you call the public members like this:

  
myObject->setLoc(x,y);  

See also http://books.google.com/books?id=hklfknZ02eMC&lpg=PA153&ots=cBgwpzgZ0x&dq=c%2B%2B%20dot%20pointer%20heap%20stack&pg=PA153#v=onepage&q=c++%20dot%20pointer%20heap%20stack&f=false

My point was that in the linked example, the constructor does not appears to have been called. The header file has:

ofBall myBall1;

but testApp.cpp does not have:

myBall1 = new ofBall();

Now that I don’t have my class as a member of ofBaseApp, I get an error in the form of, “No matching function for call to ‘ofBall::ofBall();’” when I did define a constructor in an included file. As mentioned originally, I checked that the constructor is not being called by adding a call to cout in it. In testApp, I used exactly the syntax above, except that there are parameters for the constructor- ints and arrays of unsigned chars for colors.

The OOP examples are located here: http://wiki.openframeworks.cc/index.php?title=Ooops!-%3D-Object-Oriented-Programming-%2B-Classes

I downloaded the first example, and changed the constructor with a cout:

  
  
ofBall::ofBall()  
{  
	cout << "constructor\n";  
	  
	speedX = ofRandom(-1, 1);  
	speedY = ofRandom(-1, 1);  
	  
	x = ofRandom(0, ofGetWidth());  
	y = ofRandom(0, ofGetHeight());  
	  
	dim=20;  
}  

When run, “constructor” is written to the output.

Explanation:

  
ofBall myBall;  

in the testApp header file calls the constuctor.

  
ofBall* myBall;  

in the header file does NOT call the constructor, only when you instantiate it with

  
myBall = new ofBall();  

Here’s testApp.cpp from the example (before they start working with arrays of objects):

http://wiki.openframeworks.cc/index.php-…-x1-cpp.jpg

This is what I was referring to when I said it does not call the constructor. The errors I was getting are in my own project (where I do call the constructor in the .cpp file)- I am not trying to compile this example. I am just wondering why Xcode is telling me it can’t find my constructor, when it’s defined exactly as in the example- accept in a separate header file, which I included. I’m attaching the source.

src.zip

Like I said, you are calling

  
myFunction = new functionGraph(...)  

while myFunction is not declared as pointer.

If you in the header want to stick to

  
functionGraph myFunction;  

instead of

  
functionGraph* myFunction;  

, you can create an init method and do the initialization there instead of in the constructor.

Alright, so I declared myFunction as a pointer and now I get errors when calling it’s member functions: “request for member ‘drag’ in ‘((testApp*)this)->testApp::myFunction’, which is of non-class type ‘functionGraph*’”

Do you use

  
myFunction->drag()  

?

Yes, that was the problem. I had used the dot operator. Definitely need to read up on the whole stack/heap distinction.

Lastly, how do I access testApp’s mouseX and mouseY from my class? In Java I would use parent.mouseX, but I understand it works a little differently in C++.

Thanks,
Zach

There’s two ways to get the mouseX, mouseY positions. 1. If it works for your setup, it’s simplest to just have the application pass them to the Ball instance in the update() of your application like

  
  
void testApp::update() {  
ball.update(mouseX, mouseY);  
}  
  

Or, slightly trickier, you’d need to pass your ball a pointer to your app, for instance in the constructor like this:

Ball.h

  
  
ofBaseApp* parent;  
  

Ball.cpp

  
  
Ball(ofBaseApp *app) {  
   parent = app;  
}  
  

and when you make a new Ball in testApp.cpp you pass the “this” pointer to the Ball instance:

  
  
myball = new Ball(this);  
  

and then anywhere in the Ball class, you can access the mouseX and mouseY with the -> operator like you did with the drag() method.

Thanks, Joshua. Finally got it compiled, although I’ll have to do some debugging from here…

First, I want to make sure I understand the whole stack/heap thing. Am I correct that I only need to delete public variables declared with a pointer? For instance, I would delete the unsigned chars passed to my constructor, but not those that take on their values inside the class?

Ok, clearly I don’t understand this fully as I am only getting the red values from my colors. I swear I read this http://www.cplusplus.com/doc/tutorial/pointers/, but it doesn’t cover passing objects to functions.

I just learned of ofColor, so rewrote everything to use that. It compiles, but crashes upon launch. This is basically it:

  
  
void testApp::setup(){  
	ofColor* lcolor;  
	lcolor->r = 10;  
	lcolor->g = 92;  
	lcolor->b = 115;  
  
	myball = new Ball(lcolor);  
}  
  

  
  
ofColor lineColor;  
void Ball::Ball(ofColor *lColor){  
	lineColor = *lColor;  
}  
  

What am I doing wrong?

this is wrong:

  
  
 ofColor* lcolor;  
   lcolor->r = 10;   // crash here, you are accessing some memory, which hasn't been allocated.   
   lcolor->g = 92;  
   lcolor->b = 115;  
  

should be:

  
  
 ofColor* lcolor;  
lcolor = new ofColor();  
   lcolor->r = 10;  
   lcolor->g = 92;  
   lcolor->b = 115;  
  

in the first version, lcolor is a pointer a color object, which hasn’t been allocated. in the second one, we allocate a color object and set the pointer equal to the position where we allocate.

however, unless you need it as a pointer, you don’t need to use ofColor like that, you can always do:

  
  
ofColor  lcolor;  
   lcolor.r = 10;  
   lcolor.g = 92;  
   lcolor.b = 115;  
  

and change your function not to take a pointer but to take an object or a reference (pass by copy or pass by reference).

most OF objects have default constructors, so you can allocate them like other variables (on the stack), like,

float position;
ofVideoPlayer myVideo;
int temp;
ofColor blah;

hope that helps -
zach

Thanks, Zach! I didn’t realize it would work to pass ofColor by copy. I thought I had to pass them as a pointer based on the trouble I ran into passing unsigned chars.