C#) 제너릭과 ref, out
이번엔 제너릭, 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++의 포인터(\*)와 유사하지만, 반드시 값이 할당되어야 한다.
댓글남기기