0

trying to see how structs and constructors work in header, implementation, and main files. Using constructor and default constructor. I get compilation error in mains.cpp of "undefined reference to 'numbers::numbers()'

In test.h I have:

#ifndef H_TEST
#define H_TEST

struct numbers{

   int a;
   int b;
numbers();

numbers(int x, int y);

};
#endif

In Numbers.cpp I have:

#include "test.h"

 numbers::numbers()
  {
     a=0;
     b=0;
  }
  numbers::numbers(int x, int y)
  {
      a=x;
      b=y;
  }

In mains.cpp I have:

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

 numbers num;//compilation error occurs here
 int main()

{





 return 0;
 }
Alex
  • 119
  • 3
  • 9
  • 2
    The most likely reason is that you're not linking correctly, you're linking only `mains.cpp`. – Sam Varshavchik Jun 18 '16 at 02:09
  • 1
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Dimitri Podborski Jun 18 '16 at 02:24
  • It's working fine in MSVS 2013. Which one have you used ? – Md. Monirul Islam Jun 18 '16 at 02:43
  • I'm using codeblocks – Alex Jun 18 '16 at 03:04
  • Neither of the inline constructor definitions in the structure definition initializes the member variables. I'm not sure what you think `numbers(3, 5);` is doing in `main()`, but it isn't affecting `num`. You need to remove the `{}` from the constructors in `test.h`, I believe. – Jonathan Leffler Jun 18 '16 at 03:06
  • 2
    You're defining `numbers::numbers() {}` as an empty function in *test.h*. It's never calling the `numbers::numbers()` in *numbers.cpp* – Ryan Bemrose Jun 18 '16 at 03:07

2 Answers2

3

Looks like you're declaring inline constructors in the header file by putting in function bodies (albeit empty function bodies) for the constructors.

I would expect that in files that include the header, when the compiler sees the inline definitions it will use those and so never generate a symbol to be linked with the definitions in the .cpp file and therefore the definitions in the .cpp file will not be called.

Try deleting the empty function bodies in the header.

QuantumMechanic
  • 13,795
  • 4
  • 45
  • 66
  • It wouldn't compile unless I added {}; in the header files. – Alex Jun 18 '16 at 03:09
  • 2
    @Jane That's a different problem, then. You should post the error you got, because an empty function body in the header is wrong if you want to define the function body elsewhere. – Ryan Bemrose Jun 18 '16 at 03:11
3

The problem is that you're default-constructing num and not reassigning it.

numbers num; // Constructs a numbers object with a = 0, b = 0 and stores it in num.
int main()
{
    numbers(3,5); // Constructs a numbers object with a = 3, b = 5.
                  // The object is discarded after the constructor call finishes.

    cout<<num.a; // Prints a from the global variable num.

    return 0;
}

I think you intended to reassign num:

numbers num; // num is default-constructed to a = 0, b = 0, as before.
int main()
{
    num = numbers(3,5); // num now holds a = 3, b = 5.

    cout<<num.a; // Prints 3, as expected.

    return 0;
}

Side notes: You generally should avoid non-const global variables. Also, when possible, initialize variables in the same line you declare them to avoid assigning the data members twice (doesn't really matter for very small objects like this one).

Edit: I didn't notice the problem that QuantumMechanic pointed out. You'll have to fix both errors for the program to work as you expect.

Jonathan Sharman
  • 636
  • 6
  • 16
  • Yeah I'm getting compilation errors of undefined reference to numbers::numbers() and numbers(int,int) from mains.cpp – Alex Jun 18 '16 at 03:25
  • You mentioned you're using Code::Blocks. Did you add Numbers.cpp to the project? (It should probably appear under Sources.) – Jonathan Sharman Jun 18 '16 at 08:02
  • Yes it was a source file in my project. I was able to get it to compile finally. I don't know why it wouldn't before! – Alex Jun 19 '16 at 12:07