pImpl의 원리
5356 단어 imp
재앙이 못의 고기에까지 미치다
pImpl
관용 기법의 운용 방식은 모두가 잘 알고 있는데 그 주요 역할은 유형의 사용 인터페이스를 풀고 실현하는 결합이다.
하면, 만약, 만약...
pImpl
상습적인 수법으로 코드는 다음과 같다.
1 #include<x.hpp>
2 class C
3 {
4 public:
5 void f1();
6 private:
7 X x; // X
8 };
위와 같은 코드는
C
그것과의 실현은 강한 결합이다. 의미에서 보면
x
구성원 데이터는 에 속함
C
실현된 부분은 사용자에게 노출되어서는 안 된다.언어의 본질적으로 말하자면, 사용자의 코드에서 매번 사용된다.
”new C”
및
”C c1”
이런 문장은 모두
X
컴파일된 바이너리 코드 세그먼트에 하드코딩된 크기
X
허함수가 있는 것은 이뿐만이 아니다.
”new C”
이런 문장은 사실
operator new(sizeof(C) )
뒤에 따라와.
C
의 구조 함수
”C c1”
현재 창고에서 비우기
sizeof(C)
크기 공간
C
의 구조 함수입니다.그래서 매번
X
사용하다
c.hpp
원본 파일을 다시 컴파일해야 합니다. 왜냐하면
X
크기가 바뀌었을 수도 있어요.
대형 프로젝트에서 이런 결합은 맞을 수 있다
build
시간은 상당히 큰 영향을 끼친다.
pImpl
상투적인 수법은 이런 결합을 없애고 사용할 수 있다.
pImpl
일반적으로 사용되는 코드는 다음과 같습니다.
1 //c.hpp
2 class X; // include
3 class C
4 {
5 ...
6 private:
7 X* pImpl; // X* ,class X
8 };
이미 정해진 플랫폼에서, 모든 바늘의 크기는 같다.이유
X*
,
Y*
이런 각양각색의 지침은 주로 고위층의 추상적인 의미를 제공한다. 즉, 이 지침이 도대체 그 종류의 대상을 가리키고 컴파일러에게 지시를 함으로써 사용자에게 정확한 조작(예를 들어 호출)을 할 수 있다.
X
의 구성원 함수)를 결정하고 검토합니다.그러나 운행 기간의 측면에서 볼 때, 모든 지침은 단지
32
비트 크기
64
기계
64
비트, 현재 하드웨어에 따라 다름).
바로... 때문
pImpl
지침
X
의 바이너리 정보(
sizeof(C)
등) 결합되지 않습니다.
C
인터페이스로 올라가다
”new C”
또는
”C c1”
컴파일러가 생성한 코드에 섞이지 않습니다
X
사용자가 사용할 수 있는 모든 정보
C
쓰다
C
과
X
무관하다
X
이 지침에 의해 사용자와 철저히 차단되었다.오직
C
알고 조작할 수 있다
pImpl
구성원이 가리키는
X
대상.
방화벽
수정
X
정의는 모든 사용을 초래한다
C
의 원본 파일을 다시 번역하는 것은'성문에 불이 나서 연못의 물고기에게 재앙을 끼친다'는 것과 같다. 그 이유는'호성하'가'성문'과 너무 가깝기 때문이다(결합).
pImpl
관용 수법은 또'편역기 방화벽'이 되었다. 무엇이'방화벽', 지침입니까?아니야.
C++
의 컴파일 모드는'분리식 컴파일링', 즉 서로 다른 원본 파일은 분리적으로 컴파일된 것이다.즉, 서로 다른 원본 파일 사이에 천연의 방화벽이 있는데 하나의 원본 파일이 불이 나면 다른 원본 파일에 영향을 주지 않는다는 것이다.
그러나 여기서 우리가 고려한 것은 첫 번째 문건이다. 만약 첫 번째 문건이 불이 나면 어떨까?헤더 파일은 직접 컴파일할 수 없습니다. 원본 파일에 포함되며 원본 파일의 일부분으로 함께 컴파일됩니다.
소스 파일
S.cpp
사용
C.hpp
그러면
class C
의 변동은 피할 수 없는 결과를 초래할 것이다
S.CPP
라고 재컴파일했다.하지만
class C
실현적
class X
전혀 초래해서는 안 된다
S.cpp
라고 재컴파일했다.
그래서 우리는
class X
단절
C.hpp
이외이렇게
class C
소스 파일
class X
분리
class X
동일한 컴파일 단위가 아님).하지만
class C
사용
class X
대상은 그것의 실현 부분으로서 피할 수 없이
class X
.다만 이'의존'은 다음과 같이 묘사되어야 한다.
class C
에 의존하다.
class X
"은(는) 아니어야 합니다."
class C
의 사용자 사용 인터페이스 부분은
class X
”.
하면, 만약, 만약...
X
에서
class C
데이터 구성원 안에서는 뚜렷하고 사용하기 쉽다.
class C
사용자가 보지 말아야 할 것을 보았다.
class X
그것들 사이에 결합이 생겼다.하지만 지향 하나를 사용하면
class X
바늘
X
의 바이너리 정보 "push"
class C
실현 서류에 가다
#include”x.hpp”
, 모든 구성원 함수를 정의하고
X
실현
C
의 실현은 본래
X
이때
class X
의 변동은 단지
class C
의 구현 파일 재컴파일, 사용자 사용
class C
원본 파일은 무사합니다!
지침이 이곳에 다리 하나를 충당했다.의존 정보를 다른 컴파일러 단원으로 밀어내어 사용자와 차단합니다.방화벽은
C++
컴파일러의 고유 속성.
통과
C++
컴파일러 방화벽
뭐가 타임슬립이야?
C++
컴파일기 방화벽?지침이다!포인터를 사용하는 원본 파일은 포인터가 가리키는 대상이 무엇인지 알지만, 그 대상을 직접 볼 필요는 없다. 포인터는 다른 컴파일러 단원에 있을 수도 있고, 포인터가 컴파일러 방화벽을 통과해서 그 대상에 연결되어 있을 수도 있다.
어떤 의미에서 말하자면, 주소를 대표하는 기호라면 모두 통과할 수 있다
C++
컴파일러 방화벽
(constructs)
의 기호는 사용할 수 없습니다.
예를 들어 함수 이름은 함수 코드의 시작 주소를 가리키기 때문에 함수는 하나의 컴파일러 단원에 성명할 수 있지만 다른 컴파일러 단원에 정의되면 컴파일러가 그것들을 연결하는 것을 책임진다.사용자는 함수의 성명만 얻으면 그것을 사용할 수 있다.클래스는 다르다. 클래스 이름은 하나의 언어 구조를 대표하고 클래스를 사용하려면 클래스의 정의를 알아야 한다. 그렇지 않으면 2진 코드를 만들 수 없다.변수의 기호는 실질적으로도 주소이지만 변수를 사용하는 데는 일반적으로 변수의 정의가 필요하고
extern
수식자는 변수의 정의를 다른 컴파일러 단원에 놓을 수 있다.