-2

I was trying to write a header file in C++ which declares a class, but when I try to use the actual code it gives me the error "undefined reference" to the methods of the class in the header file; what should I do to fix it?

Class code
#include <iostream>
#include <Punto2D.h>
#include <math.h>

class Punto2D {
  private:
    int x;
    int y;

  public:
    Punto2D() {
        x = 0;
        y = 0;
    };
    int get_x() {
        return x;
    };
};
Header file
#ifndef Punto2D_H
#define Punto2D_H

#include <iostream>
#include <math.h>

class Punto2D {
  private:
    int x;
    int y;
  public:
    Punto2D();
    int get_x();
};

#endif
Main file
#include <iostream>
#include "Punto2D.h"

using namespace std;

int main() {
    Punto2D A;
    cout << A.get_x();
}

At first, I though that it was because I forgot some part of the code so I tried some trouble shooting the thing that made me the closer to actually make the code work was adding to the header files methods the curly brackets but as far as I understand you shouldn't put them there.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Krobbolo
  • 9
  • 1
  • You need to remove the class definition of `Punto2D` from `Punto2D.cpp` file. Only define the member functions there, not the actual class. – Ted Lyngmo Aug 27 '23 at 19:47
  • You already got correct answers to your question below. But maybe you want consider a few more questions? As @TedLyngmo already pointed out: which member functions might be `const`? And what are the best member types for your values? Is `int` always the answer? Are negative values legal in your case (if not -> `unsigned`)? Do you need integer or floating point values? Might it even be worth to introduce strong types (e.g. `struct coord { unsigned long value; }`)? Much to think about on designing a simple point class ;) – kaba Aug 27 '23 at 20:15
  • You would have gotten a compiler error if your source file with the class was compiled. The compiler would have told you that you're re-defining the class, which would have made it obvious. Your first and greatest mistake was forgetting to make `Puncto2D.cpp` or whatever it's called part of your build. – Jan Schultke Aug 27 '23 at 20:29
  • https://stackoverflow.com/a/280099/5740428 shows how to do it right – Jan Schultke Aug 27 '23 at 20:36

4 Answers4

3

As noted in the comments, you only provide the member implementations in your .cpp file, not the whole class definition again. Your header is fine. Here's what your .cpp should look like.

#include <iostream>
#include <Punto2D.h>
#include <math.h>

Punto2D::Punto2D() {
  x = 0;
  y = 0;
}

int Punto2D::get_x(){
  return x;
}

And your constructor should be using constructor initialization syntax, so I would recommend this for the constructor, actually.

Punto2D::Punto2D() :
    x(0), y(0) {}

It doesn't matter a whole ton for simple fields like integers, but when you start storing instances of other classes in your class, you'll appreciate the direct initialization.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
1

You need to remove the class definition of Punto2D from Punto2D.cpp. Only define the member functions in the implementation file, not the actual class.

// Punto2D.cpp
#include <Punto2D.h>

Punto2D::Punto2D() : x(0), y(0) {
};

int Punto2D::get_x(){
    return x;
};

Sidenote: get_x doesn't change the value of any member variable and should therefore be const qualified:

// Punto2D.h

class Punto2D{
public:
    int get_x() const;       // <-
};
// Punto2D.cpp

int Punto2D::get_x() const { // <-
    return x;
};
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

I don't know what you use to build your project, but there are a few things off. In "Puncto2D.cpp" (I suppose this is where your first code snippet is located) you use #include <Punto2D.h> instead of #include "Punto2D.h". Using "" makes the compiler first look at relative paths to the file with the #include statement which you probably want. I don't think that the compiler would find a file named "Punto2D.h" when using angle brackets since it would usually search in its implementation for the standard.

If #include <Punto2D.h> however works as you might expect, you should get an additional error saying something like 'Punto2D': 'class' type redefinition. Therefore there might be some errors with how you build your project and you might need to add "Punto2D.cpp" to be compiled and linked against.


Your files should look like this:

Punto2D.h

#pragma once    // you can use this instead of your ifdef headerguard

class Punto2D {
private:
    int x;
    int y;

public:
    Punto2D();
    int get_x();
};

Punto2D.cpp

#include "Punto2D.h"

Punto2D::Punto2D() {
    x = 0;
    y = 0;
};

int Punto2D::get_x() {
    return x;
};
Joel
  • 721
  • 1
  • 13
0

There are a couple of issues with the class code. Firstly, your error message is caused by, I presume, a simple oversight: the directive

#include <Punto2D.h>

should be

#include "Punto2D.h"

The other error is in having redefined the class. In the implementation file, you should only put the definition of the methods. Here the full code:

#include <iostream>
#include "Punto2D.h"
#include <math.h>

Punto2D::Punto2D() {
    x = 0;
    y = 0;
};

int Punto2D::get_x() {
    return x;
}
Dani_DD
  • 41
  • 3