2017-05-21 2 views
-2

두 개의 인스턴스 변수와 해당 클래스에 대한 참조를 가져 와서 인스턴스 변수를 변경하는 B 클래스가 있습니다. B 클래스가 이러한 변수를 변경 한 후에는 클래스의 원래 인스턴스에서 변경 될 것이라고 생각할 수 있지만이 경우에는 변경되지 않습니다. 왜 이런 일이 일어나고 어떻게 해결할 수 있습니까?참조로 전달 된 클래스를 수정하는 C++은 원본 객체를 변경하지 않습니다.

class Foo { 
public: 
    int x; 
    int y; 
    Foo() { 

    } 
    Foo(int x, int y) { 
     this->x = x; 
     this->y = y; 
    } 
}; 

class Bar { 
public: 
    Foo foo; 
    Bar() { 

    } 
    Bar(Foo& foo) { 
     this->foo = foo; 
    } 
    void Swap() { 
     int tmp = foo.x; 
     foo.x = foo.y; 
     foo.y = tmp; 
    } 
}; 
int main() 
{ 
    Foo foo(4, 8); 
    Bar bar(foo); 

    std::cout << "this is x: " << foo.x << std::endl; //prints 4 
    std::cout << "this is y: " << foo.y << std::endl; //prints 8 

    bar.Swap(); 
    std::cout << "this is x: " << foo.x << std::endl; //prints 4, but should print 8 
    std::cout << "this is y: " << foo.y << std::endl; //prints 8, but should print 4 
} 
+0

스택 오버플로에 오신 것을 환영합니다. [The Tour] (http://stackoverflow.com/tour)를 읽으신 후 [Help Center] (http://stackoverflow.com/help/asking)의 자료를 참조하십시오. 여기에 물어보십시오. –

+0

이러한 문제를 해결하는 올바른 도구는 디버거입니다. 스택 오버플로를 묻기 전에 코드를 단계별로 실행해야합니다. 자세한 도움말은 [작은 프로그램 디버깅 방법 (Eric Lippert 작성)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)을 참조하십시오. 최소한 디버거에서 관찰 한 내용과 함께 문제를 재현하는 [Minimal, Complete, Verifiable] (http://stackoverflow.com/help/mcve) 예제를 포함하도록 질문을 편집해야합니다 . –

+2

'Bar'는'Foo' 소스에 대한 참조가 아닌'Foo' 소스의 사본을 보유합니다. 'Foo'는 참조로 함수에 전달되었지만 복사되었습니다. – user4581301

답변

3

B 클래스의 생성자 참조로 foo (파라미터)을 거쳐야하지만, (특히, foo 부재로) A의 개별 인스턴스로 바로 복사를; Swapfoo 구성원에서 작동합니다. 위에서 말했듯이 이는 원래 개체의 복사본입니다.

당신이 할 필요가 예상대로 코드 동작합니다을 만들려면 심지어 멤버 foo 참조 (또는 포인터) :

class Bar { 
public: 
    Foo &foo; 
    Bar() { 

    } 
    Bar(Foo& foo) : foo(foo) { 
    } 

(내가 cannot be default-initialized and then reseated 참조 때문에 the member initialization list syntax을 사용했다 통지)

+0

도와 주셔서 감사합니다. C#에서 C++로가는 것은 포인터가 amd 참조를 처리하는 방식에 조금 까다 롭습니다. –

0

당신은 당신이 bar.foo을 참조하여 통과 한 foo는 바의 생성자에 foo는, 그러나 (복사) 할당에 대한 참조를 전달합니다.

별도의 Foo 객체가 아닌 Foo 객체에 대한 참조 (또는 포인터)로 선언하고자합니다.

0

문제는 여기에 있습니다.

Foo foo; 
    Bar(Foo& foo) { 
     this->foo = foo; 
    } 

당신이 참조로 foo 인수를하더라도, 당신은 사본을 초래하고 제기 된 문제에 대한 계정이 아닌 참조 값에 할당합니다. 솔루션의 첫 번째 단계는 인스턴스 필드를 참조로 선언하는 것입니다.

Foo& foo; 

그러나 할당하려고하면 오류가 발생합니다. 이를 위해 특수 생성자 초기화 구문을 사용하려고합니다. 기본적으로 할당과 동일한 작업을 수행하지만 일반 할당보다는 구성 작업을 수행합니다. 다음과 같이 생성자를 작성하십시오.

Bar(Foo& foo) : foo(foo) {} 

또한 대부분의 C++ 컴파일러가 초기화되지 않은 참조가 발생할 수있는 코드를 거부합니다으로 완전히 기본 생성자 Bar()을 제거해야합니다.

관련 문제