C++ - Binding) 복습을 위해 작성하는 글 2023-11-07

rizz·2023년 11월 7일
0

C

목록 보기
21/25

📒 C++ - Binding

📌 Binding이란?

- 프로그램 소스에 쓰인 내부 요소들에 대해 값 또는 속성을 확정하는 과정

📌 Static Binding이란?

- 컴파일 시점에 요소들에 대한 값 또는 속성이 확정되는 것

- 빠르다는 장점이 있지만 비이성적이다.

- 에러를 조기 발견할 수 있다.

- 대표적으로 오버로딩이 있다.

📌 Dynamic Binding이란?

- 런타임 시점에 요소들에 대한 값 또는 속성이 확정되는 것

- 느리지만 이성적이다.

- 메모리가 낭비될 수 있다.

- 대표적으로 오버라이딩이 있다.

// C++
#include <iostream>

using namespace std;

class Animal
{
public:
	void eat() const
	{
		cout << "나는 동물" << endl;
	}
};

class Cat : public Animal
{
public:
	void eat() const
	{
		cout << "나는 고양이" << endl;
	}
};

class Dog : public Animal
{
public:
	void eat() const
	{
		cout << "나는 강아지" << endl;
	}
};

void func(Animal* animal)
{
	animal->eat();
}

int	main()
{
	Animal* a = new Dog();
	a->eat();
}

Output:
나는 동물

- eat 함수에 virtual 키워드를 붙이지 않으면 정적 바인딩이 일어나게 되어, Animal 클래스의 eat 함수가 출력된다.

 

// C++
#include <iostream>

using namespace std;

class Animal
{
public:
	virtual void eat() const
	{
		cout << "나는 동물" << endl;
	}
};

class Cat : public Animal
{
public:
	virtual void eat() const override
	{
		cout << "나는 고양이" << endl;
	}
};

class Dog : public Animal
{
public:
	virtual void eat() const override
	{
		cout << "나는 강아지" << endl;
	}
};

void func(Animal* animal)
{
	animal->eat();
}

int	main()
{
	Animal* a = new Dog();
    func(a);
}

Output:
나는 강아지

- func 함수 입장에서는 Animal 타입이 어느 객체인지 알 수 없기 때문에 런타임시에 결정된다. (동적 바인딩)

- eat 함수에 virtual 키워드를 붙이는 순간, 내부적으로 함수 테이블에서 virtual 함수를 가리키게 된다.

 

// C++
// static binding & dynamic binding

#include <iostream>

using namespace std;

class Animal
{
public:
	int* ptr; // 4byte(32bit)
	void eat() const
	{
		cout << "냠" << endl;
	}
};

class Cat : public Animal
{
public:
	void eat() const
	{
		cout << "냥" << endl;
	}
};

class Dog : public Animal
{
public:
	void eat() const
	{
		cout << "멍" << endl;
	}
};

int	main()
{
	Animal a;
	cout << sizeof(Animal) << endl;
	cout << &a << endl;
	cout << &(a.ptr) << endl;
}

Output:
4

- 현재 Aniaml 클래스의 크기는 4바이트 (msvc++ 32bit)

 

// C++
// static binding & dynamic binding

#include <iostream>

using namespace std;

class Animal
{
public:
	int* ptr; // 4byte(32bit)
	virtual void eat() const // 4byte(32bit)
	{
		cout << "냠" << endl;
	}
};

class Cat : public Animal
{
public:
	virtual void eat() const
	{
		cout << "냥" << endl;
	}
};

class Dog : public Animal
{
public:
	virtual void eat() const
	{
		cout << "멍" << endl;
	}
};

int	main()
{
	Animal a;
	cout << sizeof(Animal) << endl;
	cout << &a << endl;
	cout << &(a.ptr) << endl;
}

Output:
8
00B5F94C
00B5F950

- 현재 Aniaml 클래스의 크기는 8바이트 (msvc++ 32bit)

- 함수에 virtual 키워드를 붙이는 순간 함수 테이블에서 가상 함수를 가리키게 되어 추가로 메모리가 할당된다.

- a와 a.ptr의 주소를 보면 사이에 4byte의 공간이 있다는 것을 알 수 있다.

 

- 또한, 디버거를 통해 확인해 보면, Aniaml 클래스는 _vfptr(virtual function pointer로 추측됨)을 가리키는 것을 확인해 볼 수 있고, _vfptr은 가상 함수 테이블을 가리키고 있다.

profile
복습하기 위해 쓰는 글

0개의 댓글