1

I have a class, myClass, which is split into a .h and .cpp file. I then have a main.cpp file, in which I declare a global instance of myClass as such

myClass class1(0,0);

I also have a few other cpp files which use class1, such as Funcs.cpp. Therefore, I created an extern file, extern.h, and declared the myClass instance as extern as well:

extern myClass class1;

There are two constructors available for myClass, one takes in two parameters and the other three (overloaded). There is no constructor which takes in no parameters. The constructor with two parameters is something like this:

myClass:myClass(int id, int mode);

My issue is that I am getting the following error message:

Identifier myClass is undefined "extern myClass class1"

...even though I have included myClass.h in both main.cpp, myClass.cpp and extern.h.

What is the correct way to share a global instance of myClass between several cpp files? I read through Issue declaring extern class object and the differences are that myClass has two parameters it takes in, and that my global instance is declared in main.cpp rather than myClass.cpp.

Tryb Ghost
  • 419
  • 1
  • 4
  • 14
  • 1
    the correct way is not to use a global instance. If some other instance or function needs `class1` (not the best name btw) then pass it to them. Btw dont think in terms of "cpp files". You could put all code in a single file and it would still do the same (with some exceptions of course). – 463035818_is_not_an_ai May 22 '19 at 09:56
  • The superficial problem is that the 'user' of your class needs access to both the *declaration* of the global variable and the full declaration of `myclass`, ie the header file must contain both. The actual *definition* of the global variable can go into a single `.cpp` file somewhere. The underlying problem (how to define a global variable safely) is embodied by the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern). – Botje May 22 '19 at 09:59
  • can you paste a very trimmed down version of your files? – xception May 22 '19 at 10:01
  • Should work. Show us your [MCVE]. – Lightness Races in Orbit May 22 '19 at 10:16

3 Answers3

3

The problem could be the order of the include files. The compiler trustfully processes each compilation unit line by line, including the content of a .h file at the position of the #include.

That means that you must include myclass.h before extern.h:

#include "myclass.h"
#include "extern.h"
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • actually if that is the problem he should include "myclass.h" from inside "extern.h", so he never has the problem again, however the question states that he included these already. – xception May 22 '19 at 10:14
  • @xception: I learned to never include other include files unless multiple inclusions are carefully protected with `#ifndef __SOME_UNIQUE_ID #define __SOME_UNIQUE_ID content of file #endif` – Serge Ballesta May 22 '19 at 10:16
  • This has helped me quite a bit. I have put include "extern.h" in "myClass.h", which is why "extern.h" was getting executed first. Removed it and the error is indeed gone! Thank you. – Tryb Ghost May 22 '19 at 10:24
3

A very trimmed down version of your requirements that should work:

myclass.h:

#ifndef MYCLASS_H
#define MYCLASS_H

class myClass
{
public:
        myClass(int, int);
};

#endif // MYCLASS_H

extern.h:

#ifndef EXTERN_H
#define EXTERN_H

#include "myclass.h"
extern myClass class1;

#endif // EXTERN_H

usingextern.cpp:

#include "extern.h"

bool variable_named_class1_exists()
{
        return (bool)&class1;
}

In more modern versions of C++ / using modern compilers I prefer #pragma once as a guard instead of the #ifndef UNIQUE_ID, #define UNIQUE_ID, #endif combo, because, for a bigger project, it's really hard not to end up with collisions on the 'UNIQUE_ID's.

xception
  • 4,241
  • 1
  • 17
  • 27
  • _"for a bigger project, it's really hard not to end up with collisions"_ Shouldn't be. And note that `#pragma once` has nothing to do with "modern versions of C++" because it's non-standard by definition. – Lightness Races in Orbit May 22 '19 at 10:44
  • Best not to call instances "classes". `object1` perhaps. Regardless this is the code the OP already claims to have so we should wait to find out what the real problem is. – Lightness Races in Orbit May 22 '19 at 10:45
  • @LightnessRacesinOrbit renamed the function to more explicitly say what it does, can't rename the var cause the OP said he already named variables like that. – xception May 22 '19 at 10:50
0

Although perfectly legal using such a global variable is more C like code, rather than C++ OOP. Then you should consider to make it a static member of your class. If you think it is meaning less in your context, then it means your variable should probably not be global either.

If you make it a static member it will solve your problem, because then you need only to include the header declararing your type.

P. PICARD
  • 386
  • 1
  • 10