いつもお世話になっておりますKonです。よろしくお願いします。
PCはWinXP、Visual C++ 2005 Express Edition を使用しています。
Windowsフォームアプリケーション でプロジェクトを作成しています。
やりたいことは、Value_container の値に、
UIとProcessesの両方からのアクセスです。
下記の記述ですと、実体が2つできてしまい、
共通の変数として扱えません。
何が間違っているのか、ご指摘頂きたく、よろしくお願いします。
以前、”クラスの値の取得”という質問をさせて頂き、
関数の引数に、ポインタで渡せばOKという結論になったのですが、
諸般の事情で、その手は使えなくなりました。
Value_container,h----------------------
lass Value_container {
public:
int Apple;
int Grape;
};
class Hoge{
public:
Hoge() {
ValCon = new Value_container;
};
public:
Value_container *ValCon;
};
Processes.h------------------------
#include Value_container.h
public ref class Processes{
Hoge *hoge_pro;
Value_container *Val_pro;
public: System::Void MainProcesses(){
hoge_pro = new Hoge;
Val_pro = hoge_pro -> ValCon;
int Test1 = Val_pro->Apple;
int Test2 = Val_pro->Apple;
}};
UI.h-----------------------------------------
#include Value_container.h
public ref class UI{
public:
Hoge *hoge_ui;
Value_container *Val_ui;
public: System::Void GetVal(){
hoge_ui = new Hoge;
Val_ui = hoge_ui -> ValCon;
Val_ui -> Apple = 100;
Val_ui -> Grape = 200;
}};
...ぐちゃぐちゃです。なにをしたいんだかわかりません。
シングルトン・パターンを使えばこんな感じ。
ref class Value_container {
public:
int Apple;
int Grape;
private:
Value_container() {}
public:
static Value_container^ instance() {
if ( instance_ == nullptr ) {
instance_ = gcnew Value_container();
}
return instance_;
}
static Value_container^ instance_ = nullptr;
};
ref class Processes{
public:
void MainProcesses(){
int Test1 = Value_container::instance()->Apple;
int Test2 = Value_container::instance()->Grape;
System::Console::WriteLine(LApple:{0} Grape:{1}, Test1, Test2);
}
};
ref class UI {
public:
void Init(){
Value_container::instance()->Apple = 100;
Value_container::instance()->Grape = 200;
}
};
int main() {
UI^ ui = gcnew UI();
ui->Init();
Processes^ proc = gcnew Processes();
proc->MainProcesses();
}
>...ぐちゃぐちゃです。なにをしたいんだかわかりません。
いつも、ぐちゃぐちゃにお付き合い頂き、ありがとうございます。
教えて頂いたコードですと、
static Value_container^ instance_ = nullptr;
の部分で、
スタティック const 整数データ メンバ以外をクラス内で初期化することはできません
というエラーが出てしまいました。そこで、
--------------------------------------------------------
class Value_container {
public:
int Apple;
int Grape;
private:
static Value_container *instance_;
Value_container(){}
public:
static Value_container *Getinstance(){
if(instance_ == nullptr ){
instance_ = new Value_container();
}
return instance_;
}
};
Value_container *Value_container::instance_ = nullptr;
----------------------------------------------------------
public ref class UI{
public:
void GetVal(){
Value_container* VC = Value_container::Getinstance();
VC->Apple = 100;
VC->Grape = 200;
}
};
-----------------------------------------------------------
public ref class Processes{
public:
void MainProcesses(){
Value_container* VC = Value_container::Getinstance();
int Test1 = VC->Apple;
int Test2 = VC->Grape;
}
};
----------------------------------------------------
こんな感じにしてみました。一応、希望通りに動いているようです。
さて、gcnew でインスタンスを作成する場合は、delete は必要ないんですよね?
new を使っているため、delete の必要が有ると思いますが、
どこで、delete してやるのが正解ですか?
余談ですが、シングルトンパターンを教えて頂いたおかげで、
先任者が書いたコードが、やっと理解できました。
ほんとうに、ありがとうございました。感謝感謝です。m(_ _)m
> どこで、delete してやるのが正解ですか?
誰も必要としなくなった時点。
>誰も必要としなくなった時点。
確かにそうですね・・・;;;
すみません。質問をさぼりました。
デストラクタで delete することを考えたのですが、
Webを色々渡り歩いてみたところ、コンストラクタの下に、
public:
~Value_container(){
delete instance_;
}
と書いただけでは、デストラクタは呼ばれないとの情報でした。
確かに、呼ばれません。
”誰も必要としなくなった時”を知る方法が分からないので、困っています。
プロセス終了時にプロセスが確保したリソースは解放されるので
大した問題ではない。という情報も有ったりしますが、
それじゃ、なんで delete なんてものが存在するのでしょう?
補足
上記の私の記述で、
スタティック const 整数データ メンバ以外をクラス内で初期化することはできません
というエラーが発生するというモノがありますが、
これは、私の記述が ”class Value_container”
であるためです。 ”ref class Value_container”
の時は、発生しません。
誤解を招く記述で申し訳ありませんでした。
> ”誰も必要としなくなった時”を知る方法が分からないので、困っています。
main() のいっちゃんケツ。
メンドクセーならいっそのこと:
class Value_container {
public:
int Apple;
int Grape;
private:
static Value_container instance_;
Value_container(){}
public:
static Value_container *Getinstance(){
return &instance_;
}
};
Value_container Value_container::instance_;
> それじゃ、なんで delete なんてものが存在するのでしょう?
後始末しなきゃいけないものはメモリだけじゃないから。
> プロセス終了時にプロセスが確保したリソースは解放されるので
> 大した問題ではない。という情報も有ったりしますが、
> それじゃ、なんで delete なんてものが存在するのでしょう?
簡単な話で
newだけしまくってdeleteしないでいるとメモリが足りなくなるから。
ただし、gcnewならGCがめんどう見てくれるので気にしなくてもよろしいかと。
メモリは有限にしか無いので開放しないでメモリの確保をしまくっていれば
メモリは足りなくなります。これは解りますよね。
プログラムの中で一回しかnewを使用せず、それ以降はnewしたものを
ずっと使いまわすと言うなら良いかもしれませんが、
ある程度の規模のプログラムになれば、そうはいきません。
当然のように必要な段階で必要な回数newでメモリの確保を行ないます。
また、使いまわせないよう場合は常に新しくnewしなおす必要が出てきます。
この場合、使わなくなった用済みの領域は開放しなくてはなりません。
そうしないとメモリが足りなくなるからです。
したがってdeleteの存在価値はちゃんとあると言う事になります。
> これは、私の記述が ”class Value_container”
> であるためです。 ”ref class Value_container”
> の時は、発生しません。
refが付く時と付かない時の違いをちゃんと勉強された方が良いと思います。
全く知らないと言うのであればなおさら。
C++/CLIの参考書が本屋に出ていると思うので一度系統立てて勉強された方が
良いと思いますよ。
追記
deleteにはそのクラスのデストラクタを呼ぶと言う大切な使命があります。
それがなければ、C言語のfreeと一緒になってしまいます。
επιστημη さん、PATIO さんありがとうございます。
delete については、よく分かりました。
>refが付く時と付かない時の違いをちゃんと勉強された方が良いと思います。
>全く知らないと言うのであればなおさら。
今回は、Value_container をマネージドクラスにできない事情があったので、
思いこみで書いてしまった次第です。すみません。
なかなか系統立ててとはいきませんが、勉強しながらやってます。
ご不快な点は、許して頂きたく m(_ _)m
επιστημη さんが書いて下さったコードでいけそうです。
ありがとうございました。