본문 바로가기

C,C++76

[C++] 가상 함수와 가상 소멸자에 대해 알아보자(feat. 가상테이블) | virtual 가상 함수와 가상 소멸자는 상속 관계에서 사용되는 용어이며, 멤버 함수에 virtual 키워드가 붙은 함수를 말한다. 이는 C++에서 OOP의 중요한 특징 중 하나인 다형성(Polymorphism)을 지원하기 위한 기능 중 하나이다. C++의 멤버 함수는 기본적으로 컴파일 타임에 호출할 클래스의 형이 결정된다.(정적 바인딩) virtual 키워드는 호출 대상을 컴파일 타임이 아닌 런타임에 판단하여 해당 포인터가 가리키는 오브젝트의 실제 클래스 타입을 찾아 그 클래스의 함수를 동적으로 호출할 수 있게 해준다. 참고로 자바에선 모든 멤버 함수가 가상 함수이다. 따라서 상위 클래스의 함수를 재정의하면 알아서 하위 클래스의 함수가 호출된다. 예를 들어, 아래와 같이 상위 클래스의 포인터 변수 pBase에 하위 .. 2019. 12. 10.
[C++] 포인터와 레퍼런스(참조)의 차이를 이해해보자 C++에는 포인터(Pointer)와 레퍼런스(Reference)라는 개념이 있다. 포인터는 C 에도 있었던 개념이며 레퍼런스는 C++ 에서 등장한 개념이다. 언뜻 보면 용도가 비슷한데 정확히 어떤 차이점이 있는지, 내부적으로 어떻게 동작하는지, 왜 레퍼런스가 나오게 됐는지에 대해서 정리해보자. 포인터에 대해 헷갈려 하시는 분들을 위해 간단하게 용어 정리를 해보자면.. 포인터는 변수의 주소를 저장하는 특별한 타입의 변수이다. 주소값 자체를 포인터라고 생각해도 좋다. 주소만을 저장할 수 있는 변수를 포인터 변수라고 하고 일반적인 변수 선언과는 다르게 자료형에 * 표시를 붙여 선언한다. int* p; 는 int형 변수의 주소를 저장하는 포인터 (변수) p를 선언한 것이다. 포인터, 포인터 변수 다 같은 말이다.. 2019. 12. 5.
[C++] LNK2019, LNK1120 클래스 템플릿 사용 시 링크 오류 클래스 구현 도중 틀린 건 없는데 아래 에러가 계속 발생하였다. LNK2019, LNK1120 https://docs.microsoft.com/ko-kr/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=vs-2019 결론 먼저 말하면 클래스 템플릿은 헤더와 소스를 분리하면 안되고 그 선언과 구현(정의)을 같은 파일(.h)에 해야 한다. 나는 헤더 파일과 소스 파일을 따로 작성하였는데 main 함수가 있는 소스파일에서 헤더파일만 include 했더니 제대로 참조를 하지 못했다. 그 이유를 살펴보면 우선 우리가 클래스 템플릿가 아닌 일반 클래스의 선언과 구현을 헤더와 소스 파일에 분리하여 작성했다고 생각해 보자. 그리고 main에서 해당 클래스.. 2019. 11. 28.
[C++] const 키워드 위치에 따른 적용 범위 (포인터 및 멤버 함수) const 키워드는 대상을 상수화한다. 즉 대상이 초기화 이후로 값 수정을 하지 못하도록 만든다. const 키워드는 위치에 따라 적용되는 대상이 다르다. 1. 포인터가 가리키는 대상의 값을 변경 못하게 하려면 다음과 같이 선언한다. const char* c_ptr; - 포인터가 가리키는 대상의 값을 변경할 수 없다. - 하지만 포인터가 가리키는 대상(주소값)을 변경할 수 있다. 2. 포인터가 가리키는 대상(주소)을 변경 못하게 하려면 다음과 같이 선언한다. char* const ptr; - 포인터가 가리키는 대상(주소)을 변경할 수 없다. - 하지만 포인터가 가리키는 대상의 값을 변경할 수 있다. 3. 대상과 대상의 값을 모두 변경하지 못하게 하려면 다음과 같이 선언한다. const char* cons.. 2019. 11. 27.
[C++] typename 키워드 | C2760, C7510 typename 키워드 - 템플릿 정의에서 알 수 없는 식별자가 형식(Type)이라는 것을 컴파일러에게 알려줍니다. - 템플릿의 타입 매개변수로 정의된 타입을 사용하는 선언문을 정규화하는데 사용합니다. template void func(const T& obj) { T::size_type _size; } 위 코드는 아래와 같은 컴파일 에러를 발생시킵니다. 예를 들어 string 타입을 인자로 전달할 경우 string::size_type 타입을 사용하려는 의도이지만 T의 타입은 컴파일 과정에서 해당 함수 호출 시점에서 정해지기 때문에 미리 컴파일러에게 T::size_type이 타입이라는 것을 알려주어야 합니다. 따라서 아래와 같이 사용하면 typename 키워드와 함께 사용하면 정상적으로 컴파일이 됩니다. .. 2019. 11. 25.
[C++ STL] 라이브러리 알고리즘의 반복자 인자가 마지막 요소의 다음을 참조하는 이유 라이브러리에서 알고리즘의 범위를 지정하기 위해 2개의 반복자를 지정한다. 하나는 첫 요소를 참조하기 위한 반복자와, 나머지는 마지막 요소의 다음을 참조하는 반복자이다. 컨테이너는 아래와 같은 위치를 참조하는 반복자를 반환하는 멤버 함수를 가지고 있다. 왜 마지막 요소를 참조하지 않고 마지막 요소의 다음을 참조하는 반복자를 사용할까? 이에는 크게 3가지 이유가 있다. 첫 번째 만약 마지막 요소의 다음이 아닌 마지막 요소를 참조한다면 요소가 없는 컨테이너의 범위, 즉 크기가 0인 범위를 나타낼 경우 요소가 존재하지 않기 때문에 다른 무언가의 방법으로 표현해야 한다. 이는 크기가 0인 컨테이너의 범위와 크기가 1 이상인 컨테이너의 범위를 나타낼 때의 방법이 다르게 되어 혼동을 줄 수 있고 신뢰하기 어렵게 된다.. 2019. 11. 25.