2010-02-26 2 views
5

다음 코드는 Visual C++ 2008에서 잘 작동합니다. 그러나 Visual C++ 6에서는 다음 오류가 발생합니다. 이유를 알 수 있고 오류를 해결할 수는 있지만 소멸자는 여전히 비공개로 유지할 수 있습니까?Visual C++ 6이 개인 소멸자에 대해 불만한 이유

class X 
{ 
public: 
    static X& instance() 
    { 
     static X database; 
     return database; 
    } 

private: 

    X() {}     // Private constructor 
    ~X() {}     // Private destructor 
    X(const X&);    // Prevent copy-construction 
    X& operator=(const X&); // Prevent assignment 
}; 

int main() 
{ 
    X::instance(); 
} 

C : 프로젝트 \ \ ttt6의 \의 MAIN.CPP (178) : 오류 C2248 : 'X :: ~ X': C 'X'클래스에서 선언 private 멤버에 액세스 할 수 없습니다 : \ 프로젝트 \ ttt6 \ MAIN.CPP (175)의 선언을 참조 'X :: ~ X'fun()에서

+0

생성자/소멸자가 항상 public이되어서는 안됩니까? – vpram86

+3

@Aviator : 생성자가 항상 공개되어서는 안됩니다. 예 : 추상 클래스의 경우, 생성자를 호출하는 파생 클래스 만 필요하므로 (추상 클래스의 인스턴스화를 방지 할 수있는 방법입니다) 따라서 'protected'로 만듭니다. 싱글 톤의 경우 클래스의 정적'CreateInstance()'메소드 만 인스턴스를 생성하기를 원한다. 그래서 당신은 생성자를 private로 만든다. –

+0

@ Scott : 고마워요. 나는 그것을 지금 이해한다. – vpram86

답변

7

수정 된 샘플은 VC6에 대해 확인 된 컴파일러 버그를 보여줍니다. 일반적인 해결 방법은 간단히 소멸자를 공개하는 것입니다.

+0

이 버그에 대한 참고 자료가 있습니까? –

+0

http://www.codeguru.com/forum/archive/index.php/t-236067.html –

+1

과 같은 더 좋은 참조를 찾으면 내 기억이나 오래된 스레드를 찾는데 어려움이 있습니다. 질문 : http://stackoverflow.com/questions/2130864/cannot-access-private-member-in-singleton-class-destructor –

4

별도의 객체, aa을 만든 다음 할당 연산자를 통해에 a::instance()에 의해 반환 된 객체 참조의 값을 복사합니다. 이것은 생성자와 소멸자가 모두 private이기 때문에 작동하지 않습니다. 재미의 끝은()에 도달하면

a &aa = a::instance(); 
+0

실제로 복사 ctor를 통해 복사하려고합니다. –

+0

죄송합니다. 내 코드 예제에서 실수. 나는 개정했다. 코드는 여전히 VC6에서 오류를 발생 시키지만 VC2008에서는 통과합니다. –

+1

@Yan : 그것은지나 가지 않는다, 나는 약속한다. 너의 시험은 틀렸다. 예제 코드 대신 실제 코드를 제공하십시오. – GManNickG

2

, 당신의 변수가 범위를 벗어나 이동하고 소멸자가 호출됩니다 : aa는 참조해야한다.

싱글 톤을 구현하려는 것처럼 보입니다. 아마도 이것을 의미할까요?

a &aa = a :: instance();

aa가 인스턴스가 아니라 참조 인 경우 소멸자는 fun()가 끝날 때 호출되지 않습니다.

+0

죄송합니다. 내 코드 예제에서 실수. 나는 개정했다. 코드는 여전히 VC6에서 오류를 발생 시키지만 VC2008에서는 통과합니다. –

0

그냥 VC6 버그입니다. VC6는 매우 버그입니다. 해결 방법으로 std :: auto_ptr <>을 사용할 수 있습니다.

#include <memory> 

class X 
{ 
    friend std::auto_ptr<X>; 
public: 
    static X& instance() 
    { 
     static std::auto_ptr<X> database(new X); 
     return *database; 
    } 
..... 
}; 

그리고 instance() 구현을 cpp 파일로 이동하십시오. 죄송합니다, 정확한 사례는 기억이 나지 않지만 헤더 파일에 싱글 톤 구현이있는 또 다른 VC6 버그가 있습니다. 몇 년 전에 VC6을 사용할 때 두 번 충돌이있었습니다. 문제는 instance() implmenetation을 cpp로 옮기는 것이 었습니다.