본문 바로가기
카테고리 없음

생성자의 초기화 리스트 & static 변수

by fromnothing1 2021. 10. 17.

초기화 리스트 

C+++ 에는 클레스에 초기화 리스트 기능을 지원한다. 

 

Marine 클래스 생성 예시

 

Marine::Marine() 
{
  hp = 50;
  coord_x = coord_y = 0;
  damage = 5;
  is_dead = false;
}

//--------------------------------------초기화 리스트 사용------------

Marine::Marine() : hp(50), coord_x(0), coord_y(0), damage(5), is_dead(false) {}

두가지 코드의  모두 동일한 일은 한다.  변수들의 초기화가 그것이다. 

 

하지만 초기화 리스트는 변수를 생성과 동시에 초기화가 가능하다. 즉  int a = 1000; 처럼 하는 것이 초기화 리스트이다. 

 

별로 중요하지 않다고 생각 할 수 있지만 const 상수는 생성즉시 초기화를 해야하는데 생성자를 호출해서 할경우에는 초기화 리스트를 사용해야 한다. 

 

 

static  변수 

// static 멤버 변수의 사용

#include <iostream>
using namespace std;

class Marine {
    static int total_marine_num;

    int hp;                // 마린 체력
    int coord_x, coord_y;  // 마린 위치
    bool is_dead;

    const int default_damage;  // 기본 공격력

public:
    Marine();            
    void show_status();
    static void show_total_marine();
    ~Marine() { total_marine_num--; } // 선언과 동시에 초기화
};

void Marine::show_total_marine() {
    std::cout << "전체 마린 수 : " << total_marine_num << std::endl;
}
int Marine::total_marine_num = 0; // static 변수 초기화 

Marine::Marine()
    : hp(50), coord_x(0), coord_y(0), default_damage(5), is_dead(false) {
    total_marine_num++;
}

void Marine::show_status()
{
    cout << total_marine_num << '\n';
}

int main() 
{


    Marine marin1;
    Marine::show_total_marine();
    Marine marin2;
    Marine marin3;
    Marine::show_total_marine();
}

static 변수는 다른 인스턴스 변수처첨 class 안에서 선언과 동시에 초기화 할수 없다. 

 

int Marine::total_marine_num = 0; 

이와 같이 밖에서 초기화 해줘야한다 ( 원래 0 으로 초기화 되지면 명시적으로 적어주는 편이 좋다.)

 

호출은 위와 같이 스태틱 함수를 만들어서 호출해준다. 

Marine::show_total_marine();

 

this 

인스턴스 객체를 가르치는  포인터 

 

#include<iostream>
using namespace std;

class A 
{
	int x;

	public:
		A(int c) : x(c) {}

		int& access_x() { return x; }
		int get_x() { return x; }
		void show_x() { cout << this->x << endl; }
};

int main() 
{
	A a(5);
	a.show_x();

	int& c = a.access_x();
	c = 4;
	a.show_x();
    
// 아래는 오류
// int& e = a.get_x();
// e = 2;
// a.show_x();
}

위의 예제는 this -> 이용해서 맴버 변수에 접극하는 것과 레퍼런스를 return 해서 밖에서 인스턴스 객체의 맴버 변수에 접근 하는 것을 보여 주고 있다. 

 

오류 설명 

값 을 return 하는것은 임시로 같은 type 을 가진 변수를 선언하고 거기에 값을 복사해 주는것이다. 

물론 return 이 끝나면 임시 변수는 없어진다. 

 

 

문제 1

아래와 같은 코드에서 복사 생성 은 몇 번 이나 표시될까요?

#include <iostream>

class A {
  int x;

 public:
  A(int c) : x(c) {}
  A(const A& a) {
    x = a.x;
    std::cout << "복사 생성" << std::endl;
  }
};

class B {
  A a;

 public:
  B(int c) : a(c) {}
  B(const B& b) : a(b.a) {}
  A get_A() {
    A temp(a);
    return temp;
  }
};

int main() {
  B b(10);

  std::cout << "---------" << std::endl;
  A a1 = b.get_A();
}

 

 

 

1. A temp(a) 에서

2. return temp 에서 temporary materialization 이 일어나면서. Named Return Value Optimization으로 생략 가능

3. A a1 = b.get_A() 에서 (2)의 temporary instance가 쓰이면서. c++11에서는 non-mandatory elision 으로 생략 가능, c++17에서는 mandatory elision 으로 무조건 생략해야함

 

 

 

출처:https://modoocode.com/197

 

씹어먹는 C++ - <4 - 4. 스타크래프트를 만들자 ② (const, static)>

 

modoocode.com

 

댓글