views:

262

answers:

3

My code is stored in a main.cpp file which contains the void main() function, and a class MyClass which I now want to split to another file. IDE is Microsoft Visual Studio 2008 Professional.

myclass.h

#include <tchar.h>
class MyClass {
public:
    static bool MyFunction (TCHAR* someStringArgument);
};

myclass.cpp

#include <tchar.h>
class MyClass {
private:
    static bool someProperty;
    static void doSomeOneTimeCode () {
        if (!someProperty) {
            /* do something */
            someProperty = true;
        }
    }
public:
    static bool MyFunction (TCHAR* someStringArgument) {
        doSomeOneTimeCode();
        /* do something */
        return true;
    }
};
bool MyClass::someProperty = false;

main.cpp

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "myclass.h"
void main () {
    if (MyClass::MyFunction(TEXT("myString"))) {
        _tprintf(TEXT("Yay\n"));
    }
}

However, when I try to run it, I get two linker errors.

  • LNK2019: unresolved external symbol ... (mentions MyClass::MyFunction)
  • LNK1120: 1 unresolved externals

What can I do to prevent these linker errors?

+3  A: 

Yo can't split a class definition in parts. It must be defined as a whole in one place. If you want to just have some methods of the class defined create a interface class that the MyClass class will later inherit. You should put the class' definition in a header file (myclass.h) and it's implementation in a cpp file (myclass.cpp). That way you can include the "myclass.h" in your main cpp file and use the class in your main function (which should be int main() or int main( int argc, char *argv[] )).

Kasprzol
what speaks against `void main()` ?
Etan
The C and C++ Standards both explicitly call out `int main(void)` and `int main(int argc, char *argv[])` as two valid forms of `main` in a hosted environment. Interestingly enough, C++ only requires that it is named `main` and it's return type is `int`... In any case, `void main()` is not allowed by either Standard.
D.Shawley
ah okay, so visual studio permits `void main()` against the standard.
Etan
+2  A: 

Strange that you didn't get a compiler error, as you are redefining MyClass.

Definitions (implementations) go into the cpp, and they are defined like this:

#include "myclass.h"
//helper functions, particularly if static, don't need to be in the class
//unnamed namespace means this stuff is available only for this source file
namespace 
{
    bool someProperty;
    void doSomeOneTimeCode () {
        if (!someProperty) {
            /* do something */
            someProperty = true;
        }
    }
}

bool MyClass::MyFunction (TCHAR* someStringArgument) {
    doSomeOneTimeCode();
    /* do something */
    return true;
}
UncleBens
There is no compiler error because myclass.cpp does not include myclass.h
Timbo
Ok. Added the include to show that the declaration of MyClass is still needed.
UncleBens
+3  A: 

You declared two classes here. One of them is in myclass.h and the other is in myclass.cpp. Try the following instead:

myclass.h

#ifndef myclass_h_included
#define myclass_h_included

#include <tchar.h>

class MyClass {
private:
    static bool someProperty;
    static void doSomeOneTimeCode ();
public:
    static bool MyFunction (TCHAR* someStringArgument);
};

#endif //!myclass_h_included

myclass.cpp

#include "myclass.h"

/*static*/ bool MyClass::someProperty = false;

void
MyClass::doSomeOneTimeCode() {
    //...
}
bool
MyClass::MyFunction(TCHAR* someStringArgument) {
    //...
}

Your main.cpp can stay the same. I would pay attention to UncleBens reply as well. One time initialization code should be hidden if at all possible.

D.Shawley