마지막 업데이트: 08.10.2017

객체와 직접적으로 관련된 변수 및 메서드 외에도 C++를 사용하면 클래스 또는 기타와 직접적으로 관련된 변수 및 메서드를 정의할 수 있습니다. 정적 멤버수업. 정적 변수와 메서드는 일반적으로 전체 클래스를 참조합니다. static 키워드는 이들을 정의하는 데 사용됩니다.

예를 들어, 은행에는 다양한 예금이 있을 수 있지만 모든 예금에는 공통 이자율이 있습니다. 따라서 은행 계좌를 설명하기 위해 다음 클래스를 정의하고 사용합니다.

#포함 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: 이중 합계, 정적 int rate; ); int 계정::비율 = 8; int main() ( 계정 account1(20000); 계정 account2(50000); Account::setRate(5); // 비율 재설정 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; }

Account 클래스는 이 변수를 관리하기 위해 하나의 정적 변수, rate 및 두 개의 정적 함수를 정의합니다. 정적 함수를 정의할 때 그 내부에서 비율 변수와 같은 정적 클래스 변수만 사용할 수 있다는 점을 명심하십시오. 비정적 변수는 정적 함수에서 사용할 수 없습니다.

또한 this 포인터는 현재 개체를 가리키고 정적 함수는 전체 클래스를 참조하기 때문에 원칙적으로 명백한 정적 함수에서 사용할 수 없습니다.

클래스에 정적 변수가 포함된 경우 클래스 외부에서 추가로 정의해야 한다는 것도 중요합니다.

Int Account::rate = 8;

변수에 초기값을 할당할 필요는 없습니다.

정적 멤버는 전체 클래스를 전체적으로 참조하기 때문에 정적 멤버는 클래스 이름 다음에 :: 연산자를 사용하여 참조된다는 점도 주목할 가치가 있습니다. 또는 이 클래스의 변수를 통해 클래스의 공개 멤버에 액세스할 수도 있습니다.

계정::getRate() account1.getRate()

프로그램의 콘솔 출력:

비율: 5 비율: 5 소득: 21000 비율: 5 소득: 52500

또한 정적 상수는 종종 클래스에서 사용됩니다. 예를 들어, Account 클래스에서 가변 비율을 상수로 설정해 보겠습니다.

#포함 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() ( 계정 account1(20000); 계정 account2(50000); std::cout<< "Rate: " << account1.rate << "\tIncome: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.rate << "\tIncome: " << account2.getIncome() << std::endl; return 0; }

정적 변수와 달리 정적 상수는 클래스 외부에서 더 이상 정의할 필요가 없습니다.

접근 한정자 외에도 필드, 메서드 또는 속성 이름 앞에 키워드를 작성할 수 있습니다. 공전 .
« 공전 "는 주어진 필드, 메서드 또는 속성이 클래스의 각 개체에 속하지 않고 모두 함께 속한다는 의미입니다.

고전적인 예: 같은 클래스의 객체가 얼마나 많이 생성되었는지 확인하는 방법은 무엇입니까? 이 문제를 해결하려면 정적 필드 및 메서드.

호랑이의 예를 살펴보자. 클래스를 정의하자 " 호랑이". 클래스 필드를 다음과 같이 작성하면: 공개 정수 수;그러면 각 개체에는 이 필드가 있고 각 개체에는 고유한 필드가 있습니다. 또한 단일 개체가 생성되지 않으면 이 필드는 전혀 존재하지 않습니다.
따라서 이 필드를 정적( 공전).

카운터를 증가시킬 생성자를 만들어 봅시다. 세다각각의 새로운 객체를 생성할 때:
공개 Tiger() ( count++; ).
여기서 우리는 또한 호랑이의 개별 특성(체중, 키, 별명)을 설정할 수 있습니다.

생성된 객체의 수를 표시하는 정적 메서드도 작성합니다.
공개 정적 무효 ShowNumberOfObjects().

그러면 콘솔 애플리케이션에는 두 가지 클래스가 있습니다.

Public 클래스 Tiger ( public static int count; public Tiger() ( count++; ) public static void ShowNumberOfObjects() ( Console.WriteLine("Tigers = (0)", Tiger.count.ToString()); ) ) 클래스 Program ( static void Main(string args) ( // 객체를 생성하지 않은 호랑이의 수는 얼마입니까? Tiger.ShowNumberOfObjects(); // 아직 객체를 생성하지 않았기 때문에 0 // 3개의 호랑이 생성 Tiger t1 = new Tiger(); Tiger t2 = new Tiger(); Tiger t3 = new Tiger(); Tiger.ShowNumberOfObjects(); // 3마리의 호랑이가 나옵니다 Console.ReadLine(); ) )

결과: 3.

결론. 정적 메서드를 사용하면 사용 가능한 개체 없이도 호출할 수 있습니다. 객체의 이름 대신 메서드를 호출할 때 Tiger 클래스의 이름이 지정됩니다. Tiger.ShowNumberOfObjects();

정적 메서드와 비 정적 메서드의 차이점:

1. 정적 메서드를 호출하기 위해 개체가 필요하지 않습니다.
2. 정적 메서드 내에서 개체를 가리키는 this 변수를 사용할 수 없으므로 이 클래스의 모든 비정적 필드를 사용할 수 없습니다. 물건이 없는 것처럼.
3. 일반 메서드 내에서는 정적 필드와 비 정적 필드를 모두 사용할 수 있습니다.
4. C# 4.0부터 클래스 자체를 정적으로 만드는 것이 가능해졌습니다.

Math 클래스와 같이 정적 메서드로만 구성된 클래스를 만드는 경우가 있습니다. 실제로 이러한 클래스는 전역 함수의 컨테이너이지만 이것은 OOP의 개념에서 벗어납니다. 또한 각각 정적 클래스의 인스턴스를 생성하는 것도 불가능합니다.

이제 "구조"의 개념을 다루고 클래스와의 차이점을 알아 보겠습니다.

마지막 업데이트: 2018년 12월 25일

일반적인 필드, 메서드, 속성 외에도 클래스에는 정적 필드, 메서드, 속성이 있을 수 있습니다. 정적 필드, 메서드, 속성은 전체 클래스를 참조하며 유사한 클래스 멤버에 액세스하기 위해 클래스의 인스턴스를 만들 필요가 없습니다. 예를 들어:

클래스 계정 ( 공개 정적 십진수 보너스 = 100, 공개 십진수 totalSum, 공개 계정(십진수 합계) ( totalSum = 합계 + 보너스; ) ) 클래스 프로그램 ( 정적 void Main(string args) ( Console.WriteLine(Account.bonus); / / 100 Account.bonus += 200;계정 account1 = new Account(150);Console.WriteLine(account1.totalSum); // 450 계정 account2 = new Account(1000);Console.WriteLine(account2.totalSum); // 1300 콘솔.ReadKey(); ) )

이 경우 Account 클래스에는 두 개의 필드(보너스 및 합계 합계)가 있습니다. 보너스 필드는 정적이므로 단일 개체가 아닌 전체 클래스의 상태를 저장합니다. 따라서 클래스 이름으로 이 필드를 참조할 수 있습니다.

Console.WriteLine(계정.보너스); Account.bonus += 200;

정적 필드의 메모리 수준에서 클래스의 모든 개체에 공통적인 메모리 영역이 생성됩니다.

동시에 이 클래스의 객체가 생성되지 않은 경우에도 정적 변수에 대한 메모리가 할당됩니다.

정적 속성 및 메서드

마찬가지로 정적 메서드와 속성을 만들고 사용할 수 있습니다.

클래스 계정 ( 공개 계정(소수 합계, 소수점 비율) ( if (sum< MinSum) throw new Exception("Недопустимая сумма!"); Sum = sum; Rate = rate; } private static decimal minSum = 100; // минимальная допустимая сумма для всех счетов public static decimal MinSum { get { return minSum; } set { if(value>0) 최소합 = 값; ) ) public decimal Sum ( get; private set; ) // 계정의 금액 public decimal Rate ( get; private set; ) // 이자율 // 일정 기간 후 특정 비율로 계정에 있는 금액 계산 public 정적 십진수 GetSum(십진수 합계, 십진수 비율, int 마침표) ( 십진수 결과 = 합계; for (int i = 1; i<= period; i++) result = result + result * rate / 100; return result; } }

minSum 변수, MinSum 속성 및 GetSum 메서드는 여기에서 static 키워드로 정의됩니다. 즉, 정적임을 의미합니다.

minSum 변수와 MinSum 속성은 송장을 생성할 수 있는 최소 금액을 나타냅니다. 이 지표는 특정 계정을 나타내는 것이 아니라 일반적으로 모든 계정에 적용됩니다. 한 계정에 대해 이 표시기를 변경하면 다른 계정에 대해서도 변경해야 합니다. 즉, 객체의 상태를 저장하는 Sum 및 Rate 속성과 달리 minSum 변수는 지정된 클래스의 모든 객체에 대한 상태를 저장합니다.

GetSum 방법과 동일 - 특정 초기 금액에 대해 특정 이자율로 특정 기간 후 계정의 금액을 계산합니다. 이 메서드의 호출과 결과는 특정 객체나 객체의 상태에 의존하지 않습니다.

따라서 클래스의 모든 객체에 공통적인 상태를 저장하는 변수와 속성은 정적으로 정의해야 합니다. 또한 모든 개체에 공통적인 동작을 정의하는 메서드도 정적으로 선언해야 합니다.

클래스의 정적 멤버는 해당 클래스의 모든 개체에 공통적이므로 클래스 이름으로 참조해야 합니다.

정적 메서드는 클래스의 정적 멤버에만 액세스할 수 있습니다. 정적 메서드 내에서 비정적 메서드, 필드, 속성을 참조할 수 없습니다.

종종 정적 필드는 카운터를 저장하는 데 사용됩니다. 예를 들어 User 클래스가 있고 생성된 User 개체 수를 알려주는 카운터가 필요하다고 가정해 보겠습니다.

Class User ( private static int counter = 0; public User() ( counter++; ) public static void DisplayCounter() ( Console.WriteLine($"Created (counter) User objects"); ) ) class Program ( static void Main(string) args) ( 사용자 user1 = new User(), 사용자 user2 = new User(), 사용자 user3 = new User(), 사용자 user4 = new User(), 사용자 user5 = new User(), User.DisplayCounter(), / / 5 Console.ReadKey(); ) )

정적 생성자

일반 생성자 외에도 클래스에는 정적 생성자가 있을 수 있습니다. 정적 생성자는 다음과 같은 구별되는 기능을 가지고 있습니다.

    정적 생성자는 액세스 한정자가 없어야 하며 매개변수를 사용하지 않아야 합니다.

    정적 메서드와 마찬가지로 정적 생성자는 this 키워드를 사용하여 현재 클래스 개체를 참조할 수 없으며 정적 클래스 멤버에만 액세스할 수 있습니다.

    정적 생성자는 프로그램에서 수동으로 호출할 수 없습니다. 이 클래스의 개체를 처음 만들 때 또는 정적 멤버(있는 경우)에 처음 액세스할 때 자동으로 실행됩니다.

정적 생성자는 일반적으로 정적 데이터를 초기화하는 데 사용되거나 한 번만 수행해야 하는 작업을 수행합니다.

정적 생성자를 정의해 보겠습니다.

Class User ( static User() ( Console.WriteLine("첫 번째 사용자가 생성됨"); ) ) class Program ( static void Main(string args) ( User user1 = new User(); // 정적 생성자가 여기에서 작동합니다. User user2 = 새로운 사용자(); Console.Read(); ) )

정적 클래스

정적 클래스는 정적 한정자로 선언되며 정적 필드, 속성 및 메서드만 포함할 수 있습니다. 예를 들어 Account 클래스에 정적 변수, 속성 및 메서드만 있는 경우 정적으로 선언할 수 있습니다.

Static class Account ( private static decimal minSum = 100; // 모든 계정에 허용되는 최소 금액 public static decimal MinSum ( get ( return minSum; ) set ( if(value>0) minSum = value; ) ) // 계정 계산 일정 기간 후 일정 비율로 금액 public static decimal GetSum(decimal sum, decimal rate, int period) ( decimal result = sum; for (int i = 1; i<= period; i++) result = result + result * rate / 100; return result; } }

C#에서 정적 클래스의 좋은 예는 다양한 수학 연산에 사용되는 Math 클래스입니다.

25과

지금까지 생성한 각 개체에는 고유한 데이터 요소 집합이 있습니다. 응용 프로그램의 목적에 따라 동일한 클래스의 개체가 하나 이상의 데이터 멤버를 공유해야 하는 상황이 있을 수 있습니다. 예를 들어, 직원 1,000명의 근무 시간을 추적하는 지불 프로그램을 작성한다고 가정합니다. 세율을 결정하려면 프로그램에서 각 직원이 근무하는 조건을 알아야 합니다. 이를 위해 클래스 변수를 사용합시다. state_of_work.그러나 모든 직원이 동일한 조건에서 일하는 경우 프로그램은 다음 유형의 모든 개체에 대해 이 데이터 요소를 공유할 수 있습니다. 직원.따라서 프로그램은 동일한 정보의 999개 사본을 폐기함으로써 필요한 메모리 양을 줄입니다. 클래스의 요소를 공유하려면 해당 요소를 다음과 같이 선언해야 합니다. 정적(정적).이 단원에서는 여러 개체 간에 클래스 요소를 공유하기 위해 수행해야 하는 단계를 다룹니다. 이 강의를 마치면 다음 핵심 개념을 마스터하게 될 것입니다.

    C++에서는 클래스의 하나 이상의 멤버를 공유하는 동일한 유형의 개체를 가질 수 있습니다.

    프로그램이 공유 요소에 값을 할당하면 해당 클래스의 모든 개체가 즉시 새 값에 액세스할 수 있습니다.

    공유 클래스 데이터 멤버를 생성하려면 클래스 멤버 이름에 키워드를 접두어로 붙여야 합니다. 공전.

    프로그램이 클래스 멤버를 다음과 같이 선언한 후 공전,공유 클래스 멤버에 해당하는 전역 변수(클래스 정의 외부)를 선언해야 합니다.

    귀하의 프로그램은 키워드를 사용할 수 있습니다 공전,프로그램이 아직 해당 클래스의 객체를 선언하지 않았을 때 클래스 메소드를 호출 가능하게 만들기 위해.

공유 항목

일반적으로 특정 클래스의 개체를 만들 때 각 개체는 고유한 데이터 멤버 집합을 가져옵니다. 그러나 동일한 클래스의 개체가 하나 이상의 데이터 요소를 공유해야 하는 상황이 있을 수 있습니다. (정적 전자데이터 항목). 이러한 경우 데이터 멤버를 다음과 같이 선언합니다. 일반 실트그리고 사적인,그런 다음 유형 앞에 키워드를 추가합니다. 공전,아래:

개인: 정적 int 공유 값;

클래스를 선언한 후에는 아래와 같이 요소를 클래스 외부의 전역 변수로 선언해야 합니다.

int class_name::shared_value;

다음 프로그램 SHARE_IT.CPP는 클래스를 정의합니다. 책 시리즈,공유 요소 page_count,이는 클래스(시리즈)의 모든 객체(책)에 대해 동일합니다. 프로그램이 이 요소의 값을 변경하면 변경 사항이 클래스의 모든 객체에 즉시 반영됩니다.

#포함

#포함

수업 책_시리즈

( public: book_series(char *, char *, float); void show_book(void); void set_pages(int) ; private: static int page_count; char 제목; char 작성자[ 64 ]; float 가격; );

int book_series::page__count;

무효 book_series::set_pages(int 페이지)

( page_count = 페이지; )

book_series::book_series(char *제목, char *저자, 부동 소수점 가격)

( strcpy(book_series::title, title); strcpy(book_series::저자, 저자); book_series::price = 가격; )

무효 book_series::show_book(무효)

( 외우다<< "Заголовок: " << 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("Windows용 Word 사용 방법 배우기", "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(); }

보시다시피 클래스는 다음을 선언합니다. page_count어떻게 정적 정수클래스 정의 직후 프로그램은 요소를 선언합니다. page_count전역 변수로. 프로그램이 요소를 변경할 때 page_count,변경 사항은 클래스의 모든 객체에 즉시 반영됩니다. 책 시리즈.

클래스 멤버 공유

프로그램에 따라 개체의 여러 인스턴스 간에 특정 데이터를 공유해야 하는 상황이 있을 수 있습니다. 이렇게 하려면 이러한 요소를 static으로 선언합니다. 다음으로 이 요소를 클래스 외부에 전역 변수로 선언합니다. 프로그램에서 이 요소를 변경하면 해당 클래스의 개체에 즉시 반영됩니다.

속성이 있는 요소 사용공개 정적 경우 개체가 존재하지 않습니다

방금 배웠듯이 클래스의 멤버를 다음과 같이 선언할 때 공전이 요소는 주어진 클래스의 모든 객체가 공유합니다. 그러나 프로그램이 아직 개체를 생성하지 않았지만 요소를 사용해야 하는 상황이 있을 수 있습니다. 요소를 사용하려면 프로그램에서 다음과 같이 선언해야 합니다. 공공의그리고 공전.예를 들어 다음 프로그램 USE_MBR.CPP는 요소를 사용합니다. page_count수업에서 책 시리즈,이 클래스의 객체가 존재하지 않더라도:

#포함

#포함

수업 책_시리즈

( public: static int page_count; private: char 제목 ; char 작성자; float 가격; );

int book_series::page_count;

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

이 경우 클래스는 클래스의 요소를 정의하기 때문에 page_count어떻게 공공의,프로그램은 클래스의 객체가 책 시리즈존재하지 않는다.

정적 멤버 함수 사용

이전 프로그램은 사용법을 설명했습니다. 공전데이터 요소. 마찬가지로 C++에서는 다음을 정의할 수 있습니다. 공전멤버 함수(메서드). 생성하는 경우 공전메서드를 사용하면 객체가 생성되지 않은 경우에도 프로그램에서 해당 메서드를 호출할 수 있습니다. 예를 들어 클래스에 클래스 외부의 데이터에 사용할 수 있는 메서드가 포함되어 있으면 이 메서드를 만들 수 있습니다. 공전.아래는 클래스 메뉴, ANSI 드라이버의 esc 시퀀스를 사용하여 디스플레이 화면을 지웁니다. 시스템에 ANSI.SYS 드라이버가 설치되어 있으면 다음 방법을 사용할 수 있습니다. clear_screen화면을 지우려면. 이 메서드는 다음과 같이 선언되어 있기 때문에 공전,프로그램은 유형의 개체가 있는 경우에도 이를 사용할 수 있습니다. 메뉴존재하지 않는다. 다음 프로그램 CLR_SCR.CPP는 이 방법을 사용합니다. clear_screen디스플레이 화면을 청소하려면:

#포함

( public: static void clear_screen(void); // 다른 메소드는 여기에 있어야 합니다 private: int number_of_menu_options; );

무효 메뉴::clear_screen(무효)

( 외우다<< "\033" << "}