2009-03-16 3 views
2

C++에서 변경할 수없는 형식 (클래스)을 만들려고합니다.C++에서 값을 기준으로 참조를 전달하는 방법은 무엇입니까?

모든 메서드 "aka member functions"이 개체를 수정하고 대신 새 인스턴스를 반환하도록 만들었습니다.

저는 많은 문제를 겪고 있지만, 모두 C++의 참조 유형에 중점을두고 있습니다.

일례 참조 동일한 클래스 유형의 파라미터를 전달하는 경우 :

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

오류는 참조 값을 전달함으로써 야기된다. 대신 값으로 참조를 전달하면 위의 오류 줄은 오류가 아닙니다.

은 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 
     .... 
    } 
    .... 
} 

이 어떻게 이런 일을 할 수있는 Java/C# 예제를 고려? 포인터를 사용할 수는 있지만 전체 메모리 관리가 엉망이됩니다. 나는 객체에 대한 참조를 소유하고있는 사람에 대해 걱정하고 싶지 않습니다.

이상적으로 나는 클래스를 파이썬에서 불변의 문자열처럼 디자인하고 싶습니다. 당신은 그들이 변하지 않는다는 것을 알아 채거나 심지어 알지 못하는 사이에 그것들을 사용할 수 있으며, 당신이 예상대로 행동합니다; 그들은 단지 작동합니다.

편집 내가 전달별로 값 또는 (내가 현재 뭘하는지 인) 임시 변수를 사용하여 주위를 얻을 수 있습니다 물론

. 내가 물어 보는 것은 "C++에서 값으로 참조를 전달하는 방법"이다.

나는 STL에서 뭔가를 중심으로 답할 것을 기대하고있다. 현재 템플릿의 smart_ptr 패밀리를 찾고있다. 응답에 대한

UPDATE

덕분에, 나는 탈출이 포인터에서 없다 실현. (내 other question을 참조하십시오.이 내용은 실제 후속 작업입니다.)

+0

을 사용할 수 있습니다 인스턴스 B에있는 메소드에 "Imm", "someOp"및 "someOtherOp"의 의미를 설명 할 수 있을까요? 컴파일러가 불변의 객체를 변경하지 못하게하는 것처럼 보입니다. –

+0

그건 중요하지 않아, 일반적인 대답이 필요해. 왜 인스턴스를 매개 변수로 메소드에 보냅니 까? 음, 문자열 연결을 고려하십시오 : str1.append (str2) – hasen

답변

4

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). 

특별히 "가치에 의한 참조"를 전달하려는 경우 본질적으로 모욕을 요구합니다. 참고 문헌은 정의에 의해 참조로 전달됩니다. 다른 곳에서 지적했듯이 포인터를 값 또는 다른 값으로 전달할 수 있습니다. 당신이 정말로 원하는 경우에, 당신은 클래스의 참조 붙잡고 값으로 그 주위를 전달할 수 있습니다하십시오 CONST이 기준에 적용하는 것도

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

참고 상수가 아닌 참조 오브젝트 언급하고있다. 참조는 항상 const입니다.

+0

OP가 그의 문제를 어떻게 해결할 것이냐? 당신의 대답에 그것을 포함 시키십시오. – strager

1

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

편집 : 그래서 const가 고정되었습니다.

어쩌면 당신은

Imm & tmp = p_im.someOtherOp(); 

그런 다음 TMP 변수에 추가 작업을 할

같은 것을해야한다.

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

4

정의 상 상수 연산이 아닌가?

const 레퍼런스에 아이디어를 할당하는 것처럼 보입니다. const 레퍼런스 아이디어를 완전히 무효로합니다.

난 당신이 참조 대신 포인터를 찾고있을 것 같아요.

+0

"전적으로 const 참조의 아이디어를 무효화합니다."나는 사실 그 후에 생각했습니다. Java 스타일 참조에 관해서 생각하고있는 것 같습니다. – hasen

+0

C++에서는 포인터라고합니다. – Eclipse

0

수신 인수의 새 복사본을 만들어야합니다. 당신은 여러 상응하는 방법으로 당신이 원하는 것을 할 수 있습니다 : 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) 
} 

두 양식은 동일합니다.

+0

정확히 일치하지는 않습니다. 첫 번째 예제에서는 할당 연산자/복사 생성자를 사용하는 하나의 객체가 있습니다. 다른 하나는 두 개의 객체가 있고 생성자를 사용하고 있습니다 (필자 생각). 당신은 그 (것)들이 동등하다는 것을 예상 할 것입니다, 그러나 이것은 항상 사실이 아닙니다. – strager

+0

당신은 tmp를 선언하는 것을 잊었습니까? – rlbond

+0

@rlbond, 고마워, 고쳐 둔다 – jwfearn

3

C++에서와 같이 작동하지 않습니다.

개체에 대한 참조를 전달하면 실제로 개체의 메모리에 주소가 전달됩니다. 참조는 다른 객체에도 재 장착 될 수 없으므로 C++ 어구 "참조는 객체입니다." 수정하려면 사본을 만들어야합니다. 자바는 당신의 입장에서 이것을 뒤에서 할 것입니다. C++, 그냥 복사해야합니다.

0

확인이 임시 수명 http://herbsutter.wordpress.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-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 
    ... 
} 

에 대해 알아야 할하지만 당신은 부스트 ​​:: shared_ptr을 매개 변수로 임의 예 A를 전달하는 이유가 나에게 분명하지 않다

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(); 
} 
관련 문제