프로그래밍 언어론 6-1-3강(4). 생성자 초기화 (Constructors)

[프로그래밍 언어론]

2019. 11. 15. 18:16

 

[Counstructors(생성자)]

: 수 많은 객체지향 언어(Java, C#등)들은 프로그래머가 '선언에 대해 초기값이 없어도 동적 할당 변수들의 초기화가 자동으로 이뤄지는' 타입을 정의하는 것을 허용한다. ( = 생성자 )

=> 생성자 함수의 멤버 변수를 초기화 하기 위한 목적

 

 

 

[생성자 초기화]

: 몇몇 언어들(C++등) 또한 초기화와 할당(대입)을 구분한다.

+) C# : 초기화와 할당의 장점을 가져다 사용

+) JAVA : 초기화와 할당 구분하지 않음

: 사용자 정의 추상 데이터 타입인 클래스에 대해서 초기화와 할당(대입)을 구별하는것은 특히 더 중요하다.

 

 

 

[타입 초기화 방법 세가지]

1) 생성자 호출

  : 초기화는 변수들의 타입에 대한 생성자 함수의 호출로 해석된다. (argument 형태로 전달)

    ( A a = new A();  : a를 A 생성사 함수 호출로 초기화한다)

2) assignment 호출

  : coercion(자동형변환)이 없으면, assignment는 타입의 assignment operator의 호출로 해석된다.

3) bit-wise copy 방식

 : assignment operator 조차 없으면, 할당의 오른쪽 값을 bit-by-bit 로 복사한다.

 

# 상황에 따라 위 세가지 방식중 하나의 방식으로 호출한다.

 

 

 

[여러 언어에서의 모델방식에 따른 초기화]

# JAVA에서 변수의 대입

A a = new A();

A b = a;

: 생성자 A()와 변수 a, b는 heap에 저장된다.

: reference model 방식 (a, b는 포인터 역할 / b도 a의 주소값 참조)

 

# C++에서 변수의 대입

A* a = new A;

A* b = a;

: 언어는 value model 방식이지만 포인터를 사용해서 reference model 방식을 흉내냈다.

: 하지만 생성자 A()는 heap에 저장되지만, 변수 a, b는 그 외부에 저장된다.

: b는 a의 주소값을 복사! (reference model 방식을 흉내내서 그 값을 저장하는게 아니라 주소값을 저장하는 방식)

=> 흉내내도 중요한 차이가 있음을 인지!

 

# C#에서 모델 방식

: C#은 reference model 방식과 value model 방식 두가지다 사용이 가능하다.

- class : referece model

- struct : value model

 

 

 

[예시를 통한 정리]

#includ <iostream>
...
class Test {
public:
  Test() {                    // 1번 방식(단순 생성자 호출 argument형태로 전달)
    cout << "Test()" << endl;
    }
  Test(const Test& t) {       // 3번 방식(복사연산자)
    cout << "Test(const Test& t)" << endl
  }
  Test& operator=(Test& t) {  // 2번 방식(대입연산자)
    cout << "Test& operator=(Test& t)" << endl;
    return *this;
  }
  
  
int main()
{
  Test t;           //t, t2, t3 아래 3개다 생성자 호출한다.
  Test t2(t);       //아래 t3과 동일한 의미
  Test t3 = t;      //**이거 없으면 bit-by-copy로 일어난다.
  t2 = t;
  return 0;