Static data types c. Static methods in Java

Class members can be used with keyword static. In this context, its meaning is similar to that which it has in C. When a class member is declared as static, the compiler is thereby instructed that only one copy of that member should exist, no matter how many objects of that class are created. A static member is shared by all objects of a given class. All static data is initialized to zero when the first object is created, and no other initialization is provided.

When you declare a static data member of a class, the member is not defined. Instead, you need to provide a global definition for them outside of the class. This is done by re-declaring the static variable, using the scope operator to identify the class to which the variable belongs. This is necessary so that memory is allocated for the static variable.

As an example, consider next program:

#include
class counter (
static int count;
public:
void setcount(int i) (count = i;);
void showcount()(cout<< count << " "; }
};
int counter::count; // definition of count
int main() (
counter a, b;
a.showcount(); // outputs 0
b.showcount(); // outputs 0
a.setcount(10); // setting static count to 10
a.showcount(); // prints 10
b.showcount(); // also outputs 10
return 0;
}

First of all, let's pay attention to the fact that the static variable of the integer type count is declared in two places: in the counter class and then as a global variable. Borland C++ initializes count to zero. This is why the first call to showcount() returns zero. Object a then sets count to 10. Objects a and b then both output the same value, 10, using the showcount() function. Since there is only one copy of count, shared by objects a and b, the output is in both cases the value is 10.

It is also possible to have static member functions. Static member functions cannot directly reference non-static data or non-static functions declared in their class. The reason for this is that there is no this pointer for them, so there is no way to know which non-static data to work with. For example, if there are two objects of a class that contain a static function f(), and if f() tries to access a non-static variable var defined by that class, how can one determine which copy of var should be used? The compiler cannot solve such a problem. This is the reason why static functions can only access other static functions or static data. Also, static functions cannot be virtual or declared with const or volatile modifiers. A static function can be called either using a class object or using the class name and a scope operator. However, we must not forget that even when calling a static function using an object, it is not passed the this pointer.

The following short program illustrates one of the many ways to use static functions. A fairly common situation is when you need to provide access to a limited resource, such as a shared file on a network. As this program illustrates, the use of static data and functions provides a method by which an object can check the status of a resource and access it if possible.

#include


class access (
static enum access_t acs;
// ...
public:


{
return acs;
}
// ...
};

int main()
{
access obj1, obj2;
access::set_access(locked); // call using class name
// ... code

if (obj2.get_access()==unlocked) ( // call using object

cout<< "Access resource.\n";
}
else cout<< "Locked out.\n";
// ...
return 0;
}

When you run this program, “locked out” will appear on the screen. Note that the set_access() function is called with the class name and the scope operator. The get_access() function is called with an object and the dot operator. When calling a static function, either of these forms can be used and both have the same effect. It's worth experimenting with this program a little to make sure you understand how it works.

As noted, static functions only have direct access to other static functions or static data within the same class. To check this, let's try to compile the following version of the program:

// this program contains an error and will not compile
#include
enum access_t (shared, in_use, locked, unlocked);
// class controls rare resource
class access (
static enum access_t acs;
int i; // not static
// ...
public:
static void set_access (enum access_t a) (acs = a;)
static enum access_t get_access()
{
i = 100; // will not compile
return acs;
}
// ...
};
enum access_t access::acs; // acs definition
int main()
{
access obj1, obj2;
access::set_access(locked); // call using class name
// ... code
// can obj2 access the resource
if(obj2.get_access()==unlocked) ( // call using object
access::set_access(in_use); // call using class name
cout<< "Access resource.\n";
}
else cout<< "Locked out.\n";
// ...
}

This program will not compile because the get_access() function is trying to access a non-static variable.

At first, you may not feel the immediate need to use static members, but as you gain more experience with C++ programming, they become very useful in certain situations because they avoid the use of global variables.

Most C++ keywords do one thing. You use int to declare an integer variable, either when a function returns an integer value or takes an integer as an argument. You use the new operator to allocate memory and the delete operator to free it. You can use const to indicate that the value of a variable cannot be changed. Ironically, the static keyword, although it means “unchangeable,” has multiple (and apparently unrelated) uses. The static keyword can be used in three main contexts:

  • inside a function;
  • inside a class definition;
  • before a global variable within a file that makes up a multi-file program.

Using static inside a function is the simplest. This simply means that once a variable has been initialized, it remains in memory until the end of the program. You can think of it as a variable that holds its value until the program completes. For example, you can use a static variable to record the number of times a function has been called by simply adding the lines static int count = 0; and count++; into a function. Since count is a static variable, the line static int count = 0; will only be executed once. Whenever the function is called, count will have the last value given to it.

You can also use static in a way that prevents the variable from being reinitialized inside the loop. For example, in the following code, the number_of_times variable will be equal to 100, even though the line static int number_of_times = 0; is located inside a loop, where it appears to be executed every time the program reaches the loop. The trick is that the static keyword prevents the variable from being reinitialized. One of the things about using the static keyword is that it automatically sets the variable to null for you - but don't rely on this (it makes your intentions unclear).

For(int ix=0; ix< 10; ix++) { for(int iy = 0; iy < 10; iy++) { static int number_of_times = 0; number_of_times++; } }

You can use static variables to store information about the last value returned by a function, for example if you want to store the maximum value calculated by a function. If you are parsing a string, you can also store the last character returned by the function so that you can call it with an argument indicating that it should return the last character.

The second use of static is inside a class definition. Although most variables declared within a class may have a different value in each instance of the class, the static fields of a class will have the same meaning for all instances of a given class and do not even need to create an instance of that class. It's useful to think of static class variables as holding the information needed to create new objects (for example, in a class factory). For example, if you want to number instances of a class, you can use a static variable to keep track of the last number used. It's important to note that good practice when using static class variables is to use class_name::x; , not instance_of_class.x; . This helps remind the programmer that static variables do not belong to a single instance of a class, and that you do not have to create an instance of that class. As you may have noticed, you can use the scope operator, ::, to access static when you access it through the class name.

It's important to keep in mind when debugging or implementing a program using static that you cannot initialize it inside a class. In fact, if you decide to write all the class code in a header file, you won't even be able to initialize a static variable inside the header file; do this in the .cpp file. Additionally, you need to initialize the static members of the class, or they won't be in scope. (The syntax is a little strange: type class_name::static_variable = value .)

You can also have static class functions. Static functions are functions that do not require an instance of a class and are called in the same way, by analogy with static variables, with the name of the class, and not with the name of the object. For example, a_class::static_function(); , not an_instance.function(); . Static functions can only operate on static members of a class, since they do not refer to specific instances of the class. Static functions can be used to change static variables, keep track of their values ​​- for example, you can use a static function if you decide to use a counter to give each instance of a class a unique identifier.

For example, you can use the following code:

Class user ( private: int id; static int next_id; public: static int next_user_id() ( next_id++; return next_id; ) // other methods for the user class user() // class constructor ( id = user::next_id++; // or method call, id = user.next_user_id(); ) ); int user::next_id = 0;

Note that you must include the type of the static variable when you set it!

User a_user;

will set the ID to the next ID number not used by any other user object. Note that it is good style to declare an identifier as a constant.

The last use of static is as a global variable in a code file. In this case, using static indicates that source code in other files that are part of the project cannot access the variable. Only code inside the same file can see the variable (its scope is limited to the file). This technique can be used to model object-oriented code because it limits the visibility of variables and thus helps avoid naming conflicts. This way of using static is a relic of C.

In addition to the access modifier, you can write a keyword before the name of a field, method or property static .
« static " means that this field, method or property will not belong to each object of the class, but to all of them together.

A classic example: how to determine how many objects of the same class have been created? To solve this issue, they serve precisely static fields and methods.

Let's look at the example of tigers. Let's define the class " Tiger" If we write the class field like this: public int count; then each object will have this field, and each object will have its own. Moreover, if not a single object is created, then this field will not exist at all.
Therefore, let's make this field static ( static).

Let's create a constructor in which we will increase the counter count when creating each new object:
public Tiger() ( count++; ).
Here we can set the individual characteristics of the tiger: weight, height, nickname.

Let's also write a static method that displays the number of created objects:
public static void ShowNumberOfObjects().

Then our console application will have two classes:

Public class Tiger ( public static int count; public Tiger() ( count++; ) public static void ShowNumberOfObjects() ( Console.WriteLine("Tigers = (0)", Tiger.count.ToString()); ) ) class Program ( static void Main(string args) ( // What is the number of tigers without creating objects? Tiger.ShowNumberOfObjects(); // 0, because we have not created objects yet // Let's create 3 tigers Tiger t1 = new Tiger (); Tiger t2 = new Tiger (); Tiger t3 = new Tiger (); Tiger.ShowNumberOfObjects(); // 3 tigers will be released Console.ReadLine(); ) )

Result: 3.

Conclusion. A static method allows you to call it without having any objects. Instead of the object name, when calling a method, the name of the Tiger class is specified: Tiger.ShowNumberOfObjects();

Differences between a static method and a non-static one:

1. An object is not needed to call a static method.
2. Inside a static method, the this variable, which points to an object, is not available; therefore, all non-static fields of this class are not available, because like there is no object.
3. Both static and non-static fields are available inside a regular method.
4. Starting with C# 4.0, it became possible to make the class itself static.

Sometimes classes are created that consist only of static methods, such as the Math class. Essentially, such classes are containers of global functions, but this departs from the concept of OOP. It will also be impossible to create instances of a static class.

Now let’s understand the concept of “structure” and find out its difference from a class.

Last update: 10/08/2017

In addition to variables and methods that relate directly to an object, C++ allows you to define variables and methods that relate directly to a class or otherwise static members of a class. Static variables and methods apply to the entire class. The static keyword is used to define them.

For example, a bank may have many different deposits, but all deposits will have some common interest rates. So, to describe a bank account, we define and use the following class:

#include class Account ( public: Account(double sum) ( this->sum = sum; ) static int getRate() ( return rate; ) static void setRate(int r) ( rate = r; ) double getIncome() ( return sum + sum * rate / 100; ) private: double sum; static int rate; ); int Account::rate = 8; int main() ( Account account1(20000); Account account2(50000); Account::setRate(5); // reset the rate value std::cout<< "Rate: " << Account::getRate() << std::endl; std::cout << "Rate: " << account1.getRate() << " Income: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.getRate() << " Income: " << account2.getIncome() << std::endl; return 0; }

The Account class defines one static variable rate and two static functions to control this variable. When defining static functions, it is worth considering that inside them we can only use static class variables, such as the rate variable. Non-static variables cannot be used in static functions.

In addition, the this pointer cannot be used in static functions, which is in principle obvious, since this points to the current object, and static functions refer to the entire class.

It is also important that if a class contains static variables, then they must be additionally defined outside the class:

Int Account::rate = 8;

Assigning an initial value to a variable is optional.

It is also worth noting that since static members refer to the entire class, the class name followed by the :: operator is used to refer to static members. Or we can also access public members of a class through variables of that class:

Account::getRate() account1.getRate()

Console output of the program:

Rate: 5 Rate: 5 Income: 21000 Rate: 5 Income: 52500

It is also common to use static constants in classes. For example, let’s make the rate variable in the Account class a constant:

#include class Account ( public: const static int rate = 8; Account(double sum) ( this->sum = sum; ) double getIncome() ( return sum + sum * rate / 100; ) private: double sum; ); int main() ( Account account1(20000); Account account2(50000); std::cout<< "Rate: " << account1.rate << "\tIncome: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.rate << "\tIncome: " << account2.getIncome() << std::endl; return 0; }

Unlike static variables, static constants do not need to be further defined outside the class.

Lesson 25. Static functions and data members

Until now, each object you created had its own set of data elements. Depending on the purpose of your application, there may be situations where objects of the same class must share one or more data elements. For example, suppose you are writing a payroll program that tracks work hours for 1,000 employees. To determine the tax rate, the program must know the conditions in which each employee works. Let's use a class variable for this state_of_work. However, if all employees work under the same conditions, your program could share this data element among all objects of type employee. So your program reduces the amount of memory needed by throwing away 999 copies of the same information. To share a class element you must declare that element as static (static). This tutorial covers the steps you must follow to share a class element among multiple objects. By the end of this lesson, you will have mastered the following core concepts:

    C++ allows you to have objects of the same type that share one or more members of a class.

    If your program assigns a value to a shared element, then all objects of that class immediately have access to that new value.

    To create a shared class data member, you must precede the class member name with a keyword static.

    After the program has declared a class element as static it must declare a global variable (outside the class definition) that corresponds to that shared class member.

    Your programs can use the keyword static to make a class method callable while the program may not have yet declared any objects of that class.

SHARING A DATA ELEMENT

Typically, when you create objects of a particular class, each object gets its own set of data members. However, there may be situations in which objects of the same class need to share one or more data elements (static e data elements). In such cases, declare the data elements as general silt And private, and then preface the type with the keyword static as below:

private: static int shared_value;

After declaring the class, you must declare the element as a global variable outside the class, as shown below:

int class_name::shared_value;

The following program SHARE_IT.CPP defines the class book_series, sharing element page_count, which is the same for all objects (books) of the class (series). If a program changes the value of this element, the change is immediately reflected in all objects of the class:

#include

#include

class book_series

( public: book_series(char *, char *, float); void show_book(void); void set_pages(int) ; private: static int page_count; char title; char author[ 64 ]; float price; );

int book_series::page__count;

void book_series::set_pages(int pages)

( page_count = pages; )

book_series::book_series(char *title, char *author, float price)

( strcpy(book_series::title, title); strcpy(book_series::author, author); book_series::price = price; )

void book_series:: show_book (void)

( cout<< "Заголовок: " << title << endl; cout << "Автор: " << author << endl; cout << "Цена: " << price << endl; cout << "Страницы: " << page_count << endl; }

( book_series programming("Learning to program in C++", "Jamsa", 22.95); book_series word("Learning to work with Word for Windows", "Wyatt", 19.95); word.set_pages(256); programming.show_book (); word.show_book() ;cout<< endl << "Изменение page_count " << endl; programming.set_pages(512); programming.show_book(); word.show_book(); }

As you can see, the class declares page_count How static int. Immediately after the class definition, the program declares an element page_count as a global variable. When a program changes an element page_count, the change is immediately reflected in all objects of the class book_series.

Sharing Class Members

Depending on your program, there may be situations where you need to share certain data across multiple instances of an object. To do this, declare the element as static. Next, declare this element outside the class as a global variable. Any changes your program makes to this element will be immediately reflected in objects of this class.

Using Elements with Attributespublic static if objects don't exist

As you just learned, when declaring a class element as static this element is shared by all objects of a given class. However, there may be situations where the program has not yet created the object, but needs to use the element. To use an element, your program must declare it as public And static. For example, the following program USE_MBR.CPP uses the element page_count from the class book_series, even if objects of this class do not exist:

#include

#include

class book_series

( public: static int page_count; private: char title; char author; float price; );

int book_series::page_count;

void main(void) ( book_series::page_count = 256; cout<< "Текущее значение page_count равно " << book_series::page_count << endl; }

In this case, since the class defines an element of the class page_count How public a program can access this class element even if the objects of the class book_series does not exist.

USING STATIC ELEMENT FUNCTIONS

The previous program illustrated the use static data elements. Similarly, C++ allows you to define static element functions (methods). If you are creating static method, your program can call such a method even if the objects have not been created. For example, if a class contains a method that can be used on data outside the class, you could make that method static. Below is the class menu which uses the ANSI driver esc sequence to clear the display screen. If you have the ANSI.SYS driver installed on your system, you can use the method clear_screen to clean the screen. Since this method is declared as static, a program can use it even if the objects are of type menu does not exist. The following program CLR_SCR.CPP uses the method clear_screen To clear the display screen:

#include

( public: static void clear_screen(void); // There should be other methods here private: int number_of_menu_options; );

void menu::clear_screen(void)

( cout<< "\033" << "}