문제
나를 호출해야 const 기능에서 비 const 개체입니다.예를 참조하십시오
struct IProcess {
virtual bool doSomeWork() const = 0L;
};
class Foo : public IProcess {
virtual bool doSomeWork() const {
...
}
};
class Bar
{
public:
const IProcess& getProcess() const {return ...;}
IProcess& getProcess() {return ...;}
void doOtherWork {
getProcess().doSomeWork();
}
};
전화
getProcess().doSomeWork();
항상 결과에 통화
IProcess& getProcess()
할 수 있는 다른 방법이 있을 통화
const IProcess& getProcess() const
에서 일정한 구성원 기능입니까?내가 지금까지 사용
const_cast<const Bar*>(this)->getProcess().doSomeWork();
는 그러나 같은 지나치게 복잡합니다.
편집:나도 언급해야 하는 코드 리팩터링하고 결국 하나의 기능만이 남아 있습니다.
const IProcess& getProcess() const
그러나,현재 부작용 및 const 호출이 반환할 수 있는 다른 인스턴스의 IProcess 부분의 시간입니다.
유의하시기 바랍에서 주제입니다.
해결책
캐스트를 피하십시오 : 이것을 a에 할당하십시오 const Bar *
또는 무엇이든 전화를 걸어 사용하십시오 getProcess()
.
그렇게해야 할 몇 가지 이유가 있지만, 컴파일러가 잠재적으로 안전하지 않은 일을하도록 강요하지 않고도 당신이하고있는 일을 더 분명하게 만듭니다. 물론, 당신은 그 사건에 결코 영향을 미치지 않을 수도 있지만,이 경우 캐스트를 사용하지 않는 것을 쓸 수도 있습니다.
다른 팁
const_cast
캐스팅을위한 것입니다 떨어져 있는 콘트 스네스!
당신은 안전한 비정규부터 콘트로로 캐스팅하고 있으므로 사용하므로 사용하십시오. static_cast
:
static_cast<const Bar*>(this)->getProcess().doSomeWork();
기술적으로 말하면 당신은 const_cast
, 그러나 운영자의 실용적인 사용은 아닙니다. 새로운 스타일 캐스트의 목적 (오래된 C 스타일 캐스트와 비교하여)은 캐스트의 의도를 전달하는 것입니다. const_cast
코드 냄새이며 최소한 사용을 검토해야합니다. static_cast
반면에 안전합니다. 그러나 그것은 C ++ 스타일의 문제입니다.
또는 새 (개인) const 메소드를 만들고이를 호출 할 수 있습니다. doOtherWork
:
void doSomeWorkOnProcess() const { getProcess().doSomeWork(); }
Const 임시 사용 옵션도 있습니다 ( "MSN"의 답변) :
const Bar* _this = this;
_this->getProcess().doSomeWork();
만약에 getProcess()
그리고 getProcess() const
동일한 개체에 대한 참조를 반환하지 않으면 (그러나 다르게 자격을 갖추 었음) class Bar
. 과부하 const
기능의 Ness는 다른 동작으로 기능을 구별하는 좋은 방법이 아닙니다.
그들이 같은 개체에 대한 참조를 반환하는 경우 :
const_cast<const Bar*>(this)->getProcess().doSomeWork();
그리고
getProcess().doSomeWork();
정확히 동일하게 호출하십시오 doSomeWork()
기능을 사용할 필요가 없습니다 const_cast
.
캐스트가 당신에게 너무 못 생겼다면 대신에 메소드를 추가 할 수 있습니다. Bar
그것은 단순히 const 참조를 반환합니다 *this
:
Bar const& as_const() const {
return *this; // Compiler adds "const" without needing static_cast<>
}
그런 다음 전화 할 수 있습니다 어느 const
방법 Bar
선수만으로 as_const().
, EG :
as_const().getProcess().doSomeWork();
기능이 과부하되지 않으면 캐스팅 속임수를 할 필요가 없습니다. 정점이 아닌 객체의 const 메소드를 호출하는 것은 괜찮습니다. 금지 된 const 객체에서 비 초가 메소드를 호출하고 있습니다. 메소드가 const 및 비 초보 함수로 무시되면 개체를 Const에 캐스팅하면 트릭을 수행합니다.
const_cast<const IProcess&> (getProcess()).doSomeWork();
편집 : 나는 전체 질문을 읽지 않았습니다. 예, const_cast가 필요합니다 이것 포인터 또는 만듭니다 eotherwork 호출 할 기능 const iprocess & getProcess () const.
요점은 전화 할 수있는 개체가 필요하지 않다는 점이 남아 있습니다. 일 좀해라. 그것이 목표이기 때문에, 당신은 const 메소드가 필요합니까?
또 다른 옵션은 지나친 기능의 이름을 바꾸는 것입니다. 두 기능이 실제로 다른 동작/부작용을 갖는 경우 이것은 정말 좋은 생각입니다. 그렇지 않으면 함수 호출의 효과는 분명하지 않습니다.
템플릿을 정의합니다
template< class T >
const T & addConst ( T & t )
{
return t;
}
그리고 전화
addConst( getProcess() ).doSomeWork();
글쎄, 당신은 선언 할 수 있습니다
void doOtherWork const ()
?
그렇게 할 것입니다.
Const_cast 방법이 최선의 선택이라고 생각합니다. 이것은 C ++의 Const 프레임 워크의 한계 일뿐입니다. 캐스팅을 피할 수있는 유일한 방법은 const iprocess 인스턴스를 반환하는 메소드를 정의하는 것입니다. 예를 들어.
const IProcess* getProcessConst() const { return ... }
...
getProcessConst().doSomeWork();
나는 당신이 const 객체에서 호출되었는지 여부에 따라 두 개의 getprocess 전화 중 하나를 호출하기를 원한다고 가정합니다.
내가 제안 할 수있는 최선은 이것입니다.
class Bar
{
public:
const IProcess& getProcess() const {return ...;}
IProcess& getProcess() {return ...;}
void doOtherWork { // should use getProcess()
getProcess().doSomeWork();
}
void doOtherWork const {
getProcess().doSomeWork(); // should use getProcess() const
}
};
그것이 효과가 있더라도 이것은 나에게 나쁜 냄새처럼 보입니다. 나는 물체의 콘트 스네스에 따라 급진적으로 변화하는 계급 행동에 대해 매우 조심합니다.
Monjardin에 의해 게시되었습니다
또 다른 옵션은 지나친 기능의 이름을 바꾸는 것입니다. 두 기능이 실제로 다른 동작/부작용을 갖는 경우 이것은 정말 좋은 생각입니다. 그렇지 않으면 함수 호출의 효과는 분명하지 않습니다.
IProcess & 주로 속성을 통해 다른 코드로 액세스됩니다.
__declspec(property(get=getProcess)) IProcess& Process;
따라서 이름을 변경하는 것은 옵션이 아닙니다. 대부분의 시간 Const호출 함수의 ness는 getProcess ()와 일치하므로 문제가 없었습니다.
당신은 기본적으로 붙으로 이름을 바꾸면 다른 방법이나 const_cast.
BTW,이것은 하나의 이유가 사 스마트 포인터를 하지 않는 실제로 잘 작동에서는 C++.복사에서 쓰는 스마트 포인터를 하나의 공유할 수 있는 무.사용자가 액세스하는 데이터에서 비 const 컨텍스트,데이터의 복사본을 만들(사용자의 경우 보유하지 않은 고유 참조).이 종류의 포인터를 수 있는 매우 편리하게 사용할 경우 공유형 데이터 구조는 단지 어떤 클라이언트가 필요한 수정할 수 있습니다.가장"논리적"구현하는 것입 const 및 비 const 자>.Const 버전을 반환합의 기본 참조.Non-const 버전은 독특한 확인 및 검사를 사용하지 않습니다.하지 못하기 때문에 유용 비 const 스마트 포인터를 사용하여 비수자->는 기본적으로,심지어 당신을 사용하고 싶었 const 버전입니다.이 const_cast 요구 사항이 매우 사용자가 쌀쌀.
나는 환영하는 사람이 증명한 나에게 잘못하여 사용자 친화적 복사 포인터에서는 C++...