Program Tip

복사 생성자에서 개인 변수에 액세스 할 수있는 이유는 무엇입니까?

programtip 2020. 10. 11. 11:13
반응형

복사 생성자에서 개인 변수에 액세스 할 수있는 이유는 무엇입니까?


클래스의 get-function을 통해서만 private 변수에 액세스 할 수 없다는 것을 배웠습니다. 그런데 왜 복사 생성자에서 액세스 할 수 있습니까?

예:

Field::Field(const Field& f)
{
  pFirst = new T[f.capacity()];

  pLast = pFirst + (f.pLast - f.pFirst);
  pEnd  = pFirst + (f.pEnd - f.pFirst);
  std::copy(f.pFirst, f.pLast, pFirst);
}

내 선언 :

private:
  T *pFirst,*pLast,*pEnd;

IMHO, 기존 답변은 "이유"를 설명하지 못합니다. 행동이 유효한지 반복하는 데 너무 집중합니다. "액세스 수정자는 객체 수준이 아닌 클래스 수준에서 작동합니다." -그래, 그런데 왜?

여기서 가장 중요한 개념은 원하는 OO 캡슐화를 이해하고 구현을 조정할 수있는 권한을 부여받은 클래스를 설계, 작성 및 유지 관리하는 프로그래머 (들)라는 것입니다. 따라서을 작성 class X하는 경우 개별 X x객체가 액세스 권한이있는 코드 에서 개별 객체를 사용할 수있는 방법뿐만 아니라 다음 방법도 인코딩 합니다.

  • 파생 클래스는 (선택적으로 순수한 가상 기능 및 / 또는 보호 된 액세스를 통해) 상호 작용할 수 있습니다.
  • 고유 한 X개체가 협력 하여 의도 된 동작을 제공하는 동시에 설계의 사후 조건과 불변성을 존중합니다.

복사 생성자 뿐만이 아닙니다. 매우 많은 작업이 클래스의 두 개 이상의 인스턴스를 포함 할 수 있습니다. 비교, 추가 / 곱하기 / 분할, 복사 생성, 복제, 할당 등을 수행하는 경우 자주 발생합니다. 단순히 다른 개체의 개인 및 / 또는 보호 된 데이터에 액세스 할 수 있어야하거나 더 간단하고 빠르거나 일반적으로 더 나은 기능 구현을 허용하기를 원합니다.

특히, 이러한 작업은 다음과 같은 작업을 수행하기 위해 권한있는 액세스를 활용할 수 있습니다.

  • (복사 생성자) 이니셜 라이저 목록에서 "rhs"(오른쪽) 개체의 전용 멤버를 사용하여 멤버 변수가 기본 생성 (적법한 경우라도) 대신 복사 생성 된 다음 다시 할당되도록합니다 (다시, 합법적 인 경우)
  • 리소스 공유-파일 핸들, 공유 메모리 세그먼트, shared_ptr참조 데이터 등
  • 사물의 소유권을 가져옴, 예를 들어 auto_ptr<>소유권을 건설중인 개체로 "이동"
  • 새 개체를 처음부터 다시 생성 할 필요없이 최적으로 사용 가능한 상태로 새 개체를 구성하는 데 필요한 개인 "캐시", 보정 또는 상태 구성원을 복사합니다.
  • 복사 / 액세스 진단 / 추적 정보는 복사중인 객체에 보관되어 있으며 공개 API를 통해 액세스 할 수는 없지만 일부 이후의 예외 객체 또는 로깅에서 사용할 수 있습니다 (예 : "원본"비 복사 구성 인스턴스의 시간 / 상황에 대한 정보 건설되었습니다)
  • 일부 데이터의보다 효율적인 복사를 수행합니다. 예를 들어 객체는 예를 들어 unordered_map멤버를 가질 수 있지만 공개적으로 만 노출 begin()end()반복자 size()있을 수 있습니다. 직접 액세스하여 reserve빠른 복사 를 수행 할 수 있습니다. 더 나쁜 아직 그들은 단지 노출하는 경우 at()insert()그렇지 않은 경우와 throw....
  • 클라이언트 코드에 대해 알 수 없거나 쓰기 전용 일 수있는 상위 / 조정 / 관리 개체에 대한 참조를 다시 복사합니다.

액세스 수정자는 객체 수준이 아닌 클래스 수준 에서 작동 합니다 .

즉, 동일한 클래스의 두 개체가 서로 개인 데이터에 액세스 할 수 있습니다.

왜:

주로 효율성 때문입니다. 액세스 수정자가 객체 수준에서 작동 하는지 확인해야 this == other할 때마다 액세스 other.x때마다 확인하는 것은 무시할 수없는 런타임 오버 헤드 입니다.

또한 범위 지정 측면에서 생각해 보면 의미 론적으로 논리적입니다. "개인 변수를 수정할 때 염두에 두어야하는 코드 부분은 얼마나됩니까?" – 전체 클래스의 코드를 염두에 두어야하며 이는 런타임에 존재하는 객체와 직교합니다.

그리고 복사 생성자와 할당 연산자를 작성할 때 매우 편리합니다.


다른 인스턴스의 경우에도 클래스 내에서 클래스의 개인 멤버에 액세스 할 수 있습니다.


답을 이해하기 위해 몇 가지 개념을 상기시키고 싶습니다.

  1. 생성 한 객체의 수에 관계없이 해당 클래스의 메모리에는 하나의 함수 복사본이 하나만 있습니다. 함수는 한 번만 생성된다는 의미입니다. 그러나 변수는 클래스의 각 인스턴스에 대해 별개입니다.
  2. this 포인터는 호출 될 때 모든 함수에 전달됩니다.

이제 this포인터로 인해 함수가 특정 인스턴스의 변수를 찾을 수 있습니다. 그것이 공공의 사적이든 상관 없습니다. 해당 함수 내에서 액세스 할 수 있습니다. 이제 동일한 클래스의 다른 객체에 대한 포인터를 전달하면. 이 두 번째 포인터를 사용하여 개인 멤버에 액세스 할 수 있습니다.

이것이 귀하의 질문에 답하기를 바랍니다.


복사 생성자는 클래스의 멤버 함수이므로 'private'로 선언 된 경우에도 클래스의 데이터 멤버에 액세스 할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/4117002/why-can-i-access-private-variables-in-the-copy-constructor

반응형