공용/보호된 액세스를 가로 지르는 콘스트 기반 함수 오버로드
-
23-12-2019 - |
문제
(나는 믿는다)나는 일관성에 기반한 오버로드 함수에 대해 알고있다:만약 인스턴트가 콘스트라면 콘스트 메소드가 호출되고,그렇지 않으면 콘스트가 아닌 메소드가 호출됩니다.
예(또한 아이디온):
#include <iostream>
struct S
{
void print() const { std::cout << "const method" <<std::endl };
void print() { std::cout << "non-const method" <<std::endl };
};
int main()
{
S const s1;
s1.print(); // prints "const method"
S s2;
s2.print(); // prints "non-const method"
return 0;
};
나는 내 코드에서 그것을 사용하려고 시도했지만 몇 가지 문제가 발생했을 때 const
오버로드 된 메서드에는 동일한 액세스 범주가 없습니다.나쁜 스타일 일 수 있지만 복사 및 사용을 피하기 위해 참조를 반환하는 아이디어를 반영하는 예가 있습니다 const
의도하지 않은 변경을 제한하려면:
struct Color;
struct Shape
{
double area;
};
class Geometry
{
public:
// everybody can alter the color of the geometry, so
// they get a mutable reference
Color& color() { return m_color; };
// not everybody can alter the shape of the Geometry, so
// they get a constant reference to the shape.
Shape const& shape() const { return m_shape; };
protected:
// derived classes can alter the shape, so they get
// access to the mutable reference to alter the shape.
Shape & shape() { return m_shape; };
private:
Shape m_shape;
Color m_color;
};
내가 지금 직면하고있는 문제는 내가 컴파일러가 대중을 데리러 가기를 원한다는 것이다, const
-모양 기능을 반환 다른 기능은 형상과 놨 경우,이 형상의 모양에 액세스 할 필요가있는 자신의 영역에 의해 색상을 말한다:
// this one fails
void colorByArea() {
for( Geometry g : geometryList )
{ g.color() = colorMap[g.shape().area]; }
}
// this one is a clunky workaround
void colorByArea() {
for( Geometry g : geometryList )
{
Geometry const& g_const = g;
g.color() = colorMap[g_const.shape().area];
}
}
이(또는 이와 유사한 것)은 다음과 같은 상당히 이해할 수있는 오류로 실패합니다:
‘Shape& Geometry::shape()’ is protected
Shape & shape() { return m_shape; };
^ error: within this context
g.color() = colorMap[g.shape().area];
(나는 약간 단순화 된 비 컴파일 예제를 아이디온.)
왜 이런 일이 벌어지는지 알 수 있습니다.:g
아니다 const
따라서 비콘스트 모양()은 프로텍텍이라고 불리지만,분명히 실패합니다.
그래서 나는 내 질문 이:비 콘스트 함수에 액세스 할 수없는 경우 콘스트 함수에 일종의"폴백"을 얻을 수있는 방법이 있습니까?
해결책
비 콘스트 함수에 액세스 할 수없는 경우 콘스트 함수에 일종의"폴백"을 얻을 수있는 방법이 있습니까?
아니;액세스 확인 전에 과부하 해결이 발생합니다.
이것은 단지 나쁜 스타일이 아닙니다;그것은 나쁜 디자인입니다.공개 게터 함수는 개념적으로 다른 내부에 대한 지식을 가진 코드가 객체의 내부 상태를 수정할 수 있도록 하는 보호된 함수에서일반적으로 두 함수는 관련된 반환 타입을 가질 필요가 없습니다.따라서 그들은 같은 이름을 가져서는 안됩니다.
다른 팁
당신은 사용할 수 있습니다 const_cast
콘스트 버전을:
int main()
{
S s2;
const_cast<const S&>(s2).print(); // prints "const method"
return 0;
};
그러나 방법 중 하나의 이름을 바꾸는 것이 더 좋고 간단 할 것입니다.