2012-03-12 10 views
0

대부분 잘 작동하는 클래스로 작업하고 있지만 재귀 함수를 사용 중일 수있는 일부 기능을 수행 중이므로 NULL 포인터를 클래스 형식의 컨트롤로 반환 할 수 있습니다. 짧은 내 클래스 객체에 너무 오래 이야기를 NULL 포인터를 할당 할 수 :할당 연산자 C++ NULL 할당

Thing& Thing::operator=(Thing * _other){ 
    if (_other == NULL){ 
     *this = NULL;  // compiler throws here 
     return *this;  
    } 
    // does other assignment work 
    return *this; 
} 

내 컴파일러 VS2010는 this는 I-값 아니라고 발생합니다. 그렇다면 값을 NULL으로 설정하는 방법 또는 내부에서 항목을 NULL로 설정할 수 있습니까?

EDIT : 수정 된 this ~ *this 이제는 어떤 이유로 프로그램이 할당 연산자에 대한 무한 호출로 중단됩니다. 무슨 일이 일어나고 있는지 전혀 모른다

+2

'* this = NULL'은 연산자를 다시 호출합니다. if는 연산자를 호출합니다. 복사 할당 연산자를 쓰려면 const 참조 나 값을 인수로 받아야합니다 (참조 : 카피 - 스왑 (copy-and-swap) 관용구). –

+0

복사 생성자를 사용하지 않는 이유는 무엇입니까? – Alex

+0

@Alex와 유사한 것은 복사 생성자에서 수행되어야합니다. 왜냐하면 대부분의 복사 생성자는 단순히 객체 arg을 복사하기 때문에 NULL 데이터를 복사하려고하면 대부분의 디버거/실행 파일이 충돌하거나 실패합니다. – gardian06

답변

1

그 수업? 개체가 어떻게 든 값이 없거나 초기화되지 않았 음을 나타내려면 상수 인 "this"를 할당하는 대신 fileds 0 (정수) 및 null (포인터) 등을 할당하는 것이 좋습니다.

+0

테스트를 변경해야하지만 가장 직설적 인 것으로 보이며 제 구현을 바꿔야 할 필요가 없습니다 – gardian06

+0

아마도 올바른 멤버 함수'void Thing :: initializeNull() {}'을 호출하고이 할당을 수행하여 필요할 때마다 그리고 Thing의 기본 생성자에서 호출합니다. – rene

2

this 포인터에 값을 직접 설정할 수 없습니다. 따라서

this = NULL; 

은 의미 론적 및 구문 론적으로 잘못된 것입니다.

_otherNULL인지 확인하기 위해 예외를 사용할 수 있습니다. 예를 들어 :

Thing the_thing, other_thing; 
try { the_thing = &other_thing; } 
catch(const null_object_exception& e) { the_thing = NULL; } 
+0

이됩니다. 그러면 할당 된 것이'NULL '일 경우'NULL'에 대한 할당을 어떻게 수행합니까 – gardian06

+0

'catch' 문에서 할 수 있습니다 – ApprenticeHacker

+0

@ gardian06 편집을 확인하십시오 희망이 문제를 해결합니다 – ApprenticeHacker

1

당신 this에 할당 할 수 없습니다 :

class null_object_exception : public virtual exception {}; 
... 
if (_other == NULL) throw null_object_exception(); 

NULL 할당을 수행합니다.

또한, 당신이 그렇게 Thing& operator= (const Thing& other)

C++에 큰 SO 질문 있어요, const 참조하여 인수를해야합니다 - 연산자 오버로딩에 대한 자주 묻는 질문 태그, 당신은 찾을 수 있습니다 그것의 멤버 변수 무엇 here

+2

'this'는'const'가 아니며, 우위 값을 나타냅니다. –

+0

@CatPlusPlus는 일부 검사를 한 후에 현재 오브젝트에 대한 const *이며, 다른 오브젝트처럼 취급하지만'* this'라고 지정하여 할당 할 수 있습니다. – gardian06

+1

@ gardian06 : const 포인터가 아니며 exp입니다. rvalue 포인터를 생성하는 영역. const에 대한 포인터 일 수도 있지만, 그것은 객체의 constness에 달려있다. 그것을 역 참조하는 것은 다른 포인터를 산출하지 않고, 객체에 대한 참조 (아마도 const)를 산출합니다. 불가능하기 때문에'this' 포인터를 수정하지 않습니다. –

1

짧은 대답, 아니요, C++에서 this에 할당 할 수 없습니다.

길게 대답; 당신의 대입 연산자가 호출되기까지, 당신은 다음과 같은 구조를 가져야 만합니다;

MyObject a; 
a = NULL; // can change the content of `a` but not which object the name `a` refers to. 

이 구문에 대해 생각하는 경우; 그것은 객체이 아닌 포인터에 연산자이기 때문에

MyObject *a; 
a = NULL; 

과제 연산자도 호출되지 않습니다. a 포인터에 지정하면 할당 연산자를 정의하지 않아도 작동합니다.

+0

"MyObject a = NULL"이라도 Thing :: operator = (Thing * _other)를 호출합니까? NULL은 Thing * 타입이 아니기 때문에 왜 그 오버로드가 호출 될까요? –

+0

@KJTsanaktsidis 그것은 그렇지 않다고 이해할 수 있습니다. 포인터를 사용하는 오버로드가 여러 개있는 경우 모호한 오버로드로 인해 컴파일 오류가 발생합니다. –

2

"허용 가능"클래스를 작성하려고합니다. "null"상태가 Thing의 인스턴스가 될 수있는 상태 중 하나라고 생각하고, 포인터 의미론으로 그것을 convolute하지 마십시오.

일반적인 방법은 인스턴스가 null 상태인지 여부를 추적하는 부울 플래그를 클래스에 추가하는 것입니다. 나는 이것을 다음과 같이 구현할 것이다 :

class Thing 
{ 
private: 
    bool m_null; 

public: 
    void setnull() { m_null = true; } 
    bool isnull() const { return m_null; } 

    Thing() : m_null(true) {} 

    ... // rest of class 
}; 

이제 기본 할당 연산자가 잘 동작한다.