C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: const/非constの使い分けについて


(過去ログ 22 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■9747 / inTopicNo.1)  const/非constの使い分けについて
  
□投稿者/ sato (4回)-(2007/11/03(Sat) 19:57:34)

分類:[C/C++] 

c++での質問です。
皆さんは、関数、戻り値、引数のconst指定をどのような基準で決めていますか?
自分の場合、

関数、戻り値・・・Getter関数のうち、メンバ変数の情報を書き換えないもの
引数・・・関数内で情報を書き換えない参照orポインタ

という感じにしていますが、次のような場合に困ってしまいます。

Flower {
  public:
    void setColor(int Color) {color=Color;}
    int getColor() const {return color;}
  private:
    int color;
}

Garden {
  public:
    Flower* getFlower(int n) {return &flowers[n];}
  private:
    vector<Flower> flowers;
}

garden.getFlower(n)->setColor(WHITE);    //庭のn番目の花の色を白に

このような操作を可能にする場合、getFlower()とその戻り値は非constにしなければなりません。
しかしそうなると、

bool IsAllFlowersWhite(Garden &granden) {
  for (int i=0; i<garden.getFlowerCount(); i++)
  {
    if (garden.getFlower(i)->getColor()!=WHITE) return false;
  }
  return true;
}

のように内部情報を一切変更しないような関数の引数がconstにできなくなってしまいます。
キャストで非constにしたり、
const Flower* getFlowerConst(int n) constのようにconstなFlowerポインタを返す関数を作れば
解決できなくもないですが、スマートでない感が否めません。

何かよい方法がありましたら、ご教授下さい。

引用返信 編集キー/
■9748 / inTopicNo.2)  Re[1]: const/非constの使い分けについて
□投稿者/ 囚人 (219回)-(2007/11/03(Sat) 20:26:32)
ちょっと微妙かもしれないけど、mutable かな。

class Garden {
  public:
    Flower* getFlower(int n) const {return &flowers[n];}
  private:
    mutable vector<Flower> flowers;
};


#スペルミスとかしないで、コンパイルできるソースコードを貼ってホスィ…。

引用返信 編集キー/
■9760 / inTopicNo.3)  Re[2]: const/非constの使い分けについて
□投稿者/ 774RR (57回)-(2007/11/04(Sun) 07:50:22)
STL container も const と nonconst と両方を持っているし、両者を用意するのがスマートだと思う。
クラスの主体となるメンバに mutable を指定するのは猛反対。
mutable は最小限のメンバにこっそり使うべきだろうね。

引用返信 編集キー/
■9764 / inTopicNo.4)  Re[1]: const/非constの使い分けについて
□投稿者/ επιστημη (629回)-(2007/11/04(Sun) 10:37:35)
επιστημη さんの Web サイト
んー...僕だったら getFlower() の const版/non-const版を用意するかな。

class Garden {
public:
  Flower* getFlower(int n)             { return &flowers[n];}
  const Flower* getFlower(int n) const { return &flowers[n]; } // コレ追加
  int getFlowerCount() const { return flowers.size(); }
private:
  std::vector<Flower> flowers;
};

bool IsAllFlowersWhite(const Garden &garden) { // ココ変更
  for (int i=0; i<garden.getFlowerCount(); i++) {
    if (garden.getFlower(i)->getColor() != WHITE ) return false;
  }
  return true;
}

引用返信 編集キー/
■9787 / inTopicNo.5)  Re[1]: const/非constの使い分けについて
□投稿者/ sato (5回)-(2007/11/04(Sun) 21:12:14)
すみません、解決策を一度テストして下さる方もいらっしゃることを考えればもっと丁寧に書くべきでした。
mutableはちょっと微妙なので、const版/non-const版の両方を用意することにします。
επιστημηさんのやり方でコンパイラが判別してくれるとは知りませんでした。

囚人さん、774RRさん、επιστημηさん、どうもありがとうございました。
解決済み
引用返信 編集キー/
■9793 / inTopicNo.6)  Re[2]: const/非constの使い分けについて
□投稿者/ επιστημη (630回)-(2007/11/04(Sun) 22:51:26)
επιστημη さんの Web サイト
> επιστημηさんのやり方でコンパイラが判別してくれるとは知りませんでした。

ライブラリのヘッダをざっくり眺めると勉強になりまっせ。
たとえばここで使われてるvectorなんかでも:

iterator begin();
const_iterator begin() const;

なんて宣言がされてます。

解決済み
引用返信 編集キー/
■9796 / inTopicNo.7)  Re[3]: const/非constの使い分けについて
□投稿者/ 囚人 (222回)-(2007/11/04(Sun) 23:50:41)
>επιστημηさんのやり方でコンパイラが判別してくれるとは知りませんでした。

Effective C++ だったか More Effective C++ だったかに const のあるなしでオーバーロードできることが書いてあります。

mutable を使用するシーンは、ビットレベル(Effective C++ で使っている用語)では中身を書き換えるけど、論理的には const だって時に使用するみたいです。
引用返信 編集キー/
■9797 / inTopicNo.8)  Re[4]: const/非constの使い分けについて
□投稿者/ 囚人 (223回)-(2007/11/04(Sun) 23:51:24)
解決済みのオーバーライド忘れ
解決済み
引用返信 編集キー/
■9798 / inTopicNo.9)  Re[3]: const/非constの使い分けについて
□投稿者/ 774RR (58回)-(2007/11/04(Sun) 23:52:34)
判別というあたりに誤解があるかも知れないので蛇足など
# 俺も昔誤解してたし・・・

Garden g; // non-const
g.getFlower(n)->getColor() // read-only access to flower
この場合 getFlower() は non-const 版が呼ばれる。

this の best-match 規則は、その時点で判明している this に対してのみ有効
その先どう使われるかは無関係。

g は non-const だから g.getFlower() の best-match は non-const 版
これに対して、その後で行われる ->getColor() の best-match は
(1つしかないのでしょうがないから) getColor() const ということになるわけだ。

const Garden& r=g; // r は const
この場合 r.getFlower() は const 版が best-match (non-const 版は不適合)

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -