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.
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 already read a lot of posts and articles all over the net, but I couldn't find a definite answer about this.
I have some functions with similar purposes that I want to have out of the global scope. Some of them need to be public, others should be private (because they are only helper functions for the "public" ones).
Additionally, I don't have only functions, but also variables. They are only needed by the "private" helper functions and should be private, too.
Now there are the three ways:
making a class with everything being static (contra: potential "Cannot call member function without object" - not everything needs to be static)
making a singleton class (contra: I WILL need the object)
making a namespace (no private keyword - why should I put it in a namespace at all, then?)
What would be the way to take for me? Possible way of combining some of these ways?
I thought of something like:
making a singleton, the static functions use the helper function of the singleton object (is this possible? I'm still within the class, but accessing an object of it's type)
constructor called at programm start, initializes everything (-> making sure the statics can access the functions from the singleton object)
access the public functions only through MyClass::PublicStaticFunction()
Thanks.
As noted, using global variables is generally bad engineering practice, unless absolutely needed of course (mapping hardware for example, but that doesn't happen THAT often).
Stashing everything in a class is something you would do in a Java-like language, but in C++ you don't have to, and in fact using namespaces here is a superior alternative, if only:
because people won't suddenly build instances of your objects: to what end ?
because no introspection information (RTTI) is generated for namespaces
Here is a typical implementation:
// foo.h
#ifndef MYPROJECT_FOO_H_INCLUDED
#define MYPROJECT_FOO_H_INCLUDED
namespace myproject {
void foo();
void foomore();
}
#endif // MYPROJECT_FOO_H_INCLUDED
// foo.cpp
#include "myproject/foo.h"
namespace myproject {
namespace {
typedef XXXX MyHelperType;
void bar(MyHelperType& helper);
} // anonymous
void foo() {
MyHelperType helper = /**/;
bar(helper);
}
void foomore() {
MyHelperType helper = /**/;
bar(helper);
bar(helper);
}
} // myproject
The anonymous namespace neatly tucked in a source file is an enhanced private section: not only the client cannot use what's inside, but he does not even see it at all (since it's in the source file) and thus do not depend on it (which has definite ABI and compile-time advantages!)
Don't make it a singleton
For public helper functions that don't directly depend on these variables, make them non-member functions. There's nothing gained by putting them in a class.
For the rest, put it in a class as normal non-static members. If you need a single globally accessible instance of the class, then create one (but don't make it a singleton, just a global).
Otherwise, instantiate it when needed.
The classic C way of doing this, which seems to be what you want, is to put the public function declarations in a header file, and all the implementation in source file, making the variables and non-public functions static. Otherwise just implement it as a class - I think you are making a bit of a mountain out of a molehill here.
What about using a keyword static at global scope (making stuff local to the file) as a privacy substitute?
From your description it looks like you have methods and data that interact with each other here, in other words it sounds to me like you actually want a non-singleton class to maintain the state and offer operations upon that state. Expose your public functions as the interface and keep everything else private.
Then you can create instance(s) as needed, you don't have to worry about init order or threading issues (if you have one per thread), and only clients that need access will have an object to operate upon. If you really need just one of these for the entire program you could get away say a global pointer that's set in main or possibly an instance method, but those come with their own sets of problems.
Remember that the singleton instance of a singleton class is a valid instance, so it is perfectly able to be the recipient of nonstatic member functions. If you expose your singleton factory as a static function then have all of your public functionality as public nonstatic member functions and your private functionality as private nonstatic member functions, anyone that can get at the class can access the public functionality by simply invoking the singleton factory function.
You don't describe whether all of the functionality you're trying to wrap up is as related as to justify being in the same class, but if it is, this approach might work.
If you take a "C-like" approach and just use top-level functions, you can make them private by declaring them in the .cpp file rather than the publicly-included .h file. You should also make them static (or use an anonymous namespace) if you take that approach.
We recently found issue with our project caused by this error:
namespace sim
{
class ClassA
{
private:
static std::list<uint16_t> m_variable;
}
std::list<uint16_t> ClassA::m_variable;
}
So what happened is that m_variable became static for all instances of ClassA, not just for the particular instance of it. I'm not an expert with C++ so please bear with me if the problem is staring directly at my face, I'm still on the learning phase.
Can someone explain why this happened?
After your comment, you want to understand how to use static members of class.
For normal data members, one instance of the member exists in each and every instance of the class. OTOH a static data member exists only once and is shared among all object instances of the class.
Simply the simple declaration of a static member inside a class definition is only a declaration. Because of the One Definition Rule, that object also needs a definition.
In C++ language, that definition normally occurs outside of the class definition, so the line std::list<uint16_t> ClassA::m_variable; is required.
There are exception to that rule, mainly for static const integral members that can be defined inside the class definition provided you only use their value and not their address (search for One Definition Rule if you want to go further that way). But this is a rather advanced corner case, so if you are a beginner just remember that a static member of a class need a definition outside the class definition.
I have a class whose private member is a static map:
Class Devices
{
...
private:
struct DevicePair
{
int nCtr;
bool isToAdd;
};
DevicePair m_DevPair;
static map <string, DevicePair> m_SYSdeviceMap;
};
Why can't I just do this in the cpp file?
map <string, DevicePair> Devices::m_SYSdeviceMap;
How do I initialize this in the cpp file?
With this line:
map<string, Devices::DevicePair> Devices::m_SYSdeviceMap;
Also, as a good coding practice, remove the using namespace std; from your header, and qualify your use of map - std::map.
You cannot use the declaration you have said because it doesn't know what DevicePair is at that scope, you must be Devices:: before it
private statics are usually a bad idea by the way, you are usually better off having this instance hidden away in the "anonymous namespace" section in the .cpp file where it is visible to the functions in the compilation unit (usually the class members) but not external files.
The reason is that it is an implementation detail that you are exposing to all users of your class.
In your case that will be hard to do as DevicePair is private in your class and you cannot simply move that because it is needed in the header for m_DevPair.
Of course if you need your class to be thread-safe you need a mutex, etc. to control the accesses to the map (unless it is all initialised in one thread and then only read by multiple threads). The mutex would well of course be in your anonymous namespace (and almost certainly should be).
I would still re-think your design though.
I already read a lot of posts and articles all over the net, but I couldn't find a definite answer about this.
I have some functions with similar purposes that I want to have out of the global scope. Some of them need to be public, others should be private (because they are only helper functions for the "public" ones).
Additionally, I don't have only functions, but also variables. They are only needed by the "private" helper functions and should be private, too.
Now there are the three ways:
making a class with everything being static (contra: potential "Cannot call member function without object" - not everything needs to be static)
making a singleton class (contra: I WILL need the object)
making a namespace (no private keyword - why should I put it in a namespace at all, then?)
What would be the way to take for me? Possible way of combining some of these ways?
I thought of something like:
making a singleton, the static functions use the helper function of the singleton object (is this possible? I'm still within the class, but accessing an object of it's type)
constructor called at programm start, initializes everything (-> making sure the statics can access the functions from the singleton object)
access the public functions only through MyClass::PublicStaticFunction()
Thanks.
As noted, using global variables is generally bad engineering practice, unless absolutely needed of course (mapping hardware for example, but that doesn't happen THAT often).
Stashing everything in a class is something you would do in a Java-like language, but in C++ you don't have to, and in fact using namespaces here is a superior alternative, if only:
because people won't suddenly build instances of your objects: to what end ?
because no introspection information (RTTI) is generated for namespaces
Here is a typical implementation:
// foo.h
#ifndef MYPROJECT_FOO_H_INCLUDED
#define MYPROJECT_FOO_H_INCLUDED
namespace myproject {
void foo();
void foomore();
}
#endif // MYPROJECT_FOO_H_INCLUDED
// foo.cpp
#include "myproject/foo.h"
namespace myproject {
namespace {
typedef XXXX MyHelperType;
void bar(MyHelperType& helper);
} // anonymous
void foo() {
MyHelperType helper = /**/;
bar(helper);
}
void foomore() {
MyHelperType helper = /**/;
bar(helper);
bar(helper);
}
} // myproject
The anonymous namespace neatly tucked in a source file is an enhanced private section: not only the client cannot use what's inside, but he does not even see it at all (since it's in the source file) and thus do not depend on it (which has definite ABI and compile-time advantages!)
Don't make it a singleton
For public helper functions that don't directly depend on these variables, make them non-member functions. There's nothing gained by putting them in a class.
For the rest, put it in a class as normal non-static members. If you need a single globally accessible instance of the class, then create one (but don't make it a singleton, just a global).
Otherwise, instantiate it when needed.
The classic C way of doing this, which seems to be what you want, is to put the public function declarations in a header file, and all the implementation in source file, making the variables and non-public functions static. Otherwise just implement it as a class - I think you are making a bit of a mountain out of a molehill here.
What about using a keyword static at global scope (making stuff local to the file) as a privacy substitute?
From your description it looks like you have methods and data that interact with each other here, in other words it sounds to me like you actually want a non-singleton class to maintain the state and offer operations upon that state. Expose your public functions as the interface and keep everything else private.
Then you can create instance(s) as needed, you don't have to worry about init order or threading issues (if you have one per thread), and only clients that need access will have an object to operate upon. If you really need just one of these for the entire program you could get away say a global pointer that's set in main or possibly an instance method, but those come with their own sets of problems.
Remember that the singleton instance of a singleton class is a valid instance, so it is perfectly able to be the recipient of nonstatic member functions. If you expose your singleton factory as a static function then have all of your public functionality as public nonstatic member functions and your private functionality as private nonstatic member functions, anyone that can get at the class can access the public functionality by simply invoking the singleton factory function.
You don't describe whether all of the functionality you're trying to wrap up is as related as to justify being in the same class, but if it is, this approach might work.
If you take a "C-like" approach and just use top-level functions, you can make them private by declaring them in the .cpp file rather than the publicly-included .h file. You should also make them static (or use an anonymous namespace) if you take that approach.