문제

스마트 포인터를 사용하는 C ++ 프로젝트에서 boost::shared_ptr, 사용에 관한 좋은 디자인 철학은 무엇입니까?this"?

고려하십시오 :

  • 나중에 사용하기 위해 스마트 포인터에 포함 된 원시 포인터를 저장하는 것은 위험합니다. 객체 삭제 제어를 포기하고 적시에 스마트 포인터를 신뢰합니다.

  • 비 정적 클래스 멤버는 본질적으로 사용합니다 this 바늘. 그것은 원시 포인터이며 변경할 수 없습니다.

내가 저장 한 경우 this 다른 변수에서 나중에 저장하거나 콜백에 바인딩 할 수있는 다른 함수로 전달하는 경우 누군가 내 수업에 대한 공유 포인터를 만들기로 결정할 때 소개되는 버그를 만들고 있습니다.

그 사실을 감안할 때, 내가 명시 적으로 사용하는 것이 언제라도 적절합니까? this 바늘? 이와 관련된 버그를 방지 할 수있는 설계 패러다임이 있습니까?

도움이 되었습니까?

해결책

나는 일반적인 대답이나 관용구가 없지만 boost::enable_shared_from_this . Shared_ptr에서 이미 관리하는 객체를 관리하는 Shared_ptr을 얻을 수 있습니다. 멤버 함수에서 shared_ptr을 관리하는 사람들에 대한 참조가 없으므로 ENABLE_SHARED_PTR을 사용하면 Shared_PTR 인스턴스를 얻고이 포인터를 전달해야 할 때 전달할 수 있습니다.

그러나 이것은 통과 문제를 해결하지 못합니다 this 생성자 내에서, 그 당시에는 Shared_ptr이 아직 객체를 관리하지 않습니다.

다른 팁

잘못된 질문

스마트 포인터를 사용하는 C ++ 프로젝트에서

이 문제는 실제로 스마트 포인터와 관련이 없습니다. 소유권에 관한 것입니다.

스마트 포인터는 단지 도구 일뿐입니다

그들은 소유권의 개념을 바꾸지 않습니다. 귀하의 프로그램에서 잘 정의 된 소유권이 필요합니다, 소유권은 자발적으로 양도 될 수 있지만 고객이 취할 수는 없습니다.

스마트 포인터 (자물쇠 및 기타 RAII 개체)는이 값이 동시에 값과 관계를 나타내는 것을 이해해야합니다. ㅏ shared_ptr 대상에 대한 참조이며 관계를 설정합니다. shared_ptr, 그리고 이것이 언제 shared_ptr 이 객체를 칭찬하는 마지막 사람이라면 객체를 즉시 파괴해야합니다. (unique_ptr 특별한 경우로 볼 수 있습니다 shared_ptr 정의에 따라 별명이없는 경우 unique_ptr 항상 객체를 별칭하는 마지막 것입니다.)

스마트 포인터를 사용해야하는 이유

스마트 포인터는 변수와 함수 선언만으로도 많은 것을 표현하기 때문에 스마트 포인터를 사용하는 것이 좋습니다.

스마트 포인터는 잘 정의 된 디자인 만 표현할 수 있으며 소유권을 정의 할 필요가 없습니다. 대조적으로, 쓰레기 수집은 메모리 거래를 담당하는 사람을 정의 할 필요성을 없애줍니다. (그러나 다른 자원 정리에 책임이있는 사람을 정의 할 필요성을 없애지 마십시오.)

불화가없는 기능적 쓰레기 수집 언어에서도 소유권을 명확하게해야합니다. 다른 구성 요소에 여전히 이전 값이 필요한 경우 객체의 값을 덮어 쓰고 싶지 않습니다. 이는 돌연변이 가능한 데이터 구조의 소유권 개념이 스레드 프로그램에서 매우 중요합니다.

생 포인터는 어떻습니까?

원시 포인터를 사용한다고해서 소유권이 없다는 것을 의미하지는 않습니다. 변수 선언으로 설명되지 않습니다. 주석, 디자인 문서 등에 설명 할 수 있습니다.

그렇기 때문에 많은 C ++ 프로그래머는 적절한 스마트 포인터 대신 원시 포인터를 사용하는 것이 못한: 표현력이 떨어지기 때문에 (의도적으로 "좋은"및 "나쁜"이라는 용어를 피했습니다). Linux 커널은 관계를 표현하기 위해 몇 가지 C ++ 객체로 더 읽을 수 있다고 생각합니다.

스마트 포인터의 유무에 관계없이 특정 디자인을 구현할 수 있습니다. 스마트 포인터를 적절하게 사용하는 구현은 많은 C ++ 프로그래머에 의해 우수한 것으로 간주됩니다.

당신의 진짜 질문

C ++ 프로젝트에서 "this"의 사용과 관련하여 좋은 디자인 철학은 무엇입니까?

끔찍하게 모호합니다.

나중에 사용하기 위해 원시 포인터를 저장하는 것은 위험합니다.

나중에 사용하기 위해 포인터가 필요한 이유는 무엇입니까?

객체 삭제 제어를 포기하고 적절한 시간에 책임있는 구성 요소를 신뢰합니다.

실제로, 일부 구성 요소는 변수의 수명을 담당합니다. 당신은 책임을 맡을 수 없습니다 : 그것은 양도되어야합니다.

이것을 다른 변수에 저장하거나 다른 기능으로 전달하는 경우 나중에 저장하거나 콜백에 바인딩 할 수있는 다른 함수로 전달하는 경우 누군가 내 수업을 사용하기로 결정할 때 소개되는 버그를 만들고 있습니다.

분명히, 발신자는 함수가 발신자의 제어없이 나중에 포인터를 숨기고 나중에 사용한다는 사실을 알지 못하므로 버그를 생성하는 것입니다.

솔루션은 분명히 다음 중 하나입니다.

  • 객체의 수명을 함수로 처리하는 책임 전달
  • 포인터가 발신자의 제어하에 만 저장되고 사용되는지 확인하십시오.

첫 번째 경우에만 클래스 구현에서 스마트 포인터로 끝날 수 있습니다.

당신의 문제의 원천

당신의 문제는 당신이 스마트 포인터를 사용하여 문제를 복잡하게하려고 노력하고 있다는 것입니다. 스마트 포인터는 더 쉽지 않고 쉽게 일을 할 수있는 도구입니다. 스마트 포인터가 사양을 복잡하게한다면 더 간단한 것들로 사양을 다시 생각하십시오.

문제가 있기 전에 스마트 포인터를 솔루션으로 소개하려고하지 마십시오.

잘 정의 된 특정 문제를 해결하기 위해 스마트 포인터 만 소개합니다. 잘 정의 된 특정 문제를 설명하지 않기 때문에 특정 솔루션을 논의 할 수는 없습니다 (스마트 포인터 포함).

올바른 사용의 한 가지 예입니다 return *this; 연산자 ++ () 및 연산자 << ()와 같은 함수에서.

스마트 포인터 클래스를 사용하는 경우 직접 노출 할 위험이 있습니다. "this". 관련된 포인터 클래스가 있습니다 boost::shared_ptr<T> 사용 중일 수 있습니다.

  • boost::enable_shared_from_this<T>
    • 객체에 동일한 참조 계산 데이터를 기존 공유 포인터와 객체에 사용하는 공유 포인터를 반환 할 수있는 기능을 제공합니다.
  • boost::weak_ptr<T>
    • 공유 포인터와 함께 작동하지만 객체에 대한 참조를 보유하지 마십시오. 모든 공유 포인터가 사라지고 개체가 풀리면 약한 포인터는 객체가 더 이상 존재하지 않으며 귀하를 반환 할 수 있습니다. NULL 유효하지 않은 메모리에 대한 포인터 대신. 약한 포인터를 사용하여 유효한 참조 카운트 객체에 공유 포인터를 얻을 수 있습니다.

물론 이들 중 어느 것도 어리석은 일이 아니지만 적어도 코드를 더 안정적이고 안전하게 만들면서 객체에 대한 적절한 액세스 및 참조 계산을 제공합니다.

사용해야하는 경우 this, 그냥 명시 적으로 사용하십시오. 스마트 포인터는 자신이 소유 한 객체의 포인터 만 포장합니다.unique_ptr) 또는 공유 방식 (shared_ptr).

나는 개인적으로 사용하는 것을 좋아합니다 이것 클래스의 멤버 변수에 액세스 할 때 포인터. 예를 들어:

void foo::bar ()
{
    this->some_var += 7;
}

스타일에 대한 무해한 질문 일뿐입니다. 어떤 사람들은 그것을 좋아하고 어떤 사람들은 그렇지 않습니다.

그러나 사용 이것 다른 것에 대한 포인터는 문제를 일으킬 수 있습니다. 정말 멋진 일을해야한다면 디자인을 실제로 재고해야합니다. 한 번은 클래스의 생성자 에서이 포인터를 다른 포인터에 다른 곳에 저장 한 코드를 보았습니다! 그것은 단지 미쳤다. 그리고 나는 그렇게 할 이유를 생각할 수 없다. 그건 그렇고 전체 코드는 큰 혼란이었습니다.

포인터로 정확히 무엇을하고 싶은지 말해 줄 수 있습니까?

또 다른 옵션은 침입 스마트 포인터를 사용하고 포인터가 아닌 객체 자체 내에서 참조 계산을 관리하는 것입니다. 이를 위해서는 좀 더 많은 작업이 필요하지만 실제로는 더 효율적이고 제어하기 쉽습니다.

이 주위를 통과 해야하는 또 다른 이유는 모든 객체의 중앙 레지스트리를 유지하려는 경우입니다. 생성자에서 객체는 이로 레지스트리의 정적 메소드를 호출합니다. 다양한 게시/가입 메커니즘에 유용하거나 레지스트리가 시스템에 어떤 개체/클래스인지에 대한 지식이 필요하지 않은 경우에 유용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top