Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

2D vector class

  1. Apr 30, 2016 #1

    ChrisVer

    User Avatar
    Gold Member

    I have the following class Vec2D:
    Code (C):

    #ifndef Vec2D_H
    #define Vec2D_H

    class Vec2D
    {
         private:    
               double fX;
               double fY;
        public:
               Vec2D();
               Vec2D(double x=0, double y=0);
               ~Vec2D() {};
               double const X();
               double const Y();
               void SetX(double a);
               void SetY(double b);
               void print();
               Vec2D addVector(const Vec2D& v2) const;
               double scalarProduct(const Vec2D& v2) const;
    };

    #endif
     
    Code (C):

    #include "Vec2D.h"
    #include <iostream>

    Vec2D::Vec2D(){
        fX= 0.;
        fY= 0.;              
    }

    Vec2D::Vec2D(double x, double y)
    {
        fX=x;
        fY=y;                  
    }

    void Vec2D::SetY(double a){
        fY=a;    
    }
    void Vec2D::SetX(double b){
        fX=b;    
    }
    double const Vec2D::X(){
        return fX;    
    }
    double const Vec2D::Y(){
        return fY;      
    }

    void Vec2D::print(){
        std::cout<<"("<<fX<<", "<<fY<<")";  
    }

    Vec2D Vec2D::addVector(const Vec2D& v2) const
    {
        double v2_x,v2_y,v1_x,v1_y;
        v2_x=v2.fX;
        v2_y=v2.fY;
        v1_x=fX;
        v1_y=fY;
        double x_new, y_new;
        x_new= v1_x +v2_x;
        y_new= v1_y +v2_y;
        return Vec2D(x_new, y_new);
    }

    double Vec2D::scalarProduct(const Vec2D& v2) const
    {
        double v2_x, v2_y, v1_x, v1_y,prod;
        v2_x= v2.fX;
        v2_y= v2.fY;
        v1_x=fX;
        v1_y=fY;
        prod=(v2_x*v1_x)+(v2_y*v1_y);      
        return prod;  
    }
     
    My problem is when I am trying to do something with the Vec2D::scalarProduct() and Vec2D::addVector() methods I am getting an error of the following type:
    "[linker error] undefined reference to Vec2D::addVector(Vec2D&)"
    "[linker error] undefined reference to Vec2D::scalarProduct(Vec2D&)"
    And this error started appearing when I tried to implement the keyword "const" in my arguments of those two methods (const Vec2D) and at the end of the methods' names METHOD(ARGS) const{ ... }.
    Without that keyword my code runs smoothly...any help? Thanks.
    ooh yes my main code also is:
    Code (C):

    #include <iostream>
    #include "Vec2D.h"
    int main(){
    Vec2D a= Vec2D(1.,2.);
    Vec2D b= Vec2D(3.,4.);
    Vec2D c= Vec2D(2.,-1.);
    Vec2D sum = a.addVector(b);
    sum.print();
    double p1= a.scalarProduct(b);
    double p2= a.scalarProduct(c);
    double p3= c.scalarProduct(b);
    std::cout<<p1<<"\t"<<p2<<"\t"<<p3<<std::endl;
     system("pause");
     return 0;
    }
     
     
  2. jcsd
  3. Apr 30, 2016 #2
    Why do you need the 'const' keyword in there... from as much as I can tell it doesn't look like it's a constant at all... Why would you need a function that returns a constant?
     
  4. Apr 30, 2016 #3
    For example. const Vector2d::X returns fX, which isn't a constant, so it can't be evaluated at compile time, which is probably what the compiler is complaining about
     
  5. Apr 30, 2016 #4

    ChrisVer

    User Avatar
    Gold Member

    What is not constant?
    the Vec2D::X() returns fX, but the return value is a constant... fX doesn't have to be... I don't think the compiler raises any error (at least I tried it now) with the assignment of non-constant objects to constants....
    It raises an error if you try to change the const ones.

    What I don't understand is why the code results to such an error after I inserted the const keywords on the addVector and scalarProduct methods.. From looking around for that error message I was left with the impression that there is a problem for the compiler when it tries to connect/match my cpp with my header file (and so the linker)... But in both those files I am using the same naming etc.
    And let me elaborate with an example?
    I have a vector A=(1,2)
    and a vector B= (1,5)
    I want the addition C=A+B = (2,7)
    Now I can take the object A and using the method addVector add to its elements the vector's B ones? I can make sure that my B is not changed (read-only object) by passing it as a constant reference.
     
    Last edited: Apr 30, 2016
  6. Apr 30, 2016 #5
    Can you try omitting the const keyword from the cpp file and leaving it in the header file?

    I'm no expert at this, but I've done this enough to know the frustration you can get from compiler errors!.. Maybe someone else will chime in.
     
  7. Apr 30, 2016 #6

    ChrisVer

    User Avatar
    Gold Member

    Well I just did to make sure of my fear that it wouldn't work; omitting it of course results in not finding the method in the header file.
     
  8. Apr 30, 2016 #7
    I just understood that constants had to be evaluable at compile time, and an instance of your class will always return the same value, but each different instance will have a different return value, meaning it's not constant...
    I'm going to fiddle a little with it myself :)
     
  9. May 1, 2016 #8

    Mark44

    Staff: Mentor

    I could be wrong, but I think you really should remove the const attributes from your function return values, as also noted by Rx7man.

    In addition, your definitions for the two functions I copied above are overly complicated. You should not have the declarations you show in the first line of each of these methods. In both methods the parameter is the vector that will be used to add to the vector on which the method is called, or to calculate the scalar product of the vector on which the method is called. One important fact that you're ignoring is that for methods of a class, the implied first argument is the this pointer, where this points to the instance of the class.

    In the first method (addVector), this.fx and this.fy are the coordinates of the vector on which the method is called. The parameter, v2, has its own coordinates; namely, v2.fx and v2.fy.

    Your addVector method could be rewritten like so:
    Code (C):

    Vec2D Vec2D::addVector(const Vec2D& v2)
    {
        Vec2D v_new(this->x, this->y);
        return v_new;
    }
    For this to work, though, you need a copy constructor, and to be able to use this method, you need to overload the assignment operator. Note that I have renamed your private class members from fX and fY to x and y.

    The copy constructor looks like this:
    Code (C):
    Vec2D::Vec2D(const Vec2D& v)
    {
       this->x = v.x;
       this->y = v.y;
    }
    My overloaded assignment operator looks like this:
    Code (C):
    Vec2D Vec2D::operator= (const Vec2D & v)
    {
       this->x = v.x;
       this->y = v.y;
       return *this;
    }
     
    Last edited: May 1, 2016
  10. May 1, 2016 #9

    Mark44

    Staff: Mentor

    In addition to what I said above, my implementation of the scalarProduct() method has one line of code. Again, methods on classes always have an implied first argument, the this pointer, a pointer to (the address of) the object on which the method is called. You aren't using this in your method implementations.
     
  11. May 1, 2016 #10

    ChrisVer

    User Avatar
    Gold Member

    Is the this keyword the C++ analogue of self in python? Although python doesn't have pointers for the ->.
     
  12. May 1, 2016 #11

    Ibix

    User Avatar
    Science Advisor

    Yes - or as close as you can get. But you don't have to declare it in the method definition. It's just there automagically.
     
  13. May 1, 2016 #12

    Mark44

    Staff: Mentor

    They're similar, with self in Python representing the object, and this being a pointer to the object.
     
  14. May 1, 2016 #13
    I don't know how it works in C++, but in VB, typically when you call the default constructor, you pass default default values to the non-default constructor...

    so it would look something like this, and would reduce the locations of code to debug

    Code (Text):

    Vec2D::Vec2D(){
         Vec2D(0,0);           //call the non default constructor with default values (syntax may not be right)
    }

    Vec2D::Vec2D(double x, double y)
    {
        fX=x;   //do the initialization for both cases here in the non-default contructor.. and you may need "this" here as well
        fY=y;                  
    }
     
     
  15. May 1, 2016 #14

    Mark44

    Staff: Mentor

    In the code that @ChrisVer posted at the start of this thread, the header file contains these declarations:
    Code (C):
    Vec2D();
    Vec2D(double x=0, double y=0);
    The first constructor can be removed; the second constructor passes default values of 0 and 0 if a Vec2D object is created with no initializers. If a Vec2D object is created with initializer values, those values are used to set the x and y members.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: 2D vector class
  1. Pointers and classes (Replies: 1)

  2. Friend classes (Replies: 9)

Loading...