2014-03-31 7 views
1

일부 Java 코드를 C++로 변환하려고합니다. 내가 코드를 작성하려고 할 때 같은 :집합에서 중첩 된 클래스를 사용하는 동안 완료되지 않은 형식 오류가 발생했습니다.

.H :

class A { 
    private: 
    class B; 
    std::set<B> b_set; 
}; 

통화 당 :

class A::B { 
}; 

내가 불완전한 유형의 오류가 발생했습니다. b_set에서 사용하기 전에 중첩 된 클래스가 불완전하기 때문에 그 점을 이해합니다. 그러나 그것을 고치는 가장 좋은 방법은 무엇입니까?

답변

2

전체 B 클래스를 .h 파일로 설명 할 수 있습니다.

다음은 작동하는 예제입니다. 당신이 당신의 정의와 인스턴스를 구분합니다

#include<set> 
class A { 
    private: 
    class B{ 
     B():foo(1){} 
     int foo; 
    }; 
    std::set<B> b_set; 
}; 

그러나, 당신은이 작업을 수행 할 수 있습니다

#include<set> 
class A { 

    private: 
    class B{ 
     public: 
     B(); 
     private: 
     int someMethod(); 
     int foo; 
    }; 
    std::set<B> b_set; 
}; 

A.cpp

#include "A.h" 
    A::B::B():foo(1){} 
    int A::B::someMethod(){ 
    return 42; 
    } 

아 일반적으로 말하기 중첩 된 클래스는 심각한 PITA가 될 수 있습니다. 왜냐하면 당신이 그들로부터 무엇이든 접근하기 위해 뛰어 내야하는 모든 농구 때문입니다.

중첩 된 클래스에 대한 또 다른 좋은 참고 : 완전히 클래스 B의 내부를 멀리 숨기려면 Nested class definition in source file

+0

감사 앤디! 그러나이 경우 구현은 ".h"파일에 있습니다. 좋은 습관입니까? – xieziban

+0

@xieziban : 내 편집을 참조하십시오. 중첩 된 클래스를 사용하려면 정말 좋은 인수가 필요합니다. 그래서 담요 문은 전혀 가지지 않아야합니다. – AndyG

+0

@ xieziban : 왜이 ​​대답을 포기하지 않으시겠습니까? – GingerPlusPlus

2

글쎄, 나는 늦게 알아, 아직도 내가, 또 다른 가능성을 지적하고자 해요 :

class A 
{ 
    private: 
    class B; 
    std::set<B*> b_set; 
}; 

집합의 포인터 사용에 유의하십시오. 그러나 중요한 차이점이 남아 있습니다. 포인터 만 삽입되기 때문에 동일한 내용을 가진 다른 인스턴스에 포인터를 삽입 할 수 있습니다.

class A 
{ 
    private: 
    class B; 
    struct Less 
    { 
    bool operator() (B const* x, B const* y) const 
    { 
     return *x < *y; 
    } 
    }; 
    std::set<B*, Less> b_set; 
}; 

가 알고 있어야합니다 (이 역시 이전의 대답에 언급되지 않은,하지만이 필요합니다!) B (B 또는 참조하는 비교가 정의되어야 함 :이 문제를 해결하려면 사용자 정의 비교가 필요합니다 , 하지 포인터) :!

#include <set> 
class A 
{ 
    private: 
    class B; 
    struct Less 
    { 
    bool operator() (B const* x, B const* y) const; 
    }; 
    std::set<B*, Less> b_set; 
}; 

A.cpp

class A::B 
{ 
    friend bool Less::operator() (B const* x, B const* y) const; 
    bool operator<(B const& other) const 
    { 
    return foo < other.foo; 
    } 
    int foo; 
}; 

bool A::Less::operator() (B const* x, B const* y) const 
{ 
    return *x < *y; 
} 

이렇게하면 어떤 이유로 든 원할 경우 B에서 헤더를 완전히 숨길 수 있습니다. 그러나 복사되지 않고 신속하게 무효화되는 스택에 대한 포인터가 있으므로 스택의 객체를 더 이상 직접 삽입 할 수 없습니다. 객체가 더 이상 필요하지 않거나 메모리 누수가 발생하면 객체를 삭제할 때 특별한주의를 기울여야합니다. Java에서 알 수 있듯이 가비지 콜렉션이 없음을 기억하십시오.C++ 11을 사용하는 경우, 당신은 사용하여 문제를 완화 할 수 있습니다 : 표준 : : unique_ptr을하기 전에, : 표준 : : auto_ptr은 :

A.h

#include <set> 
#include <memory> 
class A 
{ 
    private: 
    class B; 
    struct Less 
    { 
    bool operator() (B const* x, B const* y) const; 
    }; 
    std::set<std::unique_ptr<B>, Less> b_set; 
}; 
+0

당신의 대답은 제가 alot.thnx 도움이됩니다. –