C++. Classes of memory that can be declared when working with classes and class objects. Keywords register, extern, static, mutable
Contents
- 1. What memory classes can class objects and classes be declared with?
- 2. How is the ‘auto’ memory class used for classes? Example
- 3. How is ‘register‘ memory class used? Example
- 4. How is the ‘extern‘ memory class used? Example
- 5. How are static class objects used? Example
- 6. In which cases is the memory class ‘mutable‘ used for the class object? Example
- Related topics
Search other websites:
1. What memory classes can class objects and classes be declared with?
Class objects and classes can be declared with these memory classes:
- automatic (auto);
- registered (register);
- external (extern);
- static.
- mutable.
For each storage class is determined by its own specifier: auto, register, extern, static. The specifiers of memory classes determine how the variable should be stored.
2. How is the ‘auto’ memory class used for classes? Example
The ‘auto‘ memory class defines automatic variables. By default, these are local variables that are placed on the stack or internal registers of the processor. The “lifetime” of an automatic variable is limited by the execution time of a function (method) or a block in which this variable is defined. When you normally declare a local class object or a local variable, for example
int a; double x; char c; CMyClass MC; // class object
this variable gets the ‘auto‘ memory class.
It is important that after the declaration, the automatic variables are initialized. Since, the contents of the cells that are allocated for these variables is undefined.
Example. Let’s have a fragment of the function that computes the sum of the elements of the array A consisting of n integers.
int MySum(int A[], int n) { // declaring the automatic variable sum int sum; // the beginning of the "life" or the existence of the variable sum sum = 0; for (int i=0; i<n; i++) // a loop that contains a block {...} { // the beginning of the existence of the automatic variable i sum = sum + A[i]; // // the end of the existence of the automatic variable i } return sum; // the end of the existence of the automatic variable sum }
The MySum() function has the following automatic variables:
- A, n – formal parameters are also automatic variables;
- sum, i – internal local variables of the MySum() function.
This also applies to declaring a class object. If a class object is declared in the method (function), then this object has an auto memory class.
For example. Suppose, is given a certain class CMyClass.
class CMyClass { int d; public: // constructor CMyClass(void) { d = 0; }; // class methods int Get(void) { return d; } void Set(int nd) { d = nd; } };
Then, in some function MyFun() the object of the class will belong to the memory class ‘auto‘.
void MyFun(...) { CMyClass MC; // declaration of a class object with the memory class 'auto' ... }
3. How is ‘register‘ memory class used? Example
A class object can be declared with the ‘register‘ keyword. Setting the ‘register‘ keyword – this is an indication to the compiler allocate the internal registers of the processor to store the object data. But this does not mean that the compiler will necessarily place the object data in the registers of the processor. In addition, when ‘register‘ keyword is specified, the compiler can place the data in the cache. The main purpose of declaring a variable (object) with the ‘register‘ keyword is to provide the fastest possible access to this variable and handling this variable.
Example. Let’s have the declaration of class CMyClass.
class CMyClass { int d; public: // constructor CMyClass(void); // class methods int Get(void) { return d; } void Set(int nd) { d = nd; } }; // constructor CMyClass::CMyClass(void) { d = 0; }
A class object is a variable of the type of this class. Therefore, an object like a variable can have a ‘register‘ memory class.
// declaration of a class object with 'register' memory class register CMyClass MC1; int t; t = MC1.Get(); // t = 0 MC1.Set(15); t = MC1.Get(); // t = 15
4. How is the ‘extern‘ memory class used?
If a class is declared in one module, but you want to declare that this class is external in another module, then this class is declared with the ‘extern‘ keyword. In this case, you do not need to further describe the internal implementation of data and class methods.
For example. Let two modules “MyClass.h” and “Main.h” be given. The “MyClass.h” module implements the declaration of the CMyClass class. The module “Main.h” implements the use of the class “MyClass.h”, which is connected from the outside with the #include directive.
To use the capabilities of the external CMyClass class, the following code must be added in the text of the module “Main.h”
#include "MyClass.h" extern class CMyClass; // declaration that the CMyClass class is external
In this case, the class CMyClass is considered external, that is, one that has a memory class ‘extern‘.
5. How are static class objects used?
A class object can be used with the ‘static‘ keyword. In this case, the place for the object is allocated in a fixed memory area. Working with static class objects that are declared with the ‘static‘ keyword is no different from working with regular static variables.
More information about using static variables in classes is described in the article:
Example. Let the class CMyCounter be given.
class CMyCounter { public: int d; CMyCounter(void) { d = 0; }; // class constructor ~CMyCounter(void) {}; // class destructor };
The class declares a public variable d, a constructor, and a destructor. The class constructor sets the initial value of d to zero.
To demonstrate the use of a static class object, you need to write a function that changes the values of d relative to its previous value. In this case, a function is implemented that increases the previous value of d by 1. The function declares a static object of class CMyCounter.
// function in which a static object of class is declared int IncMyCounter(void) { // declaring a class object with a static memory class static CMyCounter MC; // the object is placed in a fixed memory area MC.d = MC.d + 1; // increasing to 1 return MC.d; }
Using the IncMyCounter() function from another program code demonstrates the fact that a static object is not destroyed after the function call is terminated
... int t; t = IncMyCounter(); // t = 1 t = IncMyCounter(); // t = 2 - taken into account the previous value CMyCounter::d t = IncMyCounter(); // t = 3 - taken into account the previous value CMyCounter::d ...
As you can see from the above code snippet, the function is called 3 times. The last two calls take into account the previous value of the variable d of the CMyCounter class.
If you declare an MC object of the CMyCounter class in the IncMyCounter() function without the ‘static‘ keyword
void IncMyCounter(void) { // declaring a class object without the 'static' keyword CMyCounter MC; // temporary (non-fixed) memory MC.d = MC.d + 1; // increase by 1 }
then this object will refer to the auto memory class. In this case, each time the IncMyCounter() function is called,
... int t; t = IncMyCounter(); // t = 1 t = IncMyCounter(); // t = 1 - the previous value of CMyCounter :: d is not taken into account t = IncMyCounter(); // t = 1 - the previous value of CMyCounter :: d is not taken into account ...
for the internal variable d of the CMyCounter object, the memory will be allocated again. As a result, the variable d of the MC object will be:
- created anew in the non-fixed area of memory when it is declared;
- initialized using the class constructor (d = 0);
- destroyed when you exit the IncMyCounter() function, because the MC class object is declared as automatic (auto memory class).
6. In which cases is the memory class ‘mutable‘ used for the class object? Example
The mutable memory class is used in conjunction with so-called constant functions (functions that are declared with the ‘const‘ keyword).
Example of a function with a const modifier in the CMyRadius class
class CMyRadius { double r; // object radius public: // constant function - calculates the area of a circle double GetSquare(void) const { return (double)(3.1415 * r * r); } }
If a constant function is declared in a class, then this function can not modify class data. This is the main purpose of declaring a constant function in a class – not to allow modification of the object that will cause it. That is, the following function in the CMyRadius class can not be implemented:
// constant function - sets new r - disabled void SetR(double nr) const { r = nr; }
But, there are times when you need to change data values using a constant function. For example, if the class data can also include a complex object of another class, in which some of the data needs to be changed.
To get out of this situation, you need to use the mutable keyword when declaring class data. In our example, so that you can change the value of the variable r using a constant function, you need to declare it as follows
mutable double r; // object radius
Such a record means that the value of r in the class can be changed using a constant function. That is, the constant function Set() can be declared in the class.
After the changes, the class text is as follows:
class CMyRadius { mutable double r; // r is declared as mutable public: // constant function - calculates the area of the circle - it is possible double GetSquare(void) const { return (double)(3.1415 * r * r); } // constant function - sets a new r - it is possible void SetR(double nr) const { r = nr; } }
Using a class in another program code
CMyRadiusMR; int t; MR.Set(2); t = MR.GetSquare(); // t = 12.566
The above statements are only valid for native classes. In the CLR environment in managed classes, the use of const and volatile qualifiers is not supported
Related topics
- The concept of class. Class declaration. The object of the class. Classes in CLR. Data encapsulation in the class
- Using the class data members. Static data members in the class. Static data members for native-classes and managed-classes