2012-06-11 3 views
1

객체에 대한 포인터를 반환하는 함수가 있습니다. 이처럼 :포인터로 반환 된 객체의 변경 방지

class SomeClass 
{ 
public: 
    Object* getObject() const { return &obj; }; 
private: 
    Object obj; 
} 

문제는 내가, 그것을 내부적에서 작동 함수를 호출 할 수 반환 된 객체를 변경하는 호출 작동하지 않습니다,하지만 SomeClass 내부의 OBJ을 변경하지 않는 것이 있습니다 .. 예제는 이해하기 쉽습니다.

- 함수가 const 개체 const Object* getObject() const에 대한 포인터를 반환하면 호출하는 함수는 개체의 비 const 메서드를 사용할 수 없지만 할 수 있는). 단순히 포인터를 반환 - 만약

는, 호출 기능은 객체를 변경할 수 있습니다

Object* pointer = sclass.getObject(); 
*pointer = Object(); 

그래서 지금 (나는 일이하고 싶지 않은) 다른 객체이다 sclass 내부의 개체입니다.

해결 방법이 있습니까?

+0

가장 큰 문제는 내가 돈 '이다 당신은 당신이

이 제한이 가치가 있는지 결정해야합니다 이전에 생성/초기화 된 객체를 잃고 싶지 않습니다 ... –

+2

설명 : 객체에 비 const 메소드를 사용할 수 있지만 반환 된 포인터가 다른 객체를 가리 키지 않도록하려면 하시겠습니까? –

+0

@ 한스 그렇습니다. –

답변

8

tl; dr 버전 :const Object *을 반환하십시오.

함수가 호출하는 함수가 객체의 const가 아닌 방법을 사용할 수 없게됩니다 const를 객체 const Object* getObject() const에 대한 포인터를 반환하는 경우

(하지만 난 그들에게 수 있어야합니다).

하지만 그게 바로 const- 정답입니다! 개체의 관찰 가능 상태를 수정하지 않는 모든 Object 메서드는 const으로 선언해야합니다. 이 점에 대해 일관성이 있다면 문제가 사라질 것입니다. 만약 당신이 이 아니고이 이것에 대해 일관성이 없다면 모든 것이 떨어져 버릴 것입니다 (이것은 아마도 당신의 문제의 원인입니다!).

물론, 당신은 다음 thisconst -ness을 멀리 캐스팅으로 일을 파괴 const 방법에 대해 아무것도 할 수 있지만 항상 문제입니다.

+0

목표가'const' 메소드의 사용을 허용하는 것이라면, 호출 사이트에서 오브젝트를 복사하는 접근법이있을 수 있습니다 :'Object foo = * (sclass.getObject()); foo.nonConstMethod();'. 또한 OP가 참조를 사용하지 않는 이유에 대해 궁금해합니다 ... – cdhowie

+0

@cdhowie 그러나 SomeClass 내부의 객체는 호출 된 함수의 영향을받지 않습니다 ... 내 프로그램이 이보다 더 복잡하기 때문에 참조를 사용하지 않습니다. 간단한 예제 ... –

+0

@TiagoCosta 그런 다음이 객체가 불변인지 아닌지를 결정해야합니다. 변경하지 말고 상수 개체에 대한 포인터를 반환합니다. 그렇지 않으면 포인터를 반환하지 않습니다. 당신은 두 가지 방법 모두 가질 수 없습니다. – cdhowie

2

사용자가 개체를 수정할 수 없도록하려면 const 개체에 대한 포인터를 반환하십시오.

개체가 const-correct라고 가정하면 개체를 수정하지 않는 모든 작업을 수행 할 수 있음을 의미합니다. 맞지 않는 경우 const 수정 문제를 수정하려는 경우 (예 : 객체를 수정하지 않는 모든 멤버 함수에 const이라고 표시)

1

Object API가 const 정확성을 적용하지 않으면 클라이언트 기능이 수정하지 못하게 할 수 없습니다. 지금까지 이상적인 객체 지향 디자인.

해결 방법 (내 자신은 아닙니다)은 getObject() 메서드 내에서 개체의 복사본을 반환하는 것일 수 있습니다.

Object* getObject() const { Object* o = new o(obj); return o; }; 

하지만 삭제 등의 돌봐 줘야하지만, 원래 OBJ 변수가 수정되지 않습니다 귀하의 요구 사항과 일치처럼이 불필요한 머리의 통증이 함께 제공됩니다.

+1

이 해결 방법은 Object getObject() {return obj; }'이것은 API 변경이지만 사용자가 반환 된 포인터를 '삭제'해야합니다. –

+0

@unni, obj를 취하는 생성자가 존재하지 않는 경우는 어떻게합니까? 또는 객체 생성이 무거운 경우 무엇입니까? 그것은 다른 사람들이 제안한 바와 같이 요구되는 const-correctness입니다. – Jagannath

0

케이크를 가지고 먹을 수 있다는 것을 깨달았습니다. Object 클래스의 구현을 제어 할 수만 있다면 제공됩니다. 특정 예에서

는 할당 연산자 (operator=()는)

*pointer = Object(); 

이 무효가 다음 식, Object에 대한 비활성화 된 경우.

: 물론,이 결정의 영향은 SomeClass::getObject()보다 큰 : 코드의 다른 부분은 서로 Object의 인스턴스를 할당 할 수 없습니다. , operator=을 해제 private로 선언 (더 구현이 필요하지 않습니다)에 :

class Object 
{ 
    // ... current member declarations/definitions 
    private: 
    Object& operator=(const Object&); // no implementation 
}; 
관련 문제