4

In the header I declared

#ifndef SOUND_CORE #define SOUND_CORE static SoundEngine soundEngine; ... 

but the constructor for SoundEngine gets called multiple times, how is it possible, when it's declared as global static

I call it as

#include "SoundCore.h" 

and use it directly

soundEngine.foo() 

thank you

5 Answers 5

7

I would use extern instead of static. That's what extern is for.

In the header:

extern SoundEngine soundEngine; 

In an accompanying source file:

SoundEngine soundEngine; 

This will create one translation unit with the instance, and including the header will allow you to use it everywhere in your code.

// A.cpp #include <iostream> // other includes here ... extern int hours; // this is declared globally in B.cpp int foo() { hours = 1; } // B.cpp #include <iostream> // other includes here ... int hours; // here we declare the object WITHOUT extern extern void foo(); // extern is optional on this line int main() { foo(); } 
Sign up to request clarification or add additional context in comments.

Comments

7

A copy of static variables declared in header files gets created for each translation unit where you include the header.
Never declare your static variables inside header files.

You could use a singleton object.

13 Comments

yes, static is per translation unit. The remedy would be a Singleton or the like.
stupid me was thinking: Can you do 'extern SoundEngine soundEngine' and then implement in one compilation unit as static(that is, without the extern keyword)?
@Mario The Spoon: Yes you can do that and it is perfectly valid and will work, but as a matter of personal choice i really don't like to use extern in that way.
Both singletons and extern objects have issues (both from a design point of view, and from the way they work in C++). My preferred approach is to instantiate the object inside a function (main() or something similarly high in the call chain), and pass a reference (or possibly a smart pointer, depending on how complicated the objects' lifetimes are) to everything that needs it.
@Mike, @Als: well, if the application needs a true global configuration/storage object, why not make it global (inside a namespace)? The only issue I can see with this, is threading, but that can be helped by using the correct threading idioms either enforced outside of the object, or hidden inside of the global/static.
|
2

As others mentioned in the answers, static variable in header file gets included in every file where the the header is included. If you want to still keep it static and avoid multiple instantiations then wrap it in a struct.

//SoundCore.h struct Wrap { static SoundEngine soundEngine; }; 

Now define this variable in one of the .cpp files.

//SoundCore.cpp SoundEngine Wrap::soundEngine; 

And use it simply as,

Wrap::soundEngine.foo(); 

3 Comments

Why would you want to wrap it in a class rather than declaring it extern at namespace scope?
@Mike, actually extern is the best idea for such single variables. Since @rubenvb already suggested the same; I gave this another way (saying if you still want to keep it static).
you're not "keeping it static" in any way other than preserving the static keyword, which has a different meaning in this context. This is precisely equivalent to making it extern (i.e. it changes the linkage from internal to external), but with an extra layer of confusion caused by introducing a meaningless class.
0

If you include this header file in multiple files, your class will be instantiated for every inclusion. I think you better take a look at Singleton pattern, to get only 1 instance, i.e., just one constructor call.

Comments

0

As many other reserved words, static is a modifier that has different meanings according with the context.

In this case, you are creating an object of the class SoundEngine which is private in this module. This means that it is not visible from other modules.

However, you put this line in the header, so it is a private object in various modules. I guess that's the reason of the constructor being called multiple times.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.