▶ C# 에서 포인터가 없으면 어떡하죠?
C++ 에서는 포인터를 지원하여 임의의 객체의 멤버에 접근할 수 있습니다.
하지만 C# 에서는 포인터를 지원하지 않습니다. (물론, unsafe 키워드를 이용해서 포인터를 사용할 수 있긴 하지만 극히 제한됩니다.)
그렇다면 포인터 없이 객체에 접근하려면 어떻게 해야 할이지 난감할 수 있습니다.
C# 에서는 참조 타입이라고 하여, 값 타입을 제외한 모든 타입이 참조 타입이 됩니다.
예를 들어 보겠습니다.
C# 프로젝트 형식을 Windows 응용 프로그램으로 지정하여 프로젝트를 생성하면 기본적으로 Form1 라는 클래스가 나옵니다.
namespace refForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
이런 형태가 나온다는 얘기입니다.
이 클래스에 myMoney 라는 멤버 변수를 정의하겠습니다.
public partial class Form1 : Form
{
private int myMoney = 1000;
...
}
이 질문의 요지는 "Form1 에 있는 커스텀 변수에 어떻게 접근할 수 있는가?" 이므로, 교육 목적상 새로운 폼 클래스를 하나 정의하겠습니다.
새로운 폼은 다음처럼 정의합니다.
public class Form2 : Form
{
Form1 refForm1;
public Form2(Form1 referenceForm)
{
this.refForm1 = referenceForm;
//폼의제목
this.Text = "Another Form";
//버튼추가
Button btn_refForm1 = new Button();
btn_refForm1.Left = this.Left + 30;
btn_refForm1.Top = this.Top + 30;
btn_refForm1.Text = "Form1 의멤버변수출력하기";
btn_refForm1.AutoSize = true;
btn_refForm1.Parent = this;
btn_refForm1.Click += this.btn_OnClick;
}
private void btn_OnClick(object sender, EventArgs e)
{
}
}
Form2 의 멤버 변수로 다음을 정의했습니다.
Form1 refForm1;
즉, C# 에서는 값 타입을 제외한 모든 타입이 참조이므로, 위와 같은 문장은 Form1 타입의 개체를 참조하는 refForm1 변수라고 해석하시면 됩니다.
refForm1 변수에 Form1 또는 Form1에서 파생된 그 어떠한 객체를 할당할 수 있습니다.
Form2 클래스의 생성자를 보면 다음과 같은 문장이 있습니다.
this.refForm1 = referenceForm;
이렇게 되면, Form2 의 멤버 변수 refForm1 은 referenceForm 이라는 객체를 가리키게 됩니다.
이제는 Form2 클래스 내부에 다른 Form1 객체를 가리키는 멤버 변수를 가지게 되는 셈입니다.
이 refForm1 변수를 잘 활용하면, refForm1 이 가리키는 객체에 접근할 수 있습니다.
여기서 중요한 점이 있는데, refForm1 이라는 변수는 스택에 할당됩니다. 객체 그 자체가 아닙니다.
다만 Form1 또는 Form1에서 파생된 객체를 참조할 (가리킬) 뿐입니다.
또한, refForm1 이 Form1 또는 Form1에서 파생된 객체를 참조한다고 해도, 참조되는 대상에 아무렇게나 접근할 수는 없습니다.
참조되는 대상이 외부에 대해 통로(public 멤버)를 개방해줘야만 가능합니다.
refForm1 참조는 참조되는 대상이 제공하는 public 멤버만 사용할 수 있습니다.
이제, Form1 클래스로 돌아와보겠습니다.
public partial class Form1 : Form
{
private int myMoney = 1000;
public Form1()
{
InitializeComponent();
Form2 newForm = new Form2(this);
newForm.Show();
}
public int Money
{
get
{
return myMoney;
}
set
{
myMoney = value;
}
}
}
뭔가가 보이십니까?
Form1 클래스에 private 멤버 변수 myMoney 에 접근할 수 있도록, 프로퍼티(Property)를 설정했습니다.
C# 프로퍼티는 종래의 get_XXX()/set_XXX() 멤버 함수를 대체하도록 설계되었습니다.
물론 C++ 에서처럼, get_XXX()/set_XXX() 멤버 함수를 사용해도 되지만, .NET 의 대세는 프로퍼티를 추천합니다.
이 프로퍼티를 private 멤버에 대한 인터페이스로 활용하면 됩니다.
그럼, 이제 Form2 클래스로 돌아가겠습니다.
Form2 클래스의 버튼 객체 btn_refForm1 의 클릭 이벤트 핸들러를 설정해서, refForm1 변수가 참조하는 대상의 멤버 변수를 출력하도록 해보겠습니다.
private void btn_OnClick(object sender, EventArgs e)
{
MessageBox.Show(refForm1.Money.ToString(), "Form1 개체에접근하기");
}
관련 소스 파일은 http://blog.naver.com/poweryang1 [지식iN QandA]에서 찾아보시면 됩니다.