오브젝트 라이프 타임

Object lifetime

객체 지향 프로그래밍(OOP)에서 객체수명(또는 수명 주기)은 객체의 생성과 파괴 사이의 시간입니다.오브젝트 라이프 타임의 규칙은 언어마다, 경우에 따라서는 특정 언어의 구현 간에 크게 달라지며, 특정 오브젝트의 라이프 타임은 프로그램의 실행마다 다릅니다.

경우에 따라서는 객체의 라이프타임이 변수 라이프타임과 일치하고 그 객체가 값(스태틱 변수와 자동 변수 모두)인 경우도 있습니다만, 일반적으로 객체의 라이프타임이 1개의 변수의 라이프타임과 관련되지 않습니다.많은 경우(특히 Garbage Collection(GC; 가비지 컬렉션)을 사용하는 경우) 기본적으로는 오브젝트는 에 할당되며 오브젝트의 라이프 타임은 특정 변수의 라이프 타임에 의해 결정되지 않습니다.개체를 보유하는 변수의 값은 실제로 오브젝트 자체가 아닌 오브젝트에 대한 참조에 대응합니다.변수를 삭제하면 참조만 삭제되고 기본 개체는 삭제되지 않습니다.

개요

오브젝트의 라이프 타임에 대한 기본적인 개념은 간단하지만 오브젝트는 작성, 사용, 파기할 수 있습니다.상세한 내용은 언어에 따라, 그리고 특정 언어의 실장에 따라 크게 다릅니다.메모리 관리의 실장 방법에 밀접하게 관련되어 있습니다.게다가 스텝과 언어 레벨의 개념과 실장 레벨의 개념 사이에는 많은 미세한 차이가 있다.용어는 비교적 표준적이지만, 주어진 용어에 대응하는 단계는 언어마다 크게 다릅니다.

용어는 일반적으로 반의어 쌍으로 제공되는데, 하나는 창조 개념, 다른 하나는 해당 파괴 개념(초기화/최종화 또는 생성자/파괴자)입니다.생성/파괴 쌍은 시작/종료라고도 합니다.할당 및 할당 해제 또는 해방이라는 용어는 메모리 관리와 마찬가지로 사용됩니다.단, 오브젝트 작성과 파괴는 단순히 메모리 할당과 할당 해제를 수반하는 것이 아니라 할당과 할당 해제가 각각 생성과 파괴의 단계로 보다 적절하게 고려됩니다.

결정론

주요 차이점은 물체의 수명이 결정론적인지 비결정론적인지 여부입니다.이는 언어에 따라 다르며 언어 내에서는 객체의 메모리 할당에 따라 달라집니다.객체의 라이프 타임은 가변 라이프 타임과는 다를 수 있습니다.

정적 메모리 할당을 가진 오브젝트, 특히 정적 변수에 저장된 오브젝트 및 클래스 모듈(클래스 또는 모듈 자체가 객체이고 정적 할당되어 있는 경우)은 여러 언어로 미묘한 비결정론을 가지고 있습니다.이러한 오브젝트의 라이프 타임이 프로그램의 실행 시간과 일치하는 것처럼 보이지만 생성과 파괴의 순서는 다음과 같습니다.tic 객체가 먼저 생성되고, 두 번째 객체 등은 일반적으로 [a]비확정적입니다.

자동 메모리 할당 또는 동적 메모리 할당이 있는 객체의 경우 객체가 명시적으로 생성되었을 때(예를 들어 v-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-in-innewC++ 또는 Java) 또는 변수 수명 시작 시 암묵적으로, 특히 선언 [b]시 등 자동 변수 범위가 입력된 경우.그러나 오브젝트 파괴는 다양합니다.특히 C++ 언어에서는 자동 및 동적 오브젝트가 스코프 종료, 명시적 파괴(수동 메모리 관리에 의한), 레퍼런스 카운트가 0에 도달하는 등 결정론적 시점에서 파괴됩니다.C#, Java, Python 등의 다른 언어에서는 이들 오브젝트가 비결정론적 파괴됩니다.횟수는 가비지 컬렉터에 따라 다르며 파괴 중에 오브젝트가 부활하여 수명이 연장될 수 있습니다.

가비지 컬렉션 언어에서 오브젝트는 일반적으로 (스택 또는 레지스터에서) 자동으로 할당되는 원시 값을 가진 자동 변수와 달리 처음에 자동 변수에 바인딩되어 있더라도 일반적으로 동적으로 할당됩니다.이를 통해 오브젝트는 파기되지 않고 함수("탈옥")에서 반환될 수 있습니다.그러나 경우에 따라서는 컴파일러 최적화가 가능합니다.즉, 이스케이프 분석을 실행하여 이스케이프가 불가능함을 증명함으로써 오브젝트를 스택에 할당할 수 있습니다.이것은 Java에서 중요합니다.이 경우 오브젝트가 즉시 파괴됩니다.변수의 라이프 타임 중(범위가 종료되기 전)이라도 도달 불가능한 경우에는 오브젝트가 즉시 파괴될 수 있습니다.

복잡한 경우로는 오브젝트 풀을 사용하는 경우가 있습니다.이 경우 오브젝트는 미리 작성하거나 재사용할 수 있습니다.따라서 명백한 작성과 파괴는 오브젝트의 실제 작성과 파괴에 대응하지 않을 수 있습니다.생성 및 파괴를 위한 (재)초기화만 하면 됩니다.이 경우 생성과 파괴는 모두 비결정적일 수 있습니다.

순서

오브젝트 작성은 메모리 할당 초기화라는2가지 조작으로 나눌 수 있습니다.초기화에는 오브젝트필드에 값을 할당하고 임의의 다른 코드를 실행할 수 있습니다.이는 구현 수준의 개념으로, 변수의 선언과 정의의 구별과 거의 유사하지만 나중에 언어 수준의 구별이 됩니다.변수에 연결된 객체의 경우 선언은 메모리 할당(객체의 공간 예약) 및 초기화에 대한 정의(값 할당)로 컴파일될 수 있지만 선언은 컴파일된 코드에 직접 대응하지 않고 컴파일러 전용(이름 해결 등)일 수도 있습니다.

마찬가지로 오브젝트 파괴는 두 가지 조작으로 나눌 수 있습니다., 최종화와 메모리 할당 해제입니다.변수에는 유사한 언어 수준의 개념이 없습니다.변수 라이프 타임은 암묵적으로 종료됩니다(자동 변수, 스택 언바인드, 스태틱 변수, 프로그램 종료).이 시점에서(또는 실장에 따라서는 나중에) 메모리는 할당 해제되지만 일반적으로 최종화는 이루어지지 않습니다.그러나 객체의 수명이 변수의 수명에 연결되어 있을 때, 변수의 수명의 끝은 객체의 완성을 야기합니다. 이것은 C++의 표준 패러다임입니다.

이를 통해 4가지 구현 수준의 단계를 얻을 수 있습니다.

할당, 초기화, 완료, 할당 해제

이러한 순서는 언어 런타임, 인터프리터 또는 가상 머신에 의해 자동으로 실행되거나 서브루틴에서 프로그래머가 구체적으로 메서드를 통해 수동으로 지정할 수 있습니다.이 순서의 빈도는 스텝과 언어에 따라 크게 다릅니다.초기화는 클래스 기반 언어에서 프로그래머가 지정하는 것이 일반적이지만, 엄격한 프로토타입 기반 언어에서는 복사를 통해 자동으로 초기화됩니다.최종화는 결정론적 파괴가 있는 언어(특히 C++)에서도 매우 흔하지만 가비지 수집 언어에서는 훨씬 더 흔하지 않습니다.할당은 거의 지정되지 않으며 일반적으로 할당 해제를 지정할 수 없습니다.

생성 및 삭제 중 상태

중요한 미묘함은 작성 또는 파기 중 오브젝트 상태, 작성 또는 파기 실패 등 오류가 발생하거나 예외가 발생하는 처리 사례입니다.엄밀히 말하면, 개체의 수명은 할당이 완료되면 시작되고 할당 해제가 시작되면 종료됩니다.따라서 초기화 및 최종화 중에는 오브젝트가 활성화되어 있지만 일관성 있는 상태가 아닐 수 있습니다.클래스 불변성이 초기화의 중요한 부분임을 보증합니다.초기화가 완료된 후 최종화가 시작될 때까지의 기간은 오브젝트가 활성화되어 있을 뿐만 아니라 일관성 있는 상태가 될 것으로 예상되는 경우입니다.

생성 또는 파괴에 실패하면 오류 보고가 복잡해질 수 있습니다(대부분 예외를 발생시킴으로써). 개체 또는 관련 개체가 일관되지 않은 상태에 있을 수 있습니다.또한 일반적으로 암묵적으로 발생하므로 지정되지 않은 환경에서 발생하는 파괴의 경우 오류를 처리하기가 어려울 수 있습니다.반대되는 문제(발신 예외가 아닌 수신 예외)는 다른 동작이 필요한 경우 예외 처리 중에 생성 또는 파괴가 발생할 경우 다르게 동작해야 하는지 여부입니다.

또 다른 미묘한 점은 정적 변수의 생성과 파괴가 발생하는 경우입니다.이 변수의 수명은 프로그램의 실행 시간과 일치합니다.생성과 파괴는 정기적인 프로그램 실행 중 또는 정기적인 실행 전후의 특별한 단계에서 이루어집니까?또한 프로그램이 실행되지 않을 때 오브젝트가 어떻게 파괴됩니까?평소와 같은 상태이것은 특히 가비지 수집 언어에서 문제가 됩니다.이는 프로그램 종료 시 가비지가 많이 발생할 수 있기 때문입니다.

클래스 베이스 프로그래밍

클래스 기반 프로그래밍에서 객체 생성은 인스턴스화(클래스의 인스턴스 생성)라고도 하며 생성과 파괴는 생성자파괴자 또는 이니셜라이저 피니셔로 알려진 메서드를 통해 제어할 수 있습니다.따라서 생성과 파괴는 구축 파괴라고도 하며, 이러한 방법을 구축 또는 파괴('파괴'가 아님)라고 할 때 각각 초기화되거나 최종화됩니다.

이들 메서드의 관계는 복잡할 수 있으며 언어에는 컨스트럭터와 이니셜라이저(Python 등)가 모두 포함되거나 디스트럭터와 파이널라이저(C++/CLI 등)가 모두 포함되거나 "destructor"와 "finalizer"라는 용어는 언어 수준 구축 대 구현(C# 대 CLI 등)을 나타낼 수 있습니다.

중요한 차이점은 오브젝트가 생성될 때까지 사용할 수 있는 오브젝트(클래스 인스턴스)가 없기 때문에 컨스트럭터는 클래스 메서드이지만 다른 메서드(디스트럭터, 이니셜라이저 및 파이널라이저)는 오브젝트가 생성되었을 때의 인스턴스 메서드입니다.또한 생성자와 이니셜라이저는 인수를 받아들일 수 있지만 파괴자와 최종자는 일반적으로 암묵적으로 불리기 때문에 인수를 받지 않습니다.

일반적으로 컨스트럭터는 오브젝트를 생성하기 위해 사용자 코드에 의해 명시적으로 호출되는 메서드이며, 반면 "destructor"는 결정론적 오브젝트 라이프타임이 있는 언어로 오브젝트 파괴에 대해 호출되는 서브루틴이다.원형은 C++이고 "finalizer"는 에 의해 암묵적으로 호출되는 서브루틴이다.오브젝트 파괴에 관한 가비지 컬렉터는 결정적이지 않은 오브젝트 라이프 타임을 가진 언어로 표시됩니다.archetype은 Java 입니다.

최종화의 순서는 메모리 관리에 따라 크게 다릅니다.수동 메모리 관리(C++ 또는 수동 레퍼런스 카운트)에서는 프로그래머에 의해 레퍼런스를 명시적으로 파기할 필요가 있습니다(레퍼런스 클리어, 레퍼런스 카운트 감소).자동 레퍼런스 카운트에서는, 이것은 최종화 중에도 발생합니다만, 자동화가 됩니다.ted(Python에서와 같이 프로그래머가 지정한 피니셔가 호출된 후 발생할 경우), 가비지 컬렉션을 추적하는 경우 이 작업은 필요하지 않습니다.따라서 자동 참조 카운팅에서는 프로그래머 지정 피니셔가 짧거나 존재하지 않는 경우가 많지만 가비지 컬렉터를 추적하는 경우에는 종종 최종화가 필요하지 않은 반면 여전히 상당한 작업이 수행될 수 있습니다.

자원 관리

오브젝트의 라이프타임이 결정적인 언어에서는 오브젝트의 라이프타임이 자원 관리에 사용될 수 있습니다.이것을 RAII(Resource Acquisition Is Initialization) 관용어라고 합니다.리소스는 초기화 중에 취득되어 최종화 중에 해방됩니다.오브젝트의 수명이 결정적이지 않은 언어(특히 가비지 수집으로 인해)에서는 일반적으로 메모리 관리는 다른 리소스 관리와는 별도로 유지됩니다.

오브젝트 생성

일반적인 경우 프로세스는 다음과 같습니다.

  • 오브젝트 크기를 계산합니다.크기는 클래스의 크기와 거의 동일하지만 다를 수 있습니다.문제의 객체가 클래스가 아닌 프로토타입에서 파생된 경우 객체의 크기는 일반적으로 슬롯을 유지하는 내부 데이터 구조(예: 해시)의 크기입니다.
  • 할당 – 메모리의 공간을 오브젝트의 크기에 더해 나중에 증가분을 미리 알 수 있도록 할당합니다.
  • 바인딩 메서드– 보통 오브젝트 클래스에 맡기거나 디스패치해결되지만 일부 오브젝트 모델은 작성 시 메서드를 바인딩할 수 있습니다.
  • 슈퍼클래스의 초기화 코드(클래스, 컨스트럭터)를 호출
  • 생성 중인 클래스의 초기화 코드를 호출합니다.

이러한 작업은 한 번에 완료할 수 있지만 완료되지 않은 상태로 남아 있을 수 있으며 작업 순서가 달라 여러 가지 이상한 동작을 일으킬 수 있습니다.예를 들어, 다중 상속의 경우 어떤 코드를 먼저 호출해야 하는지 묻는 질문은 답변하기 어렵습니다.그러나 슈퍼 클래스 생성자는 하위 클래스 생성자보다 먼저 호출해야 합니다.

각 개체를 [further explanation needed]배열의 요소로 만드는 것은 복잡한 문제입니다.일부 언어(예: C++)는 프로그래머에게 이 작업을 맡깁니다.

오브젝트 작성 중에 예외를 처리하는 것은 특히 문제가 됩니다.이는 일반적으로 예외 송출의 구현이 유효한 오브젝트 상태에 의존하기 때문입니다.예를 들어 메모리의 빈 공간이 부족하여 그 이전에 개체를 할당하지 못한 경우 예외 개체에 새 공간을 할당할 방법이 없습니다.따라서, OO 언어의 구현은 자원의 공급이 부족할 때에도 예외를 발생시킬 수 있는 메커니즘을 제공해야 하며, 프로그래머나 타입 시스템은 그들의 코드가 예외적으로 안전함을 보장해야 한다.예외를 전파하면 리소스를 할당하는 것보다 리소스가 해방될 가능성이 높아집니다.그러나 객체 지향 프로그래밍에서 객체 구축은 실패할 수 있다. 왜냐하면 객체를 구축하는 것은 클래스 불변성을 설정해야 하기 때문이다. 클래스 불변성은 종종 생성자 인수의 모든 조합에 유효하지 않다.따라서 생성자는 예외를 발생시킬 수 있습니다.

추상 팩토리 패턴은 객체 생성을 위해 코드에서 객체의 특정 구현을 분리하는 방법입니다.

작성 방법

개체를 만드는 방법은 언어에 따라 다릅니다.일부 클래스 기반 언어에서는 생성자로 알려진 특수 메서드가 개체 상태를 검증하는 역할을 합니다.일반 메서드와 마찬가지로 지정된 다른 속성으로 개체를 만들 수 있도록 생성자를 오버로드할 수 있습니다.또한 생성자는 불변[Wrong clarification needed] 객체의 상태를 설정하는 유일한 장소입니다.복사 생성자는 생성자 클래스와 동일한 유형의 기존 개체의 (단일) 매개 변수를 가져와서 매개 변수로 전송된 개체의 복사본을 반환하는 생성자입니다.

Objective-C와 같은 다른 프로그래밍 언어에는 클래스 메서드가 있습니다.클래스 메서드는 컨스트럭터 타입 메서드를 포함할 수 있지만 오브젝트의 인스턴스화에만 국한되지 않습니다.

C++와 Java는 명명된 생성자를 제공하지 않는다는 비판을 받아왔다[by whom?]. 생성자는 항상 클래스와 이름이 같아야 한다.프로그래머가 예를 들어 두 개의 부동소수점 번호로 표현되는 데카르트 좌표 또는 극좌표에서 점 객체를 생성하기 위해 동일한 인수 유형을 가진 두 개의 생성자를 제공하고자 하는 경우 이는 문제가 될 수 있습니다.Objective-C는 프로그래머가 초기화 메서드를 사용하여 Point 클래스를 만들 수 있다는 점에서 이 문제를 회피할 수 있습니다.예를 들어 다음과 같습니다.+newPointWithX:andY:,그리고.+newPointWithR:andTheta:C++ 에서는, 스태틱 멤버 [1]기능을 사용해 같은 것을 실행할 수 있습니다.

생성자는 특히 함수 언어에서 태그 부착 유니언의 값을 작성하기 위해 사용되는 함수를 참조할 수도 있습니다.

오브젝트 파괴

일반적으로 오브젝트가 사용된 후 메모리에서 삭제되어 다른 프로그램이나 오브젝트가 그 오브젝트를 대신할 공간을 확보합니다.그러나 메모리가 충분하거나 프로그램의 실행 시간이 짧으면 객체 파괴가 발생하지 않고 단순히 프로세스 종료 시 메모리가 할당 해제될 수 있습니다.경우에 따라서는 오브젝트 파괴가 단순히 메모리의 할당 해제, 특히 가비지 수집 언어에서 이루어지거나 "오브젝트"가 실제로는 단순한 오래된 데이터 구조인 경우로 구성됩니다.다른 경우에는 할당 해제 전에 일부 작업이 수행되며, 특히 멤버 오브젝트를 파괴하거나(수동 메모리 관리), 오브젝트에서 다른 오브젝트로의 참조를 삭제하여 참조 카운트를 감소시킨다(기준 카운트).이것은 자동일 수도 있고 오브젝트에 대해 특별한 파기 방법이 호출될 수도 있습니다.

결정론적 객체 수명을 가진 클래스 기반 언어, 특히 C++에서 소멸자는 클래스의 인스턴스가 삭제되었을 때 메모리 할당이 해제되기 전에 호출되는 메서드입니다.C++에서 소멸자는 여러 면에서 생성자와 다릅니다. 즉, 오버로드될 수 없고, 인수가 없어야 하며, 클래스 불변수를 유지할 필요가 없으며, 예외를 발생시킬 경우 프로그램 종료를 일으킬 수 있습니다.

가비지 수집 언어에서는 실행 중인 코드로 더 이상 연결할 수 없는 개체가 파괴될 수 있습니다.클래스 기반 GCed 언어에서 소멸자의 아날로그는 개체가 가비지 수집되기 전에 호출되는 최종자입니다.가비지 수집은 예측할 수 없고 C++ 디스트럭터보다 훨씬 덜 사용되고 덜 복잡하기 때문에 이들 명령어는 예측할 수 없는 시간과 순서가 다릅니다.이러한 언어의 예로는 Java, Python, Ruby 등이 있습니다.

개체를 삭제하면 개체에 대한 참조가 비활성화되고 수동 메모리 관리에서는 기존 참조가 행잉 참조가 됩니다.가비지 컬렉션(트레이스 가비지 컬렉션과 참조 카운트 모두)에서는 오브젝트에 대한 참조가 없는 경우에만 오브젝트가 파기되지만 최종화로 오브젝트에 대한 새로운 참조가 생성될 수 있습니다.또한 참조가 행잉되는 것을 방지하기 위해 오브젝트가 부활하여 참조가 유효한 상태로 유지됩니다.

C++

학급 푸우 {  일반의:   // 이것은 생성자의 시제품 선언입니다.   푸우(인트 x);   푸우(인트 x, 인트 y);    // 생성자가 오버로드되었습니다.   푸우(컨스턴트 푸우 &늙은);  // 생성자를 복사합니다.   ~푸우();               // 파괴자. };  푸우::푸우(인트 x) {   // 이것은 의 실장입니다.   // 1소문자 생성자. }  푸우::푸우(인트 x, 인트 y) {   // 이것은 의 실장입니다.   // 두 개로 구성된 생성자. }  푸우::푸우(컨스턴트 푸우 &늙은) {   // 이것은 의 실장입니다.   // 복사 생성자. }  푸우::~푸우() {   // 이것은 디스트럭터의 실장입니다. }  인트 주된() {   푸우 후우(14);       // 첫 번째 생성자를 호출합니다.   푸우 foo2(12, 16);  // 오버로드된 생성자를 호출합니다.   푸우 foo3(후우);     // 복사 생성자를 호출합니다.    // 소멸자가 역순으로 호출됨   // 여기, 자동으로. } 

자바

학급 푸우 {     일반의 푸우(인트 x)     {         // 이것은 의 실장입니다.         // 1소문자 생성자     }      일반의 푸우(인트 x, 인트 y)     {         // 이것은 의 실장입니다.         // 두 개로 구성된 생성자     }      일반의 푸우(푸우 늙은)     {         // 이것은 의 실장입니다.         // 복사 생성자     }      일반의 정적인 무효 주된(스트링[] args)     {         푸우 후우 = 신규 푸우(14); // 첫 번째 생성자를 호출합니다.         푸우 foo2 = 신규 푸우(12, 16); // 오버로드된 생성자를 호출합니다.         푸우 foo3 = 신규 푸우(후우); // 복사 생성자를 호출합니다.         // 가비지 수집은 커버 아래에서 이루어지며 오브젝트는 파기됩니다.     } } 

C#

네임스페이스 오브젝트 라이프시간을;  학급 푸우 {     일반의 푸우()     {         // 이것은 의 실장입니다.         // 기본 생성자.     }      일반의 푸우(인트 x)     {         // 이것은 의 실장입니다.         // 1소문자 생성자.     }      ~푸우()     {         // 이것은 의 실장입니다.         // 파괴자.     }      일반의 푸우(인트 x, 인트 y)     {         // 이것은 의 실장입니다.         // 두 개로 구성된 생성자.     }       일반의 푸우(푸우 늙은)     {         // 이것은 의 실장입니다.         // 복사 생성자.     }       일반의 정적인 무효 주된(스트링[] args)     {         변화하다 디폴트 = 신규 푸우(); // 기본 생성자를 호출합니다.         변화하다 후우 = 신규 푸우(14); // 첫 번째 생성자를 호출합니다.         변화하다 foo2 = 신규 푸우(12, 16); // 호출 오버로드된 생성자         변화하다 foo3 = 신규 푸우(후우); // 복사 생성자를 호출합니다.     } } 

목표-C

# Import <objc/Object>H>, @ 인터페이스 포인트:Object{이중 x, 이중 y;}//These는 수업 방법, 우리가 생성자 두개(포인트*)newWithX:(더블)andY:(더블)+을 선포했다;+(포인트*)newWithR:(더블)andTheta:(더블);//Instance 방법-(포인트*)setFirstCoord:(더블);-(포인트*)setSecondCoord:(더블);/*은 이래로 포인트는 서브 클래스다.generic Object * 클래스, 이미 일반 할당초기화 * 메서드 +alloc-init을 얻습니다.의 특정 컨스트럭터 *는 이러한 방법으로 만들  있습니다.* 상속받은 방식입니다. */ @end @valation Point - (포인트 *) setFirstCoord: (이중) new_val { x = new_val; } - (포인트 *) setSecondCoord: (이중) new_val {y = new_val; } + (이중) newWithX: (이중) x_val 및 Val 및 Val: (이중) newVal: (이중) return [[ [ Point allocate ]setFirst Coord : x _ val ]setSecond Coord : y _ val ]; } + (Point * ) newWithR : ( double ) r_val Theta : ( double ) seta _ val { // 위와 같은 작업수행하는 대신 이전 메서드결과를 사용할 있습니다.[ Point : ], pq.  *p = [Point newWithX:4.0 및 Y:5.0],  *q = [Point newWithR:1.0  Theta:2.28]; //...프로그램 텍스트......p가 종료되었습니다. //p가 개체를 위해 메모리를 할당해야 할 수 있습니다. //. 하지만 그렇지 않기 때문에 [p free]; //...많은 텍스트... [q free];0을 반환한다; }

오브젝트 파스칼

관련 언어: "Delphi", "Free Pascal", "Mac Pascal"

프로그램. ;  유형    DimensionEnum =     (       할당 해제,       de2D,       3D,       4D     );    포인트 클래스 = 학급   사적인     치수: DimensionEnum;    일반의     X: 정수;     Y: 정수;     Z: 정수;     T: 정수;    일반의     (* 컨스트럭터의 프로토타입*)      생성자 만들다();     생성자 만들다(AX, AY: 정수);     생성자 만들다(AX, AY, AZ: 정수);     생성자 만들다(AX, AY, AZ, ATime: 정수);     생성자 CreateCopy(카피 작성)(포인트: 포인트 클래스);      (*파괴자의 프로토타입*)      파괴자 파괴하다;   끝.;  생성자 포인트 클래스.만들다(); 시작한다.   // 일반 비인수 생성자 구현   자신.치수 := 할당 해제; 끝.;  생성자 포인트 클래스.만들다(AX, AY: 정수); 시작한다.   // 인수 생성자 2개 구현   자신.X := AX;   Y := AY;    자신.치수 := de2D; 끝.;  생성자 포인트 클래스.만들다(AX, AY, AZ: 정수); 시작한다.   // 3 인수 생성자 구현   자신.X := AX;   Y := AY;   자신.X := AZ;    자신.치수 := 3D; 끝.;  생성자 포인트 클래스.만들다(AX, AY, AZ, ATime: 정수); 시작한다.   // 4 인수 생성자 구현   자신.X := AX;   Y := AY;   자신.X := AZ;   T := ATime;    자신.치수 := 4D; 끝.;  생성자 포인트 클래스.CreateCopy(카피 작성)(포인트: 포인트 클래스); 시작한다.   // "복사" 컨스트럭터 구현   포인트.X := AX;   포인트.Y := AY;   포인트.X := AZ;   포인트.T := ATime;    자신.치수 := 4D; 끝.;  파괴자 포인트 클래스.포인트 클래스.파괴하다; 시작한다.   // 일반 비인수 소멸자 구현   자신.치수 := 할당 해제; 끝.;  변화하다   (* 정적 할당 변수*)   S:  포인트 클래스;   (* 동적 할당용 변수 *)   D: ^포인트 클래스;  시작한다. (* of program *)   (* 정적 할당이 있는 개체 라이프라인*)   S.만들다(5, 7);    (*'S'로 뭔가 해 주세요*)    S.파괴하다;     (* 동적 할당이 있는 개체 라이프라인*)   D = 신규 포인트 클래스, 만들다(5, 7);    (*'D'로 작업*)    처분하다 D, 파괴하다; 끝..  (* of program *) 

파이썬

학급 소켓:     방어하다 __init__(자신, remote_host: 스트레이트) -> 없음.:         # 리모트 호스트에 접속      방어하다 보내세요(자신):         # 데이터 전송      방어하다 인식하다(자신):         데이터 수신 수              방어하다 가까운.(자신):         # 소켓을 닫습니다.              방어하다 __del__(자신):         # __del__ 매직 함수는 객체의 참조 수가 0일 때 호출됩니다.         자신.가까운.()  방어하다 f():     소켓 = 소켓("example.com")     소켓.보내세요('테스트")     돌아가다 소켓.인식하다() 

소켓에 대한 참조가 모두 손실되었기 때문에 "f" 함수가 실행되고 반환된 후 다음 가비지 컬렉션 라운드에서 소켓이 닫힙니다.

「 」를 참조해 주세요.

메모들

  1. ^ 예를 들어 C++에서는 정적 로컬 변수가 함수를 처음 호출할 때 결정적으로 생성되지만 파괴는 결정적이지 않습니다.
  2. ^ C++에서 정적 로컬 변수 작성은 처음 선언에 도달했을 때와 같은 방식으로 결정적으로 이루어집니다.

레퍼런스