This question already has answers here:
static class member of class's own type [duplicate]
(2 answers)
Closed 6 years ago.
The C++ programming language book mentions like below:
It is not possible to declare new objects of a struct until its complete declaration has been seen. For example:
struct No_good {
No_good member; // error : recursive definition
};
This is an error because the compiler is not able to determine the size of No_good.
But below piece of code is compiling for me.
struct No_good {
static No_good member; // OK: compiling
};
how static keyword allowing compiler to know the size of member. AFAIK static decides the storage class of a named variable.
The reason you can't have a full No_good member inside the No_good class, as pointed out by Francois Moisan is because it would be infinitely recursive and take infinite space.
A No_good* member would be ok because it has a finite space(size of a pointer) and can be null stopping the recursion.
A static member is also ok becuase it is not stored in every instance of No_good but instead shared by all of the instances. It is not technically part of the object but something associated with the namespace of No_good.
Hope this clears it up.
You can think the static variable as a global variable. Only difference is it is under the class's namespace. So if it was a global variable you could reach it like No_good but if it is static you have to type No_good::No_good. You can do that even you never instantiate the class.
The same troubles you can get into with globals you will get with statics as well. You never know which static variable initializes first if they depend on each other you are still in trouble.
The way I experience it, lots of statics usage comes from writing C++ code with C point of view.
Related
This question already has answers here:
Why use a const member function?
(3 answers)
What are the semantics of a const member function?
(9 answers)
Closed 2 months ago.
This post was edited and submitted for review 2 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Edit: From #Jeremy Friesner's answer, he provides another view point that Why use a const member function & semantics of a const member function don't cover. It can improve clarity and disambiguous your code. People can have a brief idea of what this function is supposed to do or not do at the first glance. Very useful especially in working with others.
I come across the constant function lately.
It says:
Constant functions are those have denied permission when attempting
to change the member variables of their classes.
My questions are
In a programmer perspective, if you don't want a function being able to change member
variables, why not just moving the parts responsible for changing variables outside
of the function at the first place? (e.g using another function)
What/when are some practical moments of having the neediness to use a constant
function?
Appreciate any answers
class Foo
{
public:
int x = 0;
int Bar(int arg) const
{
x++; // fails
return x; // okay
}
};
The purpose of const-tagged methods isn't to prevent the programmer from intentionally modifying member variables, but rather to allow the compiler to assist the programmer by producing a compile-time error when the programmer accidentally modifies a member-variable. This is useful because it's much easier and quicker to correct a compile-time error than to chase down a run-time misbehavior through manual testing.
The const tag also assists later programmers who are reading the class's header file by helping them quickly understand what a method does or does not do. For example, if you see this in a class declaration:
class MyClass
{
[...]
int CalculateTheValue();
... you might ask yourself, "does calling CalculateTheValue() change the state of the MyClass object?" With a name like CalculateTheValue() it seems like it shouldn't, but there's no way to know for sure without finding the corresponding .cpp file and reading through the code that implements that method... which is a tedious and error-prone way to do things.
On the other hand, if you see this:
class MyClass
{
[...]
int CalculateTheValue() const;
... then you know right away that CalculateTheValue() will not modify the MyClass object you call it on, because it says so in the declaration. (if it did try to modify the MyClass object, the code wouldn't compile; so if the code compiled, we know it doesn't modify it)
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
This question already has answers here:
When are static C++ class members initialized?
(7 answers)
Closed 8 years ago.
I started using C++ for object oriented programming and I've come across static member variables.
In my particular case, I have the following in my header file (Class.hpp):
private:
const static string DEFAULT_PATH;
static string path;
Not that really matters, but is as valid as any example.
So, to do the proper initialisations I had to do some research and find out that this can't be done in the class body and has to be done in the source (Class.cpp) file. In my source file, I added:
const string Class::DEFAULT_PATH = "./";
string Class::path = DEFAULT_PATH;
I found this to be counter-intuitive, but tried to deal with it. Then I wondered:
When exactly did the compiler call this initialization code? How can I assume when will this fields have a value? I don't really understand what's happening there and I'd like to know.
And what's most intriguing for me: which symbols can I see whithin Class.cpp when including class.hpp? And why those declarations have be outside the class body and in another file?
Static members are initialized before the main starts, so they are already initialized in your main. Non static members of the class are initalized in the constructor.
If you want to enforce the initialization order (which is the case because one variable refers to the other), you can use a function to initalize the function C++ static initialization order.
boost::call_once (or its c++11 equivalent) can help you for that. http://www.boost.org/doc/libs/1_31_0/libs/thread/doc/once.html
The standard tells you that it has to be initalized somewhere outside the class definition, so generally you do it on the cpp file
Once this is done you can access the variables with Class::static_member
This question already has answers here:
When to use static member function? [duplicate]
(7 answers)
Closed 9 years ago.
I know static class member function don't need to be instantiated. But, since class member functions' manipulation are always based on its' own member variables, why we still use the static member functions? can someone tell me by some detail examples? Thanks in advance.
P.S. I am writing a program that in one class member function create two threads, so that I need to pass the thread callback function address to when create the two threads. I want the thread callback function also be the same class's member function. According to some references, if a callback function is a class's member, it should be static. There comes the question: in the static callback, I can't call other non-static function in the same class, and can't modify it's non-static member variables. (English is my secondary language, so I'am not good at it. hope some help me describe it more succinctly:-)
I will just give you an example. If you want to calculate how many instances you have declared about your class, you may have a static member like
int instance_count;
and in the class constructor you can add the instance_count like:
instance_count++;
and in your destructor :
instance_count--;
As a result, you can get how many instances you have currently in your program.
This question already has answers here:
Why is a class allowed to have a static member of itself, but not a non-static member?
(2 answers)
Closed 8 years ago.
How can I make an instance of a class inside its definition?
class Test{
Test _test;
};
This throws
error: field _test has incomplete type
Using a pointer works but I would like to avoid using a pointer if possible.
Just imagine you could do something like that: this would be a recursive definition. An object of type Test contains an object of type Test, which contains an object of type Test, and so on without a termination until you or your compiler go crazy.
I don't really think you would want anything like that, even if it compiled. Using pointers, on the other hand, is OK for two reasons:
A pointer could by null, thus breaking the otherwise infinitely recursive chain of Test objects (which would take infinite space at run-time);
A pointer has fixed size, so the compiler doesn't need to compute the size of Test in order to compute the size of Test itself (leading to infinite recursion at compile-time).
Using a pointer works but I would like to avoid using a pointer if possible.
If you are worried about manual memory management, just use a smart pointer:
#include <memory>
class Test
{
std::unique_ptr<Test> _test;
};
Answer this question: how big would your class be?
The only two solutions I can think of is either by using a pointer:
class Test
{
public:
Test * data;
};
This solution is common in advanced structures, such as lists or trees.
Another way is to declare the internal field as static:
class Test
{
public:
Test(int i);
static Test data;
}
Test Test::data = Test(5);
This solution is common for singletons, multitons or similar structures. Notice though, that you can access the field only from the class, not from its instance:
Test test = Test::data;
Your Test is not yet defined completed so how come you create its instance. Sure you can create pointer. Because pointer is incomplete type.
That is why Singleton class and link list have pointers to their reference and not complete object itself.
The memory for the class variables is initialized when an object of the class is made. But if one makes the object of the class in its definition only then during that point the compiler will not be able to initialize the variable of the class as at that point the definition of the class is yet not completed.