42Seoul

CPP Module 00 개념 & 서브젝트 정리

seomoon 2022. 3. 23. 07:20

개념

Namespace

  • 어떤 대상(함수, 객체 등)의 소속을 지정해준다. 같은 이름이더라도 소속된 namespace가 다르면 다른 대상으로 취급한다.
  • 범위 지정 연산자 (Scope Operator)
    • className:: - 인스턴스를 생성하지 않고 클래스 멤버 변수 및 멤버 함수에 접근할 때
      class Name {
        public:
            void Print();
      }
      ​
      void Name::Print() {
        ...
      }
    • 다음과 같이 사용할 수 있다.
    • namespaceName:: - namespace 영역에 있는 변수 / 함수를 호출할 때 사용할 수 있다.
    • :: - 전역 함수, 전역 변수를 지역 변수와 구분하여 사용할 수 있게 한다.

Class, member function

  • CPP은 멀티 패러다임 언어이지만, 일반적으로 객체 지향 프로그래밍 언어로 일컫는다.
  • 하나의 객체는 객체의 정보를 나타내는 변수들과, 이 변수를 가지고 어떠한 작업을 하는 함수들(행위)로 이루어져 있다.
  • 객체의 변수는 인스턴스 변수, 객체의 함수는 인스턴스 메소드라고 부른다.
  • 외부에서 객체의 인스턴스 변수 값을 직접 바꾸지 못하고, 객체의 인스턴스 함수를 통해서만 인스턴스 변수들의 값에 접근할 수 있게 하는 것을 캡슐화라고 한다.
  • 캡슐화 : 객체가 구현 정보를 사용자로부터 숨기고, 사용자는 객체의 공개 인터페이스를 통해 접근할 수 있도록 하는 방식이다. 즉, 인터페이스와 구현을 분리하는 방식이다.
  • 캡슐화된 클래스는 사용하기 쉽고 프로그램의 복잡도를 줄여 실수를 줄여준다는 장점이 있다. 또한 클래스 재사용성과 유지보수 측면에서도 이점이 있다. C++ 표준 라이브러리의 클래스는 모두 캡슐화되어 있다.
  • 클래스 :
    • CPP에서 클래스(틀, 설계도)를 이용해 만들어진 객체를 인스턴스라고 한다.
    • 아직 인스턴스가 생성되지 않고, 클래스만 선언된 상태일 경우 클래스 내의 변수, 함수는 각각 멤버 변수, 멤버 함수라고 한다.
  • 접근 지시자 : private 영역의 멤버들은 외부에서 접근 불가. 객체 내에서만 접근이 가능하다. public 영역의 멤버들은 외부에서도 접근이 가능하다.일반적으로 멤버 변수는 private 으로 하고, 멤버 함수는 public 으로 한다.
  • 기본 접근 지시자는 private 이다.

stdio stream

  • iostream : CPP에서 표준입출력에 필요한 기능들을 포함하는 표준 라이브러리. (std::cout 등)

초기화

1) 변수 초기화

C++에서는 변수를 초기화하는 세 가지 방법이 있다.

  1. 복사 초기화 (copy initialization)
    int value = 5;

  2. 직접 초기화 (direct initialization)
    int value(5); // 함수 호출과 유사한 방식으로 변수 초기화
    일부 데이터 타입에서 복사 초기화보다 성능이 뛰어나다.따라서 복사 초기화보다는 직접 초기화를 사용하는 것이 좋다.
    초기화와 할당을 구분하는 데도 도움이 된다. (+ 클래스에 관련한 이점도 있음)

  3. 유니폼 초기화 (uniform initialization / brace initialization) (C++ 11)
    복사 초기화, 직접 초기화는 일부 타입의 변수에 대해서만 작동한다. 
    모든 데이터 타입에서 작동하는 단일 초기화 메커니즘을 제공하기 위해
    C++ 11에서
    유니폼 초기화 라는 새로운 형태의 초기화 메커니즘이 추가되었다.  
    {} 로 변수를 초기화하면 기본 초기화가 된다. 기본 초기화는 변수를 0으로 초기화한다.
    유니폼 초기화는 형 변환을 허용하지 않는다. 변수를 다른 타입으로 초기화하려고 하면 컴파일러에서 경고가 발생한다.
int value{5};
int value{}; //기본 초기화(default initialization)
int value{4.5}; //error: 형 변환 허용 X


2) 클래스 초기화

  • 클래스의 모든 멤버 변수가 public 인 경우, 초기화 목록 (initialization list) 또는 유니폼 초기화 (uniform initialization)을 사용해서 직접 초기화할 수 있다.
    Class MyClass
    {
        public:
            int x;
            int y;
    };
    ​
    int main()
    {
        MyClass myClass1 = { 4, 5 }; //initialization list
        MyClass myClass2 { 4, 5 }; //uniform initialization (C++ 11)
        ​
        return (0);
    }
  • 생성자 (Constructor) 를 통한 초기화
    MyClass myClass(5); //직접 초기화 형식으로 클래스 초기화
    ​
    //복사 초기화 형식으로 클래스 초기화 -> 효율이 떨어지므로 사용하지 않는 것이 좋음.
    MyClass one = MyClass(5);
    MyClass two = 5;

    • 클래스의 인스턴스를 만드는 방법을 명시적으로 나타내기 위해, 항상 하나 이상의 생성자를 정의하는 것이 좋다.
    • 컴파일러는 생성자 호출 전에는 객체에 대한 메모리를 할당하지 않는다.
    • 클래스는 다른 클래스를 멤버 변수로 포함할 수 있다.
    • 클래스 A를 멤버 변수로 갖는 클래스 B를 생성하면, A가 먼저 생성된 후에 B가 생성된다.

  • 생성자 멤버 초기화 리스트 (Constructor member initializer list)
    • 생성자에서 대입 연산자를 사용해 클래스 멤버 변수를 초기화하는 방식은
    • 비교적 효율적이지 못하고, 일부 유형의 데이터에는 적용할 수 없다. (const, 참조 변수 등 일부 유형의 데이터는 선언과 동시에 초기화해야 하기 때문. )
      • 멤버 초기화 리스트는 생성자 매개변수 뒤에 삽입되며, : 으로 시작한다.
      • 초기화 리스트가 멤버 변수 초기화 기능을 대체하므로,
      • 생성자 본문에서 할당을 수행할 필요가 없다. 또한 생성자 본문에서 값을 할당하는 것보다 성능이 더 우수하다.
      • 3 과 같이 배열 멤버를 0으로 초기화할 수도 있다.
      • 초기화 리스트는 4 와 같이 호출자가 초기화 값을 전달할 때에도 유용하다.
      • 클래스인 멤버도 멤버 초기화 리스트를 사용해 초기화할 수 있다.C++ 에서는 이 문제를 해결하기 위해 생성자 멤버 초기화 리스트를 통해 멤버 변수를 초기화 하는 방법을 제공한다.
    • 멤버 초기화 리스트를 사용하는 것은 직접 초기화를 수행하는 것과 유사하다.

static

  • 클래스의 모든 멤버 변수와 멤버 함수는 정적(static) 멤버로 지정될 수 있다.
  • 정적 멤버 변수, 정적 멤버 함수는 인스턴스가 생성될 때마다 독립적으로 생기는 멤버 변수와 달리, 해당 클래스에 하나만 생성된다.
  • 모든 인스턴스에서 공동으로 접근/호출할 수 있다.

const (상수)

상수 : 값을 변경할 수 없는 변수.
변수를 상수로 설정하려면 변수 자료형 앞이나 뒤에 const 키워드를 붙이면 된다.
(주로 자료형 앞에 붙임)

상수 변수는 정의할 때 반드시 초기화해야 하며, 할당을 통해 값을 변경할 수 없다.
상수 변수는 일반 변수 값을 이용해 초기화할 수 있다.

상수 변수는 함수의 매개변수로 사용하는 경우가 많다.

+) 함수 선언 시 프로토타입 뒤에 const 가 오는 경우 :

이 함수 안에서는 어떠한 변수도 바꿀 수 없음(mutable 제외)을 뜻한다.
함수가 클래스 멤버인 경우에만 const 키워드를 함수 뒤에 삽입할 수 있으며,
이는 해당 함수가 속한 객체의 멤버 변수를 해당 함수 안에서는 변경할 수 없다는 뜻이다.
또한 const 가 붙은 함수 내에서는 const 가 붙은 다른 함수를 제외한 일반 함수는 호출하지 못한다.
이러한 특성으로 인해 함수 내의 불변성을 유지할 수 있다.
주로 getterbool 을 반환하는 함수에서 많이 사용된다.



서브젝트

  • 헤더에 구현된 함수(템플릿 제외)가 있거나 protect되지 않은 헤더일 경우 0점
  • 모든 출력은 표준 출력에 출력되며, 개행 문자로 끝난다.
  • 파일 이름 윗부분에는 letter, 클래스 이름, 함수 이름, 메서드 이름이 와야 한다.
  • *alloc, printf, free 사용 금지
  • 표준 라이브러리의 모든 것을 사용할 수 있지만, C에서 익숙했던 함수들의 CPP 버전을
  • 사용하는 것을 권장함. 모듈 8 이전에는 STL (<algorithm> 헤더의 vector, lists, maps 등)을 사용할 수 없다.
  • using namespace, friend 키워드 사용은 금지.
  • 클래스와 관련된 파일명은 ClassName.hpp, ClassName.cpp 이어야 함.
  • 제출 디렉토리는 ex00, ex01, exn ...
  • 예제를 꼼꼼하게 읽어볼 것. 과제 설명에 명확하게 나와있지 않은 필수 구현 사항을 포함하고 있을 수 있음. 애매하게 느껴지는 사항이 있다면 CPP에 대한 이해가 부족한 것.
  • 외부 라이브러리 사용 불가 (C++11, Boost 등)
  • 많은 양의 클래스들을 작성해야할 수 있음. 선호하는 에디터를 사용하는 것을 추천함.
  • clang++ -Wall -Wextra -Werror 로 컴파일
  • 각 execrcise를 다 읽고 시작하기 (반드시!)
  • 각 includes는 독립적이어야 함. (해당 include가 의존하는 모든 includes를 포함하고 있어야 함)
  • 코드 스타일은 자유. (Norme 적용 X) 단, 가독성이 너무 떨어지면 안 됨.
  • 뮬리넷 채점 X.

Ex 00: Megaphone

  • ex00/ Makefile, megaphone.cpp
  • 입출력은 cin, cout 사용하기
  • C++ i/o stream 학습

Ex 01: My Awesome PhoneBook

  • ex01/ Makefile *.cpp *.hpp, *.h
  • 동적 할당 없이 클래스 사용하기
  • 실행 파일 이름은 직접 정하기
  • string, iomanip 헤더 사용
  • 전화번호부 프로그램 만들기
    • ADD, SEARCH, EXIT 명령을 입력받아 처리 (이 외의 모든 입력은 무시됨)
    • 전화번호부는 비어있는 상태로 시작, 동적 할당 사용 X
    • 연락처는 최대 8개까지만 저장 (9번째 연락처가 추가되면 가장 오래된 연락처와 교체)
    • EXIT : 프로그램 종료, 연락처들은 사라짐
    • (동적 할당을 하지 않았으므로 메모리 해제할 필요 없이 그냥 프로그램 종료하면 됨)
    • ADD : 사용자로부터 한 번에(한 줄에) 한 필드씩 연락처 정보를 받음. 모든 필드가 채워질 때까지 입력을 받는다.
      • 필드 : first name, last name, nickname, phone number, darkest secret
      • 전화번호부는 한 클래스의 인스턴스로 표현되어야 하며, 연락처 배열 하나를 포함해야 한다.
      • 하나의 연락처는 반드시 클래스의 인스턴스로 표현되어야 한다. 클래스는 원하는 대로 설계하되,
      • 일관성 있게 설계해야 한다.
    • SEARCH : 현재 연락처 리스트를 출력한 다음, 인덱스를 입력 받고, 해당 인덱스의 연락처 필드를 한 줄에 하나씩 출력한다.
      • index, first name, last name, nickname 4개의 열로 출력한다.
      • 각 열의 너비는 10칸, 오른쪽 정렬되어야 하고, | 로 구분되어야 한다.
      • 열의 너비보다 긴 출력은 자르고, 출력가능한 마지막 문자(10번째 문자)를 . 로 대체한다.
      • index 를 입력받아 해당하는 연락처의 필드를 한 줄에 하나씩 출력한다. (입력이 잘못된 경우 에러 처리하기)
    • 명령이 제대로 실행되면, EXIT 이 입력되기 전까지 계속 다음 입력을 받는다.

Ex 02: The Job Of Your Dreams

  • Account.hpp, tests.cpp, Account.cpp, Makefile 제출 (로그 파일 제출 X)
  • 과제에서 제공하는 로그, 테스트.cpp, Account.hpp 파일을 보고
  • Account.cpp 파일을 추론해서 작성하는 과제.
  • 과제에서 제공하는 로그는 우분투 환경에서 생성된 로그.
  • 맥OS에서는 소멸자가 역순으로 호출되어 로그도 역순으로 찍힘