Suppose I have have a Car.h which define a class called Car , and I have implementation Car.cpp which implement my class Car, for example my Car.cpp can be :
struct Helper { ... };
Helper helpers[] = { /* init code */ };
Car::Car() {}
char *Car::GetName() { .....}
What is the life time of the helpers array ?
Do I need say static Helper helpers[]; ?
If I have done some bad practices, please let me know.
Any variable declared/defined in global / namespace scope has a complete life time until the code ends.
If you want your Helper helpers[]; to be accessible only within Car.cpp then only you should declare it as static; otherwise let it be a global. In other words,
Helper helpers[]; // accessible everywhere if `extern`ed to the file
static Helper helpers[]; // accessible only in `Car.cpp`
Edit: As, #andrewdski suggested in comment below; you should make helpers[] as static variable since you are using it within this file; even though Helper is not visible outside. In C++, if 2 entirely different unit has same named global variables then compiler silently create a mess by referring them to the same memory location.
Objects defined at file scope are called Static Storage Duration objects.
In most situations you can think of them as being created before main() is entered and destroyed after main() is exited (there are exceptions but I would not worry about that).
The order of destruction of static storage duration variables is the reverse order of creation.
The order of creation within the same compilation unit (file) is the order they are declared.
Note: There is no guarantee about the order of creation of Static Storage Duration objects across different compilation units.
Related
I inherited a project from a former colleague, and I found these code snippets (and some similar ones in SO questions: can a c++ class include itself as an member and static member object of a class in the same class)
// Service.h
class Service
{
// ...
public:
static Service sInstance;
void Somememberfunc();
//...
};
// Service.cpp
#include "Service.h"
Service Service::sInstance;
void Service::Somememberfunc()
{
//...
}
// Main.cpp
#include "Service.h"
void Fun()
{
Service &instance = Service::sInstance;
//...
instance.Somememberfunc();
//...
}
However, I did not find any explanation on when to use this pattern. And what are the advantages and disadvantages?
Notice that the member is a static, so it's part of the class, not of instantiated objects. This is important, because otherwise you would be trying to make a recursive member (since the member is part of the object, it also contains the same member and so on...), but this is not the case here.
The best pattern to describe this is: global variable. The static member is initialized before main() and can be accessed from any part of the program by including the header file. This is very convenient while implementing but becomes harder to handle the more complex the program gets and the longer you have to maintain it, so the general idea is to avoid this. Also, because there is no way to control the order of initialization, dependencies between different global variables can cause problems during startup.
Static member is roughly a global variable in the scope of the class.
Static members have also the advantage of visibility access (public/protected/private) to restreint its usage (file scope might be an alternative).
That member might be of type of the class.
Global are "easy" to (mis)use, as they don't require to think about architecture.
BUT (mutable) global are mostly discouraged as harder to reason about.
Acceptable usages IMO are for constants:
as for a matrix class, the null matrix, the diagonal one matrix.
for Temperature class, some specific value (absolute 0 (O Kelvin), temperature of water transformation(0 Celsius, 100 Celsius), ...)
in general NullObject, Default, ...
Singleton pattern. For example, you can use it to store your app configurations. And then you can easily access configurations anywhere(globally) within your app.
This is often used in the singleton design pattern
Visit https://en.wikipedia.org/wiki/Singleton_pattern
I have been reading through other questions on here and there is something that has me confused and hopefully it can be explained. I am sure there it is a simple thing but it is alluding me.
So in C++ we have private variables that are only viewable within the class:
class MyClass
{
private:
int i;
};
But we can also have unnamed namespaces:
namespace
{
int i;
}
Both appear to be private to the class but in the 2nd case you cannot see they exist from the header file. From reading other questions it seems that functions are different as you can't pass class objects to them? But I am not sure what the difference is here for variables.
Is there a disadvantage to the 2nd way that means you should still use private variables?
They aren't the same.
Integer i in the anonymous namespace will be shared by all instances of MyClass.
The private integer i in MyClass will be unique for each instantiation of the class.
The equivalent using private would be to make i static:
//.h
class MyClass
{
private:
static int i;
};
And instantiate the one single shared i like this:
//.cpp
int MyClass::i = 0;
Both appear to be private to the class ...
No, only the first is private to the class. It's a non-static member variable; one is instantiated in every object of the class type.
The second is not in a class at all; it has static storage duration, so one is instantiated for the whole program. Anything that accesses it is accessing the same variable as anything else that accesses it. Being in an unnamed namespace, it's only accessible within the translation unit (i.e. the source file) that defines it; but it's accessible to any code there, not just a particular class.
Is there a disadvantage to the 2nd way that means you should still use private variables?
If you want a copy of the variable in each class object, then you need it to be a non-static member.
If you want to share it between all objects, then it's up to you whether to make it a static member, or put it in a namespace inside the class's implementation file. I often do the latter to simplify the class definition. Disadvantages are that access isn't restricted just to the class but to anything else in that file, and you can't access it from any code that you might want to put in the header.
Namespaces are unrelated to objects/classes. In particular, if you have two objects, each has its own copy of a private variable.
They are quite different concepts. The private data member is visible only to a class, and in the non-static case, each class instance owns one of these. The anonymous namespace allows you to make code available only to other code in the same file. So in the case of the single int variable, all code defined in the same place as the anonymous namespace would see the same, single variable.
I have been reading different articles on memory management in preparing for how I want my architecture to work, with my biggest worries on how the allocators will be used, created and handled throughout the code base. One of the issues is that my design always has the allocator(s) at a global scope, since I don't have a typical singleton design to contain the allocators, they have no real place to live. I would like to avoid using globals for this due to all the issues typical had with using globals.
This lead me to the design of having something such as
void* operator new(size_t size, uint32_t type)
{
return gAllocator.Alloc(size, type);
}
This would then lead to having just the new definition in a header file, with the declaration in a .cpp. This .cpp file would then have the gAllocator, only in the .cpp file (and can be accessed in place else except for the new call.
If my design would to be like this, would the gAllocator still be a global variable, if not, what type of variable would it be considered? What if it was in the scope of just a namespace?
It seems a plain global is just what you want. For review, in C++ a global (or singleton) should be a local static variable in an inline function.
class myAllocator {
public:
static myAllocator &getDefaultInstance() {
static myAllocator theInstance( parameters );
return theInstance;
}
};
This way, the object is initialized the first time it's used. If you use a typical header declaration + .cpp definition, the order of initialization with respect to other globals is undefined, with possible unpredictable consequences. (The "static initialization order fiasco.")
So I recently found some source code which used a particular technique(idiom?) I hadn't seen before; to put it simply; instead of using a static variable for the class in question, it used a local variable inside the classes source file.
myclass.h
class myclass {
//static int myint;
public:
myclass();
~myclass();
int count();
};
myclass.cpp
#include "myclass.h"
int myint = 0;
myclass::myclass() {
myint++;
}
myclass::~myclass() {
myint--;
}
int myclass::count() {
return myint;
}
main.cpp
#include "myclass.h"
#include <iostream>
int main() {
myclass aclass;
myclass theclass;
std::cout << theclass.count(); //outputs 2
return 0;
}
My question is, why would someone take this approach over using a static variable?
My take on it is that, since ideally the variable would only be known to the myclass class (private static), and inheritance is not of importance at all (in this case), this could stop others knowing about this variable. But that is the only advantage I can see; not sure if that would warrant it.
The same question goes for (static / non - static) member functions that are private; when inheritance is not important.
EDIT: After reading around, I'm going to make a stab that it is because some people still use C programming style...
It doesn't really matter whether you use a static member variable or a global variable or a locally declared static variable; the only important thing is that the object has to have static storage duration. Beyond that, the choice is mostly based on personal preference or coding style guidelines.
Unfortunately, this code is basically wrong. While myint is "hidden" and only directly accessible from within myclass.cpp, it still has external linkage. This means that it is accessible from other translation units (by using extern int myint in those other translation units) and its definition can conflict with other definitions of myint in other translation units.
To correct this, it should either be declared static (giving it internal linkage) or, preferably, it should be declared in an unnamed namespace,
namespace {
int myint;
}
(an object in an unnamed namespace may still have external linkage, but it is uniquely named so it cannot be used by its name from outside of the translation unit in which it is compiled.)
In your example the variable is not static and is technically visible outside the compilation unit if properly declared. If this is not intentional it can be a source of problems if another compilation unit uses the same trick on a variable with the same name (to fix this see James McNellis answer).
Assuming a properly declared static (e.g. using the unnamed namespace approach) this technique can be better than a class static because it hides completely the variable from class users. This means that if you need to add or modify that variable the clients don't even need to be recompiled (you just need to recompile the implementation .cpp file and then to relink the program). This can be a big difference if your class is used everywhere in a big project (compile just one file instead of recompiling the whole world because of a change in an internal detail).
Also if the static variable is not an int but something more complex (e.g. a templated class instance) then putting the variable in the class as a static requires to expose much more data to clients, introducing not needed dependencies.
Sometimes this unwanted dependency problem is considered so important that you can find implementation of the "compiler firewall" idiom. This hiding is sort of a partial and light version of it.
My question is, why would someone take this approach over using a static variable?
it makes sense if you have something to hide -- an int is not worth usually hiding, but a large library is. an author may also prefer to hide implementation details from clients in some cases.
regarding static functions -- i'll typically hide them if they are just free helpers, and really don't belong in, or are required to be a part of the class interface.
generally, i'll put it in the class interface simply for organizational purposes.
In C++, say you want to declare a global variable to be used by many. How do you do it?
I commonly use declare and define in cpp file, and then use extern in other cpp file (and not headers).
I don't like this approach, and I am considering something along these lines:
In a header file:
some_file.h
Class MYGlobalClass
{
};
MyGlobalClass& MyGlobalClassInstance()
{
static MYGlobalClass instance;
return instance;
}
Edit
Consider in the following contexts:
can be used in multi-threaded applications
namespace pollution
may NOT necessery be a singleton, as many instances of this might be created
What are your thoughts, suggestions, new ideas?
The best advice is probably "try to avoid globals". People don't need global variables as often as they think. Usually it turns out that "passing everything as arguments to constructors" isn't quite as much work as people think when they hear the suggestion. It also tends to lead to cleaner code with fewer, and more explicit, dependencies.
I'm not aware of any "correct" way to declare globals in C++. The way you do it now works fine, but the order of initialization is unspecified, so if there are any dependencies between your globals, you're in trouble.
A function returning a static instance more or less solves that problem, but isn't thread safe.
And a singleton is just a terrible idea. It doesn't solve your problem, but adds additional constraints to your code, which weren't actually necessary, and will most likely come back and bite you later.
Declare as extern in one header file included by "many" and define it in one *.cpp file
Declare it in one header file (using extern), and define it in one .cpp (or whatever other extension) file. You may use a function and return a reference to a static variable like you showed to circumvent problems with construction order relative to other such namespace scope variables in other .cpp files. But remember that won't protect you from destruction order problems - which is in the exact reverse order from construction (these things are called "static initialization order fiasco". If you use a function like yours and put it into headers, make it inline to make the redefinition of the function valid when it is included into multiple .cpp files (logically, the function is still only apparent once, because the static in it will only exist once, not separately for each file it is included into). Alternatively just declare it in a header but define it in one .cpp file (but then, remove the inline from it!).
inline A& getA() { static A a; return a; }
The potential problems with destruction order can be circumvented by using new:
inline A& getA() { static A *a = new A; return *a; }
The destructor of it, however, will never be called then. If you need thread safety, you should add a mutex that protects against multiple accesses. boost.thread probably has something for that.
Your idea of a static inside the accessor function is significantly different from a global variable. The difference is when it is constructed, and is most likely to be a major problem with multiple threads. What if two threads call MyGlobalClassInstance at the same time? Depending on the environment, but I suspect this is typical of most C++ compilers, you will potentially get two calls to the constructor of MyGlobalClass running at the same time, addressing the same area of memory.
If you're single-threaded, it's less likely to be a problem.
If you declare the instance as a normal static member or as a normal global variable in the source file, you'll probably have an easier time, because the constructor will be called before main executes, before you have a chance to start other threads.
declare and define in cpp file
Keep the extern-ed declaration in a header. Define it only once in an implementation file.
You are close. Use a namespace instead for global variables.
namespace myns {
int foo = 0;
}
Now, if it is a class object, you are looking at the Singletion pattern. In fact, your sample code reflects a Singleton design. However, if you are going to define the function in the header, make it inline -- ODR violation otherwise.
It it's truly a global variable that could theoretically be accessed externally by any module, you should put the extern declaration in the header file:
// MyClass.h
class MyClass { ... };
extern MyClass myGlobalInstance;
// MyClass.cpp
MyClass myGlobalInstance;
If it's just a global object that should really only be accessed by a single module, limit its scope by either making it a private (or protected) static class variable, a static function variable (if it's only needed by one function), or in an anonymous namespace:
Option 1:
// MyClass.h
class MyClass
{
private: // or protected, if you want it accessible by subclasses
static MyClass myGlobalInstance;
};
Option 2:
// MyClass.cpp
void someFunction()
{
// it's global, but only accessible inside this function
static MyClass myGlobalInstance;
...
}
Option 3:
// MyClass.cpp
namespace
{
MyClass myGlobalInstance;
}
// it's now only accessible in this file
extern MyGlobalClass MyGlobalClassInstance;
Edit: Not static >.<
Why not use good old singleton pattern?