C++ 멤버 함수를 한 번 더 템플릿화하기
·
C++/Templates
멤버 함수를 한 번 더 템플릿화하기 클래스 템플릿에 있는 멤버 함수를 또 다시 템플릿화할 수 있다. 예제 #include using namespace std; template class A { T value_; public: A(const T & input) : value_(input) {} template void doSomething() { cout
C++ 포인터 템플릿 특수화(Pointer Templates Specialization)
·
C++/Templates
포인터 템플릿 특수화(Pointer Templates Specialization) 템플릿 파라미터가 포인터인 경우 특수화를 하고 싶다면 클래스명에 를 붙여서 작성한다. 예제 #include using namespace std; template class A { T value_; public: A(const T & input) : value_(input) {} void print() { cout
C++ 템플릿 부분 특수화 (Templates Partial Specialization)
·
C++/Templates
템플릿 부분 특수화 (Templates Partial Specialization) 템플릿에서 여러 파라미터를 받을 때, 특정 파라미터만 특수화할 수 있다. 예제 일반 함수 템플릿 부분 특수화 #include using namespace std; template class StaticArray { private: T array_[size]; public: T* getArray() { return array_; } T& operator[](int index) { return array_[index]; } }; template void print(StaticArray& array) { for (int count = 0; count < size; ++count) cout
C++ 클래스 템플릿 특수화 (Class Templates Specialization)
·
C++/Templates
클래스 템플릿 특수화 (Class Templates Specialization) 템플릿의 특정 자료형에 대해서 다르게 처리하고 싶을 때 사용한다. 함수 템플릿 특수화에서는 template을 명시하지 않아도 작동이 됐는데, 클래스 템플릿 특수화에서는 명시하지 않으면 오류가 발생한다. error C2906: &#39;A&#39;: explicit specialization requires &#39;template &#39; 예제 클래스 템플릿 특수화는 다른 클래스를 하나 따로 만들었다고 생각해야 한다. 아래의 예제에서 a_char.test 함수는 존재하지 않는다. 상속과는 엄연히 다르다. #include "MyArray.h" using namespace std; template class A { public..
C++ 함수 템플릿 특수화 (Function Templates Specialization)
·
C++/Templates
함수 템플릿 특수화 (Function Templates Specialization) 템플릿이 있는 상태에서, 특정 자료형에 대해 다른 코드를 실행하고 싶을 때 사용한다. explicit instantiation과 비슷한 느낌인데, 이렇게 정의된 함수는 템플릿에서 따로 인스턴스화하지 않는다고 생각하면 될 것 같다. 예제 #include "MyArray.h" using namespace std; template T getMax(T x, T y) { return (x > y) ? x : y; } template char getMax(char x, char y) { cout y) ? x : y; } int main() { cout
C++ 자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters)
·
C++/Templates
자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters) 템플릿 매개변수는 컴파일 타임에 결정되어야 한다. 템플릿의 원리가 여러 경우에 대해 컴파일을 따로 해주는 것이기 때문이다. Non-type 파라미터를 사용할 경우 헤더에서 함수를 정의한다. template와 같이 unsigned int가 온다고 생각해보자. 모든 숫자에 대해 explicit instantiation을 적용할 수는 없으므로 헤더에서 정의하는 것이다. 예제 main.cpp #include "MyArray.h" int main() { MyArray my_array; for (int i = 0; i < my_array.getLength(); ++i) my_array[i] = i * 0.5; my_array.p..
C++ 클래스 템플릿 (Class Templates)
·
C++/Templates
클래스 템플릿 (Class Templates) 클래스에도 템플릿을 적용할 수 있다. 예제 템플릿을 사용하지 않은 예제 main.cpp #include "MyArray.h" int main() { MyArray my_array(10); for (int i = 0; i < my_array.getLength(); ++i) my_array[i] = i * 10; my_array.print(); } /* stdout 0 10 20 30 40 50 60 70 80 90 */ MyArray.h #pragma once #include #include class MyArray { int length_; int* data_; public: MyArray() { length_ = 0; data_ = nullptr; } My..
C++ 함수 템플릿 (Function Templates)
·
C++/Templates
함수 템플릿 (Function Templates) template, template의 형태로 템플릿을 선언할 수 있다. 예제 #include template T getMax(T x, T y) { return (x > y) ? x : y; } class Cents { int cents_; public: Cents(int cents = 0) { cents_ = cents; } bool operator > (const Cents& c) { return (cents_ > c.cents_); } friend std::ostream& operator
C++ 템플릿 (Templates)
·
C++/Templates
템플릿 (Templates) 함수 템플릿 (Function Templates) 클래스 템플릿 (Class Template) 자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters) 함수 템플릿 특수화 (Function Templates Specialization) 클래스 템플릿 특수화 (Class Templates Specialization) 템플릿 부분 특수화 (Templates Partial Specialization) 포인터 템플릿 특수화(Pointer Templates Specialization) 멤버 함수를 한 번 더 템플릿화하기
따라하며 배우는 C++ 13장
·
C++/TBC++
따라하며 배우는 C++ 13장 템플릿 (Templates) 참고 따라하며 배우는 C++
C++ 유도 클래스에서 출력 연산자 사용하기
·
C++/Class
유도 클래스에서 출력 연산자 사용하기 연산자 오버로딩할 때만 사용하는게 아니라, 다형성을 더 유연하게 구현할 때도 사용되는 기법이다. 예제 멤버 함수로 만들 수 없는 연산자를 오버라이딩한 것 처럼 구현하기 위해서 다음과 같은 기법을 사용할 수 있다. print 함수를 오버라이딩하고, 연산자 오버로딩을 할 때 이를 호출하는 방식이다. #include class Base { public: friend std::ostream& operator
C++ 동적 형변환 (Dynamic Casting)
·
C++/Class
동적 형변환 (Dynamic Casting) dynamic_cast는 캐스팅이 실패하면 nullptr를 반환한다. 예제 간단한 예제 #include class Base { public: int i_ = 0; virtual void print() { std::cout
C++ reference_wrapper
·
C++/Library
reference_wrapper 라이브러리 템플릿 등에 레퍼런스로 전달할 수 있게 해주는 클래스이다. 예제 #include #include #include class Base { public: int i_ = 0; virtual void print() { std::cout
C++ 객체 잘림 (Object Slicing)
·
C++/Class
객체 잘림 (Object Slicing) 부모 클래스 자료형에 자식 클래스 자료형을 대입할 경우, 흔히 말하는 truncation이 발생한다. 예제 #include class Base { public: int i_ = 0; virtual void print() { std::cout
C++ 다이아몬드 상속 (Diamond Polymorphism)
·
C++/Class
다이아몬드 상속 (Diamond Polymorphism) 한 자식 클래스가 상속받는 서로 다른 부모 클래스들이, 같은 조부모 클래스를 상속받는 구조 예제 클래스 A를 B, C가 상속받은 후 D가 B와 C를 상속받으면, D::B::A와 D::C::A가 각각 존재하게 된다. #include class PoweredDevice { public: int i_; PoweredDevice(const int& power) { std::cout
C++ 인터페이스 클래스 (Interface Class)
·
C++/Class
인터페이스 클래스 (Interface Class) 순수 가상 함수를 이용하여 만드는 클래스 특별한 기능을 하지는 않고 자식 클래스들을 편하게 다루기 위해 사용한다. 예제 #include class IErrorLog { public: virtual ~IErrorLog() {} virtual bool reportError(const char* errorMessage) = 0; }; class FileErrorLog : public IErrorLog { public: bool reportError(const char* errorMessage) override { std::cout
C++ 추상 기본 클래스 (Abstract class)
·
C++/Class
추상 기본 클래스 (Abstract class) 순수 가상 함수가 하나라도 존재하는 클래스 순수 가상 함수가 존재하는데 오버라이딩하는 함수가 없을 경우, 에러가 발생한다. 예제 #include class Animal { protected: std::string name_; public: Animal(const std::string &name_in) : name_(name_in) {} std::string getName() { return name_; } virtual void speak() const = 0; // pure virtual function }; class Cat : public Animal { public: Cat(const std::string& name_in) : Animal(name_..
C++ 순수 가상 함수 (Pure Virtual Function)
·
C++/Class
순수 가상 함수 (Pure Virtual Function) body가 없고 값이 0으로 설정된 virtual 함수를 의미한다. body를 외부에서 정의할 수는 있는데 의미는 없다. 예제 #include class Animal { protected: std::string name_; public: Animal(const std::string &name_in) : name_(name_in) {} std::string getName() { return name_; } virtual void speak() const = 0; // pure virtual function }; class Cat : public Animal { public: Cat(const std::string & name_in) : Animal..
C++ 가상 (함수) 테이블 (Virtual Tables)
·
C++/Class
가상 (함수) 테이블 (Virtual Tables) virtual 키워드를 사용하면 내부적으로 가상 테이블의 주소가 저장된다. 예제 간단한 상속 예제 class Base { public: // FunctionPointer *_vptr; virtual void func1() {} virtual void func2() {} }; class Derived : public Base { public: // FunctionPointer *_vptr; virtual void func1() {} }; 여기서 클래스들의 가상 테이블은 다음과 같다. Base VTable 가리키고 있는 함수 func1 Base::func1 func2 Base::func2 Derived VTable 가리키고 있는 함수 func1 Derive..
C++ 동적 바인딩 (Dynamic Binding)
·
C++/Class
동적 바인딩 (Dynamic Binding) Late Binding 정적 바인딩보다 느리다. 대신 프로그래밍이 좀 더 유연해진다. 런타임에 주소를 쫓아가서 함수를 실행시키는 경우이다. 예제 #include int add(int x, int y) { return (x + y); } int subtract(int x, int y) { return (x - y); } int multiply(int x, int y) { return (x * y); } int main() { using namespace std; int x, y; cin >> x >> y; int op; cout > op; int(*func_ptr)(int, int) = nullptr; switch (op) { case 0: func_ptr = ..
C++ 정적 바인딩 (Static Binding)
·
C++/Class
정적 바인딩 (Static Binding) Early Binding 동적 바인딩보다 빠르다. 빌드 타임에 모든 변수명이나 함수명이 정의된 경우이다. 예제 #include int add(int x, int y) { return (x + y); } int subtract(int x, int y) { return (x - y); } int multiply(int x, int y) { return (x * y); } int main() { using namespace std; int x, y; cin >> x >> y; int op; cout > op; int result = 0; switch (op) { case 0: result = add(x, y); break; case 1: result = subtrac..
C++ 가상 소멸자
·
C++/Class
가상 소멸자 virtual 키워드를 소멸자에도 붙일 수 있다. 예제 가상 소멸자를 사용하지 않은 기본 예제 #include class Base { public: ~Base() { std::cout
C++ 공변 반환형(Covariant Return Type)
·
C++/Class
공변 반환형(Covariant Return Type) 포인터나 레퍼런스의 전달에서, 상속 관계의 클래스 반환 자료형에 관한 내용이다. 예제 다음은 가상 멤버 함수 getThis로 받은 포인터를 통해 일반 멤버 함수 print를 호출하는 예제이다. #include class A { public: void print() { std::cout
C++ Override, Final
·
C++/Class
Override, Final Override 부모 클래스에서 virtual로 선언한 함수를 자식 클래스에서 오버라이딩한다는 의미의 키워드이다. 컴파일러는 프로그래머의 의도를 정확하게 알 수 없기 때문에, 다음과 같이 프로그래머가 실수할 수 있는 상황이 생긴다. 예제 print 함수를 오버라이딩하려는데, 실수로 파라미터를 int가 아닌 short로 작성한 상황이다. #include class A { public: virtual void print(int x) { std::cout
C++ 가상 함수와 다형성 (virtual)
·
C++/Class
가상 함수와 다형성 (virtual) 상속 최상위 클래스에서 멤버 함수를 정의할 때 virtual 키워드를 사용하면, 가장 말단까지 오버라이딩된 함수를 찾아서 실행한다. #include class A { public: virtual void print() { std::cout
C++ 다형성의 기본 개념
·
C++/Class
다형성의 기본 개념 부모 클래스의 포인터로 자식 클래스의 주소를 가리키면, 부모 클래스의 인스턴스로 인식한다. 예제 자식 클래스에서 멤버 함수를 오버라이딩해도, 부모 클래스의 포인터에서 접근하면 부모 클래스의 멤버 함수가 호출된다. #include class Animal { protected: std::string name_; public: Animal(const std::string & name_in) : name_(name_in) {} std::string getName() { return name_; } void speak() const { std::cout
C++ 다형성 (Polymorphism)
·
C++/Class
다형성 (Polymorphism) 다형성의 기본 개념 가상 함수와 다형성 override, final 공변 반환형(Covariant Return Type) 가상 소멸자 (Virtual Destructor) 정적 바인딩 (Static Binding) 동적 바인딩 (Dynamic Binding) 가상 테이블 (Virtual Tables) 순수 가상 함수 (Pure Virtual Function) 추상 기본 클래스 (Abstract class) 인터페이스 클래스 (Interface Class) 다이아몬드 상속 (Diamond Polymorphism) 객체 잘림 (Object Slicing) 동적 형변환 (Dynamic Casting) 유도 클래스에서 출력 연산자 사용하기
따라하며 배우는 C++ 12장
·
C++/TBC++
따라하며 배우는 C++ 12장 다형성 (Polymorphism) 참고 따라하며 배우는 C++
C++ 다중 상속
·
C++/Class
다중 상속 여러 클래스에서 상속을 받을 수 있다. #include class USBDevice { int id_; public: USBDevice(int id_in) : id_(id_in) {} int getID() { return id_; } void plugAndPlay() {} }; class NetworkDevice { int id_; public: NetworkDevice(int id_in) : id_(id_in) {} int getID() { return id_; } void networking() {} }; class USBNetworkDevice : public USBDevice, public NetworkDevice { public: USBNetworkDevice(int usb_id, i..
C++ 상속받은 멤버의 접근 권한 변경
·
C++/Class
상속받은 멤버의 접근 권한 변경 using 키워드 사용 #include class Base { protected: int i_; }; class Derived : public Base { public: using Base::i_; }; int main() { using std::cout; using std::endl; Derived d; d.i_ = 1024; cout