상세 컨텐츠

본문 제목

C++ 클래스

C++/C++98

by deulee 2023. 8. 3. 15:07

본문

Class 란?

클래스는 사실 그냥 "확장된 구조체"라고 말할 수 있다.

 

선언 방법도 간단한데 struct 키워드를 class로 바꿔주기만 하면 되는 것이다. 그리고 선언문 선두에 액세스 지정자만 추가하면 된다.

 

class Point
{
public:
	int x;
    int y;
    char ch;
    void printPoint();
};

 

그럼 구조체와의 차이점은 뭘까?

 

대표적인 차이점으로는 구조체의 디폴트 액세스 지정자는 public인 반면에 클래스의 디폴트 값은 private이다.

 

이는 객체의 안정성을 위해 외부에서 함부로 값을 건드리지 못하게 하려는 의도가 숨겨져 있다.

 

그럼 왜 struct(구조체)는 public일까? 이는 기존 C언어와의 호환성을 유지하기 위해서이다.

 

하지만 양쪽 다 명시적인 액세스 지정자로 멤버의 공개 여부를 변경할 수 있다.

 

사실 이게 구조체와 클래스의 유일한 차이점이다. ㅎㅎ

 

클래스는 타입이다

c++로 넘어오게 되면서 구조체의 태그타입으로 승격되었다.

 

이 말이 무슨 말일까?

 

즉, 클래스도 하나의 타입으로 취급된다는 것인데 기존의 기본형 타입과 동등한 자격을 가지며 사용법도 완전히 똑같아지게 된다.

int main(void)
{
	Dot A; // 선언 가능
    Dot B(20); // 선언과 동시에 초기화할 수 있다.
    
    Dot C = B; // 같은 타입의 다른 객체로부터 생성된다.
    
    D = C; // 대입 연산자 가능
    D + C; // 연산자 오버로딩을 통한 사착연산 가능
    
    Dot A(3); // 변환 생성자, 변환 함수
    1 + A; // 전역 연산자 함수와 프렌드
}

위의 것들이 어떻게 가능한지는 나중에 나올 글들을 통해서 설명하도록 하겠다.

 

우선은 기존의 타입들에게만 적용되었던 것들이 클래스에게도 적용될 수 있다는 것만 알고 있으면 된다.

 

클래스 배열

기존의 C에서 사용되었던 구조체 배열과 개념적으로 동일하다.

 

int main(void)
{
	Point2 parr[50];
	Point2* ptr;

	for (int i = 0; i < 50; i++)
	{
		parr[i].x = i;
		parr[i].y = i;
		parr[i].ch = 'A' + i;
	}

	ptr = parr;

	for (int i = 0; i < 50; i++)
	{
		ptr->printPoint2();
		ptr++;
	}
    return 0;
}

인스턴스

클래스는 어디까지나 타입일 뿐 이 자체가 객체라고 보기에는 어렵다. 구조체나 클래스를 선언한다고 해서 변수가 생기는 것이 아니기에 메모리가 할당되지는 않는다.

 

즉, 클래스형의 변수를 선언해야 실제 메모리가 생긴다.

int main(void)
{
	Point P;
}

Point P; 선언에 의해 Point 타입의 변수 P가 메모리에 생성되는 과정을 거치게 된다.

 

이렇게 선언문에 의해 생성된 클래스형의 변수를 인스턴스(instance)라고 한다. 인스턴스는 클래스(타입)가 메모리에 구현된 실체이고 기존의 변수랑 동일한 개념이다.

 

그렇기 때문에 기존의 타입과 변수와 같이 한번에 여러 개의 인스턴스를 생성할 수 있다.

 

아래와 같이 인스턴스가 3개 만들어졌다고 가정해보자.

 

class Point {
public:
	int x;
	int y;
	char ch;
	void printPoint(void);
};

void Point::printPoint(void)
{
	std::cout << x << ' ' << y << ' ' << ch << std::endl;
}

int main(void)
{
	Point A, B, C;
	return 0;
}

 

각 인스턴스들은 클래스에 선언된 멤버 변수(멤버 함수 아님)를 각각 따로 가진다. 그래야 개별 인스턴스가 독립적인 정보를 저장할 수 있는 것이다.

 

printf("%p %p %p", &A.x, &B.x, &C.x);

출력결과

3개의 멤버 변수의 주소가 각각 다른 것을 확인할 수 있다.

 

이렇게 되면 각각 x, y, ch의 크기 총합 9 바이트를 가지게 될 것이다. (실제로는 컴파일러의 정렬 기능에 의해 12바이트씩 차지하게 된다.)

 

이와 반대로 멤버 함수는 클래스에 속한 모든 인스턴스들이 공유한다. 인스턴스들의 정보(멤버 변수의 내용)는 달라질 수 있어도 동작은 모두 동일하기 때문에 함수를 인스턴스 별로 따로 가질 필요가 없어지게 된다.

 

인스턴스의 다른 표현이 바로 객체(Object)라고 한다.

 

이 둘의 어감은 조금 다르다.

 

1. 인스턴스(Instance) - 실체 - 메모리에 구현됨

2. 객체(Object) - 객체 - 독립성을 가진 부품. 

 

출처

http://www.soen.kr/lecture/ccpp/cpplec.htm

 

C/C++ 강좌

 

www.soen.kr

 

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

C++ 함수 오버로딩  (0) 2023.08.03
C++ 참조자(reference)  (0) 2023.08.03
OOP란?  (0) 2023.08.03
C++에서의 구조체  (0) 2023.08.03
new 연산자  (0) 2023.08.03

관련글 더보기