Const-Based Functions Accross Public / Protected Accessのオーバーロード
-
23-12-2019 - |
質問
(私は信じています)const-nessに基づいて関数を過負荷にすることについて知っています。瞬間がconstの場合、constメソッドは呼び出されます。それ以外の場合は、const 1が1です。
例( IDEONE ):
#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
オーバーロードされたメソッドに同じアクセスカテゴリがない場合は、いくつかの問題に遭遇しました。それは悪いスタイルかもしれませんが、ここでは参照の意図しない変更を避けるために参照を返すという考えを反映する例です:
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;
};
.
今すぐ問題を解決する問題は、このような機能を持つ他の関数をめちゃくちゃにすると、その地域によってそれらを色にする必要があると言って、コンパイラがPublic、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];
.
( IDEONE 。)
でわずかに単純化されていない非コンパイル例を更新しました。私はこれが起こっている理由を取得します:const
はg
ではなく、保護されている非const形状()は想定されていません。
だから私は私の質問は: 非公式関数がアクセスできない場合は、const-functionにある種の "fall back"を取得する方法はありますか?
解決
は、非公式関数がアクセスできない場合は、ある種の「フォールバック」をconst-functionに入れる方法はありますか?
いいえ;アクセスチェックの前に過負荷解像度が発生します。
これはただ悪いスタイルではありません。それは悪いデザインです。Public Getter関数は、内部の内部状態を変更するために、保護された関数から概念的に異なるです。一般に、2つの機能に関連した戻り型を持つ必要とはなりません。したがって、それらは同じ名前を持つべきではありません。
他のヒント
Constバージョンを次のように呼び出すためにconst_cast
を使用することができます。
int main()
{
S s2;
const_cast<const S&>(s2).print(); // prints "const method"
return 0;
};
.
しかし、それは方法の1つの名前を変更するのが良い/より簡単でしょう。