본격적인 객체 지향 프로그래밍의 시작이다. 클래스를 선언하고 초기화하고 사용하는 법까지 account라는 Class를 통해 알아보도록 하자.
헤더 파일
먼저 class를 선언하는 곳은 소스 파일이 아닌 헤더 파일이라는 사실이 중요하다. 그 이유는 클래스를 헤더 파일에 선언함으로써 코드의 재사용성, 가독성, 유지 보수성을 높일 수 있고, 컴파일 타임 최적화와 컴파일 시간 단축을 이룰 수 있기 때문이며, 객체 지향 프로그래밍의 핵심 중 하나이다.
우리가 만들 account라는 클래스는 다음과 같은 구조를 가진다.
1. 계좌의 잔액
2. 계좌의 잔액을 로그에 출력하는 메서드
3. 계좌의 잔액을 다른 계좌에 전달하는 메서드
// account.h
class account {
int balance;
public:
account(int initial_balance = 0) : balance(initial_balance) { }
int get_balance() const { return balance; }
void transfer_to(account& other, int money);
};
What is public?
객체 지향 프로그래밍의 목적에는 캡슐화가 있다. 캡슐화는 관련된 데이터와 기능을 한 번에 묶어 외부에 노출되지 않도록 하는 것인데, 이를 통해 클래스의 내부 구현사항을 숨길 수 있고, 따라서 정보 은닉이 가능하다. 위 코드에서 public 아래로 작성되는 코드들이 유저 입장에서 해당 클래스를 사용할 때 접근할 수 있는 최대치라고 볼 수 있다. 유저는 account 클래스를 통해 account 객체 초기화, 잔액 반환, 송금과 같은 실행을 할 수 있다.
객체를 초기화하는 방법도 마찬가지로 유저의 접근이므로, public 내에 선언되어야 한다. account 클래스의 생성자는 초기 잔액(initial_balance)을 인자로 받아 멤버 변수 balance를 초기화하는 역할을 한다. 만약 초기화 없이 선언만 하면, 미리 지정해 둔 0으로 잔액이 설정된다.
이어서는 두 가지 메서드가 정의되어 있는데, get_balance()와는 다르게 transfer_to()는 반환 타입, 메서드의 이름, 인자만 작성되어 있고 바디가 없다. 관습적으로 헤더 파일에서 클래스의 메서드를 정의할 때에는 코드가 한 줄로 끝나는 간단한 경우에만 inlining으로 작성해 준다. inlining이란 메서드를 호출하는 것이 아닌 필요할 때마다 해당 코드를 읽는 방식으로 사용되는데, 이는 성능 중점인 애플리케이션에서는 유용하게 사용된다. 그럼 transfer_to()의 바디는 어디에 작성할까? 바로 해당 클래스를 객체로 선언할 소스 파일에서 작성해 주면 된다.
소스 파일
// account.cpp
#include "account.h"
void account::transfer_to(account& other, int money) {
this->balance -= money;
other.balance += money;
}
소스 파일에서는 해당 헤더파일을 include 해주고, 함수 작성에는 반드시 double colon(::)으로 해당 함수의 소속을 정의해 준다. 바디 내에 있는 this는 현재 객체를 가리키는 포인터이므로 화살표(->)로 멤버 변수에 접근하고, other은 단순한 객체이므로 점(.)으로 멤버 변수에 접근한다는 차이점이 있다.
using namespace std;
int main() {
account baek(100000);
account lee = 50000;
cout << baek.get_balance() << endl; // output: 100000
baek.transfer_to(lee, 25000);
cout << baek.get_balance() << endl; // output: 75000
cout << lee.get_balance() << endl; // output: 75000
return 0;
}
다음은 메인 함수에서 두 객체를 초기화하고 객체 간 값을 전달하는 코드이다. 두 객체의 초기화의 방식이 다른데 이는 여러 클래스를 선언하고 초기화해 보면서 저절로 이해하게 될 것이다.
이렇게 객체 지향 프로그래밍의 시작인 클래스의 선언, 초기화, 그리고 사용에 대해 알아보았다. 보다 심화적인 개념들도 차차 다뤄볼 예정이다. 비슷하게 연습해 볼만한 예제인 복소수(complex) 클래스를 추가로 남기며 글을 마친다.
Exercise : complex
// complex.h
#include <iostream>
using namespace std;
class complex {
double r, i;
public:
complex(double r, double i) : r(r), i(i) { }
void print() { cout << r << " + " << i << 'i' << endl; }
double magnitude() const { return sqrt(r*r + i*i); }
};
// or you can extract magnitude() to your source file like
// complex.cpp
double complex::magnitude() const {
return sqrt(r * r + i * i);
}
'Computer Science and Engineering > OOP (Object Oriented Programming)' 카테고리의 다른 글
[Syntax, C++] Reference(&) - 참조란? (0) | 2023.05.22 |
---|---|
[Syntax, C++] struct, enum, union을 활용하여 계산기 구현하기 (0) | 2023.05.02 |
[Syntax, C++] struct를 활용하여 다각형의 둘레의 길이 구하기 (0) | 2023.04.27 |
[Syntax, C++] struct, enum class를 활용하여 날짜(D - day) 계산하기 (0) | 2023.04.27 |
[Syntax, C++] Array에서의 Pointer (0) | 2023.03.21 |