Frage

I was wondering if it is possible to create class methods that are only available statically.

Given a simple Vector3 class:

class Vector3
{
public:
    float X;
    float Y;
    float Z;

    Vector3(): X(0), Y(0), Z(0) {}
    Vector3(float x, float y, float z): X(x), Y(y), Z(z) {}
    static Vector3 CrossProduct(const Vector3& rhs, const Vector3& lhs);
};

Vector3 Vector3::CrossProduct(const Vector3& rhs, const Vector3& lhs)
{ 
    Vector3 crossProductVec;

    crossProductVec.X = rhs.Y * lhs.Z - rhs.Z * lhs.Y;
    crossProductVec.Y = rhs.Z * lhs.X - rhs.X * lhs.Z;
    crossProductVec.Z = rhs.X * lhs.Y - rhs.Y * lhs.X;

    return crossProductVec;
}

and I can use it like this:

Vector3 vec1(0,1,0);
Vector3 vec2(1,0,0);

Vector3::CrossProduct(vec1, vec2); //this should work, and does. 
                                   //Static CrossProduct method.

vec1.CrossProduct(vec1, vec2);     //this shouldn't work, but it does.  
                                   //I don't want the CrossProduct  
                                   //instance method to be available

I would like CrossProduct to only be available statically. Is this possible?

I understand that the code above will not achieve what I want, I wish to know what changes could be made to achieve what I want.

Edit:

The CrossProduct() does not necessarily have to be part of the class, but I am hoping for it to appear as Vector3::CrossProduct(). I'm open to all suggestions to achieve the required result. After that a decision of whether it's a good idea or not can be worked out.

War es hilfreich?

Lösung

No, I don't think there is a way of doing what you want but you could (and possibly should) make the function a non-member non-friend function in a namespace, preferably the same namespace as Vector3. Something like:

namespace Math {
   Vector3 CrossProduct(const Vector3& rhs, const Vector3& lhs);
}

Then you can use it with:

Math::CrossProduct(vec1, vec2);

Note that if Vector3 is in the same namespace as CrossProduct, you can use argument dependent lookup (ADL) and omit the Math:: if you wish.

Andere Tipps

It is only available statically in the sense that it can only modify local and static members of the class. vect.CrossProduct() will be compiled as Vector3::CrossProduct().

You seem adamant about not having a member function and I don't know why. Instead of not having a member function, how about having a const member function that cannot modify itself:

class Vector3f
{
    //...
    public:
        Vector3f CrossProduct( const Vector3f& v ) const;
};

Vector3f Vector3f CrossProduct( const Vector3f& v ) const
{
    //...
}

v1.CrossProduct( v1, v2 ); // compiler error: parameter lists don't match

Under your declarations, these are the same

Vector3::CrossProduct(vec1, vec2); 

vec1.CrossProduct(vec1, vec2);    

Your function Crossproduct simply just have to be declared as a seperate function outside the class definition.

Vector3 CrossProduct(const Vector3& lhs, const Vector3& rhs);

or you instead of making it static, just declare it as a regular member function like

Vector3 CrossProduct(const Vector3& rhs);

which uses *this for the LHS.

I would suggest that you do both, like this;

class vector3 {
  ....
  Vector3 CrossProduct(const Vector3& rhs);
};
inline Vector3 CrossProduct(const Vector3& lhs, const Vector3& rhs) { return lhs.Crossproduct(rhs); }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top