プロが教えるわが家の防犯対策術!

よろしくお願いします。

VC++のウィザードが自動生成するChildFrm.cpp内のクラスAとMainFrm.cpp内のクラスBの間で共通の変数int xxxを使いたいのですが、どこに宣言すれば良いのでしょうか?

それともクラス間では、そのようなことは出来ないのでしょうか?

ご存知の方教えてください。

A 回答 (10件)

// M.h


class M {
private:
int xxx;
public:
void setXXX(int v) { xxx = v; }
int getXXX() const { return xxx; }
...
};

// C.cpp
#include "M.h"
#include "C.h"

void C::function() {
M* m = static_cast<M*>(GetParentFrame());
m->setXXX(123); // write
int xxx = mf->getXXX(); // read
}
    • good
    • 3
この回答へのお礼

昔のPCが生きていたので確認できました。
何度も有難う御座います。

先回うまく行かなかったのは、
#include "M.h"
が抜けていたためでした。
(ケアレスミスでは有りません。このようにしなければいけない事を知らなかっただけです。またひとつ勉強になりました)

今回のやり方でコンパイルエラーは出ませんでしたが、実行時に”不正な処理~”が出てしまいました。

自分で、もう少し考えてみます。

お礼日時:2003/03/12 00:32

> 出来ました。

とうとう出来ました。

めでたし。グローバル変数こねくりまわすよか綺麗でしょ?

> でも待てよ、親フレームのサイズはどうすればxxxに代入出来るんだ?

xxxへ代入できるのが親フレーム本人に限られるのなら、setXXXはprivate部に置いて外から使えなくするが吉でしょう。
    • good
    • 0
この回答へのお礼

epistemeさん 今回の件、本当にありがとうございました。

でもこんなに大変(?)と言うことは、起動時のフレームサイズに対して、ある大きさの子ウィンドウを開くなんてことは普通しないってことなのかなぁ・・

お礼日時:2003/03/12 17:22

# 何度もごめんなさい



> #3 にあるように、CWinAppに持たせてはいかがでしょう。

これ、やっぱり気に入らない。CWinAppには必要のないものなんだから。

AfxGetMainWnd() でMDI-親フレームが得られるはず。
こちらがbetterかな...
    • good
    • 0
この回答へのお礼

出来ました。とうとう出来ました。(以下にて)
CMainFrame* m = static_cast<CMainFrame*>(GetMDIFrame());

epistemeさん。最後まで付き合ってくださり本当にありがとうございました。

でも待てよ、親フレームのサイズはどうすればxxxに代入出来るんだ?だめだ、でもこれ以上聞けない。

てことで悩んだ末、ようやくできました。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    省略
setXXX(yyy); // write
}

再度、ありがとうございました。

お礼日時:2003/03/12 13:00

うぅぅ...PreCreateWindow中はまだWidnowが世の中に存在しないわけで、


そうなるとGetMDIFrameの類がちゃんと動いてくれるか怪しいす。(0が返っているかも)

#3 にあるように、CWinAppに持たせてはいかがでしょう。
    • good
    • 0

> 今回のやり方でコンパイルエラーは出ませんでしたが、実行時に”不正な処理~”が出てしまいました。



あ、もしかしたら GetParentFrame() 改め GetMDIFrame() かも。

この回答への補足

慌てて間違えました。
元々やりたかったのは、
1.MDIにて起動時に開く子ウインドウのサイズを”フレーム”の半分の大きさにする
2.そのために、”フレーム”のCS.CXを取得し、子ウインドウのサイズCS.CX/2を使用する
と言うものです。

補足日時:2003/03/12 08:21
    • good
    • 0
この回答へのお礼

朝起きて覗いてみたら、やった~~。またまた返信が来てるではないですか。恐る恐る実行ボタンをクリックなんとなくうまく行きそう。と思ったら、英文のエラーメッセージが出てしまいました。

無視、中止、再試行と書いてあるやつ。

そもそも、私は皆さんに対し、どこにどう書いたか示していないじゃないですか。大変失礼しました。

元々やりたかったのは、
1.MDIにて子ウインドウを起動時に2個表示
2.1個目はCS.CXにて任意の大きさや最大表示にする
3.2個目は、1個目の半分の大きさにする
  そのために1個目のCS.CXを取得し、CS.CX/2を使用
と言うものです。

コードは以下です。

// MainFrm.h : CMainFrame クラスの宣言およびインターフェイスの定義をします。
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__15A05C09_541B_11D7_AAAB_00094100E775__INCLUDED_)
#define AFX_MAINFRM_H__15A05C09_541B_11D7_AAAB_00094100E775__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMainFrame : public CMDIFrameWnd
{
//■ここから追加
  int xxx;
public:
  void setXXX(int v) { xxx = v; }
  int getXXX() const { return xxx; }
//■ここまで追加


// ChildFrm.cpp : CChildFrame クラスの動作の定義を行います。
//

#include "stdafx.h"
#include "1234.h"
#include "MainFrm.h"//■これを追加
#include "ChildFrm.h"

/////////////////////////////////////////////////////////////////////////////
// CChildFrame クラスの構築/消滅

CChildFrame::CChildFrame()
{
// TODO: メンバ初期化コードをこの位置に追加してください。

}

CChildFrame::~CChildFrame()
{
}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: この位置で CREATESTRUCT cs の設定を行って、Window クラスまたは
// スタイルを変更してください。
//■ここから追加
  CMainFrame* m = static_cast<CMainFrame*>(GetMDIFrame());
  m->setXXX(123); // write
  int xxx = m->getXXX(); // read
//■ここまで追加
if( !CMDIChildWnd::PreCreateWindow(cs) )
return FALSE;

return TRUE;
}

お礼日時:2003/03/12 07:29

前述の方達の意見を見て書いています。


まだ、VC++というかC++の勉強の最中なので間違った使用法かもしれないのでご自分で一応調べてみてください。
「グローバル変数は危険なのでやめましょう」とよく聞く、もしくは、書いてありましたが、同様の状況におちいった時、グローバル変数を使ってしまいます。但し、ネームスペース定義を行います。

namespace ネームスペース名 {
ネームスペースに所属する宣言と定義・・・(1)
}

(1)の部分で定義した識別子にはネームスペースの外側からは認識できなくなります(こうやってスコープを限定してやる)。
で、実際に使用する時は "ネームスペース名::(1)の識別子"でスコープを解決してやる。

※本来のネームスペースの使い方でないのかもしれませんので、くどいようですが、ご自分で調べてみてください。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
参考にさせて頂きます。

お礼日時:2003/03/12 00:25

> でも残念ながらグローバル変数を使わないときは、どうすれば良いかが分かりません。


> と言うか、分からないからグローバル変数を使おうとしたのですが・・・

たとえば:

- MainForm内 に private メンバ int xxx; を置く
void setXXX(int) および
int getXXX() const を定義する

- ChildFromでは
MainForm* mf = static_cast<MainForm*>(GetParentFrame());
mf->setXXX(123); // write
int xxx = mf->getXXX(); // read
    • good
    • 0
この回答へのお礼

いつも回答ありがとうございます。

クラスとは元々メンバ変数を保護するためにあると知識では知っております。
従いまして、epistemeさんがどうしてグローバル変数を使うなと言われたかは理解しているつもりです。

しかしながら、プログラマーとしては使う必要性が無くとも知識としては当然のことながら知っておきたいし、目の前のある問題を素早く処理するため知っておきたかったのです。

正攻法として、ぜひepistemeさんの教えていただいた方法をマスターしたいのですが、結局今まで考えて分かりませんでした。

やろうとしていることは、メンバ関数を通じてデータの読み書きをする。と言うことは分かります。

しかし、具体的にどこに書いたら良いか良く分かりません。

申し訳ありませんが、もう少し教えていただきたいです。

<今分かっている疑問点>
>- MainForm内 に private メンバ int xxx; を置く
MainFormはMainFrameの間違いですか?
MainForm内とはMainFrm.cpp内のどこ?or MainFrm.h内のどこ?


>- ChildFromでは
>MainForm* mf = static_cast<MainForm*>(GetParentFrame());
>mf->setXXX(123); // write
>int xxx = mf->getXXX(); // read

MainFrame(MainFrom?)は定義されていないとエラーがでるのですが、どこに書けば良いのでしょうか?


基本的なことが分かってなくてすみません。
本やネットを調べましたが、main関数とクラスが一つの例題ばかりで、クラスから別クラスの変数を読む出す例が見つけられませんでした。

PCの調子が悪いので、今から得意のOSの再インストールをします。PCが復活したときには、返信が来ていることを祈りつつ終わります。

お礼日時:2003/03/11 22:02

どのクラスでも使える変数を作成する場合、


C***App内でメンバー変数を宣言するのが良いと思います。
C***App以外のクラスで使いたい時は、

((C***App *)AfxGetApp())->xxx

でアクセスできます。

mk1234さんのケースの場合、
CMainFrame内でメンバー変数を宣言して、
AfxGetMainWnd()を使うのもいいかもしれません。
(使えるかどうかテストはしていませんが…)

>今回はグローバル変数をどこに書けばよいか教えていただきたいです
グローバル変数を利用するのが危険かどうかは、私は分かりませんが
グローバル変数を作成する場合、関数の外側で宣言します。

例として、
適当なソースファイル(*.CPP)の一番最初に

int xxx;

と書けばグローバル変数が作成されます。

複数のソースファイルで同じように宣言すると、
同じ名前の変数が2つ存在すると判断され、リンク時にエラーになります。
なので、int xxx;と宣言したソースファイル以外では

extern int xxx;

と宣言すると、リンクは正しく行われると思います。
    • good
    • 0
この回答へのお礼

いつも回答有難う御座います。

externを使うと言う巧妙な仕掛けが有ったのですね。

グローバル宣言を使ってうまく行きました。

またお願いいたします。

お礼日時:2003/03/11 21:36

グローバル変数は避けましょう。

危険です。
    • good
    • 0
この回答へのお礼

回答いつもありがとうがとうございます。

分かりました使わないことにします。

でも残念ながらグローバル変数を使わないときは、どうすれば良いかが分かりません。
と言うか、分からないからグローバル変数を使おうとしたのですが・・・

教えていただけたらと思います。

お礼日時:2003/03/11 12:56

あなたの設計次第です。


A のインスタンスが Bによって特定できる
(BはAを参照できる)なら、A側に置くのが
簡単でしょう。

グローバル変数は避けるが無難です。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

今回はグローバル変数をどこに書けばよいか教えていただきたいです。

お礼日時:2003/03/11 11:34

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!