C++ - 클래스
C++ 클래스
1. 개요
기본적으로는 특정 객체를 생성하기 위한 틀과 같다.
클래스를 정의하고 해당 클래스로 객체를 만들어야 비로소 사용할 수 있다.
기본적으로 객체 지향 프로그램에서 빠질 수 없는 기본중의 기본으로 C++에서도 당연히 클래스를 지원한다.
C++ 에서 클래스는 두가지 관점으로 나눠서 생각할 수 있는데, 값처럼 사용하는 것이 첫번째고 처리를 위한 것이 두번째이다.
값처럼 사용하는 클래스는 std::string,std::vector 와 같은 것들이고, 처리를 위한 클래스는 std::iostream 과 같은 것을 말한다.
사실 이 포스팅의 목적이 객체 지향 프로그래밍이 무엇인가에 대해서 쓰려는게 아니라, 코딩할때 그거 어떻게 쓰더라?할때 빠르게 확인하기 위함이라, 객체 지향에 대해서는 깊게 설명하지 않는다.
2. 사용법
1) Class 선언과 정의
기본적인 선언 방식은 아래와 같다.
1
class MyClass;
미리 선언해두고 별도로 정의해도 되고 정의만 미리 해두어도 괜찮다.
아래와 같이 정의하면 된다.
1
2
3
class MyClass{
// do something;
}
중괄호 내에 여러 가지가 들어가게 되는데 그 부분은 아래에서 추가적으로 설명하겠다.
2) 멤버 변수
멤버 변수를 선언하는건 어렵지 않다. 어떤 형태의 타입이든 변수로 사용할 수 있는 자료형이면 가능하며 접근 제어 수준(public,private,protected)만 결정해서 해당 label 아래에 선언해주면 된다.
1
2
3
4
5
6
7
8
class MyClass{
public:
// do something
private:
int a = 0;
std::string data = "check";
float f = 1.2;
}
3) 멤버 함수, 메소드
해당 클래스내에 선언된 함수이다. 선언 후에 따로 정의할 수 있으며, 정의와 선언을 같이 할 수도 있다.
a. 클래스 블록 내에 함수를 정의하는 경우
1
2
3
4
5
6
7
8
9
class MyClass{
public:
// do something
void setA(int n){a = n;};
private:
int a = 0;
std::string data = "check";
float f = 1.2;
}
b. 클래스 블록 밖에 함수를 정의하는 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass {
public:
void sayHello(); // 선언
int add(int a, int b); // 선언
};
void MyClass::sayHello() { // 정의
std::cout << "Hello from MyClass!" << std::endl;
}
int MyClass::add(int a, int b) { // 정의
return a + b;
}
4) 생성자
클래스는 일종의 틀과 같은 것이라 실제로 사용하려면 객체를 만들어야한다.
이 객체를 만드는 과정에서 자동으로 실행되는 함수가 바로 생성자이다.
이 생성자는 함수 이름과 동일해야하며, 인자를 받음으로써 객체가 생성될때 기본적으로 필요한 값을 받아 멤버 변수들을 초기화 할 수 있다.
기본적으로 아래은 형태로 선언이 가능하다.
1
2
3
4
5
{클래스 이름} ( );
{클래스 이름}::{클래스 이름} ( ) { body }
{클래스 이름}() = default;
{클래스 이름}::{클래스 이름} ( ) = default;
{클래스 이름}() = delete;
또한 이 생성자는 public에 위치한다.
1
2
3
4
class MyClass{
public:
MyClass();
}
5) 소멸자
변수들도 수명이 있듯이 이 객체 또한 수명이 있다.
명시적으로 없어지거나 혹은 묵시적으로 없어지거나 하는 것인데, 이 때 실행되는 함수가 바로 소멸자이다.
반환값도 없고 인자도 없으며, 객체가 스코프를 벗어나거나 delete 될 때 호출된다.
1
2
3
4
class MyClass{
public:
~MyClass();
}
대부분 소멸자 사용시 내부 자원해제를 위한 delete나 close 등의 처리에 사용된다.
※ 특수 함수
생성자와 소멸자 같은 특수한 함수들은 특수 함수라고 하며, 이외에 복사생성자(copy constructor), 이동생성자(move constructor), 복사대입연산자(copy assignment operator), 이동대입연산자(move assignment operator)등이 있다.
이러한 특수함수들은 클래스 구현시 특별히 정의하지 않는다면 객체 정의시 컴파일러가 필요한 것을 보고 자동으로 만들어준다.
생성자와 소멸자를 제외한 특수한 함수에 대한 간략한 설명은 아래와 같다.
a 복사생성자
다른 객체를 복사하여 새 객체를 생성할 때 호출한다.
1
2
3
4
class MyClass {
public:
MyClass(const MyClass& other); // 복사 생성자
};
b. 이동생성자
소유권을 다른 객체로 이동하여 새 객체를 생성할 때 호출한다.
1
2
3
4
class MyClass {
public:
MyClass(MyClass&& other);
};
c. 복사대입연산자
기존 객체에 다른 객체를 복사 대입할 때 호출한다.
1
2
3
4
class MyClass {
public:
MyClass& operator=(const MyClass& other);
};
d. 이동대입연산자
기존 객체에 다른 객체의 소유권을 이동 대입할 때 호출한다.
1
2
3
4
class MyClass {
public:
MyClass& operator=(MyClass&& other);
};
※ public? private? protected?
멤버 변수와 멤버 함수들은 해당 클래스에 소속되어있다.
이때 이 변수와 함수들은 클래스 내에서만 사용되야할 것들이 있다.
이럴 때 private를 사용하면 된다.
정확하게 표로 정리하여 보면 아래와 같다.
접근 | public | protected | private |
클래스 내부 | O | O | O |
상속 받은 클래스 | O | O | X |
클래스 외부(클래스 인스턴스를 통한 접근) | O | X | X |