반응형
(42Seoul의 CPP04 과제를 진행하며 공부한 내용을 작성한 TIL을 정리한 글 입니다.)
개념 공부📓
가상 함수
- 가상함수는 ‘virtual’ 키워드를 사용하여 선언한 함수를 의미
- 가상 함수 테이블은 대체로 아래 순서로 구현됨
- ‘virtual’ 키워드를 사용하여 가상 함수 선언
- 클래스에 대한 가상 함수 테이블을 생성함. 가상 함수 테이블은 가상 함수들에 대한 포인터들의 배열
- 객체에 가상 함수 테이블 포인터를 추가하여, 해당 클래스의 가상함수 테이블을 가리키게 함
- 가상함수 호출 시, 해당 클래스의 가상 함수 테이블 포인터를 따라가 적절한 가상 함수를 찾아 호출
가상 소멸자
- 클래스 상속 시, 해당 클래스의 소멸자도 가상 소멸자로 선언해야 함
- 가상 소멸자로 선언하지 않으면, 해당 클래스를 동적으로 할당하고 삭제 시, 메모리 누수나 undefined behavior 문제가 발생할 수 있음
- 부모클래스에서 가상 소멸자로 선언되지 않는다면, 자식 클래스의 객체를 가리키는 포인터가 삭제될 때 부모 클래스의 소멸자만 호출됨. 자식 클래스의 소멸자는 호출되지 않아 메모리 누수 발생함
const Animal* j = new Dog();
- 위 상황은 업캐스팅(Upcasting) 이라고 하며, 파생 클래스의 객체를 기본 클래스의 포인터 또는 참조형으로 변환하는 것
- 위 코드처럼 부모 클래스인 Animal 클래스의 포인터인 j 에 Dog 클래스의 객체를 가리킬 수 있는 이유는 C++ 의 다형성(polymorphism) 으로 인해 가능함
- 다형성이란, 여러 클래스들을 하나의 인터페이스로 동작시키는 개념
- 여러개의 서로 다른 객체가 동일한 기능을 다양한 방법으로 처리할 수 있음
- 부모 클래스의 포인터나 참조를 사용하여 자식 클래스의 객체에 접근할 수 있도록 함
- 이를 통해 프로그램에서 일반적인 인터페이스를 사용하며, 런타임에 실제로 실행될 객체의 타입을 결정할 수 있음
바인딩(Binding)
- 업캐스팅 상황에서 부모 클래스의 함수를 자식 클래스에서 오버로딩 시, ‘virtual’ 키워드로 선언하지 않으면, 자식 클래스에서 해당 함수 호출 시 부모클래스의 함수가 우선됨
- 업캐스팅 상황이 아니면, 가상함수로 선언하지 않아도 오버라이딩 할 수 있음
- 이유는 바인딩과 관련이 있음
- 바인딩이란, 프로그램에서 식별자와 그에 대응하는 값을 연결하는 과정. 즉, 바인딩은 변수나 함수와 같은 식별자를 해당하는 메모리 위치나 코드 블록에 연결하는 것을 말함
- 바인딩에는 정적 바인딩과 동적 바인딩이 있음
- 정적 바인딩(Static Binding)
- 컴파일 시간에 변수나 함수 호출대상이 결정되는 방식
- 컴파일러는 식별자의 타입 정보를 바탕으로 해당하는 메모리 위치를 결정하거나, 함수 호출 대상을 정적으로 결정함
- 컴파일러가 프로그램을 컴파일하는 과정에서 식별자와 값을 연결하므로, 실행시 바인딩이 발생하지 않음
- 동적 바인딩(Dynamic Binding)
- 런타임에 변수나 함수 호출 대상이 결정되는 방식
- C++에서는 주로 가상함수를 사용하여 동적 바인딩을 구현
- 객체의 타입에 따라 메모리 위치나 함수 호출대상이 동적으로 결정되므로, 실행 시 바인딩이 발생
- 정적 바인딩(Static Binding)
- 가상함수로 선언하지 않을 경우 정적 바인딩이 발생되기 때문에, 컴파일 타임에 함수 호출 대상이 결정되어 부모 클래스의 함수가 호출됨
추상화(Abstract)
- 객체의 공통적인 특징과 기능을 하나의 추상 클래스로 표현하는 것
- 실제로 구현되지 않은 순수한 가상 함수들을 가지고 있는 추상 클래스를 의미
- 추상 클래스는 인스턴스를 생성할 수 없으며, 그 자체로 완전한 클래스가 아님
- 추상 클래스는 단지 인터페이스 역할이며, 이를 상속받은 파생 클래스에서 정의된 순수 가상 함수들을 반드시 구현하여야 함.
- 이를 통해 다형성을 구현하는 기반을 마련하고, 다른 클래스들 간의 공통된 인터페이스를 정의하여 객체 지향 프로그래밍의 유연성과 재사용성을 증가
- 추상 클래스를 정의하기 위해서는 하나 이상의 순수 가상 함수를 포함해야 함
- 순수 가상 함수(pure virtual function)는 ‘virtual’ 키워드와 함께 선언되며, 함수 바디가 없고 ‘= 0’ 으로 정의됨
- 이를 통해 파생 클래스에서 해당 함수들을 오버라이딩하여 실제 기능 구현
class AbstractClass { public: virtual void example() = 0; }
인터페이스(Interface)
//인터페이스 선언
class Interface {
public:
virtual void example1() = 0;
virtual void example2() = 0;
}
//인터페이스를 상속하는 클래스 정의
class MyClass : public Interface
{
public:
void example1()
{
//함수구현
}
void example()
{
/
- 순수 가상 함수로만 구성된 클래스로, 실제로 구현을 갖지 않는 추상화된 형태의 클래스
- 다형성을 활용하여 서로 다른 클래스들을 통일된 인터페이스를 사용하게 하여 코드의 재사용성과 유지 보수성을 향상
- 인터페이스는 클래스의 외부와의 통신을 위한 계약으로 볼 수 있고, 특정 기능을 수행하는 메서드의 시그니처(함수 원형)만을 제공
클래스 포워드 선언(Forward Declaration)
- 포워드 선언이란, 클래스의 선언을 미루어서 순환참조를 피하는 방법
- 순환참조는 A.hpp 파일과 B.hpp 파일에서 서로를 include 하는 상황에서 발생하는 에러
//A.hpp #include "B.hpp" class A { //클래스 내용 }
//B.hpp #include "A.hpp" class B { //클래스 내용 }
- 컴파일러가 클래스를 정확히 인식하지 못하여 에러가 발생함
- 클래스의 멤버 변수나 멤버 함수를 선언하지 않고, 클래스의 이름만을 미리 선언하는 방법
- 해당 클래스를 사용하는 코드에서는 클래스의 세부 구현을 알 필요 없이 클래스의 포인터나 참조를 사용할 수 있음
- 클래스의 멤버 변수나 멤버 함수와 같은 세부 내용이 필요한 경우에는 헤더 파일의 하단에 해당 클래스의 헤더 파일을 포함시켜주어야 함
//A.hpp
class B;
class A
{
//클래스 내용
}
#include "B.hpp"
//B.hpp
class A;
class B
{
//클래스 내용
}
#include "A.hpp"
제가 공부한 내용을 기록하고 있습니다.
혹시 수정이 필요한 부분이 있다면, 댓글로 지적 부탁드립니다!
선한 관심과 도움 감사드립니다😊
반응형
'C++' 카테고리의 다른 글
[C++] 42SEOUL CPP03 개념 공부하기 (0) | 2023.07.28 |
---|---|
[C++] 42SEOUL CPP02 개념 공부하기 (0) | 2023.07.28 |
[C++] 42SEOUL CPP01 개념, 함수 공부하기 (0) | 2023.07.28 |