Jump to content
  • Advertisement
Sign in to follow this  
Daishim

Operator Overloaded Sub Objects

This topic is 4305 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I seem to be having some trouble with objects that are templated and have overloaded operators as being members of another object. For example, I have a 3D point object, that holds the point/particles (X,Y,Z) position. It is templated to support different coordinate storage types (float, double, int). If I want to create a vector between the two points, I subtract the point a from point b and the result is then stored in a vector object, which is also templated. This works fine. Now, let's say I have a triangle object, where the I have points A,B,C. Points A,B, and C are of the point object type mentioned above. When I trying to perform the same subtraction to create a vector between the two points, the compiler generates an error stating that it cannot find a suitable subtraction operator method to handle the situation. So given:
template<class T_POINT_TYPE>

// 3D point object
struct G_POINT
{
	T_POINT_TYPE X;
	T_POINT_TYPE Y;
	T_POINT_TYPE Z;

	G_POINT(void) : X(0), Y(0), Z(0) { /* Empty */ }
	G_POINT(const G_POINT<T_POINT_TYPE> &New) : X(New.X), Y(New.Y), Z(New.Z) { /* Empty */ }
	G_POINT(const T_POINT_TYPE Init_X, const T_POINT_TYPE Init_Y, const T_POINT_TYPE Init_Z) : X(Init_X), Y(Init_Y), Z(Init_Z) { /* Empty */ }

	const G_POINT &operator=(const G_POINT<G_Float> &New) {X = New.X; Y = New.Y; Z = New.Z; return *this;}

	const G_POINT &operator-(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}

};

struct G_TRIANGLE
{
        G_POINT<G_Float> A;
        G_POINT<G_Float> B;
        G_POINT<G_Float> C;
};



This works:
int func(void)
{
        G_POINT Point_A(4.0, 5.0, 6.0);
        G_POINT Point_B(1.5, 2.5, 3.5);
        G_VECTOR<G_Float> Vector_A = Point_B - Point_A;
}



But this does not:
int func(G_TRIANGLE &Triangle)
{
        G_VECTOR<G_Float> Vector = Triangle.B - Triangle.A;
}



Any ideas as to why the operators are not working the same when objects are sub objects? [Edited by - Daishim on September 5, 2006 8:40:42 PM]

Share this post


Link to post
Share on other sites
Advertisement
Triangle.A and Triangle.B are both of type G_POINT<G_Float>. The result of G_POINT<G_Float>::operator -(const G_POINT<G_Float> &) is a G_POINT<G_Float>, but you assign it to a variable of type G_VECTOR<G_Float>.

Do your G_VECTOR<G_Float> class have a constructor taking a G_POINT<G_Float>?

Share this post


Link to post
Share on other sites
Yes. I goofed on the example, the first working example should be a vector that it is assigned to also, which does work.

Share this post


Link to post
Share on other sites
	const G_POINT &operator-(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}



What you are doing above is often known as "evil".

Your operator- is non-const, and behaves like an operator-=.

To fix:

const G_POINT &operator-=(const G_POINT<G_Float> &Right) {X -= Right.X; Y -= Right.Y; Z -= Right.Z; return *this;}

G_POINT operator-(const G_POINT<G_Float> &Right) const {G_POINT tmp = *this; return tmp-=Right;}



I would be willing to bet you "goofed" again, and the operator- is failing for lack of a const.

Second, it is common that ALL_CAPS_WITH_UNDERSCORES_MEANS_A_MACRO, and not a template.

...

Next, it helps if you can post a minimium case of code that compiles and contains your problem. What you posted is non-compiling code.

Share this post


Link to post
Share on other sites
It might also help if you explained your rational for having seperate point and vector classes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Deyja
It might also help if you explained your rational for having seperate point and vector classes.


Naw, that makes perfect sense. Points and vectors are different things.

They both happen to be "vector fields" of the same dimension.

But if you add two points together, you have a bug. If you scale a point, you have a bug. The vector "0" is special -- but the point "0" is not special. If you use the point "0" you have a bug. If you use the vector "0" you do not have a bug.

A vector is a difference of points.

By having the static type system distinguish between them, you can catch some bugs. Sort of like rolling dimensional analysis into the static type system -- it helps sometimes. :)

Share this post


Link to post
Share on other sites
The problem was the overloaded operators not being const, due to an oversight in my hurried creation. Pays to slow down I guess.

I also chose to seperate points and vectors for that exact reason above.

Share this post


Link to post
Share on other sites
I have never yet seen a case where I didn't want to be able to apply the same set of functionality to a vector and a point.

I DO what to scale points (grab the corner, multiple it by a scale factor, reset it) ... I DO want to add, difference, average two points (average of 2 points is there midpoint, difference of two points is the line segment which would connect them - and usefull for collision detection).

I think you have fallen into the OO trap without realizing it. You have made distinct objects out of concepts that are fundamentally one idea with multiple names. The fundamental advancement of math and science is to unify all that may be unified - and nothing that may not. So if the answer to the question "when would it not work to use an X instead of a Y" would be "never" then they should be one class.

Share this post


Link to post
Share on other sites
Furthermore, you need not duplicate code to differentiate. Make it a simple template with an integer template parameter, then


typedef vector_3<float, true> Vector3;
typedef vector_3<float, false> Point3;


Differentiating mathmatical types can have benifits - but this isn't one of those cases, because a point IS A vector.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!