문제

C ++에서 Am Emutable Type (클래스)을 만들려고합니다.

모든 방법 "일명 회원 기능"이 객체를 수정하지 않고 대신 새 인스턴스를 반환하도록 만들었습니다.

나는 많은 문제를 해결하고 있지만 모두 C ++의 참조 유형을 중심으로 진행됩니다.

한 가지 예는 동일한 클래스 유형의 매개 변수를 참조별로 전달할 때입니다.

Imm Imm::someOp( const Imm& p_im ) const
{
   ...
   p_im = p_im.someOtherOp(); //error, p_im is const, can't modify it!
   ...
}

오류는 값을 참조하여 전달함으로써 발생합니다. 대신, 참조를 값으로 전달했다면 위의 오류 줄은 오류가 아닙니다!

Java/C# 예제를 고려하십시오

class Imm
{
    ...
    Imm someOp( Imm p_im )
    {
        ....
        p_im = p_im.someOtherOp(); //ok, you're not modifying the 
                 //original object, just changing the local reference
        ....  
    }
    ....
}

C ++에서 이와 같은 것을 어떻게 할 수 있습니까? 나는 포인터를 사용할 수 있다는 것을 알고 있지만 전체 메모리 관리 혼란에 빠진다. 나는 누가 물체에 대한 언급을 소유 한 사람에 대해 걱정하고 싶지 않습니다.

이상적으로는 수업을 파이썬에서 불변의 현악기처럼 디자인하고 싶습니다. 당신은 그들이 불변이 불변을 알아 차리지 않거나 알지 못하고 그것들을 사용할 수 있으며, 그들이 당신이 기대하는대로 행동합니다. 그들은 단지 일합니다.

편집하다

물론 값을 통과하거나 온도 변수를 사용하여 (현재하고있는 일)를 사용하여 주변을 둘러 볼 수 있습니다. 내가 묻는 것은 "C ++의 가치별로 참조를 전달하는 방법"입니다.

나는 STL의 무언가를 중심으로 답변을 기대하고 있습니다. 현재 Smart_PTR 템플릿 제품군을 조사하고 있습니다.

업데이트

답변 해 주셔서 감사합니다. 포인터에서 탈출이 없다는 것을 알고 있습니다. (내 참조 다른 질문, 이것은 정말로 이것에 대한 후속 조치입니다)

도움이 되었습니까?

해결책

Java와 C#에서는 실제로 참조를 다루지 않습니다. 핸들이나 포인터와 비슷합니다. C ++의 참조는 실제로 원래 객체의 또 다른 이름이며, 포인터가 아닌 포인터가 아닙니다 (포인터로 구현 될 수 있지만). 참조에 값을 할당하면 객체 자체에 할당됩니다. 당신이 사용할 수있는 참조를 초기화하기 위해 혼란이 있습니다. = 캐릭터이지만 과제가 아니라 초기화입니다.

 Imm im, im2, im3; 
 Imm &imr = im;  // initialize a reference to im
 imr = im2; // assign im2 to imr (changes the value of im as well)
 Imm *imp = &im; // initialize a pointer to the address of im
 imp = &im3; // assign the address of im3 to imp (im is unnaffected);
 (*imp) = im2; // assign im2 to imp (modifies im3 as well).

구체적으로 "가치별로 참조"를 통과하려면 본질적으로 용어로 모순을 요구하는 것입니다. 정의에 따라 참조는 참조로 전달됩니다. 다른 곳에서 지적한 바와 같이, 당신은 값으로 포인터를 전달할 수 있습니다. 당신이 정말로 원한다면, 당신은 수업에서 참조를 유지하고 가치로 주변을 전달할 수 있습니다.

 struct ImmRef
 {
     Imm &Ref;
     ImmRef(Imm &ref) : Ref(ref) {}
 };

또한 참조에 적용되는 const는 참조가 참조가 아니라 객체를 일정하게 만듭니다. 참고 문헌은 항상 Const입니다.

다른 팁

정의상, 일정한 작업이 아닌 과제가 아닌가?

당신은 당신이 Const 참조에 무언가를 할당하려고하는 것처럼 보이며, 이는 Const 참조의 아이디어를 완전히 물리칩니다.

나는 당신이 참조 대신 포인터를 찾고 있다고 생각합니다.

C ++에서는 그렇게 작동하지 않습니다.

객체에 대한 참조를 전달하면 실제로 객체를 기억하는 주소를 전달합니다. 참고 문헌은 다른 객체에 다시 적용 할 수 없으므로 C ++ 낙서 "참조는 객체입니다." 그것을 수정하려면 사본을 만들어야합니다. Java는 당신을 위해 무대 뒤에서 이것을 할 것입니다. C ++, 당신은 그것을 복사하면됩니다.

당신이 호출하는 메소드를 const로 설정하는 것을 잊지 않았습니까?

편집 : const가 고정 된 상태에서.

어쩌면 당신은 같은 일을해야합니다

Imm & tmp = p_im.someOtherOp();

그런 다음 TMP 변수에 대한 추가 작업을 수행하십시오.

변수 또는 매개 변수를 const로 설정하면 할당 할 수 없습니다.

임시 수명에 대해 알아 보려면 이것을 확인하십시오 http://herbsterter.wordpress.com/2008/01/01/gotw-88-a-candidate-for-the-mort-const/

Imm Imm::someOp( const Imm& p_im ) const
{
   ...
   //Imm& im = p_im.someOtherOp();       // will *not* work
   const Imm& im = p_im.someOtherOp();   // will work, but you get a const reference
   ...
}

그러나 boost :: shared_ptr을 사용할 수 있습니다

shared_ptr<Imm> Imm::someOtherOp() const
{
  shared_ptr<Imm> ret = new Imm;
  ...
  return ret;
}

shared_ptr<Imm> Imm::someOp(const share_ptr<Imm>& p_im) const
{
  shared_ptr<Imm> im = p_im->someOtherOp();
}

들어오는 주장의 새로운 사본을 만들어야합니다. 당신은 몇 가지 동등한 방법으로 원하는 것을 할 수 있습니다. 1) 통과 할 수 있습니다.

Imm Imm::someOp( Imm im ) const {
   im = im.someOtherOp();      // local im is a copy, original im not modified
   return im;                  // return by value (another copy)
}

또는 2) 회의별로 통과하고 사본을 명시 적으로 만들 수 있습니다.

Imm Imm::someOp( const Imm & im ) const {
   Imm tmp = im.someOtherOp(); // local tmp is a copy
   return tmp;                 // return by value (another copy)
}

두 형태는 모두 동일합니다.

C ++는 불변 유형보다 더 나은 것을 가지고 있습니다.const. 단일 유형은 귀하의 요구에 따라 변하지 않을 수 있습니다. 즉, 단기간 (근처) 사본을 다루는 데 유용한 패턴이 있습니다.

void f(const X &x) {
  // Trivial case: unconditional copy
  X x2=transform(x);
  // Less trivial: conditional copy
  std::optional<X> maybe;
  const X &use=need_copy ? maybe.emplace(transform(x)) : x;
  use.go();  // whichever, x or *maybe
}  // *maybe destroyed iff created, then x2 destroyed

std::unique_ptr C ++ 17 이전에 비슷한 방식으로 사용될 수 있지만 기능은 물론 던질 수 있습니다. std::bad_alloc.

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