1
votes

I have these two simple files that define a C++ class with a tryME function

______myclass.h________________
#pragma once

void tryME()
{

}

class myclass
{
public:
    myclass(void);
    myclass(void);


    void callTryME();
};

_________myclass.cpp____________

#include "myclass.h"


myclass::myclass(void)
{
}


myclass::~myclass(void)
{
}

void myclass::callTryME()
{
    tryME();
}

This gives the error

1>myclass.obj : error LNK2005: "void __cdecl TryME(void)" (?TryME@@YAXXZ) already defined in tryout.obj 1>C:\tryout.exe : fatal error LNK1169: one or more multiply defined symbols found

If I declare the tryME() function as static, the problem is solved. But why?

I know that the .h file is included in the .cpp file and then compiled (into a translation unit) and that static variables and functions are visible to the entire translation unit they're contained into, but why doesn't the program work without the "static" keyword? The function tryME should be "global" outside the class and thus visible, isn't that correct? Does the calling put a "this->" before the tryME() ?

3

3 Answers

1
votes

This:

inline void tryME()
{

}

Otherwise, you're breaking the one definition rule.

Defining a non-inline method in a header file will result in it being exported by all translation units that include that header, ergo the error.

1
votes

It is indeed visible. It's visible as a separate definition in every file that loads the header file, so at link time the linker is faced with multiple functions all with the same name and correctly complains that it doesn't know which one you intended to use.

Don't define functions in header files. Declaring them is good; defining them, not so much.

1
votes

You can separate function declaration and definition in header file and source file. In your case, you can move tryMe() definition from "myclass.h" to "myclass.cpp", and leave only declaration of tryMe() in "myclass.h". Other way is to use "inline" keyword, as was already mentioned in other answers.