상속 없는 객체 구조

9315 단어 물려받다
다음 코드를 고려하십시오.
Point global;                   //1)

Point Foobar()

{

    Point local;                //2)

    Point *heap = new Point;    //3)

    *heap = local;              //4)

    //...stuff...  

    delete heap;                //5)

    return local;               //6)

}

1), 2), 3) 세 가지 다른 대상을 만드는 방식: 글로벌 메모리 설정,local 메모리 설정과heap 메모리 설정.4) 하나의object를 다른 사람에게 지정하고 6) 되돌아오는 값을 설정하고 7) delete 연산자로 ehap object를 명확하게 삭제한다.하나의object의 생명은 이object의 속성이다.localobject의 생명은 정의에서 시작하여 끝날 때까지 작용한다.글로벌 object의 생명은 전체 프로그램의 생명과 같다.heap object는 new에서 태어나 delete로 죽었습니다.다음은 Point의 첫 번째 선언입니다. C 프로그램으로 작성할 수 있습니다. C++ standard는 이것이 소위 Plain Old Data 선언 형식이라고 말합니다.
typedef struct

{

    float x, y, z;

}Point;

만약 우리가 C++로 이 코드를 컴파일한다면 무슨 일이 일어날까요?관념적으로 컴파일러는 Point에 trivial default constructor, trival destructor, trivial copy constructor, 그리고 trivial assignment operator를 설명합니다.그러나 실제로 컴파일러는 이 생성명을 분석하고 Plain Old Data 볼륨을 붙인다.컴파일러가 다음과 같은 정의를 만났을 때
Point global;

이 때, 관념상 Point의trivial constructor와 destructor는 모두 생성되고 호출되며, constructor는 프로그램의 시작에서 destructor가 호출되고 프로그램의 exit () 에서 호출됩니다. (exit () 는 시스템이 생성되고main () 이 끝나기 전에 적용됩니다.그러나 사실상 trivial members는 정의가 없으면 호출되지 않고 프로그램의 행동도 C에서의 행동과 같다.
물론 작은 예외가 하나 더 있다. 바로 C에서 글로벌은 임시적인 정의로 여겨지고 프로그램에서 여러 번 발생할 수 있다. 그 실례들은 접혀서 하나의 단독 실체만 남기고 프로그램의 데이터 segment에 특별히 초기화되지 않은 글로벌 Objects에 사용되는 공간으로 보존된다.역사적 원인으로 인해 이 공간은 BSS라고 불리며 Block Started by Symbol의 줄임말로 IBM 704 assmbler의pseudo-op이다.
C++는 임시적인 정의를 지원하지 않습니다. 이것은class 구조 행위의 은밀한 응용 때문에 모두가 이 언어가class objects나Plain OldData를 판단할 수 있다고 공인하지만.그렇게 복잡하게 할 필요는 없을 것 같아.따라서 글로벌은 C++에서 완전한 정의로 간주됩니다. (두 번째 또는 더 많은 정의를 막을 수 있습니다.)C와 C++의 차이점은 BSS 데이터 segment가 C++에서 상당히 중요하지 않다는 데 있다. C++의 모든 전역 변수는 초기화된 데이터로 간주된다.
Pobar () 중에는 Point object lcal이 하나 있는데, 마찬가지로 구조되지도 해체되지도 않았다. 물론 Point object local이 먼저 초기화되지 않았다면 잠재적인 버그가 될 수 있다. 처음 사용하면 초기값이 필요할 때이다.heap object에 대한 초기화 작업:
Point *heap = new Point

new 연산자에 대한 호출로 변환됩니다.
Point *heap = __new(sizeof(Point));

new 연산자가 반환하는 Point object에 대해 default constructor가 실행되지 않았음을 다시 한 번 강조합니다.
*heap = local;

만약 local이 적절하게 초기화되었다면 모든 것은 문제가 없었을 것입니다. 그러나 사실상 컴파일 경고는 다음과 같습니다: warning,line 7: local is used before being initialized.
관념상 이런 조작은 trivial copy assignment operator에서 복사 조작을 시작한다.그러나 실제로 이 Object는 Plain Old Data이기 때문에 값 부여 작업은 C와 같은 순수한 이동 작업일 뿐입니다.마지막으로 delete 작업을 실행합니다.
delete heap;

//     

__delete(heap);

관념적으로 이런 조작은 Point의 trivial destructor를 촉발할 수 있다.그러나 우리가 보듯이,destructor는 생기지 않았거나 호출되지 않았다.마지막으로 함수는 값을 전달하는 방식으로 local을 반환값으로 되돌려줍니다. 이것은 관념적으로 trivial copy constructor를 촉발할 수 있지만 실제로return 조작은 간단한bitwise 조작일 뿐입니다. 대상은 Plain Old 데이터이기 때문입니다.
여기서 Plain Old Data의 의미를 보충하겠습니다. POD 클래스 유형은 집합 클래스(aggregate classes, 즉 POD-struct types)와 집합 유니온(POD-union types)을 가리키며 다음 멤버가 없습니다.구성원 형식에 대한 비정상적인 데이터 구성원 (그룹 포함).2. POD 클래스가 아닌 비정상적인 데이터 구성원(배열 포함).3. 인용 형식의 (reference type) 비정상적인 데이터 구성원.4. 사용자 정의 복사와 값 부여 계산기.5. 사용자 정의 분석 함수.
용어 집합은 모든 수조나 클래스를 가리키며 다음과 같은 특징을 가지지 않는다.사용자 정의 구조 함수.2. 개인 또는 보호된 비정상적인 데이터 구성원.3. 기류.4. 허함수.이를 통해 알 수 있듯이 POD류 유형은class,struct,union을 가리키며 사용자가 정의한 구조 함수, 분석 함수, 복사 산자, 부수 산자를 가지지 않는다.상속 관계가 없기 때문에 기류가 없다.허함수가 없기 때문에 허표가 없다.비정상적인 데이터 구성원은 사유나 보호 속성이 없고 인용 유형이 없고 비POD 유형이 없다(즉 플러그인 클래스는 모두 POD이어야 한다), 구성원 유형에 대한 지침이 없다(이 유형은this 지침을 포함하기 때문이다).
추상적인 데이터 형식은 Point의 두 번째 성명입니다.public 인터페이스에private 데이터가 많아져서 완전한 봉인성을 제공하지만,virtual function을 제공하지 않았습니다.
class Point

{

public:

    Point(float x = 0.0, float y = 0.0, float z = 0.0)

        :_x(x), _y(y), _z(z){}

    //no copy constructor, copyoperator

    //or destructor defined

private:

    float _x, _y, _z;

};

봉인된 Pointclass는 크기가 변하지 않았거나 세 개의 연속적인 플로트입니다. 네, 퍼블릭,private 액세스층이든, member function의 성명이든 대상의 추가 공간을 차지하지 않습니다.Point에 copy constructor나copy operator를 정의하지 않았습니다. 기본 비트 의미 (default bitwise semantics) 가 충분하기 때문에,destructor를 제공할 필요가 없습니다. 프로그램의 기본 메모리 관리 방법이 충분하기 때문입니다.Point 글로벌에 대해default constructor가 작용하고 있습니다. 글로벌이 전역적으로 정의되어 있기 때문에 초기화 작업은 프로그램이 활성화될 때까지 지연됩니다.class의 모든 구성원에게 상수 초기값을 설정하려면 explicit initialization을 주는 것이 비교적 효율적이고 심지어local scope에서도 마찬가지다. 예를 들어 다음과 같다.
void Member()

{

    Point local1 = {1.0, 1.0, 1.0};

    Point local2;

    

    //      inline expansion

    //explicit initialization     

    local2._x = 1.0;

    local2._y = 1.0;

    local2._z = 1.0;

}

local1의 초기화 작업은 local2보다 효율적입니다.함수의 activation record가 창고에 들어갈 때 상기 initialization의 상수가local1 메모리에 넣기 때문입니다.Explicit initialization list는 다음과 같은 세 가지 단점을 제공합니다. 1.class members가 모두publics일 때만 이 방법이 효과가 있습니다.상수만 지정할 수 있습니다. 왜냐하면 그것들은 컴파일 시기에 값을 평가할 수 있기 때문입니다. 3.컴파일러가 자동으로 실행되지 않았기 때문에 초기화 동작의 실패 가능성이 비교적 높습니다
그렇다면 효율이 가져온 이익을 위해 이전의 결점을 보상할 수 있을까?일반적으로 안 된다. 예를 들어 팔레트 디스크와 같은 거대한 데이터 구조를 모의하고 싶거나, 프로그램에 한 쌍의 상수를 뒤바꾸려고 한다면, explicit initialization list의 효율은 inline constructor의 효율보다 훨씬 낫다. 특히 전체적인 대상에게.컴파일러 차원에서 inline constructors를 식별하는 최적화 메커니즘이 있고 후자는 간단히member-bymember의 상수 지정 조작을 제공한다.컴파일러는 그 값을 추출하여 explicit initializationlist가 제공하는 것과 같이 constructor를 일련의 assignment 명령으로 확장하지 않습니다.따라서 local Point object의 정의는 다음과 같습니다.
{

    Point local;

    //...

}

    //   default Point constructor   inline expansion   

{

    //inline expansion of default constructor

    Point local;

    local._x = 0.0;

    local._y = 0.0;

    local._z = 0.0;

    //...

}

heap Point object의 경우 default Point constructor에 대한 조건부 호출 작업이 추가됩니다.
Point *heap = __new(sizeof(Point));

if(heap != 0){

    heap->Point::Point();

}

그리고 나서야 컴파일러가 inline expansion 조작을 했다.heap 포인터를 local object:*heap = local로 가리키기;간단한bitwise copy 조작을 유지합니다.값을 전송하는 방식으로local object를 전송하는 것도 마찬가지다.나중에 delete heap 작업을 삭제하면destructor가 호출되지 않습니다. 왜냐하면destructor 함수 실체를 명확하게 제공하지 않았기 때문입니다.관념적으로 우리의 Pointclass에는 관련된default copy constructor,copy operator와destructor가 있지만 그들은 모두trivial이기 때문에 컴파일러는 그것들을 전혀 생성하지 않았다.

좋은 웹페이지 즐겨찾기