• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    해결됨

동적 객체 생성 전에 클래스 포인터의 멤버함수 호출

23.06.29 22:06 작성 조회수 430

1

class TestClass
{
public:
void Init() { cout << "CTestClass::Init()" << endl; }
int mmmi;
};
int main()
{
TestClass* pi = nullptr;
pi->Init(); // 정상 실행
pi->mmmi = 10; // 에러
}

 

안녕하세요. 강의 잘 듣고 있습니다.

위와 같은 경우에 객체가 생성되지 않은 상태에서 멤버변수에 접근 되지 않는 건 이해가 가는데 함수는 호출이 정상적으로 됩니다. 설명 좀 부탁드립니다.

답변 1

답변을 작성해보세요.

1

이 부분은 절묘하게 멤버 변수를 딱히 건드리지 않아서 그렇습니다.
데이터를 건드리지 않았기에, 소스코드는 잘 실행되고 있지만
조금이라도 수정을 가하면 터질 수 있는 폭탄같은 존재입닏.

void Init()
{
cout << "CTestClass::Init()" << endl;
mmmi = 10;
}

이런 코드를 넣으면 바로 NULL 크래시가 날거에요.

은하수님의 프로필

은하수

질문자

2023.06.30

예 그건 알았는데, 함수 메모리를 어떻게 알고 호출하는지 궁금해서요.

객체가 생성되어야 변수, 함수 메모리가 지정되어서 사용, 호출이 가능할텐데, 호출 번지수를 알 수 없는데 호출이 되는게 궁금합니다.

클래스가 정의돼 있어도 실제 객체로 메모리에 올라가야 함수 주소가 지정되는게 아닌가 싶어서요.

객체가 메모리에 올라가서 함수가 지정되는 개념이 아닙니다.
컴파일 타임에 이미 특정 함수 XX번 주소 코드를 실행하라는 식으로
미리 코드가 만들어집니다. (가상 함수 제외)

은하수님의 프로필

은하수

질문자

2023.06.30

늦은 시간까지 답변 달아주셔서 고맙습니다.

그렇다면 강의에서 가상함수의 경우 객체 바로 다음에 가상함수 테이블로 연결되는 주소를 찾아 호출이 된다고 했는데, 이 경우는 객체를 포인팅(?)해서 함수를 호출하는 이유가 무엇인가요? 스태틱 함수처럼 클래스 지정자로 호출해도 호출돼야 하지 않을까요?

가상 함수는 자식 클래스로 만들고 부모 클래스로 들고
있는 경우가 많아 그렇게 간단하지 않습니다.
Player* player = new Knight();
player->가상함수실행();

요런 경우 player의 원본을 런타임이 아니면 알기 힘듭니다.

은하수님의 프로필

은하수

질문자

2023.06.30

컴파일 타임에 이미 특정 함수 XX번 주소 코드를 실행하라는 식으로
미리 코드가 만들어집니다.(가상 함수 제외)

이 말에서 "객체->" 가 널 이어도 번지를 찾아 간다는 것은 실제 호출할 때는 함수를 포인팅하는 객체는 애당초 참조하지 않는다는 것인가요?

다시 말해서 코딩하는 입장에서는 우리가 문법적으로는 "객체->함수"를 엄격하게 지켜서 써야 하지만, 실행하는 입장에서는 객체로는 타입만 확인하고 이미 컴파일 타임에 특정 된 번지의 함수를 호출한다는 것으로 이해하면 될까요?

 

이 말에서 "객체->" 가 널 이어도 번지를 찾아 간다는 것은 실제 호출할 때는 함수를 포인팅하는 객체는 애당초 참조하지 않는다는 것인가요?

네 물론입니다. 함수 호출할 때는 딱히 '번지'의 개념이 필수적으로 들어가는 것이 아니구요.
this 주소값을 넘겨주기는 하지만, 이를 이용해 함수가 연동되는 것이 아니라
객체의 멤버변수 (this를 넘겨주고, this.mmmi를 건드리는 것이죠)를 사용하 때 필요한 것입니다.