ページ 1 / 1
外部インスタンスへのアクセスについて
Posted: 2015年11月04日(水) 20:11
by ても
質問させて頂きます。
コード:
class UNIT{
public:
void CreateUnit(){
//処理
}
};
void func();//プロトタイプ宣言
void main(){
UNIT* unit = new UNIT;
void func();
}
void func(){
};
このようなコードがあるとして、func()からunit->CreateUnit()を呼び出したい場合、
①void func(UNIT* unit)と定義し、引数として&unitアドレスを渡してやる
②unitインスタンスをグローバル宣言する
以外の方法でインスタンスにアクセスする方法は無いでしょうか?
以上のコードは実際のものをかなり簡略化しているもので、実際のコードは大分階層が深くなっているため、ここで言うfunc()関数に至るまで全ての関数にポインタを渡してやると管理し難くなってしまいます。グローバルのインスタンスや変数はまるで悪者かのように言うサイトもあるのでやや使用に抵抗があります。
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月04日(水) 21:15
by みけCAT
ても さんが書きました:
①void func(UNIT* unit)と定義し、引数として&unitアドレスを渡してやる
②unitインスタンスをグローバル宣言する
以外の方法でインスタンスにアクセスする方法は無いでしょうか?
参照を渡すという方法があります。
コード:
#include <cstdio>
#define main mein
class UNIT{
public:
void CreateUnit(){
//処理
puts("CreateUnit");
}
};
void func(UNIT&);//プロトタイプ宣言
void main(){
UNIT* unit = new UNIT;
func(*unit);
delete unit;
}
void func(UNIT& u){
u.CreateUnit();
}
#undef main
int main(void) {
mein();
return 0;
}
オフトピック
C++ではエントリポイントとしてvoid main()は使えません。
「このようなコード」と書いてありますし、main関数内のfuncが関数呼び出しではなくてプロトタイプ宣言なので、ただの擬似コードなのだとは思いますが…
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月04日(水) 22:01
by ても
みけCAT さんが書きました:
オフトピック
C++ではエントリポイントとしてvoid main()は使えません。
「このようなコード」と書いてありますし、main関数内のfuncが関数呼び出しではなくてプロトタイプ宣言なので、ただの擬似コードなのだとは思いますが…
すみません、仰る通り擬似コードです。main関数内のfuncにvoidが付いていたりvoid main()だったりするのは確認不足によるものです。コンパイルが通ったのでロクに確認せずそのまま載せてしまいました…
そして重ねて申し訳ありません、質問の内容が明確でなかったです。今回尋ねたかったのは『グローバルに定義していないインスタンスを、参照やポインタと言った引数を渡さず外部からアクセスする方法は無いだろうか』と言うものです。
独学でやっていて、ある日突然知らない方法を見つけたりする事もあるので、今回の事も実は自分の知らない機能でどうにかなったりするんじゃないかと思って質問した次第です。
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月05日(木) 01:40
by かずま
できないことはないけれど、.....
コード:
#include <iostream> // cout
#include <fstream> // ofstream, ifstream
class UNIT {
public:
void CreateUnit() {
std::cout << "CreateUnit()\n";
}
};
void func();
int main()
{
UNIT *unit = new UNIT;
{ std::ofstream ofs("unit"); ofs << unit; }
func();
}
void func()
{
UNIT *unit;
{ std::ifstream ifs("unit"); void *p; ifs >> p; unit = (UNIT*)p;}
unit->CreateUnit();
}
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月05日(木) 03:54
by かずま
ファイル "unit" が残ってしまいますね。
#include <cstdio> と std::remove("unit");を追加しますか。
こんなのはどうでしょうか?
コード:
#include <iostream> // cout
#include <stdio.h> // sprintf, sscanf
#include <stdlib.h> // putenv, getenv
class UNIT {
public:
void CreateUnit() {
std::cout << "CreateUnit()\n";
}
};
void func();
void set(UNIT *p) { char s[32]; sprintf(s, "unigt=%p", p); putenv(s); }
UNIT *get() { UNIT *p; sscanf(getenv("unit"), "%p", &p); return p; }
int main()
{
UNIT *unit = new UNIT;
set(unit);
func();
}
void func()
{
UNIT *unit = get();
unit->CreateUnit();
}
setenv を使おうとしたけど、VC++ になかったので putenv にしました。
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月05日(木) 03:58
by かずま
かずま さんが書きました:
コード:
void set(UNIT *p) { char s[32]; sprintf(s, "unigt=%p", p); putenv(s); }
"unigt=%p" を "unit=%p" に訂正します。
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月05日(木) 08:51
by みけCAT
ても さんが書きました:今回尋ねたかったのは『グローバルに定義していないインスタンスを、参照やポインタと言った引数を渡さず外部からアクセスする方法は無いだろうか』と言うものです。
クラスに入れてメンバ変数を使うことによりグローバルにするのを避ける、とかでしょうか?
コード:
#include <iostream>
class UNIT{
public:
void CreateUnit(){
//処理
std::cout << "CreateUnit" << std::endl;
}
};
struct haveUNIT {
UNIT *unit;
void func();//プロトタイプ宣言
void main();
};
void haveUNIT::main(){
unit = new UNIT;
func();
delete unit;
}
void haveUNIT::func(){
unit->CreateUnit();
}
int main(void) {
haveUNIT hu;
hu.main();
return 0;
}
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月05日(木) 11:33
by djann
遊び心の探求をする質問だと受け取った・・・!
コード:
#include <iostream>
class Unit {
public:
void emplace(){
std::cout << "made" << std::endl;
}
};
// Unitのオブジェクト(ストレージ上に構築された実体)を持つ.
// みんなこれから取り出して操作しましょうね.
Unit &unit(){
static Unit u;
return u;
}
void func()
{
Unit &u = unit();
u.emplace();
}
int main()
{
func();
}
状態を持つ関数なんてまるでクロージャみたい!
コード:
#include <iostream>
class Unit {
public:
void emplace(){
std::cout << "made" << std::endl;
}
};
// 最後に設定されたUnitを持つ - 無引数ならただ取り出すだけ.
Unit &unit( Unit *set = nullptr ){
static Unit *u = nullptr;
if ( set ){
u = set;
}
return *u;
}
void func()
{
// 操作したらmain()内のUnit uとが変わる!凄い!.
Unit &u = unit();
u.emplace();
}
int main()
{
// 明示的に操作したいオブジェクトを渡せる(未設定の取り出しに注意).
Unit u;
unit( &u );
func();
}
Re: 外部インスタンスへのアクセスについて
Posted: 2015年11月09日(月) 00:53
by ても
>かずま 様
インスタンスのアドレスを書き出して読み込む方法ですか。ちょっと発想に至りませんでした。目から鱗です
しかし、なんじゃあこりゃあ。こんなコード初めて見ます
>みけCAT 様
別のクラスにインスタンスを持たせる形だとhaveUNITの数だけUNITインスタンスが出来てしまいますね…
作らない場合は引数で渡す必要がありますし…
…これ例用に作ったコードが悪かったな
>djann 様
staticインスタンスのアドレスをリターンとな…って言うか関数ってこんな宣言できたのか…
if ( set ) これでnullか否かわかるのか…
一人でやってると知識が偏って困ります
djann様のstaticインスタンスを返す方法が一番やりやすそうなので、
とりあえずこの形で実装してみようかと思います
皆様ありがとうございました
しかし質問しておいてナンですが、素直に引数渡した方が判りやすそうですね…