갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • c# coroutine
  • 게임 디자인 패턴
  • Unity Graph
  • C++
  • pc게임 순위
  • 유니티 그래프
  • 게임매출순위
  • C++ 상속
  • c# Thread
  • c# unboxing
  • c# delegate
  • 게임 매출 순위
  • c# 코루틴
  • pc 게임 순위
  • 2020년 게임 매출
  • C++ virtual
  • C# 예외 처리
  • C++ 소멸자
  • c# collection
  • 롤 골드그래프
  • 모바일 게임 순위
  • 유니티 골드그래프
  • 전세계게임매출순위
  • 강남 방탈출
  • 글로벌게임매출
  • C# boxing
  • 자바
  • 전세계 게임 매출
  • 알고리즘
  • 유니티 그래프 그리기

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[C++] static member data
프로그래밍/C++

[C++] static member data

2019. 11. 14. 00:33
728x90
반응형

1. 정적 멤버 데이터 (static member data)

#include <iostream>

class Car {
    int speed;
    int color;
public:
    Car()  {}
    ~Car() {}
};

int main() {
    Car c1;
    Car c2;
    Car c3;
}

  ① 객체의 생성과 소멸

    => 모든 객체는 생성 될 때 생성자를 호출하고

    => 모든 객체는 파괴 될 때 소멸자를 호출한다.


  ② 객체가 몇 개 생성되었는지 개수를 알고 싶다면

    => 생성자에서 변수 값을 +1

    => 소멸자에서 변수 값을 -1


  ③ 객체의 개수를 관리할 변수가 필요하다. 

 

객체의 개수를 관리할 변수를 만들어보자

 

#include <iostream>

class Car {
    int speed;
    int color;
public:
    int cnt = 0;

    Car()  { ++cnt; }
    ~Car() { --cnt; }
};

int main() {
    Car c1;
    Car c2;
    Car c3;
    
    std::cout << c1.cnt << std::endl;
}

 

위와 같이 코드를 짤 경우 문제는 뭘까?
우리는 현재 객체의 개수를 알고 싶으므로 출력 시 결과값이 3이 나와야 하지만 1이 나온다.

  ① 멤버 데이터를 사용해서 객체의 개수를 관리하는 경우

    => 멤버 데이터는 객체당 하나씩 별도의 메모리 공간 사용

    => 객체의 개수는 항상 1이다.

 

#include <iostream>

int cnt = 0;

class Car {
    int speed;
    int color;
public:
    Car()  { ++cnt; }
    ~Car() { --cnt; }
};

int main() {
    Car c1;
    Car c2;
    Car c3;
    
    std::cout << cnt << std::endl;
}


  ② 전역 변수를 사용해서 객체의 개수를 관리 하는 경우

    => 전역 변수는 메모리에 하나만 있고, 모든 객체가 공유

    => 모든 객체가 공유하므로 객체의 개수를 구할 수 있다.

    => 실수로 외부에서 cnt변수값을 변경한다면?

 


#include <iostream>

class Car {
    int speed;
    int color;
public:
    static int cnt;

    Car()  { ++cnt; }
    ~Car() { --cnt; }
};
int Car::cnt = 0;

int main() {
    Car c1;
    Car c2;
    Car c3;
    
    std::cout << c1.cnt << std::endl;
}

  ① 객체의 개수를 관리하는 변수

    => 모든 객체가 공유해야 한다.

    => 외부에 잘못된 사용으로부터 보호할 수 있어야 한다.


  ② 정적 멤버 데이터 (static member data)

    => static이 붙은 멤버 데이터

    => 모든 객체가 공유한다.

    => 클래스 내부에 선언(declaration)을 만들고

    => 클래스 외부에 정의(definition)를 만들어야 한다.

 

#include <iostream>

class Car {
    int speed;
    int color;
    static int cnt;
public:
    Car()  { ++cnt; }
    ~Car() { --cnt; }
    
    int getCount() { return cnt; }
};
int Car::cnt = 0;

int main() {
    Car c1;
    Car c2;
    Car c3;
    
    std::cout << c1.getCount() << std::endl;
}

  ③ 정적 멤버 데이터의 특징

    => 모든 객체가 공유한다.

    => 멤버이므로 접근 지정자를 사용할 수 있다.

 

 


// Car.h
Class Car {
public:
    int speed;
    int color;
    static int cnt;

public:
    Car();
};
//----------
// Car.cpp
#include "Car.h"

int Car::cnt = 0;

Car::Car() {
}

  ① 정적 멤버 데이터를 만드는 방법

    => 클래스 안에 변수 선언부를 제공하고 클래스 외부(소스 파일)에 정의(definition)을 제공한다.

 


2. 정적 멤버 데이터와 일반 멤버 데이터

#include <iostream>

int cnt = 0;

Class Car {
public:
    int speed;
    int color;
    
    static int cnt;
    
    Car() {}
};

int Car::cnt = 0;

int main() {
}

 


3. 정적 멤버 데이터 접근 방법

class Car {
public:
    int speed;
    int color;
    
    static int cnt;
};
int Car::cnt = 0;

int main() {
    Car c;
    c.speed = 0;
    
    c.cnt = 0;
    Car::cnt = 0;
}

  ① 일반 멤버 데이터에 접근하는 방법

    => 객체 이름으로만 접근 가능 -> c.speed

 

  ② 정적 멤버 데이터에 접근하는 방법

    => 객체 이름을 사용하거나 클래스 이름을 사용해서 접근할 수 있다.

    => 되도록이면 클래스 이름을 사용해서 접근하는 것이 좋다.


  ③ Java, C# 등의 언어는 클래스 이름으로만 접근 가능하다.

 


4. 정적 멤버 데이터의 초기화

class Test {
public:
    int data = 0; // C++11부터 가능
    
    // static int sdata1 = 0; // error
    static int sdata1; // 선언(declaration)
    
    static const int        sdata2 = 0; // ok
    static const double     sdata3 = 0; // error
    static constexpr int    sdata4 = 0; // ok
    static constexpr double sdata5 = 0; // ok
    
    inline static int sdata6 = 0; // C++17부터
};
int Test::sdata1 = 0; // 정의(definition)

int main() {
    int n1 = Test::sdata1;
    int n2 = Test::sdata2;
    int n3 = Test::sdata3;
    int n4 = Test::sdata4;
    int n5 = Test::sdata5;
    int n6 = Test::sdata6;
}

  ① C++11부터 일반 멤버 데이터는 멤버 필드 초기화를 사용가능하지만

      정적 멤버 데이터는 필드 초기화를 사용할 수 없다.

    => 클래스 외부에 정의(definition)에서 초기값을 지정해야 한다.

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

[C++] const member function  (0) 2019.11.17
[C++] static member function  (0) 2019.11.17
[C++] 객체의 복사 방법  (0) 2019.11.13
[C++] 복사 생성자 (copy constructor)  (0) 2019.11.07
[C++] explicit 생성자  (0) 2019.11.06
    '프로그래밍/C++' 카테고리의 다른 글
    • [C++] const member function
    • [C++] static member function
    • [C++] 객체의 복사 방법
    • [C++] 복사 생성자 (copy constructor)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바