CS/자료구조

[자료구조] #4 C++ 문법(2)

태연한 컴공생 2024. 4. 15. 20:44

• OOP(Object-Oriented Programming)

 

객체 지향 프로그래밍

 '객체 관점'으로 데이터와 함수를 동시에 관리할 수 있다.

 

데이터와 함수가 서로 떨어져 있으면 생산성이 떨어지기 때문에 하나로 합치기 위해 우리는 객체 지향 프로그래밍을 알아야 한다! 

 

• 클래스를 정의하는 방법

 

class 키워드를 이용해 클래스를 정의한다.

클래스에는 멤버 점근자가 포함된다.

 

1. private : 외부 접근 불가능

2. protected(상속) : 상속 구조 상황에서의 접근지정자

3. public : 외부와 내부 모두 접근 가능

 

일반적으로 데이터는 일관성 유지와 개발자가 의도한 방향성을 위해 private,

메소드는 외부에서 함수를 호출하기 위해 public이 사용된다.

class Name { // Name으로 클래스 선언
private:     // 멤버 지정자 private
    var1;    // 멤버 변수
    ···
public:
    method1; // 멤버 함수
    ···
];

 

• Constructor & Destructor(생성자와 소멸자)

 

생성자

객체가 생성될 때 호출되는 멤버 함수

객체를 초기화하거나 메모리를 할당하는 작업을 수행한다.

여러 개의 생성자를 오버로딩 할 수 있다.

 

다음은 동적 할당된 생성자이다.

public :
   Car() {
       this->name = new char[NAME_SIZE]
       this->size = 0;
       this->speed = 0;
}

  Car(int size) { // Overloading
      this -> size = size;
}

 

소멸자

객체가 소멸될 때 자동으로 호출되는 멤버 함수

(~)를 붙여서 정의한다.

 

다음은 동적 해제된 소멸자이다.

  ~Car(){
      delete[] this -> name
}

 

• Constructor Default Value(생성자 기본값 제공)

 

다음은 선언부와 구현부를 분리한 예시코드이다.

디폴드 값이 0인 것을 볼 수 있다.

class SimpleClass {
private:
    int num1;
    int num2;
public:
    // 생성자 선언
    SimpleClass(int n1 = 0, int n2 = 0); // 디폴트 값 0
    // 멤버 함수 선언
    void print();
};

// 생성자 정의
SimpleClass::SimpleClass(int n1, int n2) {
    num1 = n1;
    num2 = n2; 
}

// 멤버 함수 정의
void SimpleClass::print() {
    std::cout << num1 << " " << num2 << std::endl; // 변수 이름 수정 (num1, num2)
}

 

• Member Initializer

 

멤버 변수를 초기화해주는 기능이다.

class SimpleClass{
private:
    int num1;
    int num2;
public:
    SimpleClass(int n1, int n2);
};

SimpleClass::SimpleClass(int n1, int n2) : num1(n1), num2(n2) { // 변수 초기화
};

 

• this 포인터

 

포인터에서 객체가 만들어졌을 때 자기 자신을 가리킬 수 있다.(생성된 객체의 주소)

class SimpleClass{
private:
   int num1;
   int num2;
public:
   SimpleClass(int num1, int num2){
       this->num1 = num1;
       this->num2 = num2;
   }
};

 

• 상속

 

상속을 통해 적은 코드로 많은 일을 할 수 있고, 중복된 코드도 합칠 수 있다.

 

자식 클래스가 부모 클래스에게 '받아온다'는 개념을 떠올리면 이해하기 쉽다!

보통 Person과 같은 큰 범주가 부모 클래스이고 UnivStudent가 자식 클래스로 상속된다.

 

• Polymorphism(다형성)

 

객체는 하나인데 상황에 따라서 여러가지 종류를 가질 때 사용된다.

 

• Operator Overloading(연산자 오버로딩)

 

+, -, * 등과 같은 연산자의 동작을 재정의해서 클래스에 사용할 수 있도록 하는 기능이다.

 

예시코드

#include <iostream>

class Point {
private:
    double x;
    double y;
public:
    Point(double x, double y) : x(x), y(y) {} // 생성자를 통해 x좌표와 y좌표 초기화

    Point operator+(const Point& p) {  // + 연산자를 오버로딩 하는 함수 정의
        return Point(x + p.x, y + p.y);  // 새로운 Point 객체 반환
    }

    void show() {
        std::cout << x << " " << y << std::endl;
    }
};

int main() {
    Point P1(1, 2);
    Point P2(3, 4); // P1과 P2 객체 생성

    Point P3 = P2.operator+(P1); // 연산자 오버로딩을 직접 호출
    P3.show(); // 출력 결과: 4 6

    Point P4 = P2 + P1; // 연산자 오버로딩 사용
    P4.show(); // 출력 결과: 4 6

    return 0;
}

 

• 배열 인덱스 오버로딩

 

배열 인덱스 연산자 []를 오버로딩하면 배열 요소의 범위를 검사할 수 있다.

음수 인덱스나 배열 범위를 벗어난 인덱스에 접근하는 경우 예외처리를 할 수 있다.

int main(){
    int array[3] = {1, 2, 3};
    
    cout << array[-1] << endl;
    cout << array[-2] << endl;
    cout << array[3] << endl;
    cout << array[4] << endl;
    
    return 0;
}

 

• 템플릿

 

함수나 클래스를 개별적으로 다시 작성하지 않아도 여러 자료형으로 사용할 수 있도록 하게 만들어 놓은 틀이다.

 

함수 템플릿

함수의 일반적인 형태를 정의하고, 특정한 데이터 타입에 대해 작동하도록 일반화된 형태로 작성된다.

 

이 함수는 템플릿으로 정의되었기 때문에 배열의 타입이 무엇이든 상관없이 작동한다.

template<typename T>
T sum(T arr[], int size) {
    T result = arr[0]; 
    for (int i = 1; i < size; ++i) {
        result += arr[i];
    }
    return result;
}

 

클래스 템플릿

클래스의 일반적인 형태를 정의하고, 특정한 데이터 타입에 대해 작동하도록 일반화된 형태로 작성된다.

 

클래스 멤버 함수의 구현을 나타낸 코드

template<typename T>
class Vector {
private:
    T* elements;
    int size;
public:
    Vector(int size) : size(size) {
        elements = new T[size];
    }
};

 

또한 템플릿은 선언과 구현을 분리함으로써 코드의 재사용성을 높일 수 있다.

 

• 예외

 

프로그램 실행 도중에 발생하는 예기치 않은 상황이다.

예를 들어, 0으로 나누기와 같은 상황이나 사용자로부터 나이를 입력받는 상황에서 음수의 값이 입력되는 경우이다.

 

• 예외 처리

 

C++에서는 try-catch 블록을 사용해서 예외를 처리한다. 

 

try : 예외가 발생할 수 있는 코드를 블록으로 지정한다. try 블록 안에서 예외가 발생하면 해당 예외를 처리하기 위해 catch 블록으로 제어가 이동한다.

 

catch : 블록에서 발생한 예외를 처리하기 위한 코드 블록이다.

try{
    // 예외사항이 발생할 수 있는 코드
}catch{
   // 예외사항을 제어할 수 있는 코드
}

 

• throw문

 

에러사항이 발생했을때 호출자에게 예외를 던지는 것이다.

try{
    func();
}catch(type1 exception1){
     // 처리
}catch(type2 exception2){
     // 처리
}
// 이어서 실행

void func(){
   ···
   if(an error)
       throw exception1;
   ···
}

'CS > 자료구조' 카테고리의 다른 글

[자료구조] #6 Stack(2)  (0) 2024.04.19
[자료구조] #5 Stack(1)  (0) 2024.04.16
[자료구조] #3 C++ 문법(1)  (0) 2024.04.14
[자료구조] #2 알고리즘 분석(2)  (0) 2024.04.11
[자료구조] #1 알고리즘 분석(1)  (0) 2024.04.05