OOP - passing val by value or reference

I have years of Java experience, as well as with numerous other garbage collected langs. I'm beginning some projects in C++ and trying to get my head around new concepts such as memory management and the ability to now pass stuff by val or ref. My question/confusion is somewhat conceptual, but based on a very simplified version of what I'm building.

Let's say I have a Polygon class that encapsulate drawing calculations (but not rendering). Members might include, radius, sides, vertices[], create(), getVertices(), etc.

I have an Engine class that manages lifespan and movement of the polygons (through simple composition).

I have a Renderer class that moves and renders the polygons.

The renderer will need access to the polygon(s) geometry, which I could access with something like: eng.getPoly[i].getVertices();

If the vertices are created within the Polygon class, getVertices() can return the vertex data by reference. If I return by reference (which seems sensible and avoids extra copy constructors calls, right?) where do I delete (I assume it's better for the class that calls new to delete within its destructor?). However, the Engine class really controls lifespan of the Polygon data - not the Polygon anymore, and of course the vertices[] array in the polygon class is private. I've of course also read I can (and should) use vectors instead of raw arrays, but does that solve the delete problem?


I realize this is a fairly amorphous question, but I'm pretty exhausted trying to unravel this on my own. I'd love a suggestion.

Finally, I've read that boost and following RAII is a very good general approach to pursue with C++. Will that in itself simplify some of these issues?

Thanks!!
If you are returning by reference and you don't intend to modify the data (i.e. you are just doing it to avoid copy ctor calls), just return a const reference instead.

If you new'd it in the Polygon class's ctor, then you should probably delete it in the dtor. As long as the Engine class is delete whatever Polygons it created, then Polygon's dtor will deal with it's own stuff and you don't have to worry about it.

Yes, it would, but I can't really give you specific advice without concrete examples unfortunately.
> RAII:
It can indeed help you in several ways.

If you return a std::auto_ptr<Polygon> from a function for example the it's obvious that the caller has ownership of the polygon. Returning a (smart) pointer also enables polymorphism (which return by value prevents).

If you just want to give access to the polygon, then return by (const) reference. Since the caller doesn't own the resource he must ensure the lifetime of the object doesn't end before the last use of this reference (Don't store the reference for later usage unless you are sure that it will last that long; same applies for returning a pointer).
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Printer
{
  //...
  Printer& getPrinter();
};

class A
{
  void setPrinter(Printer& p) {_p = & p;};
  void print() {_p->print();};
  Printer* _p;
}


void f()
{
  A a;
  {
    Printer p;
    a.setPrinter(p.getPrinter()); // store reference to printer in "a"
    // printer get's destroyed here.
  }
  a.print(); // uses a reference/pointer to a destroyed printer!
}



If you want to use a polygon in a shared way (maybe the most resembling version to the java approach) the use a shared_ptr<Polygon>.

The smart pointers (auto_ptr, shared_ptr) deal with memory deallocation so you cannot forget to release the memory. If you have an auto_ptr as a member you need no special code in the destructor.


vectors/arrays:
If you use vectors that are value objects (copy does copy of values) instead of arrays which are reference objects (a "copy" of an array still points to the same elements), you'll get copies if you return a vector. You can of course return a (const) reference to a vector to share the data.
1
2
3
4
5
6
7
8
vector& getVector();

void f()
{
  vector& myRef = getVector(); // no vector is copied
  vector* myRef2 = & getVector(); // pretty much the same as the line above
  vector  myVal = getVector(); // vector is still copied although return by reference
}


Hope that helped a bit.



where do I delete
A reasonable place is to add a Remove method to the engine that removes a Polygon, since that's where Polygon lifetimes are managed.
Topic archived. No new replies allowed.