기초지식

10. 클래스

로만주 2023. 5. 20. 11:57

▶ 클래스

객체 지향의 선봉장이다.

 

- 속성에 해당하는 필드(변수)와 행위에 해당하는 메서드(함수)의 집합을 클래스라고 한다.

ㄴ 클래스를 이용하면 데이터 뿐만 아니라 함수를 특정 집합에 포함하는 게 가능하다.

특정 집합 == 이름이 있는 클래스(객체)

 

▷ C / C++ 언어의 클래스 선언 방법

클래스 안에 있는 변수들을 필드라고 부름

 

- C / C++ 언어의 클래스는 접근 제어 지시자를 이용해서 변수 또는 함수에 접근 할 수 있는 영역을 제한하는 것이 가능하다.

 

▶ 클래스의 접근 제어 지시자

 

1. private: 클래스에 포함된 함수에서만 접근이 가능하도록 허용

 

- 이 속성을 가지는 멤버는 외부에서 엑세스 할 수 없으며 구조체의 멤버 함수만 엑세스 할 수 있다.

 

- 외부에서는 private 멤버를 읽을 수 없음은 물론이고 존재 자체도 알려지지 않는다.

 

3. public: 어디서든 접근이 가능하도록 허용

 

- 이 속성을 가진 멤버는 외부로 공개되어 누구나 읽고 쓸 수 있으며 함수의 경우에는 호출까지 가능하다.

 

- 클래스가 자신의 속성이나 동작을 외부로 공개하는 수단이 되며 public 멤버를 소위 "interface"라고 부른다.

 

3. protected: 상속 관계에 있을 때 자식 클래스에서 부모 클래스에 접근하도록 허용

 

- private과 마찬가지로 외부에서는 엑세스 할 수 없으나 상속된 파생 클래스는 이 멤버를 엑세스 할 수 있다는 차이점이 존재

 

- private 멤버는 파생 클래스에서 조차 참조 할 수 없으며 오로지 자신만이 이 멤버를 참조 할 수 잇다는 점에서 차이점이 발생한다.

 

(4. internal)

ㄴ pirvate과 public의 중간 형태로 어셈블리 내에 상속 클래스에서만 접근이 가능.

ㄴ 동일 어셈블리 안이라면 public / 밖이라면 private

 

★★★★★

 

- 클래스는 객체의 안전성을 위해 외부에서 함부로 값을 건드리지 못하도록 멤버를 숨기는 경향이 있지만 구조체는 가급적으로 멤버를 공개하려는 경향이 있다.

 

- 구조체의 디폴트 엑세스 지정이 public일 수 밖에 없는 이유는 C언어와의 호환성 때문이다.

 

- 면접 사골+사골 질문

ㄴ 구조체와 클래스의 차이점에 대해서 말해보시오.

C++ / C# 어떤 기준으로 대답할 지 되묻기로 하는 것이 좋다.

 

- 구조체의 멤보는 public 속성을 가지며 외부에 공개되지만 클래스의 멤버는 private 속성을 가지기 때문에 외부로부터 숨겨진다.

 

※ 이러한 클래스의 특징 때문에 접근 제어 지시자를 명시하지 않아도 private이 기본으로 설정된다.

 

- C++11 부터는 클래스의 멤버 변수의 선언과 동시에 초기화를 시킬 수 있는 기능이 추가됐다.

 

추가가 되면서 멤버 이니셜라이저를 이용하지 않더라도 심볼릭 상수 등을 초기화 하는 것이 가능하다.

ㄴ 던, 상속 관계와 클래스가 많아질수록 잠재적인 오류를 발생시킬 여지를 가지고 있다.

 

- 생성자: 주로 멤버 변수의 값을 원하는 값으로 대입하는 작업을 한다.

ㄴ 그 외에도 객체가 동작하는데 필요한 모든 초기화 처리를 담당하기도 한다.

 

- 소멸자: 객체가 바꿔놓은 환경을 원래대로 돌려 놓거나 할당한 자원을 회수하는 역할을 한다. (동적 메모리 해제)

MainGame.cpp
#include "MainGame.h"
#define MAX_ITEM 100
enum EItem
{
	아이템
    리스트
};

class PlayerInfo
{
private:
	int x, y;
    int hp;
    int shield;
    int level;
    double exp;
    EItem items[MAX_ITEM];
    
public:
	void walk();	//◇ 다르 객체와 연동 된다는 가정이 잇어 확장성을 위해 public에서 선언
    void junp();
    void turn(int dir);
    void defence();
    bool attack(int what);
    bool hurt(int fromwho);
    bool die();
};

void main()
{
	MainGame mg;
    mg.output();
    cout << '\n';
    MainGame* mainG = new MainGame;
    // ◇ 포인터연산자 없을 경우 주소를 알 수 없다고 하여 오류를 띄움.
    mainG->showPosition();
    mainG->setPosition(100, 100);
    mainG->movePosition();
    mainG->movePosition();
    mainG->movePosition();
    
    delete mainG;
}

MainGame.h
#pragma one
#incdlue <iostream>

using namespace std;

class CUnit
{
private:
	int m_ID;
    std::string m_Name;
    
    void setInfo(int m_ID, std::string m_Name);
    
    void printInfo(void);
};

struct tagPlayer
{
public:
	int hp;
    int mp;
};

struct Mystruct
{
private: // ◇ 규모가 작지만 데이터를 묶고 캡슐화가 필요할 때 접근 제어 지시자를 사용.
};

class MainGame
{
private:
	int _Number;
    int _x;
    int _y;
    // ◇ 클래스는 헤더 파일에서 선언만 한다. / 선언부와 초기화 부분은 나눠야 함.
    // ◇ 상속이라는 것에 엮이면 선언과 초기화를 동시에 하면 모호함이 발생 할 수 있음.
	int m_nID = 0;
    std::string m_oName = "";
    
    const int m_nConstValue = 0;
    // ◇ const 변수를 명시하기 위해 바로 초기화 하는 경우가 많다.
    
public:
	MainGame();		//생성자
    ~MainGame();	//소멸자
    void output();
    void showPosition(void);
    void movePosition(void);
    void setPosition(int x, int y);
};