반응형
728x90
반응형

생성자와 소멸자

  • 생성자

위의 예제에서 11번 라인에 나타나는 함수를 생성자라고 한다.

생성자는 먼저 클래스의 이름과 동일한 함수의 형태를 띄고 있으며, 반환형이 선언되어 있지 않으며, 실제로 반환 또한 하지 않는다.

생성자의 특징으로는 객체 생성 시 딱 한번 호출되며, 함수의 일종이니 오버로딩이 가능하며, 디폴트 매개변수를 설정할 수 있다. 그리고 객체가 생성될 때에는 생성자가 무조건 호출된다. 생성자가 호출되지 않고서 객체가 생성될 수 없다.

위의 예제는 생성자를 선언하고 활용하는 예이다. 11번 라인부터 23번 라인에서는 생성자를 정의하고 있는데 생성자도 일종의 함수이기 때문에 함수 오버로딩이 적용되고, 디폴트 매개변수의 적용 또한 가능함을 볼 수 있다. 그리고 29번 라인 ~ 42번 라인까지 일반 변수 형태의 선언과 동적 할당 형태의 선언으로 나뉘어서 각각 선언될 시 생성자의 호출을 볼 수 있다. 32번 라인의 형태는 객체가 생성되지 않는다. 왜냐하면 반환 타입이 AAA형이고 매개 변수는 void형이고 함수 이름이 a0인 함수의 원형 선언으로 간주되기 때문이다.

 

  • 멤버 이니셜라이저

다음 상황에서 멤버 이니셜라이저는 멤버 변수로 선언된 객체의 생성자 호출에 활용된다.

28번 라인을 통해서 멤버 이니셜라이저를 진행하고 있는데 AAA 클래스는 BBB의 클래스의 객체를 멤버 변수로 가지고 있다. 객체 b의 초기화는 첫 번째 방법으로는 객체 b를 이용하여 set 함수를 통해 혹은 그에 준하는 함수의 호출을 통해 정보 은닉에 위배되지 않게 b 객체의 number 멤버 변수를 초기화 시키거나, 두 번째 방법으로는 생성자를 이용하여 초기화를 시켜야 한다. 그러나 위와 같이 클래스 내에서 선언되어 객체의 생성과 동시에 초기화 값 전달이 불가능하다. (BBB b(123) 형태의 선언이 불가능하다는 의미) 그러나 멤버 이니셜라이저를 이용하면 객체 형태의 멤버의 생성자를 이용한 초기화가 가능하다. 28번 라인의 내용이 멤버 이니셜라이저이다. 위 예제에서의 의미는 객체 b의 생성 과정에서 num을 인자로 전달받는 생성자를 호출한다라는 의미이다.

위와 같이 객체가 아닌 일반 기본 자료형에 대한 멤버 변수 또한 이니셜라이저를 통해서 초기화가 가능하다. 12번 라인처럼 멤버 변수 num을 생성자를 통해 넘겨온 매개 변수 n을 이용하여 초기화 하라는 의미이다. 이렇게 되면 멤버 변수를 초기화 하는 방법은 두 가지가 된다.

1.     생성자의 몸체에서 초기화
2.     이니셜라이저를 이용한 초기화

두 가지가 존재하는데 이니셜라이저를 통하여 초기화를 진행하는 경우 다음과 같은 이점을 얻을 수 있다.

1.     초기화의 대상을 명확히 인식할 수 있다.
2.     성능에 약간의 이점이 있다.
->  선언과 동시에 초기화가 이뤄지는 형태로 바이너리 코드가 생성된다.
->  생성자 몸체의 경우 int num; num=10;/이니셜라이저의 경우 int num=10; 효과를 볼 수 있다.

const 멤버 변수/참조자 멤버 변수의 초기화

이니셜라이저를 이용할 경우 선언과 동시에 초기화와 같은 효과를 얻는다는 이유로 const 멤버 변수의 초기화를 진행할 수 있다! 또한 선언과 동시에 초기화가 이루어져야 하는 참조자 멤버 변수 또한 초기화가 가능하다.

  • 객체 생성 과정의 정리

1.     메모리 공간의 할당
2.     이니셜라이저를 이용한 멤버 변수(객체)의 초기화
3.     생성자의 몸체 부분 실행

모든 객체는 세 과정이 순서대로 거치고 생성이 완료된다.

  • 디폴트 생성자

객체가 되기 위해서는 반드시 하나의 생성자가 호출되어야 한다. 그러나 생성자가 없는 클래스의 경우 객체를 생성하지 못하는 것인가? 이런 문제를 해결하기 위해서 생성자를 정의하지 않은 클래스에는 C++ 컴파일러에 의해서 디폴트 생성자가 자동으로 삽입된다.

디폴트 생성자는 전달 인자를 받지 않고, 내부적으로 아무런 일도 하지 않는 생성자이다.

이러한 디폴트 생성자는 생성자가 하나도 정의되어 있지 않을 때만 컴파일러에 의해 자동으로 삽입된다. 다른 말로 생성자가 하나라도 추가되어 있다면 디폴트 생성자는 컴파일러에 의해 자동으로 삽입되지 않는다.

  • Private 생성자

클래스 내부에서만 객체의 생성을 허용하려는 목적으로 생성자를 private으로 선언.

  • 소멸자

위와 같은 예에서 12번 라인과 같은 형태를 소멸자라고 한다.

소멸자는 클래스의 이름 앞에 ‘~’가 붙은 형태의 이름을 갖으며, 반환형이 선언되어 있지 않고 실제로 반환하지 않는다. 그리고 매개변수는 항상 void형으로 선언되어야 하고 오버로딩 및 디폴트 매개변수 설정 모두 불가능하다.

소멸자의 특징은 먼저 객체 소멸 과정에서 자동으로 호출이 된다. 그리고 아무런 소멸자가 생성되어 있지 않으면 디폴트 생성자가 컴파일러에 의해 자동으로 삽입된다. 소멸자는 생성자에서 할당한 리소스의 소멸에 사용된다.

다음은 소멸자 사용의 예이다.

 

 

 

 

728x90
반응형

'컴퓨터 언어 정리 > C++ 언어' 카테고리의 다른 글

15 복사 생성자  (0) 2020.09.13
14 클래스와 배열 및 this 포인터  (0) 2020.09.13
11, 12 정보 은닉과 캡슐화  (0) 2020.09.11
10 클래스와 객체  (0) 2020.09.11
09 C언어의 표준 함수 호출  (0) 2020.09.10
728x90
반응형

벡터

벡터가 무엇인지 한번 찾아보았다. 간단하게 정의하자면 순차 컨테이너에 속하는 동적 배열이다. C의 배열과 똑같이 행동한다.

그렇다면 C의 배열과 벡터의 차이점은 무엇일까? 

1. 타입에 상관없이 모든 타입에 대해서 일반적인 배열을 만들 수 있다.
=> int, double, char, int *, 객체 가릴 것 없이 모든 타입에 대해서 배열을 만들 수 있다는 이야기이다.
2. 배열의 크기 조절이 자동으로 이루어지며, 추가 및 삭제에 대한 인터페이스를 제공한다
=> 배열에 값을 추가하기 위해 새롭게 더 큰 메모리를 할당하고, 값을 복사하고 기존 메모리를 해체하고... 이러한 과정들을
알아서 해준다는 것이다! 개꿀!!!!ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그러나 2번과 같은 장점에 따른 단점 또한 존재한다.

C++의 벡터는 무조건 데이터를 선형적으로 만들려고 한다.( 그렇기에 이름도 순차 컨테이너. ) 중간에 끊긴다거나 하면 안된다는 소리이다. 

왼쪽과 같은 형태는 가능하지만, 오른쪽과 같은 형태는 안된다는 소리이다. 이러한 선형을 유지해야하는 특징 때문에 값을 추가할 때 단점이 발생한다.

메모리 공간이 충분하여 기존에 이어서 확장한 후 값을 그냥 더 추가할 경우에는 문제가 안된다.
아래의 그림처럼 말이야.

그런데 다음 그림과 같이 기존의 6개 메모리 뒤에 다른 관련없는 값이 이미 할당되어 기존의 6개 메모리 뒤에 연이어 추가 확장이 불가능한 경우는 문제가 발생한다.

이러한 경우에는 

이렇게 복사, 확장, 추가, 소멸 등의 여러 작업들이 필요하니 속도가 느려지는 단점이 있다.

설명은 이 정도로 정리하도록 하고, 매우 간단한 코드를 기록해보자.

7번 라인에서 볼 수 있듯이 템플릿 문법을 활용하여 사용한다. 반복자를 활용하지 않은 가장 기본 기본 기본적인 벡터 예제이다. 실행 결과는 매우 뻔하기 때문에 생략~

9번 라인에서 처럼 .size() 함수를 통해 벡터가 정의된 길이를 확인할 수 있다.

다음 vector 에서 제공하는 push_back 함수를 사용한 예이다. push_back 함수를 사용하면 벡터 열에 손쉽게 데이터를 추가할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
 
using namespace std;
 
int main(void)
{
    int max_number = 0;
    int val = 0;
    vector<int> num_vector;
 
    while (true)
    {
        cout << "벡터에 추가할 숫자를 입력하세요 (-123123 입력 시 종료) : ";
        cin >> val;
        if (val == -123123)
            break;
        else
            num_vector.push_back(val);
    }
 
    max_number = num_vector[0];
 
    for (int i = 0; i < num_vector.size(); i++)
    {
        if (num_vector[i] > max_number)
            max_number = num_vector[i];
    }
 
    cout << " 입력한 값 중에서 최대 값은 " << max_number << " 입니다." << endl;
    return 0;
}
cs

 

 

728x90
반응형

'프로그래밍응용 > Modern & STL' 카테고리의 다른 글

Deque  (0) 2020.09.13
모든 컨테이너 공통 멤버  (0) 2020.09.13
Iterator( With vector )  (0) 2020.09.13
STL:Container, Iterator, Algorithm 개념  (0) 2020.09.10
C++ STL(Standard Template Library이란?  (0) 2020.09.07
728x90
반응형

c언어의 표준 함수 호출

  • C언어의 라이브러리를 사용하기 위한 헤더 삽입

위와 같이 헤더를 선언하면 C함수의 라이브러리를 C++에서도 사용할 수 있다.

그러나 C언어 스타일로 헤더를 선언하고, 함수를 호출한다고 하더라도 그 자체를 허용한다. 그 이유는 하위 버전과의 호환성(backwards compatibility)를 제공한다.

위와 같은 헤더 삽입과 함수 호출은 허용하는 것이 바로 하위 버전과의 호환성을 제공한다고 한다.

그러나 오버로딩 되는 라이브러리 등의 문제로 모두 호환되는 것은 아니다.

728x90
반응형

'컴퓨터 언어 정리 > C++ 언어' 카테고리의 다른 글

11, 12 정보 은닉과 캡슐화  (0) 2020.09.11
10 클래스와 객체  (0) 2020.09.11
08 Malloc과 free의 대체 – new와 delete  (0) 2020.09.10
07 참조자(Reference)  (0) 2020.09.08
06 이름 공간(namespace)  (0) 2020.09.08

+ Recent posts