c++

C++ 객체 지향 프로그래밍: 연산자 오버로딩과 템플릿

난개발자 2025. 2. 2. 14:43
728x90

1. 연산자 오버로딩(Operator Overloading)이란?

연산자 오버로딩은 C++에서 기존 연산자(+, -, *, / 등)의 기능을 사용자 정의 데이터 타입에 맞게 재정의하는 기능입니다. 이를 통해 클래스 객체 간에도 직관적인 연산을 수행할 수 있습니다.

(1) 기본 연산자 오버로딩

#include <iostream>
using namespace std;

class Complex {
private:
    double real;
    double imag;

public:
    // 생성자
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // '+' 연산자 오버로딩
    Complex operator + (const Complex& obj) {
        return Complex(real + obj.real, imag + obj.imag);
    }

    // 결과 출력 함수
    void display() {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex num1(3.0, 4.0);
    Complex num2(1.0, 2.0);
    Complex result = num1 + num2;  // '+' 연산자 오버로딩 사용

    result.display();  // 4.0 + 6.0i 출력
    return 0;
}

(2) 출력 결과:

4 + 6i

이렇게 하면 Complex 클래스 객체끼리 + 연산을 직관적으로 사용할 수 있습니다.


(3) 다른 연산자 오버로딩 예제

(a) == 연산자 오버로딩

객체 비교를 위해 == 연산자를 오버로딩할 수 있습니다.

class Complex {
    // ... (생략)

public:
    bool operator == (const Complex& obj) {
        return (real == obj.real) && (imag == obj.imag);
    }
};

int main() {
    Complex num1(3.0, 4.0);
    Complex num2(3.0, 4.0);

    if (num1 == num2) {
        cout << "두 복소수는 같습니다." << endl;
    } else {
        cout << "두 복소수는 다릅니다." << endl;
    }
    return 0;
}

(b) 출력 결과:

두 복소수는 같습니다.

2. 템플릿(Templates)이란?

템플릿은 데이터 타입에 상관없이 재사용 가능한 코드를 작성할 수 있도록 도와줍니다. 이를 통해 코드 중복을 줄이고, 다양한 데이터 타입을 처리할 수 있습니다.

(1) 함수 템플릿

함수 템플릿을 사용하면 여러 데이터 타입에 대해 동일한 로직을 적용할 수 있습니다.

#include <iostream>
using namespace std;

// 함수 템플릿 정의
template <typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    cout << getMax(10, 20) << endl;        // int 타입 비교
    cout << getMax(3.14, 2.71) << endl;    // double 타입 비교
    cout << getMax('A', 'Z') << endl;      // char 타입 비교
    return 0;
}

(2) 출력 결과:

20
3.14
Z

함수 템플릿을 사용하면 다양한 데이터 타입에 대해 getMax() 함수를 재사용할 수 있습니다.


(3) 클래스 템플릿

클래스 템플릿을 사용하면 데이터 타입에 상관없이 다양한 객체를 생성할 수 있습니다.

#include <iostream>
using namespace std;

// 클래스 템플릿 정의
template <typename T>
class Calculator {
private:
    T num1, num2;

public:
    Calculator(T a, T b) : num1(a), num2(b) {}

    T add() { return num1 + num2; }
    T subtract() { return num1 - num2; }
};

int main() {
    Calculator<int> intCalc(10, 5);
    cout << "덧셈 (int): " << intCalc.add() << endl;
    cout << "뺄셈 (int): " << intCalc.subtract() << endl;

    Calculator<double> doubleCalc(3.5, 1.2);
    cout << "덧셈 (double): " << doubleCalc.add() << endl;
    cout << "뺄셈 (double): " << doubleCalc.subtract() << endl;

    return 0;
}

(4) 출력 결과:

덧셈 (int): 15
뺄셈 (int): 5
덧셈 (double): 4.7
뺄셈 (double): 2.3

3. 템플릿 특수화(Template Specialization)

템플릿 특수화는 특정 데이터 타입에 대해 별도의 동작을 정의할 때 사용합니다.

#include <iostream>
using namespace std;

// 일반 템플릿 정의
template <typename T>
class Display {
public:
    void show(T value) {
        cout << "값: " << value << endl;
    }
};

// 템플릿 특수화: char* 타입에 대한 처리

// 특수화된 템플릿 정의
template <>
class Display<char*> {
public:
    void show(char* value) {
        cout << "문자열: " << value << endl;
    }
};

int main() {
    Display<int> intDisplay;
    intDisplay.show(100);

    Display<char*> strDisplay;
    strDisplay.show("Hello, Templates!");

    return 0;
}

(5) 출력 결과:

값: 100
문자열: Hello, Templates!
728x90