본문 바로가기

Today I Learned

23.02.06 ~ 23.02.10 - 객체, 생성자, explicit, 전방선언

객체는 무엇일까?

객체는 기능속성을 포함하는 실체이다.

객체 지향 프로그래밍(OOP)는 객체에 중점을 두고 객체들간의 의사소통 방식으로 설계하는 프로그래밍이다.

클래스는 자료형이고 객체는 메모리에 할당된 클래스이다.

 

클래스 멤버 변수클래스 내에서 전역 변수처럼 사용 가능하고 멤버 변수는

객체가 할당되는 메모리에 할당되지만 명명권이 데이터 영역에 등록된다.

 

구조체는 함수를 가질 수 없지만 클래스는 멤버 변수와 멤버 함수를 가질 수 있다.

하지만 클래스는 구조체와 달리 중괄호식으로 초기화 할 수 없으며 생성자를 통해서만 초기화가 가능하다.

 

객체 생성시 먼저 메모리를 할당하고 생성자가 호출된다.

객체가 소멸될 때는 먼저 소멸자가 호출되고 메모리를 반환한다.

 

구조체 역시 생성자를 만들 수 있고 생성자가 호출된다.

클래스 크기는 구조체 크기 측정 방식과 같으며 함수는 클래스 크기에 영향을 끼치지 않는다.

 

생성자대입을 통한 초기화다. 기본 자료형 변수처럼 메모리 할당과 동시에 하는 초기화는 아니지만

생성자를 호출해야 객체가 생성되고 생성자 호출 이후에 멤버 변수를 사용할 수 있으므로 초기화라고 한다.

class A
{
public:
	A(int a)
	{
		m_iA = a;
	}
	int m_iA;
};
int main()
{
	A a(0);
	a = 3; 
	cout << a.m_iA; // 3
}

위 코드를 보면 A타입인 a에 int형 데이터 3을 대입하고 있다. 이게 가능한 것은 똑똑한 컴파일러가

묵시적으로 형변환을 해서 int형 데이터를 매개변수로 받는 생성자를 찾아 m_iA에 넣어주기 때문이다.

사실 이런 묵시적 형 변환은 개발자에게 기분 좋지는 않다. 언제 실수로 객체에 의도치 않은 값이 대입되어

예상치 못한 결과를 만들어낼 수 있기 때문이다. 그래서 이런 것을 금지하기 위한 문법이 있다.

class A
{
public:
	explicit A(int a)
	{
		m_iA = a;
	}
	int m_iA;
};
int main()
{
	A a(0);
	a = 3; // 컴파일 에러
	cout << a.m_iA;
}

explicit 키워드를 생성자 앞에 붙여주면 묵시적 형 변환이 금지되며 

컴파일 단계에서 a에 3을 대입하는 것이 허용되지 않는다.

 

 

 

클래스가 서로의 클래스 타입의 멤버를 포함하고 헤더에서 서로를 include하면 상호 참조 오류가 발생한다.

이럴 때 include가 아니라 전방 선언을 사용해 오류를 해결할 수 있다.

class 클래스명;

맨 앞에 전방 선언을 해서 자료형을 알려준다. 하지만 include 헤더와 달리 생성자나 함수 등 정보는 알 수 없고

오로지 자료형의 유무만 알려준다. 그래서 전방선언을 하고 다른 클래스를 멤버로 선언하려면 포인터로 사용해야 한다.