이번엔 제너릭, ref, out에 대해서 정리해본다.

C++과 많이 유사해 보이지만, C++의 템플릿, 레퍼런스, 포인터도 정확한 개념을 다시 잡아갈 목적으로 두 개념에 대해 비교 정리 해보고자 한다.


C# 제너릭 vs C++ 템플릿

  • C# 제너릭(Generics): 자료형을 지정하지 않고, 컴파일 시점에 타입을 결정하는 기능.
  • C++ 템플릿(Templates): 함수나 클래스를 작성할 때, 특정 타입에 의존하지 않도록 하는 기능.

C# 제너릭 예제

using System;

class GenericClass<T> // T는 타입 파라미터
{
    private T data;
    
    public void SetData(T value)
    {
        data = value;
    }

    public T GetData()
    {
        return data;
    }
}

class Program
{
    static void Main()
    {
        GenericClass<int> intObj = new GenericClass<int>(); // int 타입 지정
        intObj.SetData(10);
        Console.WriteLine(intObj.GetData()); // 10 출력

        GenericClass<string> strObj = new GenericClass<string>(); // string 타입 지정
        strObj.SetData("Hello");
        Console.WriteLine(strObj.GetData()); // Hello 출력
    }
}

C++ 템플릿 예제

#include <iostream>
using namespace std;

template <typename T> // T는 타입 파라미터
class GenericClass
{
private:
    T data;
    
public:
    void SetData(T value)
    {
        data = value;
    }

    T GetData()
    {
        return data;
    }
};

int main()
{
    GenericClass<int> intObj; // int 타입 지정
    intObj.SetData(10);
    cout << intObj.GetData() << endl; // 10 출력

    GenericClass<string> strObj; // string 타입 지정
    strObj.SetData("Hello");
    cout << strObj.GetData() << endl; // Hello 출력

    return 0;
}

C# 제너릭과 C++ 템플릿의 차이점

특징 C# 제너릭 (Generics) C++ 템플릿 (Templates)
타입 검사 컴파일 타임에서 강력한 타입 검사 수행 컴파일 타임에 타입 검사하지만, 인스턴스화 시점에서 결정됨
코드 재사용성 런타임에도 타입 안전성 유지 매번 새로운 코드가 생성됨 (코드 중복 발생 가능)
기본 타입 지원 int, string 등 모든 타입 사용 가능 기본적으로 객체 타입만 지원, template<typename T>로 지정해야 함
제약 조건 where T : ClassName 같은 제약 조건 사용 가능 enable_if 같은 추가적인 기능 필요

C# ref vs C++ Reference

  • C# ref: 변수를 참조로 전달(Reference Passing)하여 값이 변경되도록 한다.
  • C++ Reference(참조): 특정 변수의 별칭(Alias) 역할을 하며, 함수에 전달할 때 원본 변수를 직접 조작할 수 있도록 한다.

C# ref 예제

using System;

class Program
{
    static void Modify(ref int x) // ref 키워드 사용
    {
        x = 100; // 원본 변수 변경
    }

    static void Main()
    {
        int a = 10;
        Modify(ref a);
        Console.WriteLine(a); // 100 출력
    }
}

C++ Reference(참조) 예제

#include <iostream>
using namespace std;

void Modify(int& x) // 참조로 전달
{
    x = 100; // 원본 변수 변경
}

int main()
{
    int a = 10;
    Modify(a);
    cout << a << endl; // 100 출력
    return 0;
}

C# ref와 C++ Reference의 차이점

특징 C# ref C++ 참조 (&)
기본 개념 변수를 참조로 전달 변수의 별칭(Alias) 제공
사용 방법 ref 키워드 필요 (ref를 명시해야 참조 가능) &를 사용하여 참조
재할당 가능 여부 불가능 (ref는 새로운 변수를 가리킬 수 없음) 불가능 (초기 참조 후 다른 변수를 참조할 수 없음)
NULL 가능 여부 null을 전달 가능 (ref int?) NULL 참조 불가능

C# out vs C++ *(포인터)

  • C# out: 함수가 반환 값을 여러 개 가질 수 있도록 한다. (반드시 값이 할당되어야 함)

  • **C++ 포인터 **: 함수에서 값을 변경할 때 포인터를 사용하여 직접 메모리 주소를 조작함.

C# out 예제

using System;

class Program
{
    static void Calculate(int a, int b, out int sum, out int diff)
    {
        sum = a + b;
        diff = a - b;
    }

    static void Main()
    {
        int x, y;
        Calculate(10, 5, out x, out y);
        Console.WriteLine($"Sum: {x}, Diff: {y}"); // Sum: 15, Diff: 5 출력
    }
}

C++ 포인터(*) 예제

#include <iostream>
using namespace std;

void Calculate(int a, int b, int* sum, int* diff)
{
    *sum = a + b;
    *diff = a - b;
}

int main()
{
    int x, y;
    Calculate(10, 5, &x, &y);
    cout << "Sum: " << x << ", Diff: " << y << endl; // Sum: 15, Diff: 5 출력
    return 0;
}

C# out과 C++ 포인터의 차이점

특징 C# out C++ 포인터 (*)
기본 개념 다중 반환 값을 지원 (값이 반드시 할당되어야 함) 포인터를 통해 함수 내에서 값을 변경
NULL 가능 여부 NULL을 허용하지 않음 포인터는 NULL이 될 수 있음
초기화 필요 여부 호출 전에 초기화할 필요 없음 NULL 체크 필요

결론

  • C#의 Generics는 C++의 Templates와 개념이 비슷하지만, 타입 안정성을 더 보장한다.
  • C#의 ref는 C++의 &(참조)와 유사하지만, ref를 명시적으로 선언해야 한다.
  • C#의 out은 C++의 포인터(\*)와 유사하지만, 반드시 값이 할당되어야 한다.

태그: ,

카테고리:

업데이트:

댓글남기기