C++

C++) 클래스(Class)

zzugest1 2025. 1. 8. 00:16

클래스 : 구조체의 발전형으로 데이터와 그 데이터를 처리하는 함수를 하나의 단위로 묶는 사용자 정의 데이터 타입이다.

내부에 멤버변수들을 여럿 둘 수 있다는 점은 구조체와 동일하지만, 클래스는 멤버 "함수"도 넣을 수 있고, 각각의 멤버에 접근 권한을 설정해둘 수 있다는 점이 제일 큰 차이이다.

 

class student
{
	
private:
	
	char name[30];	// 이름
	int age;	 	// 연령
	int id;			// 학번
	int password;	// 비밀번호

public:

	int count;

	int get_age()
	{
		return age;
	}
	void set_age(int a)
	{
		age = a;
	}
	
	student(); 
	student(const char* n, int a, int i, int p);
	
	~student();

	void print();
};

 

위와 같이 임의로 Student라는 클래스를 헤더 파일에 생성해보았을 때, 

 

private, protected, public는 접근 지정자라고 부르며 이는 각 변수나 함수 등에 접근할 수 있는 범위를 명시한 것이다.

private : 이 접근 지정자이의 영역에 선언된 내용들은 이 클래스의 내부에서만 접근 가능, 클래스 외부에서는 조건을 불문하고 직접적인 접근이 원천적으로 차단된다.

protected : 같은 클래스내에서 그리고 상속받은 클래에서 접근 가능하다.

public : 제한을 두지 않고 일반적인 구조체처럼 어디서나 접근 가능하다. 

 

public 안의 내용을 살펴보았을 때 int get_gae() 처럼 멤버의 값을 확인할 수 있게 해주는 함수를 "접근자"라 부르며,

void set_age(int a) 처럼 멤버의 값을 바꿀 수 있게 해주는 함수를 "지정자"라 부른다.

 

기본적으로는 반드시 public으로 노출시켜야 할 데이터가 아니라면 private으로 설정한 뒤, 외부에서 간접적으로나마 접근을 허용하게 만들 데이터라면 이렇게 접근자/지정자를 만들고, 외부에서 절대 접근하지 못하게 만들 데이터라면 이런 접근자/지정자를 만들지 않는 것으로 대응한다.

 

student() 와 같이 반환형 없이 클래스의 이름만 적어돈 함수를 "생성자"라고 부른다. 생성자는 해당 클래스의 인스턴스가 만들어지는 순간 반드시 호출되는 함수로, 경위를 불문하고 인스턴스가 만들어지면 무조건 이 함수가 실행되며 이 안에 있는 내용들을 만들게 되는 것이다.

또한 student(const char* n, int a, int i, int p) 와 같이 생성자에는 매개변수가 들어갈 수 도 안들어갈 수도 있다. 

반대로 ~student()와 같이 인스턴스가 할당 해제되는 순간 반드시 호출되는 함수를 "소멸자"라 부른다.

 

 

#include "Student.h"

student::student()
{
	cout << "기본 생성자 student()가 호출되었습니다." << endl;

	strcpy_s(this->name, "temp");

	this->age = 21;
	this->id = 1103225;
	this->password = 1234;

	this->count = 0;	
}

student::student(const char* n, int a, int i, int p)
{
	cout << "매개변수 있는 생성자 student(생략)가 호출되었습니다." << endl;
	strcpy_s(this->name, n);

	this->age = a;
	this->id = i;
	this->password = p;

	this->count = 0; 
}

student::~student()
{
	cout << "소멸자 ~student()가 호출되었습니다." << endl;
}

void student::print()
{
	cout << "\"" << name << "\", " << age << ", " << id << endl;
}

 

위와 같이 Student.h 파일에서 생성자와 소멸자를 작성하면 cpp파일에 그 내용을 작성할 수 있다.

 

student::student() 는 매개변수 없는 기본 생성자라고 부르며 인스턴스를 생성할 때 값을 입력하지 않고 그냥 생성할 경우 호출된다. 안에 strcpy_s(this->name, "temp"); 와 같이 this를 쓰는데 여기서 this는 이 함수가 실행되고 있는 클래스 인스턴스 자체를 가리키는 포인터이며, 자기 자신을 가리키기 떄문에 this라 쓰는 것이다.

student::student(const char* n, int a, int i, int p) 부분은 매개변수가 있는 생성자이며 main.cpp에서 호출할 수 있다.

 

 

#include"Student.h"

int main()
{
	student* sp = new student("임시 학생", 19, 41, 6668);
	sp->print();

	delete sp;
	
	student s2("두번째 학생", 23, 152, 8888577);

	s2.print();

}

 

student* sp = new student 는 클래스 student의 객체 sp를 생성하고 그 객체에 대한 포인터를 sp라는 변수에 저장하는 코드이다. 그리고 student 클래스에는 매개변수가 있는 생성자가 있었는데 이를 이용한 것이다. 여기서 new 구문을 이용해 동적할당을 했으므로 delete를 이용해 할당 해제를 해주어야 한다. 할당 해제가 되는 순간 클래스의 소멸자가 무조건 호출되기 때문에 소멸자 ~student()의 내용이 발생한다. 만약 ("임시 학생", 19, 41, 6668) 매개변수가 없었다면 디폴트 값이 출력된다. 만약 디폴트값이 cpp파일에서 정의되지 않았고 매개변수가 없다면 컴파일 에러가 일어난다.

 

 

student s2("두번째 학생", 23, 152, 8888577) 와 같은 작성 방식은 s2라는 이름의 student 객체를 스택 메모리에 생성한다. 스택 메모리는 함수가 종료되면 자동으로 메모리가 해제되어 delete를 적상 안해도 할당 해제가 된다.

 

위 두 생성자 작성 방식의 차이는 student* sp = new student 부분은 포인터를 이용해 접근하는 것이고, student s2 부분은 객체를 이용해 접근하는 방식이다. 

 

따라서 포인터를 이용해 접근한 인스턴스는 sp->print() 처럼 멤버함수나 변수에 접근할 때 ->를 사용해야하며

객체를 이용해 접근한 인스턴스는  s2.print() 처럼 .을 사용해야 한다.

 

 

 

'C++' 카테고리의 다른 글

C++) 암시적 멤버 함수  (0) 2025.01.13
C++) 상속  (0) 2025.01.10
C++) 동적 할당  (0) 2025.01.06
C++) 포인터(Pointer)  (0) 2025.01.06
C++) 인터페이스(Interface)  (0) 2024.12.26