• 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 |