C++의 클래스 템플릿 상속

Muhammad Husnain 2024년2월15일
  1. C++의 템플릿
  2. C++의 함수 템플릿
  3. C++의 클래스 템플릿
  4. C++의 클래스 템플릿 상속
C++의 클래스 템플릿 상속

이 기사에서는 C++에서 가장 인기 있고 자주 사용되는 방법 중 하나(예: 클래스 템플릿)에 대해 설명합니다.

C++에 템플릿이 추가되면서 Generic 프로그래밍으로 알려진 새로운 코딩 패러다임이 도입되었습니다. 이것은 이제 C++ 프로그래머 툴킷의 중요한 요소이자 많은 표준 라이브러리의 기초이며 많은 새로운 C++ 해커가 이전에 접한 적이 없는 것입니다.

제네릭 프로그래밍은 때때로 개체 지향 프로그래밍의 상속 개념과 대조됩니다. 반면에 진정한 다중 패러다임 접근 방식은 두 패러다임이 상호 작용하는 방식을 살펴봐야 합니다.

C++의 템플릿

C++에서 템플릿은 기본적이지만 강력한 도구입니다. 기본 아이디어는 데이터 유형을 매개변수로 전달하여 여러 데이터 유형에 대해 동일한 코드를 작성할 필요가 없도록 하는 것입니다.

예를 들어 소프트웨어 비즈니스는 많은 데이터 종류에 대해 sort()를 요구할 수 있습니다. 수많은 코드를 작성하고 유지하는 대신 단일 sort() 함수를 구성하고 데이터 유형을 매개변수로 전달할 수 있습니다.

C++는 템플릿을 지원하기 위해 템플릿타입 이름이라는 두 개의 새로운 키워드를 추가했습니다. class 키워드는 항상 두 번째 키워드 대신 사용할 수 있습니다.

통사론:

template <typename T>
void myFunction(T var )
{
    //function definition
}

위의 구문에서 템플릿 변수를 매개 변수로 허용하는 함수를 정의하기 위해 template<typename T> 줄을 추가했음을 알 수 있습니다. 이제 이 함수는 모든 데이터 유형의 매개변수를 허용할 수 있습니다. int, char 및 기타 여러 데이터 유형에 사용되는 일반 함수입니다.

C++에서 템플릿 작동 방식

템플릿은 컴파일 프로세스 중에 확장됩니다. 이것은 매크로와 유사합니다.

반면에 컴파일러는 템플릿 확장 전에 유형 검사를 수행합니다. 개념은 간단합니다. 소스 코드에는 하나의 함수 또는 클래스만 포함되는 반면 생성된 코드에는 동일한 함수 또는 클래스의 여러 복사본이 있을 수 있습니다.

아래 예에서 자세히 설명합니다.

#include <iostream>
using namespace std;

template <typename T>
T checkMaxValue(T a, T b) {
  if (a > b)
    return a;
  else if (b > a)
    return b;
  else
    return 0;
}

// driver program
int main() {
  cout << checkMaxValue(102, 204) << endl;  // int value
  cout << checkMaxValue('c', 'f') << endl;  // char value
}

우리는 드라이버 프로그램의 첫 번째 줄에 있는 함수에 두 개의 정수를 전달했으며 결국 둘 중 최대값 정수를 반환할 것입니다. 두 번째 줄에 있는 동일한 함수에 두 개의 char 값을 전달했으며 함수는 최대 char 값을 반환합니다.

컴파일 타임에 아래와 같이 함수를 호출합니다.

int checkMaxValue(int a, int b)

그리고 두 번째 호출에 대해 다음과 같이 작성합니다.

char checkMaxValue(char a, char b)

함수를 호출할 때 전달되는 변수의 유형에 따라 컴파일 타임에 동일한 함수의 여러 복사본이 생성되는 것을 볼 수 있습니다.

함수와 클래스에 대한 템플릿을 사용할 수 있습니다. 두 가지 유형과 구현 방법에 대해 논의할 것입니다.

C++의 함수 템플릿

다양한 데이터 종류와 함께 작동할 수 있는 일반 함수를 만들 것입니다. Sort(), max(), min()printArray는 함수 템플릿의 예입니다.

예제 코드:

template <class T>
void sortArray(T arr[], int s) {
  for (int i = 0; i < s - 1; i++)
    for (int j = s - 1; i < j; j--)
      if (arr[j] < arr[j - 1]) {
        int var = arr[j];
        arr[j] = arr[j - 1];
        arr[j - 1] = var;
      }
  cout << " Sorted array : ";
  for (int i = 0; i < s; i++) cout << arr[i] << " ";
  cout << endl;
}

// Driver Code
int main() {
  int a[5] = {10, 50, 30, 40, 20};
  int n = 5;
  sortArray<int>(a, n);

  char c[5] = {'g', 'a', 'i', 'h', 'e'};
  sortArray<char>(c, n);
  return 0;
}

출력:

함수 템플릿 출력

코드 스니펫에서 배열의 템플릿 유형과 해당 배열의 크기 값을 수락하고 정렬된 배열을 인쇄할 수 있는 sortArray() 함수를 만들었습니다. 메인 코드에서 int 및 char 배열이라는 두 가지 다른 배열 유형에 대해 호출했습니다.

결과적으로 모든 데이터 유형을 사용할 수 있으며 동일한 기능이 작동합니다. 시간과 공간을 절약하고 일반 프로그래밍에서도 효율적입니다.

C++의 클래스 템플릿

함수 템플릿과 같은 클래스 템플릿은 클래스가 데이터 유형에 의존하지 않는 것을 정의할 때 유용합니다. LinkedList, BinaryTree, Stack, Queue, Array 및 더 많은 클래스가 클래스 템플릿의 이점을 누릴 수 있습니다.

통사론:

template <class T>
class className {
 private:
  T a;
  ........public : T myFunc(T x);
  ........
};

이 구문에서 T는 데이터 유형의 자리 표시자로 사용되는 템플릿 유형입니다. 이 템플릿 클래스에 대한 개체를 만들 때 다음 구문이 사용됩니다.

className<dataType> objectName;

마찬가지로 다음 구문을 사용하여 작성할 수 있습니다.

className<int> objectName;
className<double> objectName;

예:

#include <iostream>
using namespace std;

template <class T>
class Number {
 private:
  T numb;

 public:
  Number(T a) : numb(a) {}

  T get() { return numb; }
};

int main() {
  Number<int> integerNumber(50);
  Number<double> doubleNumber(8.9);
  cout << "integer Number = " << integerNumber.get() << endl;
  cout << "double Number = " << doubleNumber.get() << endl;
  return 0;
}

출력:

클래스 템플릿 출력

이 예에서 동일한 클래스가 정수와 이중 숫자를 허용할 수 있음을 알 수 있습니다. 이 예제는 클래스 템플릿의 개념을 이해할 수 있도록 매우 일반적입니다.

이 개념은 확장될 수 있으며 LinkedList, Stack, Queue 등과 같은 템플릿을 사용하여 많은 클래스를 구현할 수 있습니다.

C++의 클래스 템플릿 상속

템플릿 클래스에서 상속하는 것이 가능합니다. 모든 일반 상속 및 다형성 규칙이 적용됩니다.

새 파생 클래스가 일반적이어야 하는 경우 템플릿 인수를 기본 클래스로 보내는 템플릿 클래스로 만들어야 합니다. 이는 상속이 클래스에서만 가능하고 템플릿에 일부 데이터 유형을 전달하여 인스턴스화하지 않는 한 템플릿이 클래스가 아니기 때문입니다.

통사론:

template <class T>
class derived : public Base<T>{};

예:

#include <iostream>
using namespace std;

template <class T>
class Base {
 private:
  T val;

 public:
  void setVal(T a) { val = a; }
};
template <class T>
class Derived : public Base<T> {
 public:
  void setVal(T b) { Base<T>::setVal(b); }
};
int main() {
  Derived<int> a;
  a.setVal(4);
  return 0;
}

코드 스니펫에 템플릿 유형 변수와 멤버 함수가 포함된 Base 클래스 템플릿을 만들었습니다. 또한 클래스 템플릿이기도 하고 Base 클래스 템플릿을 확장하는 파생 클래스를 만들었습니다.

Base 클래스를 확장할 때 Base<T>와 같은 템플릿 변수를 지정해야 합니다. Base 클래스는 제네릭이며 파생 클래스도 제네릭입니다.

파생 클래스는 템플릿 매개변수도 가질 수 있습니다. 이전 예제는 다음과 같이 수정할 수 있습니다.

template <class T, class S>
class Derived : public Base<T> {
 private:
  S data;

 public:
  void setVal(T b) {
    Base<T>::setVal(b);
    data = b;
  }
};

따라서 클래스 템플릿을 사용하여 상속도 구현할 수 있음을 알 수 있습니다. 또한 클래스 템플릿을 사용하여 다형성 및 어댑터 클래스를 구현할 수 있습니다.

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn

관련 문장 - C++ Class