Small 3D and 4D vector utilities
Very good.

Couple of points:

I would remove the set() method, and allow its work to be done by the operator[]. To do this you need return the value you want by reference.

double &amp;  operator[](unsigned int i);
  //  ^^^  Return double by reference.


This allows you to do;

V4 x;
x[1] = 12;


When you pass objects as parameters it is usally best to pass by const reference. This means that no copy will be made and the original object can not be modified by the method using it:

V4 operator +(V4 const &amp; rhs);
                      ^^^


Note I always put the const on the right of the type (rather than the left). Admittedly this is a religious war so choose a side and stick to it (there is only one minor side instance were it makes difference). But I find it makes reading the type name easier (as types are read from right to left with const always binding to the left (except where it is the leftmost lexeme in the type then it binds right).

Methods that do not change the state of the object should be declared const:

V4 operator -(V4 const &amp; rhs) const;
                        //    ^^^^^  indicates that calling this method will not
                        //           change the state of the object.


Note: This means you should provide two versions of operator[] a normal one that allows mutation and a const version that can be used in contexts where it is read only.

double&amp;        operator[](unsigned int i)        { return coord[i];}
double const&amp;  operator[](unsigned int i) const  { return coord[i];}


Note: array access is not validated against the array bounds. Normally you don't check as we do not want to impose an extra burden on the responsible just because there are bad developers. But it is traditional to add at() method that does the same work as operator[] but also validates the bounds of the array access.

double&amp;        at(unsigned int i)        { if (i &gt; 3) {throw std::range_error("BLA");} return coord[i];}
double const&amp;  at(unsigned int i) const  { if (i &gt; 3) {throw std::range_error("BLA");} return coord[i];}


Implementing operator + - * / is easily done if you implement them in terms of += -= *= /=. This also provides the user of your object the opportunity to use your class more efficiently when a new object is not required (though this should be a secondary though).

V4 operator *(V4 const &amp; rhs) const;
V4 operator *=(V4 const &amp; rhs);       // This does change the sate of the object

V4 V4::operator*(V4 const&amp; rhs) const { V4 result(*this); result *= rhs; return result;}


Using a for loop is easy. But sometimes it can be simpler to use the standard algorithms to accomplish simple tasks over short containers:

double sum = 0;
for(int i= 0; i&lt;4; i++){
    sum += coords[i]*coords[i];
}


This can be replaced with:

sum = std::accumulate(coords, coords + 4, 0);


You can find good documentation here: http://www.sgi.com/tech/stl/table_of_contents.html (look for section: 5 Algorithms) 

In the moto of not doing extra work. Don't write methods that do nothing:

V4::~V4(){}//nothing to destroy?


Remove this. The class automatically provides a desttructor that will correctly destroy nothing.

I actually like using void as the return type of assignment (I think it has no down side). But traditionally assignment should return a reference to self. This then allows the object to be part of an assignment chain.

V4  a;
V4  b;
V4  c;

a = b = c; // assignment chaining.
// It also allows you to pass the object as a parameter to a mehtod:

doStuff( a = b); // Assign a to b. Then call doStuff using a.


It is also a good idea to define the streaming operators for most classes. This allowsd you to serialize and de-serialize the class to a stream (file/string etc).

So now the class looks like this.

class V4
{
    double coords[4];
 public:
    V4();
    V4(double x, double y, double z, double w);

    double module() const;
    double&amp;       operator[](unsigned int i)       {return coords[i];}
    double const&amp; operator[](unsigned int i) const {return coords[i];}

    V4&amp;  operator = (V4 const&amp; rhs);
    V4&amp;  operator +=(V4 const&amp; rhs);
    V4&amp;  operator -=(V4 const&amp; rhs);
    V4&amp;  operator *=(double k); //moltiplication of vector by a scalar k

    V4   operator +(V4 const&amp; rhs)  const {V4 result(*this); result += rhs; return result;}
    V4   operator -(V4 const&amp; rhs)  const {V4 result(*this); result -= rhs; return result;}
    V4   operator *(double rhs)     const {V4 result(*this); result *= rhs; return result;}

    double dot4(V4 const&amp; rhs) const; //the dot product

    V4 cross(V4 const&amp; u, V4 const&amp; v,V4 const&amp; w) const; //the cross product
};


Then rest of the interesting ones:

double V4::module() const
{
    return std::sqrt(std::accumulate(coords, coords + 4, 0.0);
}

V4&amp;   V4::operator +=(V4 const&amp; rhs)
{
    std::transform(coord, coord+4, rhs.coord, coord, std::plus);
    return *this;
}
V4&amp;   V4::operator -=(V4 const&amp; rhs)
{
    std::transform(coord, coord+4, rhs.coord, coord, std::minus);
    return *this;
}
V4&amp;   V4::operator *=(double k)
{
    std::transform(coord, coord+4, coord, std::bind1st(std::multiplies, k));
    return *this;
}