メンバ変数ポインタを要素に持つ配列をグローバル宣言出来ない – プログラミング – Home

メンバ変数ポインタを要素に持つ配列をグ...
 
通知
すべてクリア

[解決済] メンバ変数ポインタを要素に持つ配列をグローバル宣言出来ない


Mr.Boo
 Mr.Boo
(@Mr.Boo)
ゲスト
結合: 19年前
投稿: 15
Topic starter  

開発環境 VC++ Ver6.0 SP6 MFC
マシンOS Windows XP HOME(最終的にはXP Pro)

上記環境で、ダイアログベースのアプリを作成しております。
設定値をINIファイルから読み込むのに、数が多いため配列にポインタを入れてループで
読み込みをしようと思っています。

class CSetOvParam : public CDialog
{
public:
UINT m_MotorEnd;
UINT m_RingClamp;
UINT m_UnloadArm1;
UINT m_UnloadArm2;
UINT m_UnloadChack;
UINT m_CommImage;

protected:

typedef struct setparam{
char EntryName[32]; // INIファイルEntryName
UINT *m_ptrParams; // 各設定Pointer
}SetParam;

};

SetParam m_SetParam[6] = {
{msgUnloadArm1, &m_UnloadArm1},
{msgUnloadArm2, &m_UnloadArm2},
{msgRingClamp, &m_RingClamp},
{msgUnlaodChack, &m_UnloadChack},
{msgCommImage, &m_CommImage},
{msgMotorEnd, &m_MotorEnd)}
};

BOOL CSetOvParam ::OnInitDialog()
{
CDialog::OnInitDialog();

GetCurrentDirectory( MAX_PATH, m_dir );
wsprintf( m_inifile, %s%s, m_dir, \\Params.ini );

for(i=0;i<6;i++){ // INIファイル設定値の読み込み
*(m_SetParam[i].m_ptrParams) = GetPrivateProfileInt
(SlotSetting,m_SetParam[i].EntryName,1,m_inifile);
}
UpdateData(FALSE); // ダイアログへの反映
}

上記のプログラムをコンパイルするとエラーが出てしまいます。
error C2146: 構文エラー : ';' が、識別子 'm_OvTimeParam' の前に必要です。
error C2501: 'OvTimeParam' : 識別名を宣言するのに、型が指定されていません。
fatal error C1004: 予期せぬ EOF が検出されました。

エラー発生箇所は配列宣言の一番最初で起きています。
VC++にはまだ不慣れなため、何が原因か解りません。

配列をメンバ関数内で宣言すると、コンパイルエラーも発生せず、意図したとおりの動
作をするのですが、なにせ実際の処理で読み込む設定値がかなり多く、また、読み込み
処理だけでなく、書き込み処理やデータチェックも必要なため、それぞれのメンバ関数
内で配列宣言などしていられません。

どなたか、上記プログラムのどこに間違いがあるのか、どうすればいいのかをご教授い
ただけませんでしょうか。


引用未解決
トピックタグ
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

クラスの外では、SetParamやm_UnloadArm1などが何者か分かりません。
CSetOvParam::SetParam などとする必要があります。
しかし、SetParamはprotectedなため、クラス外からは見えないでしょう。

この関数でしか使わないのであれば、
グロバールにせずに、CSetOvParamのメンバ変数にしたらどうですか?
(場合によっては、staticやconstで修飾)
それならば、全てのメンバ関数で参照できます。

# C++では通常、構造体(クラス)のtypedefをする必要はありません。
# m_は、メンバ変数を表す接頭語ですので、グローバル変数には付けません。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

訂正です・・・

>この関数でしか使わないのであれば、
このクラスでしか使わないのであれば、


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

>error C2146: 構文エラー : ';' が、識別子 'm_OvTimeParam' の前に必要です。
m_OvTimeParam って何?どこにもないですけど。

っていうか基本ができていないとしか思えない。メンバ変数がいったいどういう代物なのか
理解していますか?判っていたらそんなコードを書こうとはしないはずです。

どう直せばいいかは、どうしたいのか次第なのですが、コードから意図が読めない
(あまりにも間違いすぎててどう解釈すればいいのか)
ので、何がしたいのかを説明してください。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

# メンバのデータ自体を配列で持って、enum なインデクスで参照するとか駄目ですか...。
# メンバがpublicな時点で個人的には....

今のままだと、メンバ変数を保持するインスタンスが特定できません。

メンバ自体を static にすればとりあえず動くようには思いますが...、
それで意図道理になるのかは不明です。

class CSetOvParam : public CDialog
{
public:
static UINT m_MotorEnd;
static UINT m_RingClamp;
...

UINT CSetOvParam::m_MotorEnd;
UINT CSetOvParam::m_RingClamp;
...


返信引用
Mr.Boo
 Mr.Boo
(@Mr.Boo)
ゲスト
結合: 19年前
投稿: 15
Topic starter  

tetrapod様
済みません、
error C2146: 構文エラー : ';' が、識別子 'm_OvTimeParam' の前に必要です。

error C2146: 構文エラー : ';' が、識別子 'm_SetParam' の前に必要です。
の間違いです。
テスト用に一部を切り出した時のメッセージと間違えました。

意図していることは、定義した配列を、複数のメンバ関数からアクセスしたいので、特
定の関数の外に出そうとしました。

>っていうか基本ができていないとしか思えない。メンバ変数がいったいどういう代物な
>のか理解していますか?判っていたらそんなコードを書こうとはしないはずです。
確かに、落ち着いて考えれば、メンバ変数をクラスの外から参照できるわけは無いので
グローバルは無理ですよね。

REE様
># C++では通常、構造体(クラス)のtypedefをする必要はありません。
済みません、ついこの間までCばかりだったので、ついCのつもりで書いてしまいまし
た。

>グロバールにせずに、CSetOvParamのメンバ変数にしたらどうですか?
これは、
class CSetOvParam : public CDialog
{
public:
UINT m_MotorEnd;
UINT m_RingClamp;
UINT m_UnloadArm1;
UINT m_UnloadArm2;
UINT m_UnloadChack;
UINT m_CommImage;

protected:

struct setparam{
char EntryName[32]; // INIファイルEntryName
UINT *m_ptrParams; // 各設定Pointer
};

const struct setparam m_SetParam[6] = {
{msgUnloadArm1, &m_UnloadArm1},
{msgUnloadArm2, &m_UnloadArm2},
{msgRingClamp, &m_RingClamp},
{msgUnlaodChack, &m_UnloadChack},
{msgCommImage, &m_CommImage},
{msgMotorEnd, &m_MotorEnd)}
};
};
にすればよいと言うことでしょうか。

上記プログラムで確認したのですが、
配列宣言部分で
error C2059: 構文エラー : '{'
error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます
のエラーメッセージが出てしまいました。

済みません、まだC++初心者の為、よくわかっていません。
どうぞ、ご教授下さい。

Ban様
それぞれの変数は、エディットボックスからの定義した変数なのですが、勝手にstatic
に変えてもいいのでしょうか?


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

構文上、非staticの配列メンバ変数を初期化することは出来ません。
constをやめて、コンストラクタで一つずつ代入するしかないです。

>const struct setparam m_SetParam[6] = {
ちなみにこのstructは不要です。


返信引用
Mr.Boo
 Mr.Boo
(@Mr.Boo)
ゲスト
結合: 19年前
投稿: 15
Topic starter  

REE様

>構文上、非staticの配列メンバ変数を初期化することは出来ません。
>constをやめて、コンストラクタで一つずつ代入するしかないです。
有り難う御座います。
コンストラクタに初期化処理を入れて実現させます。

う~ん、結構つらいなぁ。

>>const struct setparam m_SetParam[6] = {
>ちなみにこのstructは不要です。
きちんとC++の基礎部分を勉強し直します。

皆さん、有り難う御座いました。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

non-static メンバ変数のアドレスは this relative なので &m_UnloadArm1 とはできない。
static メンバ変数なら &CSetOvParam::m_UnloadArm1 とできますが、
static にするってことは設計上の用途が変わるってことなので、
変えてよいかどうかの判断はMr.Booさんにしかできません。
# なんとなく static でもいいように憶測できるが、俺なら変えない。

ではどうすればいいか、ってことになりますけど、意図が想像の範囲なのでアレですけど
Ban さんの
># メンバのデータ自体を配列で持って、enum なインデクスで参照するとか駄目ですか...。
がとりあえず簡単だと思う。

メンバ関数なら & が適用できるので
void CSetOvParam::set_UnloadArm1(UINT val) { m_UnloadArm1=val; }
とか作っておいてメンバ関数のテーブルにするとかそういう手もあり。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

> それぞれの変数は、エディットボックスからの定義した変数なのですが、
> 勝手にstaticに変えてもいいのでしょうか?

static はだめですね。
ただ、配列にすることは可能です。(ソースを編集すれば)


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

一応こういう方法もあり(動作未確認)

class CSetOvParam : public CDialog
{
(略)
protected:

struct setparam{
char EntryName[32]; // INIファイルEntryName
UINT CSetOvParam::*m_ptrParams; // 各設定Pointer
};
static const setparam m_SetParam[6];

};

// *.cppで
setparam CSetOvParam::m_SetParam[6] = {
{msgUnloadArm1, &CSetOvParam::m_UnloadArm1},
{msgUnloadArm2, &CSetOvParam::m_UnloadArm2},
{msgRingClamp, &CSetOvParam::m_RingClamp},
{msgUnlaodChack, &CSetOvParam::m_UnloadChack},
{msgCommImage, &CSetOvParam::m_CommImage},
{msgMotorEnd, &CSetOvParam::m_MotorEnd)}
};

BOOL CSetOvParam ::OnInitDialog()
{
CDialog::OnInitDialog();

GetCurrentDirectory( MAX_PATH, m_dir );
wsprintf( m_inifile, %s%s, m_dir, \\Params.ini );

for(i=0;i<6;i++){ // INIファイル設定値の読み込み
this->*(m_SetParam[i].m_ptrParams) = GetPrivateProfileInt
(SlotSetting,m_SetParam[i].EntryName,1,m_inifile);
}
UpdateData(FALSE); // ダイアログへの反映
}


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

訂正・・

>setparam CSetOvParam::m_SetParam[6] = {
CSetOvParam::setparam CSetOvParam::m_SetParam[6] = {


返信引用
Mr.Boo
 Mr.Boo
(@Mr.Boo)
ゲスト
結合: 19年前
投稿: 15
Topic starter  

tetrapod様、Ban様、REE様
皆さん、色々なアドバイスを有り難う御座います。

お教えいただいた内容を元に、もう一度トライしてみます。

本当に有り難う御座います。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました