15

끼요ㄹ힝·2023년 11월 12일

인터페이스(Interface) 및 구현(Implementation) 분리

.h와 .cpp

Time.h: 인터페이스
클래스의 멤버 함수와 변수의 선언
Time.cpp: 구현
헤더 파일에 선언된 각 메서드의 실제 코드가 작성됨. 각 함수가 실제로 어떻게 동작하는지 정의됨.

장점

  1. 재사용성: 다른 프로그래머가 'Time' 클래스를 사용하려면 헤더 파일만 보면 충분합니다. 그들은 구현 세부 사항을 몰라도 클래스의 기능을 이해하고 사용할 수 있습니다.

  2. 간결성: 사용자는 필요한 인터페이스 정보만 봄으로써 더 쉽게 클래스를 이해할 수 있습니다.

  3. 보안: 구현 세부 사항을 숨기면서도 필요한 기능을 제공할 수 있습니다. 이는 특히 상업적인 소프트웨어 개발에서 중요합니다.

  4. 유지보수: 인터페이스와 구현이 분리되어 있기 때문에, 구현 세부 사항을 변경해도 인터페이스를 사용하는 다른 코드에 영향을 주지 않습니다.



include guard

include guard: 헤더 파일이 여러 번 중복 include되는 것을 방지해주는 코드.
#ifdef, #define , #endif

#ifndef TIME_H // TIME_H가 정의되지 않았다면
#define TIME_H // TIME_H를 정의

// Time 클래스 정의 및 기타 선언

#endif // TIME_H의 끝

#ifndef (If Not Defined): 이 지시문은 TIME_H라는 심볼이 정의되지 않았는지 확인합니다. 처음 Time.h가 포함될 때, TIME_H는 정의되지 않았기 때문에, #ifndef는 참(True)이 됩니다.

#define: 그 후 TIME_H라는 심볼이 정의됩니다. 이는 Time.h가 이미 포함되었음을 나타냅니다.

#endif: 이 지시문은 #ifndef 블록의 끝을 나타냅니다.

예외 발생 명령어

throw 키워드
예외 객체를 "던지는"데 사용됨.
예외가 발생하면('throw'가 호출되면), 프로그램의 정상적인 실행 흐름이 중단.
프로그램 제어는 'throw'문을 포함하는 함수를 호출한 가장 가까운 예외처리기('catch' 블록)로 이동.

Time.cpp

string Time::toUniversalString() const {
    ostringstream output;
    output << setfill('0') << setw(2) << hour << ":"
        << setw(2) << minute << ":" << setw(2) << second;
    return output.str()
} 
  1. ostringstream 객체 생성:
    ostringstream은 C++의 표준 라이브러리에 속하는 스트림 클래스 중 하나입니다. 이 클래스는 문자열을 생성하는 데 사용됩니다. 여기서는 output이라는 이름으로 ostringstream 객체를 생성합니다.

  2. setfill과 setw 조작자 사용:
    setfill('0'): 이 조작자는 스트림에 채워질 문자를 설정합니다. 여기서는 빈 자리가 '0'으로 채워지도록 설정합니다.
    setw(2): 이 조작자는 다음에 스트림에 입력되는 값의 너비를 설정합니다. 여기서는 2자리로 설정하여 시간, 분, 초가 항상 두 자리 숫자로 표시되도록 합니다.

  3. 시간, 분, 초 스트림에 삽입:
    hour, minute, second 필드의 값을 스트림에 순서대로 삽입합니다. 각 필드 값 사이에는 콜론(:)이 삽입되어 시간의 표준 포맷을 따릅니다.

  4. 결과 문자열 반환:
    output.str(): ostringstream 객체의 str 메서드를 호출하여 스트림에 저장된 문자열을 반환합니다.

Class scope 및 멤버로의 접근

객체를 생성하기 위한 방법

  1. 객체 이름을 사용하여 객체 생성:
    'Account account;'
    이 방법은 가장 기본적인 객체 생성 방법입니다. 여기서 account는 Account 클래스의 인스턴스입니다. 이 인스턴스는 스택 메모리에 생성되며, 함수나 블록의 실행이 끝나면 자동으로 소멸합니다. 이 방식은 객체의 생명 주기가 해당 객체가 선언된 스코프에 국한되는 경우에 주로 사용됩니다.

  2. 객체에 대한 참조(reference) 사용:
    'Account& accoutRef = account;'
    이 방법은 기존에 생성된 객체에 대한 참조를 생성합니다. 여기서 accountRef는 account 객체에 대한 참조입니다. 참조는 객체의 별명(alias)과 같은 역할을 하며, 참조를 통해 객체를 조작하면 원본 객체가 영향을 받습니다. 참조를 사용하면 원본 객체에 대한 추가적인 메모리 할당 없이 객체에 접근할 수 있습니다.

  3. 객체에 대한 포인터(pointer) 사용:
    'Account* accountPtr = &account;'
    이 방법에서는 객체의 주소를 포인터 변수에 저장합니다. accountPtr는 Account 타입의 객체를 가리키는 포인터이며, account 객체의 주소를 가지고 있습니다. 포인터를 사용하면 객체에 간접적으로 접근할 수 있으며, 포인터를 통해 동적 메모리 할당 및 해제, 다양한 객체들 간의 상호작용 등을 수행할 수 있습니다. 포인터는 더 복잡한 메모리 관리를 가능하게 하지만, 사용 시 주의가 필요합니다.

소멸자 함수

기타

static 객체

  1. 생명주기:
    'static' 객체의 생명 주기: 프로그램의 실행이 끝날 때까지 살아있는. 프로그램이 시작될 때 생성되고, 프로그램이 종료될 때 소멸.

  2. 초기화:
    'static' 객체는 처음 사용될 때 한 번만 초기화 됨. 이는 객체가 선언된 함수나 블록이 여러 번 호출되어도, 객체가 처음 사용된 시점에만 초기화되고, 초기화되지 않는다는 것을 의미함.

ex.

#include <iostream>
using namespace std;

void countCalls() {
    // static 변수 선언
    static int count = 0;
    
    // 함수가 호출될 때마다 count 증가
    count++;
    
    // 현재까지의 호출 횟수 출력
    cout << "countCalls 함수가 호출된 횟수: " << count << endl;
}

int main() {
    // countCalls 함수를 여러 번 호출
    countCalls(); // 1회 호출
    countCalls(); // 2회 호출
    countCalls(); // 3회 호출

    return 0;
}
  1. 저장 위치:
    'static' 객체는 스택이 아닌 정적 데이터 영역에 저장됨. 이는 객체가 함수 호출과는 독립적으로 메모리에 유지되게 한다는 것을 의미.

  2. 사용 예시:
    함수 내에서 'static' 객체를 사용하면, 함수 호출 간 상태를 유지할 수 있음. 예를 들어, 함수가 호출될 때마다 특정 값을 증가시키는 카운터와 같은 용도로 사용될 수 있음.

  3. 범위와 접근성:
    'static' 객체는 선언된 블록이나 함수 내에서만 접근 가능함. 즉, 객체가 선언된 함수나 블록 외부에서는 접근할 수 없다. 그러나 객체의 생명 주기는 이러한 범위를 초과함.

profile
몰라몰라몰라 세상

0개의 댓글