2009-12-02 6 views
7

나는 이해할 수없는 문제에 봉착했으며 여기 누군가가 통찰력을 제공하기를 바랍니다. 다음과 같이 단순화 된 코드는 (원래 코드는 사용자 정의 큐/큐 반복자 구현했다)입니다 :참조 멤버가있는 내부 클래스의 기본 할당 연산자

foo.cpp: In member function 'B::C& B::C::operator=(const B::C&)': 
foo.cpp:46: error: non-static reference member 'B& B::C::b', can't use default assignment operator 
foo.cpp: In function 'int main()': 
foo.cpp:63: note: synthesized method 'B::C& B::C::operator=(const B::C&)' first required here 

나는이 문제를 갈 수 있습니다

class B 
{ 
public: 
    B() {}; 
    class C 
    { 
    public: 
     int get(); 
     C(B&b) : b(b){}; 
    private: 
     B& b; 
    }; 
public: 
    C get_c() { return C(*this); } 
}; 

int main() 
{ 
    B b; 
    B::C c = b.get_c(); 


    c = b.get_c(); 
    return EXIT_SUCCESS; 
} 

이 컴파일 할 때, 나에게 다음과 같은 오류를 제공합니다 두 개의 독립된 C 변수를 사용하여 독립적 인 'C'객체라고 가정하지만이 경우에만 문제가 숨겨집니다 (여전히 왜 내가이 작업을 수행 할 수 없는지 이해할 수 없음).

이유는 참조를 복사 할 수 없다고 생각하지만 이유를 이해하지 못합니다. 나 자신의 할당 연산자와 복사 생성자를 제공해야합니까?

답변

13

이 문제는 내부 클래스와는 아무런 관련이 없습니다. C++에서는 참조를 할당 할 수 없습니다. 정의 될 때 초기화해야합니다.

더 간단한 예는 다음과 같습니다

class B 
{ 
public: 
    B(int& i) : ir(i) {}; 

    int& ir; 
}; 


int main() 
{ 
    int i; 
    B b(i);  // Constructor - OK 

    int j; 
    B bb = B(j); // Copy constructor - OK 

    bb = b;  // Assignment - Error 
    return 0; 
} 
+0

바, 물론 당신 말이 맞아요, 나는 명백한 설명을 놓쳤다는 것을 믿을 수 없습니다. 아침에 커피가 더 있어야합니다 : D – laura

+2

+1. 나는 습관적으로 참조에 대해 이야기 할 때 "할당하다"가 아니라 "묶음"을 사용하는 것이 실수를 저지르는 데 도움이된다는 것을 알게되었습니다. –

+0

이제 참조를 재지 정하고 컴파일 할 것입니다. int a = 3; int b = 4; int & ref = a; ref = b; 따라서 참조를 재 할당 할 수 있습니다. – friko

6

참조를 초기 값으로 지정하면 변경할 수 없습니다. 즉, 참조 멤버의 값을 변경하는 대입 연산자를 작성하는 것은 불가능합니다. 이 작업을 수행해야하는 경우 참조 대신 포인터를 사용하십시오.

+0

실제로 가능합니다. 자세한 내용은 내 의견을 확인하십시오. – rmn

0

C++은 "내부 클래스", 단지 중첩 된 클래스 선언이 없습니다. "내부 클래스"는 다른 주류 언어에서는 발견되지 않는 Java-ism입니다. 자바에서는 내부 클래스가 포함 된 유형의 객체에 대한 암시 적 불변 참조를 포함하기 때문에 내부 클래스가 특별합니다. Java에서 C++의 중첩 선언에 해당하는 것을 얻으려면 정적 내부 클래스 사용이 필요합니다. 정적 내부 클래스에는 선언 유형의 객체에 대한 참조가 포함되어 있지 않습니다.

3

실제로이 문제에 대한 해결책이 있습니다. 당신은 implement operator= in terms of copy construction 일 수 있으며, 그것은 작동합니다 :) 그것은 그런 경우를위한 매우 유능한 기술입니다. 할당을 지원한다고 가정합니다.

+1

할당 연산자에서 소멸자를 호출하는 것은 매우 나쁜 프로그래밍 습관입니다. – Sjoerd

+1

답장을 보내 주셔서 감사합니다.이 솔루션을 직접 사용해 보았지만 자체 할당 확인 및 명시 적 소멸자 호출은 생략했습니다. 당신은 당신이 그것을 사용하는 것을 권장하지 않는다는 것을 알아 차렸고 (그리고 나는 당신의 추론에 동의한다), 이러한 단점을 고려할 때 선호되는 구현이 있기 때문에? – dukedave

관련 문제