1
votes

I'm trying to do something (as a C++ noob) that I thought should be easy: reference one class from another. For some reason, I'm getting an error:

Error 6 error LNK2019: unresolved external symbol "public: float * __thiscall Foo::Test(void)" (?Test@Foo@@QAEPAMXZ) referenced in function "void __cdecl Test(void)" (?Test@@YAXXZ) Bar.obj

Foo.h

class Foo
{
public:
    Foo(void);
    ~Foo(void);
    float* Test();
};

Foo.cpp

#include "Foo.h"
float* Test()
{
    return new float[0];
}

Bar.h

class Bar
{
public:
    Bar(void);
    ~Bar(void);
    void Test();
};

Bar.cpp

#include "Bar.h"
#include "Foo.h"
void Test()
{
    Foo* foo = new Foo();
    foo->Test();
}

Why won't the compiler let me reference the class Foo from Bar? I have no idea what this error means, nor any clue how to debug it.

3

3 Answers

5
votes
#include "Foo.h"
float* Test()
{
    return new float[0];
}

Should be:

#include "Foo.h"
float* Foo::Test()
{
    return new float[0];
}

Your version simply defines a free function Test, not the same as the member function Foo::Test.

An Unresolved external symbol error means that the compiler is telling you hey, you told me I would find the definition of this thing, but I looked and couldn't find it anywhere. Essentially, you have lied to it, and it called you out.

That other junk is the calling convention (__cdecl, __thiscall) and the mangled (actual) function name (?Test@@YAXXZ).

3
votes

You need to implement Foo::Foo(), Foo::~Foo() and similarly for Bar. Furthermore, the implementation of float* Test() should be

float* Foo::Test() { ... }

But you should really refrain from returning pointers to dynamically allocated objects to the caller. Use smart pointers, of std::vector<float> for example.

2
votes

You didn't implement member functions of Foo and Bar but free stand Test functions. To implement member functions outside class, you need to provide class name with scope resolution.

Update:

Foo.cpp

float* Test()
{
  return new float[0];
}

to

float* Foo::Test()
{
  return new float[0];
}

Bar.cpp

void Test()
{
  Foo* foo = new Foo();
  foo->Test();
}   

To:

void Bar::Test()
{
   Foo* foo = new Foo();
   foo->Test();
}

You also need to implement ~Foo(void), ~Bar(void) as well