I’d like to know some best practice when designing c++ classes.
To put it in context, I have a c++ class named Vec3.
class Vec3{ private: float elements[3]; public: Vec3(Vec3 v1){...} Vec3(int x, int y, int z){...} Vec3 add(Vec3 v1){...} Vec3 add(int x, int y, int z){...} ... Vec3 multiply(Vec3 v1){...} ... int dotProduct(Vec3 v1){...} Vec3 normalize(){...} .... int operator[](int pos){...} };
So, I have this class that does computing over a Vector of size 3. I’d like to know what’s better. Working with pointers or not.
Should I return pointer and have my parameters as Pointers or not.
Vec3 add(Vec3 v1) or Vec3* add(Vec3 v1) or Vec3* add(Vec3* v1) or ….
Now I’m confused, I don’t know if I should use pointer or not in my class. I guess there is always a way to send my arguments to function that don’t handle pointers…
Vec3* v2 = new Vec3(1,1,1); Vec3 sum = v1.add(*v2);
And there is a solution that is probably the best of all I can come up with.. having both functions
Vec3 add(Vec3 v2){...} Vec3* add(Vec3* v2){...}
But I fear this will lead to duplicate code and may be overhead.
Thank you for answers…btw, I could use a template to change the size of the Vector but I prefer to keep my Vec3 class alone and create a Vec4 class or name it Quaternion.
EDIT Here is the solution I came with. Feel free to comment or modify or reuse the code. One thing. I just want to mention that, in my case, This class is supposed to be transparent. Just like we add numbers.
int i = 10; int j = 15; int k = i + k;
If the add overload modify the object that is calling the function in this case i. I would endup with a k being a reference to i and i being equal to 25. But what we really want here is a k equal to 25 and i,k unchanged.
Thats how my class work. Vec3 k = i + k will not modify i or k because we are creating a new number from these values. The only case where I return a reference is for +=, -=, ++, –…, set([XYZ])? and normalize.
It could be fun to do something like myvec.setX(10).normalize().scale(10)
NOTE: scale should return a reference. I didn’t see it but I guess it should be better this way.
Vec3 t = myvec.normalize().scale(100).copy();
Thank you all, I’ll be working on the Matrix class now.
These are the rules I usually stick to. Note ‘usually’, sometimes there are reasons for doing things differently…
For parameters I don’t intend to modify I pass by value if they aren’t too large since they will be copied. If they are a bit large or aren’t copyable, you could use a const reference or a pointer (I prefer const reference).
For parameters I do intend to modify, I use a reference.
For return values I will return a copy whenever possible. Some times it’s handy to return a reference (this works well for a single function for get/set where you don’t need to do any special processing when the item is fetched or set).
Where pointers really shine in my opinion is for instance variables where I want control over when it is constructed or destructed.
Hope that helps.