2009-11-02 3 views
0

C++에서는 소유자를 다시 가리 키려는 객체에 대한 참조가 있지만 포함되지 않은 구조이기 때문에 포함하는 클래스의 구조에서 포인터를 설정할 수 없습니다.생성되는 객체를 참조하는 C++

class A { 
    public: 

    A() : b(this) {} 
    private: 
    B b; 
}; 

class B { 
    public: 
    B(A* _a) : a(_a) {} 
    private: 
    A* a; 
}; 

가 B는 항상 A가 B에 대한 포인터를 유지하지 않고 A *로 초기화됩니다 보장 할 수있는 방법이 있나요 : 그래서 내가 이런 일을 할 노력하고있어?

+4

매우 까다로운 커플 링입니다. 너는 무엇을 해결하고 있는가? – GManNickG

답변

6

이 시도

감사합니다 : B 이후

class A; 

class B { 
public: 
    B(A *_a) : a(_a) {}; 

private: 
    A* a; 
}; 

class A { 
public: 
    A() : b(this) {}; 

private: 
    B b; 

}; 

가 완전히 포함되어이 먼저 선언해야합니다. A를 가리키는 포인터가 필요하므로 A를 선언하기 전에 A를 forward-declare해야합니다.

이 코드는 더 많거나 적은 g ++의 최신 버전에서 컴파일됩니다.

0

C++에서는 소유자를 다시 가리키고 싶은 객체에 대한 참조가 있지만 포함하지 않는 구조이므로 포인터를 설정할 수 없습니다.

포인터를 올바르게 저장할 수 있습니다.

#include <iostream> 

class Y; 

class X 
{ 
    Y* y; 
public: 
    X(Y* y); 
}; 

class Y 
{ 
    X x; 
    int n; 
public: 
    Y(): x(this), n(42) {} 
    int get_n() const { return n; } 
}; 

X::X(Y* p): y(p) 
{ 
    //Now this is illegal: 
    //as it is, the n member has not been initialized yet for parent 
    //and hence get_n will return garbage 
    std::cout << p->get_n() << '\n'; 
} 

int main() 
{ 
    Y y; 
} 
: 부모 인스턴스가 완전히 시점에서 초기화되지 않을 수 있기 때문에

당신이 할 수없는 것은, B의 생성자에서 포인터를 통해 구성원/방법에 도착하는 것입니다

Y에서 멤버 주위를 전환하면 n이 먼저 초기화되므로 X의 생성자는 42를 인쇄하지만 이는 너무 취약하여 의존 할 수 없습니다.

관련 문제