0

Well, I'm writing this code for my class and I'm getting linker errors LNK2019 and LNK1120 using Visual Studio. I'm not all too sure why it's doing what it's doing, but I digress.

Header file:

        #ifndef PointClass   
        #define PointClass 
        #include <iostream>

namespace PointClass
    {          
     class point
      {
        public:
        // CONSTRUCTOR
        point(double initial_x = 0.0, double initial_y = 0.0);
        // MODIFICATION MEMBER FUNCTIONS
        void shift(double x_amount, double y_amount);
        void rotate90( );
        // CONSTANT MEMBER FUNCTIONS
        double get_x( ) const { return x; } 
        double get_y( ) const { return y; }
        // FRIEND FUNCTION
        friend std::istream& operator >>(std::istream& ins, point& target);
        double x, y; // x and y coordinates of this point
};

// NONMEMBER FUNCTIONS for the point class 
double distance(const point& p1, const point& p2);
point middle(const point& p1, const point& p2);
point operator +(const point& p1, const point& p2);
bool operator ==(const point& p1, const point& p2);
bool operator !=(const point& p1, const point& p2);
std::ostream& operator <<(std::ostream & outs, const point& source);
        }

        #endif 

And the CPP file:

        #include <iostream>
        #include <math.h>
        #include "point.h"
        using namespace std;

        namespace PointClass
        {
           point::point(double initial_x, double initial_y)
 {
    x = initial_x;   // Constructor sets point to a given position
    y = initial_y;
 }

void point::shift(double x_amount, double y_amount)
 {
    x += x_amount;
    y += y_amount;   
 }

void point::rotate90( )
 {
    double new_x;
    double new_y;
    new_x = y;  // For a 90 degree clockwise rotation the new y is -1
    new_y = -x; // times original x, and the new x is the original y
    x = new_x;
    y = new_y;   
  }

bool operator ==(const point& p1, const point& p2)
 {
    return
        (p1.get_x( ) == p2.get_x( )) 
        &&
        (p1.get_y( ) == p2.get_y( ));
 }

bool operator !=(const point& p1, const point& p2)
  {
    return !(p1 == p2);
  }

point operator +(const point& p1, const point& p2)
  {
    double x_sum, y_sum;

    // Compute the x and y of the sum:
    x_sum = (p1.get_x( ) + p2.get_x( ));
    y_sum = (p1.get_y( ) + p2.get_y( ));
    point sum(x_sum, y_sum);
    return sum;
  }

ostream& operator <<(ostream& outs, const point& source)
 {
    outs << source.get_x( ) <<  " "  << source.get_y( );
    return outs;
 }

istream& operator >>(istream& ins, point& target)
{
    ins >> target.x >> target.y;
    return ins;
 }

int rotations_needed(point p)
  {
    int answer;

    answer = 0;
    while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
        {
          p.rotate90( );
          ++answer;
        }
    return answer;
  }

void rotate_to_upper_right(point& p)
  {
    while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
      p.rotate90( );
  }

double distance(const point& p1, const point& p2)
{
    double a, b, c_squared;

    // Calculate differences in x and y coordinates
    a = p1.get_x( ) - p2.get_x( ); // Difference in x coordinates
    b = p1.get_y( ) - p2.get_y( ); // Difference in y coordinates

    // Pythagorean Theorem to calculate square of distance between points
    c_squared = a*a + b*b;

    return sqrt(c_squared); // sqrt calculates square root
  }

         point middle(const point& p1, const point& p2)
{
    double x_midpoint, y_midpoint;

    // Compute the x and y midpoints
    x_midpoint = (p1.get_x( ) + p2.get_x( )) / 2;
    y_midpoint = (p1.get_y( ) + p2.get_y( )) / 2;

    // Construct a new point and return it
    point midpoint(x_midpoint, y_midpoint);
    return midpoint;
         }
        }

Is there anything I can do to fix it?

Steff
  • 1
  • 6
    Copy & paste of the error messages would be a bit more constructive. – Steve-o Aug 31 '11 at 06:15
  • r u compiling with -lm option..?? – Jeegar Patel Aug 31 '11 at 06:23
  • i think this will help you http://stackoverflow.com/questions/1252049/c-lnk2019-and-lnk1120-errors – Jeegar Patel Aug 31 '11 at 06:27
  • The code you post here doesn't point to the linker errors. You should post the error messages or the whole program. – Stan Aug 31 '11 at 06:36
  • @Steff Yeah, there's a *lot* you could do to fix this code, or at least make it better. The answers you've gotten are really good and you should read them and make sure you understand them thoroughly. You should maybe rewind a little bit...stub out some functions and comment your code temporarily until you get it to compile and link and then go from there. The key is that you understand your mistake when you find it so that you don't repeat it (or at least remember how to fix it). Good luck! – Keith Layne Aug 31 '11 at 07:25

2 Answers2

7

You seem to have a namespace called PointClass, and headers guards using PointClass. Consider changing that for a start.

#ifndef PointClass // Rename this, it might be clashing with your namespace. 
#define PointClass
namespace PointClass
Darcy Rayner
  • 3,385
  • 1
  • 23
  • 15
  • +1 Good point although not OP's problem. This will produce compiler errors (since 'PointClass' is now being substituted with '') in `using namespace PointClass` statements, but `namespace PointClass {}` and `PointClass::member...` statements are fine. Good to avoid though. – Martin Gunia Aug 31 '11 at 06:32
  • No it will cause linker errors. The namespace will be turned into an unnamed namespace, which will mean that the namespace will be different for different compilation units. This means that these functions will never be defined for other compilation units. – Mankarse Aug 31 '11 at 06:36
  • @Mankarse: It does not produce linker error for me (MSVC2008). I suspect he's missing some other implementation. – Martin Gunia Aug 31 '11 at 06:38
  • 1
    @Martin. That code on its own will not cause linker errors, but if you try to use the class in a different compilation unit then it will. I agree that there may be other issues with Steff's though. – Mankarse Aug 31 '11 at 06:40
  • @Mankarse: You're right, using the function from another cpp unit causes link errors (had only one .cpp before). I'm always using more unique guards so never gave them a thought as being just like any other macro :) – Martin Gunia Aug 31 '11 at 06:41
  • Good one, I didn't spot it. Some coding rules say that the include guards should be the filename in capitals with spaces and points replaced by underscores. That would have helped here (POINTCLASS_H) – stefaanv Aug 31 '11 at 07:23
3

Read the error message:

Linker Error 2019: unresolved external symbol 'symbol' referenced in function 'function'

It gives you the name of a global variable or (more likely) a function that is called without definition, i.e. you didn't write a function body for it or did not add the source with its definition to your project.

The error LNK1120 is a consequence of the first error.

Without the complete error message it's hard to tell. As @Darcy pointed out, you should change the names in #ifdefand #define since

#define PointClass

tells the preprocessor to substitute this name with nothing in the following source code. This results in a unnamed local namespace. All names defined inside this local namespace are accessible from inside that compilation unit (cpp file) only.

Choose a unique name for the "include guard" which should not occure anywhere else in the program. A possible pattern could imitate the name of the header file:

#define POINT_H
René Richter
  • 3,839
  • 3
  • 34
  • 42