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
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();
}
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.
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();
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.
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.
Related
head.h
#pragma once
namespace foo
{
int bar;
int funct1();
}
head.cpp
#include "head.h"
int foo::funct1()
{
return bar;
}
main.cpp
#include <iostream>
#include "head.h"
int main()
{
foo::bar = 1;
std::cout << foo::funct1() << std::endl;
return 0;
}
Error LNK2005 "int foo::bar" (?bar#foo##3HA) already defined in head.obj
I don't understand what is going on. I tried looking for the answer but everyone's questions are so specific to their code and don't even look close to the problem that I am having.
I am not including .cpp files into main. I am not redefining anything. I am literally just assigning 1 to the variable then returning it with a function in the same namespace. How is it being defined multiple times?
The header head.h is included in two compilation units head.cpp and main.cpp. So the variable bar is defined twice. You could declare the variable without its definition the following way
#pragma once
namespace foo
{
extern int bar;
int funct1();
}
and then define it in some cpp module.
This foo namespace-level bar declaration:
namespace foo
{
int bar;
}
is actually a definition.
To make it a declaration, mark the bar as extern in head.h:
namespace foo
{
extern int bar;
}
Then define it in head.cpp:
int foo::bar = 0;
head.h is included in both main.cpp and head.cpp.
So the variable is defined twice.
Possible Solution: make it inline. The "extern" solutions are also good, although older in approach.
namespace foo
{
inline int bar;
}
How is it being defined multiple times?
It is defined once in head.cpp and once in main.cpp. That is a total of two times. This violates the one definition rule, which states that there may only be one definition for every variable.
int bar;
This is a definition of a variable. You've included it into two translation units.
A variable can be declared without definition in an extern declaration:
extern int bar;
Replace the definition with such declaration, and put the definition into exactly one translation unit.
I am not redefining anything. I am literally just assigning 1 to the variable
You're redefining the variable!
head.cpp has one via #include "head.h", and main.cpp has one via #include "head.h".
You need to merely declare it (unusual but not too strange) in the header:
extern int bar;
…then define it in one translation unit. This is just like what you do with static class members (albeit with slightly different syntax).
Since C++17, you may do this by instead plopping the inline keyword on to your definition.
Alternatively, avoid mutable globals…
Do carefully note that foo is not a class, but a namespace. When you declare a free variable in the header file:
int bar;
And then #include this header file multiple times (into different CPP files, causing multiple translation unit compilations), you'd get a linker error. Everyone knows it.
And, you'd add extern attribute at the declaration, and define the variable elsewhere in one of the CPP/C file.
Putting a global variable into a namespace is nothing but giving the global variable a different name. Think if foo::bar as foo__NS__bar, and hence you must add extern in the header and define foo::bar at some locatoin.
Note that this is different from a non-static member variable of a class. A class variable doesn't need to be defined/declared this way since the class is a type. Each instantiated variable of class-type would have a separate copy of the variable.
Further to that, when you add a static variable in the class, you are giving that logically global variable another name. Thence, you must have that static-variable defined one of the CPP file.
I'm trying to access the static variable in other header file from a CPP file.
"Boo.hpp"
#ifndef Boo_hpp
#define Boo_hpp
static int num;
class Boo
{
public:
Boo()
{
num = 35;
}
};
#endif /* Boo_hpp */
"Foo.hpp"
#ifndef Foo_hpp
#define Foo_hpp
class Foo
{
public:
Foo();
};
#endif /* Foo_hpp */
"Foo.cpp"
#include "Foo.hpp"
#include "Boo.hpp"
#include <iostream>
Foo::Foo()
{
std::cout << "Num : " << num << '\n';
}
"main.cpp"
#include <iostream>
#include "Foo.hpp"
#include "Boo.hpp"
int main()
{
Boo boo;
Foo foo;
}
The Result I get :
Num : 0
Program ended with exit code: 0
The Result I expect :
Num : 35
Program ended with exit code: 0
If I move the class Foo's constructor implementation from Foo.cpp to Foo.hpp, my code works as expected.
However, I would like to be able to access the num from Foo.cpp.
How should I fix my code?
All translation units which includes the Boo.hpp will have their own definition of the num variable. No other TU (Translation Unit) will have the same num variable.
That's what the static linkage storage modifier means (for non-local, non-member variables).
You need to understand two things to understand what is happening here.
In C++, header files are just text which is "copy-pasted" to each .cpp file which includes them, directly or indirectly. The resulting preprosessed source code is "compilation unit", so you can basically think one .cpp file is one compilation unit.
static global variables (not to be confused with static member variables of classes, AKA class variables, which are essentially same as non-static global variables...) are visible inside the compilation unit they are defined in. If you define static global variable in two compilation units, they are completely independent variables, and do not interfere (their names are not visible outside the compilation unit either). So, unless you know you do want separate copy of the variable in multiple .cpp files (very rare), you shouldn't put static global variables in .h file (extern declaration of global variable defined in a .cpp file is what you usually want in a .h file).
Now when you combine these two things, you realize that the static variable defined in .h file is no different from static variable defined in .cpp file. If .h file is included in several .cpp files, you get several copies of the variable, and which one is being used depends on which .cpp file it is (directly or through includes).
You have two .cpp files, which both define same static variable here, so they have two copies, and code compiled in these will use different variables.
Now there is extra quirk here. If you define a member function, including the constructor, inline (happens implicitly when you define it inside a class, if you define it in .h file but outside class you have to use the inline keyword), then every .cpp file will get a different copy of that function. Now you as programmer promise they will be the same, that is what inline means (it has only a little to do with inline optimization). If you have several copies of the same constructor (defined in a .h file), and they actually access different static variable, then they are not the same, and you break the promise. Don't do that!
The keyword static on globals in C/C++ instructs the compiler to limit that symbol to the current compilation unit, i.e. the file it's declared in. Putting static declarations into header files is a huge trap because even though you include the same header in all your source files, each file will receive its own copy of the static symbol.
What you want is the extern keyword, that declares the symbol to be shared between compilation units, i.e. extern int num.
Some more reading on storage class specifiers here
I have a project which includes 2 files: main.cc and header1.h. While main.cc instantiates a class "className" and calls the member functions of it, the header file includes definition of the class.
main.cc:
#include <header1.h>
int main(){
className classobject();
classobject.function1();
...
}
}
header1.h:
class className{
public:
className();
void function1();
...
};
double className::function1(){
double function2(){
...
}
}
With this, I met an error which says:"a function definition should not be placed before '{' token.
So I decided to put the definition of function2 outside of the class, and put it in a standalone .h file. In that way, my project would include 3 files, namely: main.cc, head1.h and function2.h file:
main.cc:
#include <head1.h>
int main(){
className classobject;
void classobject.function1();
...
}
head1.h:
#include <function2.h>
class className{
double function2();
...
}
function2.h:
double function2(){
...
}
Although function2 can also be defined as the class member function so that it can be moved out of function1 while inside the class, I want to know whether the above mentioned treatment is leagal. Besides, does the creation of header files have some implicit rules established by usage (common treatment)?
Could anyone give some comments? Thanks in advance.
The first problem in your code that I see is that you define className::function1 in a header, but forgot to declare it inline. The outcome is that you can only use the header in a single compilation unit †. That's a bad design. I recommend defining it in a source file instead.
Secondly, you try to define function2 inside another function. That's not allowed and therefore you got a compilation error. You say that you decided to move it's definition outside the class, but it's definition was already outside the class definition. Moving the definition outside the definition of className::function1 is indeed a correct choice.
If function2 is reusable outside it's use in className::function1, then it's indeed a good idea and perfectly legal to declare it in a separate header. But just like className::function1, you're defining function2 also in the header again and again without declaring it inline and therefore you will get in trouble if you try to use it in multiple compilation units. I recommend defining function2 in a source file as well.
† If you include the header in multiple compilation units, then each of those compilation units will contain the definition of the function. The One Definition Rule does not allow defining a function in more than one compilation unit. Functions that are marked inline are treated differently. They may be defined in multiple compilation units as long as they have an identical definition in each.
Do something like this in your className.hpp
class className{
public:
className();
private:
void function1();
};
Then in your className.cpp
#include"className.hpp"
className::className(){ /*defintion*/ }
void className::function1(){ /*definition*/ }
Then you could use a makefile in oder to compute the className.o file and link it to the main file.
If you want to define another function (like function2()), you can then define it the className.cpp
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is external linkage and internal linkage in C++
Actually I want to know the importance of extern.
First I wrote some code :
file1.h
extern int i;
file2.c
#include<stdio.h>
#include "file1.h"
int i=20;
int main()
{
printf("%d",i);
return 0;
}
Now my question is that: what is the use of extern variable when I have to define the i in file2.c, declaring in file1.h is in which way useful to me .
sudhanshu
extern allows you to declare a variable (notify the compiler of its existence) without defining it (bringing it into existence). The general rule is that you can declare things as many times as you want, but you can only define them once.
This is useful if, for example, it will be defined elsewhere.
Consider:
file1.c: file2.c:
extern int xyzzy; int xyzzy;
void fn (void) {
xyzzy = 42;
}
When you link together those two functions, there will be one xyzzy, the one defined in file2.c, and that's the one that fn will change.
Now that happens even without the extern. What the extern does is to declare that xyzzy exists to file1.c so that you don't get any I don't know what the blazes "xyzzy" is errors.
In your particular case (if those are your only two files), you don't need it. It's only needed if you had another file that #included file1.h and tried to access i.
It's useful when you have three files:
foo.h
extern int i;
void bar();
a.c:
#include "foo.h"
int i = 6;
int main(){
bar();
}
b.c:
#include "foo.h"
void bar(){
printf("%d\n", i);
}
As you can see, i is shared between both a.c and b.c, not redefined per-file, as would happen without the extern keyword.
The "extern" declaration in C is to indicate that there is an existence of, and the type of, a global variable.
In C mostly each .c file behaves like a seperate module. Hence a variable with "extern" is something that is defined externally to the current module.
It is always a better practise to define the global in one place, and then declare extern references to it in all the other places. When refering to globals provided by any shared library, this is important in order to make sure that your code is referring the correct and common instance of the variable.
From Wikipedia:
When a variable is defined, the compiler allocates memory for that
variable and possibly also initializes its contents to some value.
When a variable is declared, the compiler requires that the variable
be defined elsewhere. The declaration informs the compiler that a
variable by that name and type exists, but the compiler need not
allocate memory for it since it is allocated elsewhere.
Extern is a way to explicitly declare a variable, or to force a
declaration without a definition
If a variable is defined in file 1, in order to utilize the same
variable in another file, it must be declared. Regardless of the
number of files, this variable is only defined once, however, it must
be declared in any file outside of the one containing the definition.
If the program is in several source files, and a variable is defined
in file1 and used in file2 and file3, then extern declarations are
needed in file2 and file3 to connect the occurrences of the variable.
Having extern tells the compiler its a declaration of a variable.
In your example in file1.h imagine what would happen if you didn't specify extern keyword. It will look like there are two definitions of int i. Also, a header file can be included in many .c files. If you compile those .c files and link them, linker would see multiple definitions of the same variable.
extern keyword allows you to say to the compiler ... " Use this variable right now .. I will define and initialize it later ".. i.e " Compile it now .. I will link to its definition later".
You can extern the variable when you define it in some other file and you want to use it in the current context..
The declaration in the header allows you to access the variable from more than one source file, while still only defining it in one place.
I would like a function that is not a member of a class and is accessible from any class.
I assume I would have to #include the header file where the function is declared, but I don't know where to define such a global function.
Are there good reasons against having such a function in the first place?
you need a body (in a cpp file):
int foo()
{
return 1;
}
and a definition/prototype in a header file, which will be included before any use of the function:
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
int foo();
#endif
then using it somewhere else:
#include foo.h
void do_some_work()
{
int bar = foo();
}
or use an inline function (doesn't guarantee it'll be inlined, but useful for small functions, like foo):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
inline int foo()
{
return 1;
}
#endif
alternatively you can abuse the C-style header based functions (so this goes in a header, the static forces it to exist in a single compilation unit only, you should avoid this however):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
static int foo()
{
return 1;
}
#endif
What you are calling global function is usually called a free function and they are A Good Thing.
You would define it just like a class' member function, but outside of that class' scope.
double squared(double x) {
return x*x;
}
Simple functions you can define with the inline keyword in the header file, or just declare it there
double squared(double x);
and put the implementation (first example) into the *.cpp file.
In a header file:
// someheader.h
#ifndef MY_GLOBAL_FUN
#define MY_GLOBAL_FUN
void my_global_fun();
#endif
In an implementation file:
#include "someheader.h"
void my_global_fun()
{
// ...
}
In other files that require that function:
#include "someheader.h"
void f()
{
my_global_fun();
}
Free functions like this are useful and there are not many arguments against using them. Depending on your use case, its likely appropriate to put these functions in a specific namespace to avoid name collision with other libraries you may be using.
Think of main(). The function is kind of just...there. It's not within any class, struct or namespace. You just declare and give it a body. Of course, in the case of functions that are not main, it's best to put a prototype in a header and the define it in a .cpp file.
Remember, C did not have classes and structs could not hold member functions. There was nothing wrong with free functions then and there isn't now.
You have to declare its prototype in header file and define it in implementation file.
//file.h
void foo();
//file.cpp
void foo ()
{}
To shortly answer your second question, Global functions are needed when they are used by several different classes and types in a generic way. For example math functions.
Otherwise, in general you may avoid so many global functions. Also you should avoid having a static local member or global data associated with such function (so that you don't have to worry about thread safety).
In addition to the answer by #Necrolis, the use of static is deprecated in favour of unnamed namespaces. However, use of unnamed namespaces and static both creates separate copies for each translation unit which increases the size of binary. The use of inline is better than both of these in this sense.
These solutions allow for more usage specific optimisations by compilers but are less instruction cache friendly compared to definition in a source file and then linking.