メンバ構造体定数の初期化

[戻る]
メンマ 2013/08/04(日) 14:02:15
VC++2012を使用している者です。



初歩的な質問で恐縮ですが、





class CStage

{

pubcic:

    const RECT rect;

}



とおいたときの、このrectを、どうすれば初期化できるでしょうか。

επιστημη 2013/08/04(日) 18:41:00
これでいいのかな



#include <iostream>

using namespace std;



typedef int RECT;



class CStage {

public:

    CStage() : rect(123) {}

    const RECT rect;

};



int main() {

  CStage cs;

  cout << cs.rect << endl;

}

メンマ 2013/08/04(日) 18:59:54
ご返答ありがとうございます。



説明が足りず申し訳ありません。

より詳しく申しますと、構造体RECTから作った、CStageのメンバインスタンスrectの中身
(bottom,left.right,top)の各要素を書き換えられないように初期化したかったのです
が、不可能でしょうか。

επιστημη 2013/08/04(日) 20:12:25
> 構造体RECTから作った、CStageのメンバインスタンスrectの中身

> (bottom,left.right,top)の各要素を書き換えられないように

> 初期化したかったのですが、不可能でしょうか。



僕の示したやつではダメですか?

どこがダメですか?

メンマ 2013/08/04(日) 21:23:30
RECT型構造体は、bottom,left,right,topという具合に値を4つ持つので、最初にrectのそ
の4つの変数に値を格納し、、その後は書き換えられない定数としたかった、というのが
私の意図だったのですが、さらなる誤解を招いてしましました。すみません。



お示しいただきましたコードは、RECTをintと置き換え、値一つの定数としたように見受
けられました。





CStageのコンストラクタにおいて、



CStage::CStage(void):rect(0,0,800,600)

{}



というコードを試したのですが、



"int"から"tagRECT"に変換するための適切なコンストラクターが存在しません



というエラーが出ました。

επιστημη 2013/08/04(日) 21:30:18
んじゃこんなの。



#include <iostream>



using namespace std;



struct tagRECT {

  int x, y, w, h;

};



typedef struct tagRECT RECT;



class CStage {

public:

    CStage() : rect(CStage::initial) {}

    const RECT rect;

    static RECT initial;

};



RECT CStage::initial = { 1, 2, 3, 4 };



int main() {

  CStage cs;

  cout << cs.rect.x << ','

       << cs.rect.y << ','

       << cs.rect.w << ','

       << cs.rect.h << endl;

}

tetrapod 2013/08/05(月) 06:51:01
定数といっても複数種類があって static const と non-static const は別。
既に提示されたのは non-static const の例。
もしかしたら static const で事足りるのかもしれない。

/* stage.h */
class CStage {
  static const RECT rect;
  ...
};

/* stage..cpp */
RECT CStage::rect(initial_value);

仲澤@失業者 2013/08/05(月) 15:32:31
クラス化してみてはどうでしょう。
class    RECT_C : public RECT
{
  protected: RECT_C(){ left = 0; right = 0; top = 0; bottom=0;}
  public:    RECT_C( LONG l, LONG t, LONG r, LONG b){ left = l; top = t; right 
= r; bottom=b;}
};

class CStage
{
public:
  const    RECT_C    rect;

  CStage()
    : rect( 0, 0, 800, 600)
  {
  }
};
みたいな。

ホウジョウウサギ 2013/08/05(月) 16:03:24
これでどうでしょうか

class CStage
{
pubcic:
  CState(int l,int t, int r, int b) : rect( GetInitializedRect(l,t,r,b) ) {}
private: 
  const RECT rect;

  static RECT GetInitializedRect( int l, int t, int r, int b )
  {
    RECT rect;
    rect.left=l;  rect.top=t;  rect.right=r;  rect.bottom=b;
    return rect;
  }
};

forty-five 2013/08/06(火) 19:34:32
const_cast がまだ出てないようなので、

class CStage
{
public:
    const RECT rect;
    CStage() {
        const_cast<RECT&>(rect).left = 0;
        const_cast<RECT&>(rect).top = 0;
        const_cast<RECT&>(rect).right = 800;
        const_cast<RECT&>(rect).bottom = 600;
    }
};

ただ私なら仲澤@失業者さんの方法でやりますけど。

tetrapod 2013/08/06(火) 20:35:17
もともと const なブツの constness を const_cast で剥がすことは未定義動作なので
やっちゃだめ (7.1.5.1, 5.2.11)

non-static な const メンバを「初期化」したいのであれば、
メンバ初期化による初期化以外に手はない (C++98) ので
あとはどう初期化するか、具体的手段は当該ブツの定義次第。
もう既に具体的案は挙がっているので、適宜選んでくだされ>元発言者氏

メンマ 2013/08/07(水) 21:16:07
[[解決]]
多くのご返答、ありがとうございます。



いろいろ考えた結果、ホウジョウウサギさんの手法を取り入れることにしました。



他の方々からの貴重なご意見にも感謝いたします。

古いスレッドには追加発言できません。