[c++] 클래스의 완성

조히·2023년 5월 4일
0

정보은닉

제한된 방법으로의 접근만 허용을 해서 잘못된 값이 저장되지 않도록 도와야 하고, 또 실수를 했을 때, 실수가 쉽게 발견되도록 해야 한다.

멤버변수를 prive 선언, 해당 변수에 접근하는 함수(엑세스 함수)를 별도로 정의
→ 안전한 형태로 변수의 접근을 유도하는 것이 바로 정보은닉

엑세스 함수 : 클래스 외부에서 멤버변수 접근을 목적으로 정의되는 함수

const 함수 : 이 함수 내에서는 멤버변수에 저장된 값을 변경하지 않는 것을 선언, 이 함수 내에서는 const가 아닌 함수의 호출이 제한
→ 코드의 안정성이 높아짐
int GetX() const;
int GetY() const;
void ShowRecInfo() const;

캡슐화

하나의 목적 하에 둘 이상의 기능이 모여 하나의 목적을 달성하기 위함
관련 있는 함수와 변수를 하나의 클래스 안에 묶는 것

캡슐화의 범위를 결정하는 일은 쉽지 않다

캡슐화는 기본적으로 정보은닉을 포함하는 개념

생성자

생성자를 이용해 객체를 생성과 동시에 초기화할 수 있음

class SimpleClass
{
private:
	int num;
public:
	SimpleClass(int n) // 생성자
    {
    	num=n;
    }
    int GetNum() const
    {
		return num;
    }
}

생성자의 형태 : 클래스의 이름과 함수의 이름이 동일,
반환형이 선언되어 있지 않으며, 실제로 반환하지 않음
객체 생성시 딱 한번 호출

객체생성과정에서 자동으로 호출되는 생성자에게 전달할 인자의 정보를 추가
SimpleClass sc;SimpleClass sc(20);
SimpleClass *ptr = new SimpleClass;SimpleClass *ptr = new SimpleClass(30);

  • 생성자도 함수의 일종이니 오버로딩 가능
  • 생성자도 함수의 일종이니 매개변수에 '디폴트 값' 설정 가능

매개변수가 없는 생성자를 이용해 객체 생성시 SimpleClass sc1;과 같이 소괄호 생략
소괄호는 밑과 같은 함수의 원형선언에만 사용

SimpleClass(int n1=0, int n2=0)
{
	num1=n1;
    num2=n2;
}

멤버 이니셜라이저

멤버 이니셜라이저를 이용한 멤버 초기화 : 멤버변수로 선언된 객체의 생성자 호출에 활용
:upLeft(x1, y1), lowRight(x2,y2) : 객체 upLeft 생성과정에서 x1과 y1을 인자로 전달받는 생성자 호출, 객체 lowRight 생성과정에서 x2와 y2를 인자로 전달 받는 생성자 호출

객체의 생성과정

  • 1단계 : 메모리 공간의 할당
  • 2단계 : 이니셜라이저를 이용한 멤버변수(객체)의 초기화
  • 3단계 : 생성자의 몸체부분 실행

멤버 이니셜라이저를 이용한 변수 및 const 상수(변수) 초기화 : 객체가 아닌 멤버변수도 초기화 가능
num1(n1) : num1을 n1의 값으로 초기화

  • 초기화의 대상을 명확히 인식 가능
  • 성능에 약간의 이점 : 선언과 동시에 초기화가 이뤄지는 형태의 바이너리 코드 생성
  • const 변수는 선언과 동시에 초기화해야 하므로 이니셜라이저를 이용해 초기화
  • 참조자도 선언과 동시에 초기화가 이뤄져야 하므로 이니셜라이저를 이용해 초기화

디폴트 생성자

객체가 되기 위해서는 반드시 하나의 생성자가 호출되어야 함
→ 생성자 정의가 없는 클래스에는 컴파일러에 의해 디폴트 생성자가 자동 삽입

디폴트 생성자는 인자를 받지 않고, 내부적으로 아무런 일도 하지 않음

AAA *ptr = new AAA;와 같은 new를 이용한 객체 생성에도 생성자 호출
그런데,
AAA *ptr = (AAA*)malloc(sizeof(AAA));와 같은 malloc 함수호출시 생성자 호출이 안됨
객체 동적 할당시 반드시 new 연산자 이용

매개변수가 void형으로 선언되는 디폴트 생성자는, 생성자가 하나도 정의되어 있지 않을 때만 삽입
→ 다른 형태로 객체생성이 불가능

private 생성자

객체의 생성이 클래스 외부에서 진행되면 public 선언
객체의 생성이 클래스 내부에서 진행되면 private 선언

소멸자

소멸자의 형태 : 클래스의 이름 앞에 ~가 붙은 형태의 이름,
반환형이 선언되어 있지 않으며, 실제로 반환하지 않음,
매개변수는 void형으로 선언되어야 하기 때문에 오버로딩도, 디폴트 값 설정도 불가능
~AAA() {...}

소멸자는 객체소멸 과정에서 자동으로 호출
직접 소멸자를 정의하지 않으면, 디폴트 생성자와 마찬가지로 아무런 일도 하지 않는 디폴트 소멸자 자동 삽입

소멸자의 사용 : 생성자에서 할당한 리소스의 소멸에 사용
ex) 생성자 내에서 new 연산자로 할당해 놓은 메모리 공간을, delete 연산자를 이용해 이 메모리 공간 소멸

클래스와 배열

객체 기반의 배열 : SoSimple arr[10];
동적 할당 : SoSimple *ptrArr = new SoSimple[10];

배열을 선언하는 경우에도 생성자 호출이 되지만, 호출할 생성자들 별도로 명시하지 못함(생성자에 인자를 전달하지 못함)
SoSimple() {...} 의 생성자가 정의되어야 함

객체 포인터 배열 : 객체의 주소 값 저장이 가능한 포인터 변수로 이뤄진 배열
Person * parr[3];

객체를 저장할 때는 저장의 대상을 1. 객체로 하느냐 2. 객체의 주소 값으로 하느냐 결정해야함

this 포인터

객체 자신을 가리키는 용도로 사용되는 포인터

SoSimple * GetThisPointer()
{
	return this;
}

this는 객체자신의 주소 값을 의미

매개변수와 멤버변수의 이름이 같을 때는 this 포인터를 이용해 접근
this->num=207;

멤버 이니셜라이저에서는 this 포인터를 사용할 수 없지만, 저장하는 변수는 멤버변수로, 저장되는 값은 매개변수로 인식하기 때문에, 그냥 써도 됨
:num1(num1), num2(num2)

Self-Reference의 반환

Self-Reference : 객체 자신을 참조할 수 있는 참조자

SelfRef& Adder(int n)
{
	num+=n;
    return *this;
}

객체 자신을 참조할 수 있는 참조의 정보(참조 값) 반환

참조의 정보(참조 값)에 대한 이해 :
int num=7;
int &ref=num;
이면 참조자 ref에 변수 num을 참조할 수 있는 참조의 정보가 전달됨
대입 연산자의 왼편에 '참조자의 선언'이 오거나, 반환형으로 '참조형'이 선언되면, 그 때 전달되는 정보를 표현하기 위해 '참조의 정보' 또는 '참조 값'이라 표현

profile
Juhee Kim | Game Client Developer

0개의 댓글