객체지향 정리

이승우·2025년 6월 11일

다형성- 옳지 않은거

  • 상향형변환(업캐스팅):
    부모가 자식에게 접근
    class A{run();}
    class B : public A{run();run2();}
    main{A *obj = new B();}
    => obj는 run은 사용 가능 (업캐스팅은 보통 주소(*) 쓰면서 객체 생성), run2는 사용 불가능

    포인터로 객체 선언하고 쓰려면 obj.run(); 이런식이 아니라 obj->run(); 이렇게 씀

  • 참조 업캐스팅:
    B o1; //객체생성
    A& o2 = o1; //참조 업캐스팅
    -> 이러면 o2.run(); 이렇게 .으로 함수 실행함

  • 하향형변환(다운캐스팅):
    자식이 부모에게 접근
    자식에게만 있는 run2(); 사용을 위해서 부모타입에 참조되있는 인스턴스를 다시 자식타입으로 형변환
    A *obj = new B(); //업캐스팅
    B* obj2 = (B*)obj; //다운캐스팅
    obj2 -> run2(); A에 run2가 없어도 가능
    or
    B& obj2 = (B&)*obj;
    obj2.run2();

  • 다운캐스팅 예제
    Shape *ps = new Rectangle(); // 업캐스팅
    Rectangle *pr = (Rectangle *) ps; // pr로 다운캐스팅 객체 생성
    pr->setWidth(100);
     or
    ((Rectangle *) ps)->setWidth(100); // 한번만 사용할때 한번에 다운캐스팅

순수가상함수 선언하는 방법 올바른거 찾기

순수가상함수: 몸체({}) 없이 헤더만 존재하는 함수. 인터페이스 역할 (순수가상함수에서 정의도 가능하긴함)
abstract 클래스: 순수가상함수 하나 이상 가지고 있는 클래스

class [클래스이름] {
public:
  virtual 반환형 함수이름(매개변수) = 0;
}

연산자 중복(오버로드) 개념

사용자 정의 타입(예: 클래스, vector)도 기본 타입처럼 +, ==, << 같은 연산자를 사용할 수 있도록 해준다.
ex) a+b에서 +를 직접 정의함

  • 불가능한거
    ::(범위지정 연산자)
    .(멤버 선택 연산)
    .*(멤버 포인터 연산자)
    ?:(조건 연산자)

  • 멤버 함수로 구현
    [반환형] operator[연산자(ex:+, ==)]([const 클래스& 매개변수]) {}
    ex) bool operator==(const MyClass& other) {};

  • 비멤버 함수(전역 함수)로 구현
    ex) friend Point operator+(const Point& p1, const Point& p2);

연산자가 비교목적(==,!=)이면 반환형 bool, 산술 목적(+,-,*,/)으로 새로운 값을 리턴하려면 반환형 클래스 객체를 사용, 복합 대입 목적(+=,-=)으로 내 값을 바꾸려면 반환형 클래스 객체 참조(&) 사용

  • 비교(bool)

  • 산술

산술 전위,후위 증가 비교


전위는 매개변수 없음, 후위는 int 매개변수 사용
전위 증가는 자신을 반환해서 &가 붙음. (this 반환)
후위 증가는 증가 전 값의 복사본을 반환해야 되서 &가 안 붙음.

  • 복합 대입

  • ostream <<
    피연산자가 ostream(사용자 정의 타입이 아닌 기본 타입)이기 때문에, 무조건 비멤버 함수로 정의해야됨(private에 접근해야돼서)
    cout를 객체 타입으로 생각해야됨.
    멤버 함수면 [객체].operator <<(cout,[객체])

class Point {
private:
    int x, y;
public:
	Point(int x = 0, int y = 0) : x(x), y(y) {}
    friend ostream& operator<<(ostream& os, const Point& p);
};
ostream& operator<<(ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os; // 반드시 os를 반환해야 연속 출력 가능
}
//main에서 cout << p1;

외워야 할 규칙 정리

&유무

프렌드 함수 특징

클래스의 내부 데이터에 접근할 수 있는 특수한 함수
friend void [함수이름]([자신 클래스이름] [매개변수]);
프렌드 함수 특징

  • 프렌드 함수의 선언은 클래스 안에 포함
  • 멤버 함수가 아님(그래서 매개변수에 지 클래스 이름 붙이는거)
  • 정의는 외부에서 따로
  • 프렌드 함수는 클래스 내부의 모든 멤버 변수를 사용

예시)

프렌드 함수는 클래스 외부에 선언되어서 전역함수 처리로 됨(비멤버 함수)

프렌드 클래스

예외처리 다중캐치 사용하는 이유

예외처리 - 표준 예외 클래스, 기본형, 사용자 정의 클래스, 모든 예외(...)
사용자 정의 클래스 예외, 표준 예외 클래스 뒤에 & 붙임
여러 종류의 예외 처리하기 위해서

텍스트파일 이진파일(쉬움)

텍스트 파일: 아스키 코드(헥스코드가 아스키 코드)
이진 파일: 숫자 자체를 바이트로 저장(헥스코드가 바이트)

템플릿 함수 장점 단점

  • 함수 오버로딩: 이름은 같지만, 매개변수 개수나 타입이 다르게 정의하는것

템플릿 함수
자료형 다른 함수 오버로딩일때 자료형 관계없이 처리되는 함수

  • 장점
  1. 코드 재사용성
  2. 타입 안전성 보장
  3. 사용자 정의 타입 지원
  4. 유지보수
  • 단점
  1. 컴파일 시간 증가
  2. 디버깅 어려움

STL컨테이너

-라이브러리

  • 컨테이너: 자료 저장(벡터, 리스트, 맵, 집합, 큐, 스택)

  • 반복자: 컨테이너 안에 저장된 요소들을 순차적으로 처리

  • 알고리즘: 정렬이나 탐색 같은 알고리즘 구현

  • 장점

  1. STL은 전문가가 만들어서 테스트를 거친 검증된 라이브러리
  2. STL은 객체 지향 기법과 일반화 프로그램이 기법을 적용하여 만들어졌
    으므로 어떤 자료형에 대해서도 적용
  3. STL을 사용하면 개발 기간을 단축할 수 있고 버그가 없는 프로그램
  • 순차 컨테이너
    벡터: 동적 배열 처리, 뒤에서 자료 추가
    데크: 벡터와 비슷, 앞에서도 자료 추가 가능
    리스트: 중간에서 자료 추가 가능

  • 연관 컨테이너
    (자동 정렬-오름차순)
    집합(set): 중복 없는 자료 정렬(단일)
    다중 집합(multiset): 중복 허용 집합
    맵: 중복 없는 키-값 형식(쌍)
    다중 맵: 중복 허용 맵

  • 컨테이너 어댑터
    스택(후입선출), 큐(선입선출), 우선순위큐

집합예제

다중 다이나믹(정적) 캐스트

다이나믹 캐스트를 위해서 부모가 꼭 virtual이어야 한다.
객체 타입이 올바르면 반환, 그렇지 않으면 null 반환

다운 캐스팅 안전하게 하기 위해

가상함수 사용방법 (서술형)

업캐스팅 시 부모 클래스 함수와 자식 클래스 함수의 이름 같으면 부모 클래스의 함수가 호출됨.
부모 클래스 함수에 virtual 써서 정의하면 자식 함수(부모 함수와 이름 같은)가 호출됨 = 자식클래스가 오버라이딩 한거
virtual void obj(){cout << "~~";}
virtual 반환형 함수이름(매개변수) = 0; //(순수 가상함수)

예외처리 try catch 조건들 많음 다 외우기

catch (...){} //모든 예외

예외 잡을거 없으면 -> std::terminate() 종료

변환 생산자

하나의 인자를 가지는 생성자로, 다른 타입의 값을 해당 클래스 타입으로 자동 변환해주는 생성자

함수 템플릿 타입을 일반화하기 위한 키워드

template <typename T>
T add(T a, T b) {
    return a + b;
}

template <>
int add<int>(int a, int b) {
    cout << "int" << endl;
    return a + b;
}

STL컨테이너의 스택, 큐 자료구조

  • 스택
#include <stack>
stack<int> s;

s.push(x)
s.pop()
s.top()
s.empth() //비어있는지

#include <queue>
stack<int> q;

q.push(x)
q.pop() // front 제거
q.front() //꺼내는 용도
q.back() //넣는 용도
q.empth() //비어있는지

  • 데큐(양방향 삽입,삭제 가능)
    push_front(), push_back()
    pop_front(), pop_back()

서술형

가상함수 객체 포인터 예제 빈칸(동일한 함수/단어가 있으면 다 써야됨. 세개가 동일하면 세개 다써야됨)

부모에 virtual로 선언
Animal* a1 = new Dog();
a1->speak();
이러면 virtual로 선언해서 자식의 speak() 실행

연산자중복이용한 덧셈 뺄셈 예제 빈칸

0으로 나누는 상황에서 예외 만들고 처리하는 예제 빈칸

0개의 댓글