Hello fellow daniwebians.
Consider the following constructor:

Vector3f::Vector3f(float* f)
{
    x = *f;
    f++;
    y = *f;
    f++;
    z = *f;
}

Now let's create an object of the Vector3f class

//Create an object of Vector3f
Float f[] = {13,3,7};
Vector3f myVector(f);

All is well right ?
Now let's say I make a mistake

float f[] = {3,2};
Vector3f myVector(f);

So I am passing an incomplete array to the constructor.
What will happen is either that the z-coordinate will be all wrong or the program will cause a null pointer exception.

So my question is, how do I from within the constructor verify that the length of the array is at least 3 ?
I was thinking you could add another argument asking for the sizeof the array, but that seem a bit redundant doesn't it ?

Recommended Answers

All 13 Replies

>>So my question is, how do I from within the constructor verify that the length of the array is at least 3 ?

You can't, which is one big reason vectors were invented. What you might want to do is change the constructor to accept a vector so that it can validate the array's length.

I already have a Vector3f(Vector3f& v ) constructor, but I guess I'll go with the size of solution like such:

Vecto3f::Vector3f(float* f, int size ) 
{
 //Check size, if good assign else set zeros
}

Thanks for your input dragon

Consider the following ..

struct foo
{
  float f1, f2, f3;

  // Accept a pointer to an array of 3 floats
  foo(float (*f)[3]) 
  {
     f1 = (*f)[0];
     f2 = (*f)[1];
     f3 = (*f)[2];
  }
private:
  // Hide the unsafe constructor
  foo(float *);
};

// And use it like ..
float bar[] = { 1.0f, 2.0f, 3.0f };
foo f( & bar);

// Will not compile ...
float x[4] = { 1.0f, 2.0f, 3.0f };
foo f( & x); 

// Will not compile ...
float x[] = { 1.0f };
foo f( & x);

// Will not compile ...
float x[] = { 1.0f, 2.0f, 3.0f };
foo f(x); // Hidden ctor
foo(float (*f)[3]) 
  {
     f1 = (*f)[0];
     f2 = (*f)[1];
     f3 = (*f)[2];
  }

Consider the following -- a lot less complicated and does the same thing

foo(float f[3]) 
  {
     f1 = f[0];
     f2 = f[1];
     f3 = f[2];
  }

Consider the following -- a lot less complicated and does the same thing

foo(float f[3]) 
  {
     f1 = f[0];
     f2 = f[1];
     f3 = f[2];
  }

Sorry AD, but you are missing the point here, which is to be sure that you can't pass an array of invalid size to the constructor.

Now, if you have a constructor foo(float f[3]) , you cannot hide foo(float *) because they are threated as the same thing. So, foo(float f[3]) would not be allowed in this case.

commented: right +28

>>.Sorry AD, but you are missing the point here,

Yes, you are right. What I posted was crap.

mitrmkar thanks for your input, I will be sure to implement it later during the day.
I'll be back with the result.

Okay, that solved it i just have one other quick question.
Let's take this operator as an example:

Vector3f Vector3f::operator +(const Vector3f& v)
{
    Vector3f r(x+v.x,y+v.y,z+v.z);
    return r;
}

Now when doing this instead

return Vector3f(x+v.x,y+v.y,z+v.z);

I get the following error:

Vector3f.cpp:91: error: no matching function for call to ‘Vector3f::Vector3f(Vector3f)’

This is the constructor i want it to use:

Vector3f::Vector3f(float _x, float _y, float _z)
{
    x = _x;
    y = _y;
    z = _z;
}

I appreciate any reply.
Thanks in advance

Sorry but that doesn't ring a bell, the closest thing that comes into mind would be an explicit copy constructor, but that either wouldn't fully match what you are describing, as far as I understood. You might post more of the code (at least the header file).

PS. You might also have a second opinion and compile the code at Comeau

#ifndef _VECTOR3F_H
#define	_VECTOR3F_H

#include <math.h>

class Vector3f
{
public:
    /* Variables */
    float x,y,z;
    /* End variables */



    /* Constructors*/

    Vector3f();
    Vector3f(float _x, float _y, float _z);
    Vector3f(Vector3f &v);
    Vector3f(float (*f)[3]);

    /*End constructors*/

    /* Functions */
    float length();
    void normalize();
    float const dot(const Vector3f& v);
    Vector3f cross(const Vector3f& v);
    /* End functions */


    /* Operators */
    Vector3f operator =(const Vector3f& v);
    Vector3f operator +(const Vector3f& v);
    Vector3f operator -(const Vector3f& v);
    Vector3f operator *(const Vector3f& v);
    Vector3f operator /(const Vector3f& v);

    Vector3f operator +(const float& f);
    Vector3f operator -(const float& f);
    Vector3f operator *(const float& f);
    Vector3f operator /(const float& f);

    Vector3f operator !();
    bool operator == (const Vector3f& v);
    bool operator != (const Vector3f& v);
    /* End operators */





private:
    Vector3f(float* f);


};



#endif	/* _VECTOR3F_H */

That's the header file.
Also just noticed that placing the result of a calculation directly into an iostream isn't working either, like this:

Vector3f a(3,0,0);
Vector3f b;
cout << a+b << endl; // Won't work
Vector3f f;
f = a + b;
cout << f << endl; // Does work
#ifndef _VECTOR3F_H
#define	_VECTOR3F_H

#include <math.h>

class Vector3f
{
public:
    /* Variables */
    float x,y,z;
    /* End variables */



    /* Constructors*/

    Vector3f();
    Vector3f(float _x, float _y, float _z);
    Vector3f(Vector3f &v);
    Vector3f(float (*f)[3]);

    /*End constructors*/

    /* Functions */
    float length();
    void normalize();
    float const dot(const Vector3f& v);
    Vector3f cross(const Vector3f& v);
    /* End functions */


    /* Operators */
    Vector3f operator =(const Vector3f& v);
    Vector3f operator +(const Vector3f& v);
    Vector3f operator -(const Vector3f& v);
    Vector3f operator *(const Vector3f& v);
    Vector3f operator /(const Vector3f& v);

    Vector3f operator +(const float& f);
    Vector3f operator -(const float& f);
    Vector3f operator *(const float& f);
    Vector3f operator /(const float& f);

    Vector3f operator !();
    bool operator == (const Vector3f& v);
    bool operator != (const Vector3f& v);
    /* End operators */





private:
    Vector3f(float* f);


};



#endif	/* _VECTOR3F_H */

This is the header.

I'm having a hunch that this has got to do with const correctness.
Change

Vector3f(Vector3f &v);

to

Vector3f(const Vector3f &v);

As to the cout problem, does your
overload look like this? (note: const )

ostream & operator << (ostream &, const Vector3f &);

Are you sure about the return type of the assignment operator, that is returning reference vs. value?

If the problems persist (or even escalate), then maybe post more code (the .cpp files) + error messages.

PS. Rather include <cmath> instead of <math.h> . The same advice goes for all standard headers you include.
PSS. What is your compiler/version?

I realized earlier today that overloading the assignment operator is kind of stupid so i removed it, everything com

piles now.

I just figured, since i have a thread already i might as well look for an explanation for the use of consts in overloading.
I have seen three variants:

Vector3f Vector3f::operator *(const Vector3f& v)
const Vector3f Vector3f::operator *(const Vector3f& v)
const Vector3f Vector3f::operator *(const Vector3f& v) const

Which one should you use ?
And if it's the third, what is the point of the last const ?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.