Media Log


1. 클래스(class)


클래스란 무엇일까요? 다른 언어를 공부하시다가 '클래스(class)'라는 말을 들어보신 분도, 그렇지 않은 분도 계실겁니다. C++의 클래스는, 쉽게 말하자면 C의 구조체에서 확장된 C++의 구조체의 또다른 이름입니다. 클래스는 변수와 함께 함수까지도 포함시킬 수 있습니다. 그럼, C++의 구조체와 클래스는 다른게 무엇인가요? 라는 궁금증을 품고 계시는 분들도 있을텐데, 구조체와 클래스의 차이점은 기본 접근 제한자의 차이일뿐, 그 이상 다른게 없습니다. 구조체 같은 경우는 기본 접근 제한자가 public이며, 클래스의 기본 접근 제한자는 private으로 제한되어 있습니다. '둘다 동일한 기능을 하면서도 왜 사라지지 않을까요?'에 대한 답은, C언어와의 하위 호완성을 위해서 남겨두었다고 생각하시면 됩니다.


우리가 C언어에서 보았던 구조체 예제에서, struct를 class로만 바꾸어 주어도 됩니다. 조심하셔야 할 부분은 기본 접근자가 달라, 무작정 클래스에 접근하려하면 컴파일러가 에러를 내보낼 수 있습니다. 자, 이제 객체 지향 프로그래밍(OOP, Object-Oriented Programming)의 시작입니다. C언어에서는 구조체였다면, C++에서는 클래스라고 할 수 있습니다. 이제는 클래스 변수를 만든다는 것을 '객체(object)'를 생성한다라고 표현하도록 하겠습니다. 잠시 객체 지향 프로그래밍에 대해 간단히 알아보도록 할까요?


2. 객체 지향 프로그래밍(OOP)


사실, 객체 지향 프로그래밍은 이것만 다루는 책이 있을정도로 상당히 양이 방대합니다. 이번 강좌에서는 간단히 객체 지향 프로그래밍이 무엇인지에 대해 알고 넘어가보도록 하겠습니다. 객체 지향 프로그래밍에선 객체(Object)가 중심이며, 모든 데이터를 객체로 취급합니다.



객체(Object)는 '물건, 물체'라는 뜻을 가지고 있습니다. 우리 눈앞에 보이는 모니터, 마우스, 키보드, 모뎀, 노트북 등 모든게 객체라고 말할 수 있습니다. 심지어 자신 조차도 객체입니다. 이 객체 지향 프로그래밍은, 실세계의 물체, 물건의 행동(behavior)과 상태(state)를 실체화 시키는 형태의 프로그래밍입니다. 전화기를 예로 들면 전화기의 색은 상태이며, 전화를 걸거나 전화를 끊거나 하는 등의 동작은 행동이 됩니다. 또, 자동차를 예로 들자면 자동차의 속도 등이 상태가 될 수 있고, 속도를 올리거나 속도를 내리거나, 브레이크를 밟는 등의 동작은 행동이 됩니다.


위에서 객체는 상태와 행동으로 이루어진다고 했었습니다. 그렇다면 클래스는 무엇일까요? 쉽게 예를 들면, 우리가 붕어빵을 만들어내기 위해서는 붕어빵을 찍어낼 틀이 필요합니다. 여기서 붕어빵을 찍어낼 틀은 클래스라고 할 수 있습니다. 붕어빵 틀(클래스)은 하나만 있어도 붕어빵(객체)를 여러개 찍어낼 수 있습니다. 이해되시나요?


3. 클래스 살펴보기


자, 이제는 클래스를 한번 살펴보도록 하겠습니다. 아래는 클래스의 정의 형식입니다.

class 클래스명 {
   // 멤버 변수(상태), 멤버 함수(행동)..
};

클래스는 상태와 행동 즉, 멤버 변수와 멤버 함수로 이루어집니다. 마지막에 보시면 세미콜론(;)이 존재하는데, 클래스 정의 뒤에 세미콜론을 붙여주어야만 합니다. 아래 예제를 한번 보시죠.

#include <iostream>

using namespace std;

class student {
private:
	char * name;
	int age;
	char * hobby;
public:
	void ShowInfo();
	void SetInfo(char * _name, int _age, char * _hobby);
	void Study();
	void Sleep();
};

void student::ShowInfo()
{
	cout << "이름: " << name << ", 나이: " << age << ", 취미: " << hobby << endl;
}

void student::SetInfo(char * _name, int _age, char * _hobby)
{
	name = _name;
	age = _age;
	hobby = _hobby;
}

void student::Study()
{
	cout << "공부!" << endl;
}

void student::Sleep()
{
	cout << "잠!" << endl;
}

int main()
{
	student stu;

	stu.SetInfo("김철수", 16, "컴퓨터 게임");
	stu.ShowInfo();

	while(true) {
		stu.Study();
		stu.Sleep();
	}

	return 0;
}

결과:

이름: 김철수, 나이: 16, 취미: 컴퓨터 게임

잠!

공부!

잠!

공부!

잠!

..


코드를 살펴보면 5행에 클래스가 정의되었고, 그 클래스 안에 private로 제한된 name, age, hobby란 멤버 변수가 있고, public로 제한된 ShowInfo, SetInfo, Study, Sleep라는 멤버 함수가 존재합니다. 보시면 아시겠지만, ShowInfo는 이름, 나이, 취미를 보여주는 함수이며, SetInfo는 private로 제한된 멤버 변수의 값을 수정하기 위해 존재하는 함수입니다. (private로 제한되면, 외부에서 접근할 수 없습니다.) 41행을 보시면 stu란 '객체'가 만들어지고, 46~49행은 무한 루프로, 공부!, 잠!이 무한 반복됩니다. 
(접근 제한자는 'C++ 강좌 6편. 구조체의 확장'에서 맨 아랫부분에 설명되어 있습니다.)

  인스턴스(Instance)란?
인스턴스(Instance)는 객체(Object)의 또다른 표현입니다.
인스턴스는 객체 지향 프로그래밍에서 객체를 실제로 구성한 것, 즉 어떤 메모리 공간에 구현된 실체를 말합니다. 그럼 객체는 무엇일까요? 객체는 어떠한 대상이나 개념을 하나의 단위로 묶어내는 것, 프로그램의 독립적인 부품을 말합니다. 어떤 책에서는 객체와 인스턴스를 혼용하여 설명하기도 합니다. 인스턴스와 객체를 예로 들면, 학생(student)이란 클래스가 존재하고 초등학교 3학년인 철수와, 초등학교 4학년인 영희가 있다고 할때 '철수는 학생 클래스의 인스턴스이다.', '철수는 학생 객체이다.'라고 말할 수 있습니다. 하지만 객체와 인스턴스는 상당히 유사하지만 '객체 = 인스턴스'는 아니라는 것을 명심해 두시고 계셔야 합니다.

이번 강좌는 여기서 마치도록 하고, 다음 강좌부터는 생성자와 소멸자에 대해 알아보도록 하겠습니다.
  1. KHaltz at 2013.03.27 16:40 신고 [edit/del]

    알기 쉽게 잘 정리해 주셨네요.
    잘 보고 갑니다!

    Reply
  2. Ori at 2013.06.13 18:15 신고 [edit/del]

    인스턴스와 객체에 대하여 다소 헷갈리지만 잘 보고 갑니다!

    Reply
  3. 1234 at 2013.07.29 14:39 신고 [edit/del]

    인스턴스나 객체 모두 physical, logical 속성을 가지고 있지만
    인스턴스는 physical 에 가깝고, 객체는 logical 에 가깝다고 볼 수 있겠네요.

    Reply
  4. 우끼 at 2013.08.02 17:12 신고 [edit/del]

    저 클래스 예제에서 클래스 대신 구조체를 써도 다른 게 없는거맞습니까?

    Reply
  5. BlogIcon at 2014.05.11 11:07 신고 [edit/del]

    void SetInfo(char * _name, int _age, char * _hobby);

    변수앞에 왜 _age와 _는뭔가요?
    그리고 *_name 에서 *은 뭔가요?

    Reply
    • BlogIcon EXYNOA at 2014.05.11 13:55 신고 [edit/del]

      문자열을 매개변수로 넘겨받기 위해 문자 포인터를 썼던 것이며, 식별자 앞에 들어가는 언더바는 매개 변수와 멤버 변수를 구분하기 위한 것입니다. _name, _age가 아닌 다른 이름으로 쓰시고 바꿔주셔도 별 상관이 없습니다.

  6. 9reenw1ch at 2014.06.09 12:42 신고 [edit/del]

    void SetInfo(char * _name, int _age, char * hobby);

    에서 꼭 문자 포인터를 써서 매개변수로 넘겨 받아야 하는건가요?

    배열로 하면 안되는건가요?

    Reply
    • BlogIcon EXYNOA at 2014.06.10 23:30 신고 [edit/del]

      굳이 포인터를 쓰지 않고도 배열을 쓰셔도 됩니다. 그러나 배열을 매개변수로 받을 경우, 자세히 말해서 1차원 배열을 매개변수로 받을 경우에 용량을 명시하여야 하므로 유동적인 값의 입력이 힘들 수 있습니다.

  7. BlogIcon yang at 2014.07.23 16:09 신고 [edit/del]

    잘보고 갑니당

    Reply
  8. at 2014.12.30 13:19 [edit/del]

    비밀댓글입니다

    Reply
  9. Jjo at 2016.09.29 11:01 신고 [edit/del]

    클래스와 구조체 차이는 기본접근제한자 차이 있다고 하셨는데 기존접근제한자만 바꿔주면 서로 바꿔 사용할 수 있는건가요

    Reply
    • asterism at 2017.07.11 19:51 신고 [edit/del]

      접근제한자의 차이를 제외하면 사실상 둘이 똑같긴 합니다. 따라서 Jjo님 말씀대로 사용하셔도 상관은 없지만, 프로그래머들은 굳이 구조체를 사용해서 객체지향 프로그래밍을 하지는 않습니다.

  10. Lovbrand at 2017.01.24 22:57 신고 [edit/del]

    요즘 잘 보고 있습니다. 기초적인 문법 숙지하는데에 정말 좋은 것 같네요. 감사합니다.

    Reply
  11. jung at 2017.04.13 13:59 신고 [edit/del]

    변수 선언할때 char에는 원래 *을 붙이나요?
    그리고 _ 이거는 왜 붙이는건가요?

    Reply
    • vinoo39 at 2017.05.29 22:22 신고 [edit/del]

      변수를 선언할때 char *로 선언한것은
      문자형 포인터를 선언한 것입니다.
      만약에 문자형변수 char로만 선언하면 오류가 뜰것입니다.
      43행에서 setinfo라는 메소드에 "김철수"라는 문자열을 매개변수로 넣어주죠.
      여기서 중요한 것은 문자가 아닌 문자열이라는 겁니다.
      선언한 변수가 char라면 문자열을 넣을 수 없습니다.
      하지만 char *로 선언하면 문자열을 넣었을 때에 포인터 name에 첫번째 주소부터 null이 나올때까지 읽게됩니다.

      두번째 _를 붙인 이유는 크게 없습니다.
      함수를 정의 할때 매개변수의 이름은 자유입니다.

      제 생각에는 위에 클래스대한 내용을 공부하기 전에 포인터와 함수에 대해 공부하는 것이 좋을 것 같습니다.

  12. JH at 2018.02.25 17:06 신고 [edit/del]

    똑같이 복붙을 헀는데 오류가뜨네요 왜 그런지 이유를 알 수 있을까요?

    Reply
  13. Heon at 2018.03.27 11:39 신고 [edit/del]

    비주얼 스튜디오 2017을 사용하고 있습니다. c++에서 실행중 에러가 나타났는데
    C2664 코드에 'void student::SetInfo(char *, int, char *)': 인수 1을 'const char [7]'에서 'char * '으로 변환할 수 없습니다. 라는 설명과 함께 나타납니다.
    검색해 보았을떄는 프로젝트 속성 - 구속속성 - 일반 - 문자 집합을 '사용 안 함'이라고 변경하라 해서 변경했는데도 같은 오류가 뜹니다. 왜 이 오류가 뜰까요..ㅠㅠ

    Reply
  14. PARK at 2018.05.16 18:35 신고 [edit/del]

    JH 님과 Heon과 같은 오류네요... 이유가 뭘까요? ^^;;;;

    Reply

submit

티스토리 툴바