안녕하세요! 코딩하는 경제학도 쏘코입니다.
오늘 포스팅은 객체지향의 꽃, 클래스입니다.
먼저 기본적으로 제공되는 Standard Class를 알아본 후에 직접 만드는 Custom Object에 대해서 알아보도록 하겠습니다.
목차
0. 기본 C++ 클래스
0.0. String
문자(char)는 모여서 문자열(string)을 만듭니다.
C에서는 char을 배열처럼 만들고, char*를 이용하여 사용했는데,
C++에서는 조금 더 편리하게 string이라는 클래스를 이용하여 사용할 수 있습니다.
String 클래스에 들어있는 내장 함수입니다.
개인적으로 size와 [], = 정도를 제일 많이 사용하는 것 같습니다 ㅎㅎ
=와 +=를 사용한 예시입니다.
operator를 함수처럼 사용해도 되고, 연산자만 사용하여도 똑같이 사용할 수 있습니다.
0.1. Input/Output Streams
너무나도 자연스럽게 사용했던 입출력함수인 cin, cout 역시 class입니다.
많이 쓰지는 않지만 cin과 cout에도 내장 함수가 존재합니다.
0.2. File Streams
일반적인 입출력 이외에도, 파일에 자료를 입력하고, 파일의 자료를 출력할 수도 있습니다.
ifstream(파일읽기) 혹은 ofstream(파일쓰기)를 사용하면 됩니다.
두 클래스를 사용하기 위해서는 fstream을 전처리 과정에서 include를 해야합니다.
이번 포스팅에서는 클래스를 이해하는 것이 가장 주된 목적이기 때문에, File Streams 요소들의 내장 함수들은 자세하게 살펴보진 않겠습니다!!
0.3. 복소수
복소수(complex)형태의 요소들도 하나의 클래스입니다.
복소수 클래스 안에도 다양한 연산기호들이 이미 내장되어 있기 때문에 그대로 사용만 하면 됩니다!
1. 사용자 정의 클래스
1.0. 클래스의 기초
명색이 객체지향프로그래밍 포스팅인데, 객체에 대해서 명확하게 정의가 되지 않았죠?
객체는 소프트웨어 세계에 구현할 대상이고, 이를 구현하기 위한 설계도가 클래스이고, 이 설계도에 따라 소프트웨어 세계에 구현된 실체가 바로 인스턴스입니다.
실제로는 객체와 인스턴스는 상당부분 혼합되서 사용되기도 합니다.
이 객체를 만들기 위한 클래스를 한번 뜯어보도록 하겠습니다.
클래스의 구조는 아래와 같습니다.
클래스명 { }
형식으로 만들 수 있습니다.
클래스명의 특징은 첫 글자가 대문자로 시작해야 한다는 점입니다.
사용자들 사이에서의 규칙이기 때문에 되도록이면 지켜주시는 것이 좋습니다. (C++ 뿐만이 아닌 다른 언어에서도 마찬가지입니다!)
그리고 클래스가 끝나면 맨 끝에 ;를 넣어줍니다!
클래스 내부는 일반 변수와 내장 함수로 구성됩니다.
변수나 함수의 경우 .을 통해 접근할 수 있습니다. (Public인 경우 한정입니다!)
위 사진에서는 public:에 걸려있기 때문에 문제가 없지만, private: 안에 걸려있다면 .으로 불러올 수 없습니다.
특히 public: 아래에 있지 않다면 자동으로 private:으로 처리되기 때문에 주의해야 합니다.
보통 이런 경우 클래스 내부에 get, set 함수를 만들어서 해결하는데, 이 부분은 추후에 설명하도록 하겠습니다.
아래는 Account 함수입니다. 예금을 위한 deposit 내장함수, 출금을 위한 withdraw 내장함수가 public에 있고, private 변수들은 public: 위에 설정되어 있습니다.
이렇게 public: 아래에 있지 않은 일반 변수들의 경우 class의 외부에서는 .으로 접근할 수 없습니다.
내장함수의 경우 public:의 아래에 위치하여 언제든지 사용할 수 있도록 만들어주는 것이 좋습니다.
아래는 Counter이라는 클래스를 만들었습니다.
count는 private한 변수이고, 나머지 내장함수들은 public이기 때문에 main함수 내에서 사용할 수 있습니다.
1.1. 생성자
만약 클래스를 이용하여 객체를 만들 때 바로 초기화를 해 주고 싶다면 어떻게 할까요?
이럴때 이용하는 것이 바로 생성자입니다.
생성자는 클래스명(매개변수) {명령문} 형태로 만들 수 있습니다.
생성할 때 위 규칙에 따라 매개변수를 넣으면 명령문이 매개변수를 이용하여 명령을 처리하는 형식이죠.
생성자는 모든 클래스에 반드시 필요하지만, 굳이 따로 만들어주지 않아도 컴파일러가 자동으로 빈 생성자를 만들어줍니다.
그래서 초기화가 필요가 없는 클래스의 경우 따로 생성자를 만들어주지 않아도 무방합니다.
아래 예시는 Account 클래스를 조금 더 확장한 모습입니다.
public 바로 아래의 Account~(8번째 문장)이 생성자입니다!
코드가 길기 때문에 따로 첨부합니다!
// Constructors are called when an instance of a class is created.
// A constructor has the same name as the class.
// A constructor has no return type (not even void).
#include <iostream>
#include <iomanip>
#include <string>
class Account {
std::string name; int id;
double balance;
public:
Account(const std::string& customer_name, int account_number,
double amount) : name(customer_name), id(account_number),
balance(amount)
{
if (amount < 0) {
std::cout << "Warning: negative account balance\n";
balance = 0.0;
}
}
void deposit(double amt) {
balance += amt;
}
bool withdraw(double amt) {
bool result = false;
if (balance - amt >= 0) {
balance -= amt;
result = true;
}
return result;
}
void display() {
std::cout << "Name: " << name << ", ID: " << id
<< ", Balance: " << balance << '\n';
}
};
int main() {
Account acct1("Joe", 2312, 1000.00);
Account acct2("Moe", 2313, 500.29);
acct1.display(); acct2.display();
std::cout << "---------------------" << '\n';
acct1.withdraw(800.00);
acct2.deposit(22.00);
acct1.display(); acct2.display();
}
// constructor initialization list “:” , reference or const member
// A class must have at least one constructor, either defined by the
// program or by the compiler.
// The default constructor is called whenever an object is created
// without passing any arguments.
// If you define any type of constructor, you must also define a
// default constructor if it is needed.
매개변수를 어떻게 받냐에 따라 초기화를 다르게 할 수도 있습니다.
아래 예시에서는 생성자가 2번 등장하는데, 매개변수가 다릅니다.
매개변수를 2개 넣으면 numberator변수에 n, denominator변수에는 d가 들어가게 되고,
매개변수를 넣지 않으면 numberator변수에 0, denominator변수에 1이 들어가게 됩니다.
1.2. 캡슐화
위에서 public, private에 대한 이야기를 했죠?
왜 이렇게 외부에서 접근할 수 있는 요소/함수와 외부에서 접근할 수 없는 요소/함수로 나누었는지 궁금할 수 있습니다.
이것은 클래스의 보안성과 모듈화 때문인데요,
사용자에게 굳이 보여줄 필요가 없는 부분, 다른 클래스에 의해 바뀌지 않아야 하는 부분, 혹은 보안에 신경써야 하는 부분은 함부로 접근하지 못하도록 막아놓을 필요가 있을 수 있습니다.
누군가 DB에 접근하여 내 주민등록번호를 막 바꿔버리면 안되잖아요? (보안성)
아니면 개명처리를 하다가 주민등록번호가 바뀌면 안되잖아요? (모듈화)
그런 경우에는 private한 영역에 만들어주고, 그렇지 않은 경우에는 public에 작성합니다.
오늘 내용은 클래스의 기초적인 내용이었습니다!
다음 포스팅에서는 클래스를 조금 더 상세하게 다루는 방법에 대해서 알아보도록 하겠습니다!
오늘도 읽어주셔서 감사합니다 :) 좋은 하루 되세요!!
최근댓글