変数宣言の仕方 クラス内.cppか Headerか

解決


hannya  URL  2011-11-10 17:13:05  No: 73002  IP: [192.*.*.*]

これまで  皆様のお陰で紋様描画のソフトを進化させることができました。
今回  そうしている内に  これまで問題なく働いた機能がおかしくなり  助言を頂きたく質問します。
環境VS6.0 MFC WindowsXP です
課題  進化させるために  
ChildView.cpp内に
short int dgFMax;// number of Diagonal lines in ChainMode
short int dglChn_Fude[50]; 
short int dglChn_knmd[50];  //knmd = knxd +knyd*m_komaNoX;   
short int dglChn_edgd[50]; 
short int dglChn_arcln[50]; 
short arcln; 
static short diagarclnbk = -9;// backup diagonal arcline data in KoMaMode
static short diagarcln = -1;// for diagonal arcline data in ChainMode 
static short fudeNo; // fude order number,which the line following 
を追加しました。進化・追加させた描画の機能は無事に動作しました。
ところが  これまでの各変数を入力するParameterDialogからの入力を入れても  配列に不自然な(期待しない)数値が入るというか、あるいは入らないで勝手な数値になる。また  
変数宣言をChildView.hに入れたり、
それも  // Attributes
public:  にいれるとか
  // Generated message map functions
          protected:
  DECLARE_MESSAGE_MAP()
};
の後にStatic  変数宣言するなどいろいろ試みるに  

ver.4.6.1aから  0x73d11a3の命令が0x00000004のめもりを
参照した。Readにならない
とか
其の後  宣言を  Headerに  あるいは  そのStaticに  
ChildView.cppクラス本体 に移すも  即座に落ちるか  
データがおかしいKoMa描画不良
などのの不都合が生じています。
以前Stack Overとの指摘で  Static変数にして解決したのですが
今回はどうもますます混乱してきました
変数宣言の仕方が十分に理解していないとは認識しているのですが
いまいま  分からないままです  ぜひ  助言をおねがいします

編集 削除
仲澤@失業者  2011-11-10 18:19:47  No: 73003  IP: [192.*.*.*]

むやみにコードをいじっても事態を悪化させるだけです。
こういった場合は「動く状態まで元に戻す」しかありません。
せっかく書いたコードなので、バックアップしてから
作業を始めましょう。
動くようになったら、新機能部分を慎重に段階的に実装していきます。
あるところで、今回の問題が発生し、原因もつかめるでしょう。

本来は、こういう場合に備えて、正常動作している段階での
バックアップをとるのが普通です。

編集 削除
hannya  URL  2011-11-11 07:28:46  No: 73004  IP: [192.*.*.*]

そうですね。  
基本のことをおしえてください。
ChildView.h


// ChildView.h : interface of the CChildView class
//
///////////////////////////////////////////////////////////////

#if !defined(AFX_CHILDVIEW_H__00AB081C_A381_41AA_B5D2_605519F5E69E__INCLUDED_)
#define AFX_CHILDVIEW_H__00AB081C_A381_41AA_B5D2_605519F5E69E__INCLUDED_

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

#include "MemDC.h"
#include "ParameterDlg.h"  // 20021017 for ParameterDilog
#include "KolamDesigner.h"  // nagata for KolamDesignerApp
/////////////////////////////////////////////////////
// CChildView window

#define TIMER_INTERVAL 0

class CChildView : public CWnd
{
// Construction
public:
  CChildView();
// Attributes
public:

  CParameterDlg   m_wndParam;// パラメータダイアログ

  CString    m_imageD_F_Name;   // a temporary filename  
        以下多くの(一般)変数宣言

  // Generated message map functions
protected:
  //{{AFX_MSG(CChildView)
  afx_msg void OnPaint( );
  afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
  afx_msg void OnOpenKomaFile();  //for file-menu nagata
  afx_msg void OnSaveKomaFile();  //for file-menu nagata
        以下略
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};
で、この後に
static int knap; //present Koma number with Keyin 
のように多くのstatic変数を宣言しています。

このようなStatic変数の書く位置は適切でしょうか?
上述の(一般)変数宣言の後、即ち
// Generated message map functionsの前に書くべきでしょうか?

編集 削除
ホウジョウウサギ  2011-11-11 10:08:33  No: 73005  IP: [192.*.*.*]

結果としてどうなることが望まれているのか全く不明なので
的外れかもしれませんが,

class CChildView : public CWnd
{
   ...
}
static int knap;

のように書くということですか?
このヘッダを複数のcppがincludeしたら,それぞれのcpp毎に
static int knap;
が存在する形となるのでは…
で,この状況で
ある特定のknapの値を変更しても,別の場所にある別の変数たるknapの値は
変化しないわけなので
>入力されても入らない云々
といったことになっているのではないかと.
でたらめな値になっているように見えるのは単に変数が初期化されてないからかと.

編集 削除
仲澤@失業者  2011-11-11 10:42:46  No: 73006  IP: [192.*.*.*]

class A
{
  static int valA; // 1.class A全体に対して唯一のオブジェクト
  int        valB; // 2.class Aの各インスタンス毎のオブジェクト
};
static int valC;   // 3.翻訳単位内対して
                   //   唯一のオブジェクトと(できる)
となります。
valAはclass Aの全インスタンスで共有するオブジェクトです。
つまり3つのインスタンス
    A   a0;    A   a1;      A   a3;  
があったとき、
valAはa0,a1,a2のどれから参照しても唯一の実体です。
valBはa0,a1,a2毎に違う値を設定できます。
staticは対象メンバの所属がそのクラスであることをしめします。
また、valAはクラス外のコードににその実体を用意しなければなりません。
    int A::valA; // valAの実体

valCですが、これは一般的には、当該変数を、それを内包する翻訳単位内
で共有を目指すものです。アプリケーション全体で共有(グローバル変数)
することを目指しません。従って、一般的な開発者はヘッダー内に
このようには書きません。

編集 削除
hannya  2011-11-18 15:48:25  No: 73007  IP: [192.*.*.*]

みなさん  丁寧な教授をありがとうございます

class A
{
  static int valA; // 1.class A全体に対して唯一のオブジェクト
  int        valB; // 2.class Aの各インスタンス毎のオブジェクト
};
static int valC;   // 3.翻訳単位内対して
                   //   唯一のオブジェクトと(できる)
このような違いが実践で分かった部分と  どう違うのか分からない部分があり、依然として  かって実行できたことがNGになっています。
>このヘッダを複数のcppがincludeしたら,それぞれのcpp毎に
static int knap;
が存在する形となるのでは… NGとの助言と
valCについて  Header内にこのような(Staticの記述?)書き方はしないということをヒントに  それらStatic変数を
CChildView::CChildView(){
の前に置き直しました。
これにより  例えば  Dialogでの変数入力は正常になりましたが、
描画データのあるファイルでの入力で正常な場合とデータがちょっと位置がちがうなど正常でないことがあり、調査中です。

さらに  非常識な  注意事項はないでしょうか?

編集 削除
仲澤@失業者  2011-11-21 11:17:57  No: 73008  IP: [192.*.*.*]

アドバイスをまにうけていただけていようですね。
以前の自分の発言の通り、そのような状態になった場合は、
「正常に動いていた時点の状態に戻してやり直す」しか方法はありません。
現在のコードをいくらいじってもらちがあかない可能性が高いです。
比較的優秀なプログラマでもそうせざるを得ないこともあります。

テクノロジーは何でもそうですが、プログラムにおいても
「部分の妥当性が全体の妥当性を保障しません」
加筆した部分がいじらなかった過去のコードに影響を与える可能性は
大いにあります。

自分の提示したものはごく基本的な知識にすぎないため、当然直接的な
問題の解決には結びつきません。しかし、それが理解できないと、
また、基本を学ぶ姿勢を失うと、解決に至る道は閉ざされたと
言わざるをえません。一見遠回りな地道な努力が、実は最短コースで
あったりするのは良くあることです。

編集 削除
hannya  2011-11-23 16:35:04  No: 73009  IP: [192.*.*.*]

はい、実際問題として  その課題(機能)が機能したあと  次の課題を追加して
その間、ソースコードを追加変えて  その前のコードはそのままでは無くなっており  元に戻すこと自体  記憶(記録ではなく)に頼らないといけなく
同じ実行フィあるが出来ないでいます。前の実行ファイルは残っていたのですが。
どうかご理解ください
今後はきちんと変える以前のコードを保存するようにします

編集 削除
ryo  2011-11-23 18:25:30  No: 73010  IP: [192.*.*.*]

元のソースの途中が残されてないのなら
新たに、プロジェクトを作り直し、
必要箇所を、現在のソースからコピペし、順に構築しなおす
(この際、正常に動くものを残す、デバッグ・リリースでも試す)
という手があります

ソースに触れられない回答者たちは
hannyaさんのぶつかっている問題に対して、
ほぼ想像と妄想のみで、答えとなる可能性のものを
延々と言い続けるしかないわけで・・・
それを、まだありますか?まだありますか?と
要求し続けるのはどうかと思います

編集 削除
hannya  2011-11-27 08:04:53  No: 73011  IP: [192.*.*.*]

おせわになり ありがとうございました
ご迷惑な助言の請い方でした。
解決ではないですが  ひとまずこれを閉じます
具体的な項で助言を得たいときは  よろしくおねがいします

編集 削除