c++

c++ 공부

이야기prog 2025. 3. 1. 17:42
#include <iostream>

class Knight {

protected:
	int hp_;
	int attack_;
	int positionX_;
	int positionY_;
public:

	Knight(): hp_(100), attack_(1), positionX_(2), positionY_(3) { // 기본 생성자

	}

	Knight(const Knight& k) { // 복사 생성자
		hp_ = k.hp_;
		attack_ = k.attack_;
		positionX_ = k.positionX_;
		positionY_ = k.positionY_;
	}
	Knight(int hp) : hp_(hp), attack_(0), positionX_(0), positionY_(0) {} // 타입 변환 생성자 Knight k1 = 1; 도 가능하게 해줌 Kn

	Knight(int hp, int attack) : hp_(hp), attack_(attack), positionX_(0), positionY_(0) {} // k = {1,2}



	virtual void KnightPrint() {
		std::cout << hp_ << "\n";
	}

	virtual void move() = 0;
};

class GeneralKnight : public Knight {

public:
	void KnightPrint() {
		std::cout << hp_ << ", " << attack_ << "\n";
	}
	void move() {
		return;
	}
};

int main() {

	GeneralKnight k;
	k.KnightPrint();


}

virtual로 가상함수를 클래스에 구현해놓으면 .vftable을 만드는데 (virtual function table) 객체를 만들시 그 메모리의 가장 상단에 vftable의 주소가 저장되는 것으로 보인다.(어셈블리어로 살펴볼 때) 그 테이블에는 virtual 함수가 선언된 순서로 저장되어 있는 것을 어셈블리어로 확인할 수 있다.

 

00007FF624361EB0  mov         rax,qword ptr [this]  
00007FF624361EB7  lea         rcx,[Knight::`vftable' (07FF62436BC98h)]

Knight클래스를 상속받는 GeneralKnight 는 생성시

Knight클래스를 생성하고 그 뒤에 자기자신을 생성하는데 

 

높은 주소 ----------------------------------------------------------------------------------------------

                                                       [vftable의 주소]

                ----------------------------------------------------------------------------------------------

                                                       [부모 멤버]

                ----------------------------------------------------------------------------------------------

                                                       [자식 멤버]

낮은 주소 ----------------------------------------------------------------------------------------------

로 메모리에 저장되는 것을 볼 수 있다.(main에 생성했기 때문에)

 

여기서

높은 주소 ----------------------------------------------------------------------------------------------

                                                       [vftable의 주소] <- 부모의 vftable의 주소

                ----------------------------------------------------------------------------------------------

                                                       [부모 멤버]

                ----------------------------------------------------------------------------------------------

로 부모클래스가 메모리에 할당되고 자식클래스가 생성될 때

 

높은 주소 ----------------------------------------------------------------------------------------------

                                                       [vftable의 주소] <- 자식의 vftable의 주소

                ----------------------------------------------------------------------------------------------

                                                       [부모 멤버]

                ----------------------------------------------------------------------------------------------

                                                       [자식 멤버]

낮은 주소 ----------------------------------------------------------------------------------------------

이렇게 vftable을 자식의 vftable의 주소로 덮어쓰고 멤버밑에 자식 멤버들을 할당한다.

 

또한 초기화 리스트는 클래스에서 생성자에 선처리 영역에서 초기화를 하기위해 사용되는 것인데

보통 const 상수, &참조, 아니면 부모 클래스의 기본생성자 이외의 생성자를 호출하기 위해서 또는 부모 클래스에 has-A 관계가 있는 클래스의 기본 생성자 이외의 생성자를 호출하기 위해 사용된다.

 

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

c++ 공부(vector iterator 구현)  (0) 2025.03.06
c++ 공부  (1) 2025.03.03
c++ 공부  (0) 2025.03.01
c++ 공부  (0) 2025.02.27
c++공부  (0) 2025.02.24