TIl 2024/8/02

Sung Joo Lee·2024년 8월 2일

Class Member Access Modifier

  • 정보 은닉을 위해 멤버 접근을 제한할 수 있음

  • 클래스 멤버 접근 제한자

    • public
      • 어디서든 접근 가능
    • private
      • 클래스의 멤버 ,friend 클래스에만 접근 가능
    • protected
      • 상속된 클래스의 객체에서만 접근 가능 (상속 강의에서 설명 예정)
#include <iostream>

class Player
{
public: //어디서나 접근이 가능

//private: // 클래스 멤버들만 접근이 가능

	std::string name;
	int health;
	int xp;

};

int main() {

	Player* p1 = new Player();//heap에 객체 생성
	p1->health = 10;/*heap에 생성된 객체를 
					접근 할 때는 포인터로 접근하기 때문에
					*,->를 사용하여 접근한다.*/

	Player p2;//stack에 생성
	p2.health = 20; //.로 접근

	delete p1;
}

private을 봐보자

#include <iostream>

class Player
{
public:
	std::string name;

private:

	int health;
	int xp;

};

int main() {

	Player* p1 = new Player();//heap에 객체 생성
	p1->health = 10;//접근 불가능

	Player p2;//stack에 생성
	p2.name = "Joe";//접근 가능	
	p2.health = 20; // 접근 불가능

	delete p1;
}
  • 즉, private는 class 내부의 멤버들만 접근이 가능하다

  • private 멤버에 접근하기 위해서는 public 멤버 함수가 필요

다 public으로 하면 안되나요?

  • 멤버에 직접 접근하는 것이 오류를 초래할 수 있음
  • 게임에서 플레이어의 체력이 100이 상한선인데, 실수로 1000을 할당해버린다면?
    • 이런 실수를 방지하기 위함
#include <iostream>

class Player
{
public:
	std::string name;

private:

	int health;
	int xp;

};

int main() {

	Player* p1 = new Player();//heap에 객체 생성
	p1->health = 10;//접근 불가 err

	Player p2;//stack에 생성
	p2.health = 20; //접근 불가 err

	delete p1;
}
#include <iostream>

class Account
{
public:

	void Withdraw(double amount) //출금
	{
		if (balance - amount < 0) //오류방지
			return;

		balance -= amount;
	}
	void Deposit(double amount) //입금
	{
		balance += amount;
	}

private:

	std::string name;
	double balance = 100.0; //계좌 잔액
};

int main()
{
	//객체의 생성
	Account kimAccount;
	Account leeAccount;

	kimAccount.Withdraw(100);

	return 0;

}
  • 위의 코드와 같이 우리가 프로그램에서 오류를 발생 시킬 수 있는 데이터에 직접적인 접근을 막아 오류 발생 가능성을 없앤다.

예시)

내 통장에 100원이 있는데 10000원을 출금한다면 오류가 발생 할 것이다. 하지만 직접적인 접근을 막고 public Method에 예외처리를 해준다면 오류가 발생하지 못 할것이다.

멤버 함수의 구현

  • 기존 함수의 구현과 유사

  • 멤버 변수에 접근이 가능하기 때문에 인자로 전달할 데이터가 적어짐

  • 클래스 선언 내에 구현 가능

    • inline 구현
  • 클래스 선언 외부에서도 구현가능

    • ClassName::methodName
  • 명세와 구현의 분리

    • 클래스의 선언헤더파일에 작성
    • 클래스의 구현cpp파일에 작성
  • 클래스 메소드를 외부에 구현

#include <iostream>

class Account
{
public:

	void setBalance(double bal);//prototype
	double getBalance();

private:

	double balance;
};

void Account::setBalance(double bal) {
	balance = bal;
}

double Account::getBalance() {
	return balance;
}

returnType ClassName :: MethodName( ) 을 기본형으로 한다.

  • 일반 함수와 동일하게 생각하면 된다. 반환형을 적어주고 함수를 적어주는데 “이 때 이 함수가 어디서 정의된 함수인지 알아야 하기 때문에” 앞에 ClassName을 적어주고 :: 를 사용한다.

  • 이제 명세와 구현을 분리해서 봐보자!

  • AccountOuside.h
    • 보통 클래스의 이름으로 제목을 만들지만 강의를 따라가는 입장이라 다른 이름을 만들어서 했다.

    • 클래스의 선언

    • #pragma once라는 코드는 중복 해더파일을 방지하기 위해서 작성됨

      #pragma once
      #include <string>
      
      class Account
      {
      public:
      	void Deposit(double amount);
      private:
      
      	double balance;
      	std::string name;
      };
  • AccountOutside.cpp
    • 클래스 메소드의 구현을 작성하면 된다.
#include "AccountOutside.h"

void Account::Deposit(double amount) {
	balance += amount;
}
  • AccountOutsideMain.cpp
    • 메인 코드

      #include <iostream>
      #include "AccountOutside.h"
      
      int main()
      {
      	//객체의 생성
      	Account kimAccount;
      	Account leeAccount;
      
      	return 0;
      
      }
      

구조체와 클래스

  • CPP에서는 구조체와 클래스 모두 사용가능

  • 문법적으로는 , 기본 접근 권한의 차이 외에는 차이점이 존재하지 않음

    • 클래스 : 명시되어 있지 않으면 private이 기본 값
    • 구조체 : 명시되어 있지 않으면 public이 기본 값

구조체와 클래스 사용 가이드라인

  • 구조체

    • public 접근이 필요한 데이터로 사용
    • 멤버 함수를 구조체 안에 설정하지 않은 것을 권고
      • 멤버 함수가 있다면 class로 구현
  • 클래스

    • Private 멤버 변수와 멤버 함수
    • 멤버 함수를 통해서 멤버 변수에 접근하도록 get/set 구현
profile
개발로그

0개의 댓글