대상 언어에서 대상을 대상으로 하는 사용에 대해 간단히 말하다.

4920 단어 대상을 향하다
본고가 여러분을 오도하는 것을 피하기 위해서 먼저 대상 언어에서 이런 것들을 탐구하는 것은 큰 의미가 없지만 우리가 더욱 잘 이해할 수 있도록 도와줄 수 있다고 성명합니다.NET 언어 특성.이 글은 C#을 예로 들면 언급될 것이다.NET의 클론(얕은 복제).
이 토론은 합작 개발로 인해 일어난 것이다.당시 DBHelper층에서 new 키워드를 사용하여 데이터베이스 테이블 대상(DataTable)을 만들었는데 데이터 접근층(DAL)에서 데이터베이스 테이블 대상을 수신할 때 키워드 new를 추가하지 않고 DataTable의 '대상 변수': DataTable dtDataTable dt = new DataTable ().과연 이렇게 쓰는 것이 맞을까요?
쓸데없는 말은 하지 말고 원리를 직접 말해라. 지구인들은 하나의 대상을 실례화하려면 반드시 키워드 new를 사용해야 한다. 예를 들어 DataTable dt = new DataTable ();이 new는 메모리를 분배하는 역할을 한다. 컴파일러가 키워드 new를 읽을 때 메모리에 공간을 열어 클래스를 배치하는 실례를 말한다. dt에 저장된 것은 이 메모리 공간의 첫 번째 주소일 뿐이다. 저장된 것은 대상이 아니다. 한 대상이 어떻게 변수에 존재할 수 있겠는가?사실, 이 dt는 기본적으로 int32형으로, 저장된 것은 단지 하나의 주소일 뿐이고, 지침이라고 할 수도 있다.하지만 New를 사용하지 않고 DataTable dt;이렇게 하면 단지 하나의 변수를 성명할 뿐이다. 그의 유형은 DataTable이다. 이 변수는 DataTable 실례의 첫 번째 주소를 수용할 수 있지만 실제로dt는 단지 int32형의 변수일 뿐이다.따라서 다음과 같습니다.
DataTable dt1 = new DataTable();// 
DataTable dt2; // , 
dt2 = dt1; // dt1 , dt2

이런 문법에서 우리는 dt1과 dt2가 모두 완벽하게 기능을 완성할 수 있다는 것을 발견했다. 겉으로는 두 가지 실례가 있지만 실제로는 단지 하나의 실례만 있다!dt2는 dt1에 저장된 실례 주소를 인용한 것에 불과합니다!dt1과 dt2는 같은 실례를 사용하고 같은 메모리 주소를 사용합니다.그래서 그들은 서로 영향을 미친다. 만약에 dt1이 강제로 소각된다면 dt2도 정상적으로 사용할 수 없다(흥미가 있는 독자는 스스로 시험해 볼 수 있다. 여기서 예를 들지 않는다).사실 우리는 대상이 메모리의 특정한 구역을 가리키는 것이지 당신이 정의한 대상 변수가 아니라고 비정규적으로 말할 수 있다.
만약 네가 C언어를 배운 적이 있다면, 내가 위에서 말한 것을 쉽게 이해할 수 있을 것이다.그러나 또 어떤 사람은 이것이 사실은.NET의 클론 - 얕은 복제.이것은 크게 잘못한 것이다!당시에 나도 자세히 생각하지 않고 무턱대고 인정했지만 나중에 자세히 생각해 보니 이것은 근본적으로 두 개념이라는 것을 발견하였다.클론(얕은 복제)의 정의: "새 객체를 만들고 현재 객체의 비정상적인 필드를 새 객체로 복사하는 방법으로 현재 객체의 얕은 테이블 복사본을 만듭니다. 필드가 값 유형인 경우 필드를 한 위치씩 복사합니다. 필드가 참조 유형인 경우 참조를 복사하지만 참조된 객체는 복사하지 않습니다."이로써 독자들은 복제가 사실상 '불완전한 대상' 을 만들었고 위에서 말한 인용 주소와 전혀 같지 않다는 것을 알 수 있다.복제는 먼저 새로운 대상을 만들었다. 즉, 이미 메모리 공간을 개척한 다음에 복제된 대상의 수치 유형의 필드(스택 데이터, 수치 유형의 국부 변수로 간단하게 이해할 수 있음)를 새로운 대상의 메모리 공간으로 복제하고, 복제된 대상의 인용 유형 필드(즉 대상)에 대해서는 인용만 복제(그 대상의 메모리 주소를 복제)하고 메모리 공간을 개척하지 않는다.이 원리는 위에서 말한 것과 일치한다.간단하게 말하자면 클론은 수치형 데이터를 복제하고 대상을 인용했다.위에서 언급한 문법은 완전 인용이다.
더욱 설득력 있게 코드 운행 결과가 모든 것을 설명하도록 하기 위해
clsTestB 클래스:
 class clsTestB
    {
        private string strByVal;// 
        public string byval
        {
            get { return strByVal; }
            set { strByVal = value; }
        }
    }

clsTesta 클래스, 클론 인터페이스 구현:
class clsTestA:ICloneable
    {
        private string strByVal; // 
        private clsTestB clstestb = new clsTestB(); // 
        //byval 
        public string byval
        {
            get { return strByVal; }
            set { strByVal = value; }
        }
        //byref 
        public string byref
        {
            get { return clstestb.byval; }
            set { clstestb.byval = value; }
        }
        // 
        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }

전체 참조 예제 코드:
clsTestA clstest1 = new clsTestA(); // clsTestA 
clsTestA clstest2;   // clsTestA “ ”
clstest1.byval = "0"; // clstest1 
clstest1.byref = "0"; // clstest1 
clstest2 = clstest1;// clstest2 clstest1 , 
clstest1.byval = "byval";// clstest1 
clstest1.byref = "byref";// clstest1 
MessageBox.Show(clstest2.byval + "|" + clstest2.byref);   

이 코드 출력 결과는:byval|byref입니다.분석:clstest2가clstest1을 인용한 후clstest1은 수치 속성과 인용 속성을 바꾸었고clstest2의 상응하는 속성도 이에 따라 바뀌었다. 이는 수치형 필드든 인용형 필드든clstest2는clstest1과clstest2를 완전히 인용하는 것이 사실은 하나의 물건이라는 것을 의미한다.
클론 예제 코드:
clsTestA clstest1 = new clsTestA(); // clsTestA 
clsTestA clstest2;   // clsTestA “ ”
clstest1.byval = "0"; // clstest1 
clstest1.byref = "0"; // clstest1 
clstest2 = (clsTestA)clstest1.Clone();//clstest1 clstest2 
clstest1.byval = "byval";// clstest1 
clstest1.byref = "byref";// clstest1 
MessageBox.Show(clstest2.byval + "|" + clstest2.byref);   

이 코드 출력 결과는 0|byref입니다.분석:clstest2는clstest1을 통해 복제된 것이다.clstest2는 이미 새로운 실례이다.clstest2의 수치형 속성은clstest1에서 복제되어 이미clstest1의 영향을 받지 않는다.한편,clstest2의 인용형 속성은 직접 인용하는clstest1이기 때문에clstest1의 인용 속성이 바뀌면clstest2의 상응하는 속성에 영향을 줄 수 있다.
위에서 말한 바와 같이 우리는 심지어 이렇게 쓸 수 있다.
DataTable dt1 = new DataTable();// 
DataTable dt2; // , 
DataTable dt3; // , 
dt2 = dt1; // dt1 , dt2
dt3 = dt2; // dt2 , dt3

이런 작법은 완전히 가능하다!한 번만 실례화하면 나중에 실례화하지 않아도 그대로 인용할 수 있다.어떤 사람들은 의문이 있을 수 있다. 우리가 dt3을 사용할 때, dt1이 소각되면 어떻게 합니까?마음 놓으세요.NET의 위탁 관리 메커니즘은 인용되고 있는 메모리 주소를 방출하지 않습니다.dt1, dt2, dt3은 어떤 '대상'이 사용되고 있으며, 그들이 가리키는 주소는 방출되지 않습니다.(왜 풀리지 않는지 알고 싶으면 Windows Core 프로그래밍 참조
물론 우리는 좋은 습관을 길러야 한다. 실례화 대상은 모두 new를 넣어야 한다.어쨌든 우리가 사용하는 것은 대상을 대상으로 하는 언어이지 밑바닥 언어가 아니다. 이런 문제들을 너무 많이 고려할 필요가 없다. 실례화 대상을 할 때 new를 추가하면 문제가 생기지 않을 것을 보증한다!

좋은 웹페이지 즐겨찾기