Of oops tutorial

I was going through the class example in the of tutorial page :

http://www.openframeworks.cc/tutorials/first%20steps/003_ooops_object_oriented_programming.html

Can somebody list me all the advantages that i get using

 ofBall **myBall;

instead of

ofBall myBall[NBALLS];

and VICE-VERSA!

I feel kind of silly and confused here….but i really wanna know
Thanks !!

1 Like

Hi,
If you use

ofBall myBall[NBALLS]

you will not be able to pass arguments to the constructor, which is what happens in the tutorial later. Also, in this way the array of objects is statically allocated, which is not always desirable: think about the situation when you have a particle system where you want to remove particles at a certain point. If you want to avoid pointers, you can use vector and add the particles later in the setup.

why i won’t be able to pass arguments in the constructor??

ofBall myBall{1,2,3}
//or
ofBall myBall[4] ={{1,2,3},{1,2,3},{1,2,3},{1,2,3}}

Thanks !

Hi,
what I meant is the following: when in testApp.h you do something like this

ofBall balls[5]

you are creating an array of 5 objects initialized by the default constructor, i.e. ofBall(). In the same way, when you do something like

ofBall myball;

you are creating an object of type ofBall by calling the constructor ofBall(). In particular, if you try the following in testApp.h

ofBall myball = new ofBall(0, 0, 0);

you should get an error. Basically, everytime you declare objects. C++ instantiates them via the default constructor. As an exercise to see where ofBall** myBalls is necessary (unless you use vector), or at least very useful, try to do a variation of the tutorial code, such that at the beginning there is no ball, but as soon as you press a key on the keyboard a random number n between 1 and 1000 is generated, n balls are generated, and added to myBalls.

1 Like

Hi, I am digging this thread up as I also have questions about the same OOPS tutorial.

I am following the OOOPS part of the recently shared of Book.
When the tutorial speaks about how to pass arguments to an object instance, we are invited to use pointers to objects.
As it is not (yet) precisely explained ( annotations in the text is teasing… :blush: )

[KL: specify why we'd make it into a pointer vs not a pointer]

I was wondering why one should use a pointer to be allowed to pass arguments to the contructor.
Why can’t we instantiate and declare a new object without the default constructor? (just to understand)

ofBall myBall (0,0 0);

my other questions are dealing with dynamic allocation and memory leak:
Later in the tutorial we are taught how to fill a vector of pointers to objects thanks to a temporary pointer:

void ofApp::mouseDragged(int x, int y, int button){
ofBall *tempBall;
tempBall = new ofBall(x,y, ofRandom(10,40));
myBall.push_back(tempBall);
}

Silly beginner questions: why is this temporary pointer not explicitly deleted after being used?
How can I also prevent memory leak if the vector of pointers to objects is not deleted and erased as explained in this other tutorial about vectors

// delete and erase a single element with index
delete particlePointers[1];
particlePointers.erase( particlePointers.begin()+1 );

// delete and erase with a loop
vector<Particle>::iterator it = particlePointers.begin();
for(; it != particlePointers.end();){
if( (*it)->isDead ){
    delete *it;
    it = particlePointers.erase(it);
}else
    ++it;

Sorry if answers are obvious, thanks!

yes not sure in which context that’s mentioned but it’s not necessary, i would say you should almost never use raw pointers in modern c++.

as you say you can do:

Ball ball (0,0 0);

there’s one case in which that gets tricky and that’s when the object is an instance object, that is, when it’s declared on the .h of your ofApp for example. in that case you can’t initialized it there by passing arguments to the contstructor but you can do it in the container class constructor like:

// ofApp.h
ofApp();
...
Ball ball;

// ofApp.cpp
ofApp::ofApp()
:ball(0,0,0){

}

which can be relatively strange for beginners. that among other reasons is why openframeworks tends to not use parameters in constructors for most objects and instead have a setup method. the other reason is that opengl is sometimes not initialized yet when the constructor is called so doing initializations of objects that require opengl resources in the constructor might be sometimes problematic.

as for the second question, again, i’m not sure what the author is trying to explain, perhaps just memory allocation but i would avoid using pointers like that. instead use a vector of objects like:

// .h
vector<Ball> particles:

//.cpp
particles.push_back(Ball(x,y.ofRandom(10,40));

and forget about allocating memory… from OF 0.9.0 (because we’ll support c++11) you can even do:

particles.emplace_back(x,y,ofRandom(10,40));

which avoids a copy when putting a new element in a vector of objects.

in any case to answer your original question. when you create an object using new, you always need to delete it with delete. if you are used to processing or java, python or similar languages. there an element called the garbage collector takes care of deleting objects that are not used anymore from time to time. c++ doesn’t have garbage collector among other things cause that can slow things down.

in c++ you can use a shared_ptr which works pretty much the same as a raw poitner but auto deletes itself when it’s not being used anymore:

// .h
vector<shared_ptr<Ball>> particles:

//.cpp
particles.push_back(shared_ptr<Ball>(new Ball(x,y.ofRandom(10,40)));

but i would advice against doing this for small objects like particles… and instead use a vector of objects, it’s way simpler and even faster to access later because elements are aligned in memory instead of being scattered as happens when allocating new objects every time you push back a new one in the vector.

(just a quick note that I think this tutorial is a bit out of date wrt to best practices… I had the same impression when reading the chapter in OF book and will try to offer some changes.)

as a side note, I’ve found vectors of pointers useful only in cases where controlling the memory address of the object was important – ie, having a vector of particle pointers and a vector of spring objects that refer to those addresses. This example shows me using the memory address of an object in a vector (https://github.com/ofZach/algo2012/blob/master/week8/springs/src/ofApp.cpp#L23-L24) – it’s not using pointers, but it’s the instance where I’ve found pointers useful – here the potential problem is that when you start adding to / removing items in a vector their location in memory changes. I’m not using pointers here, but it gives a sense of why you might. However I’m sure I could do this with shared_ptr and it’s part of my new years resolution to get a better sense of them.

Also, When I learned C++ I used to do everything with fixed sized arrays, so you’ll see this kind of syntax in older code. very thankful for STL and modern practices :smile:

Precisely all I needed to know now (and even more dealing with best practices in C++ )
Thanks a lot Arturo and Zach for these great advices and examples.
Next step is shared pointers!