外部インスタンスへのアクセスについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ても

外部インスタンスへのアクセスについて

#1

投稿記事 by ても » 9年前

質問させて頂きます。

コード:

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()関数に至るまで全ての関数にポインタを渡してやると管理し難くなってしまいます。グローバルのインスタンスや変数はまるで悪者かのように言うサイトもあるのでやや使用に抵抗があります。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 外部インスタンスへのアクセスについて

#2

投稿記事 by みけCAT » 9年前

ても さんが書きました: ①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が関数呼び出しではなくてプロトタイプ宣言なので、ただの擬似コードなのだとは思いますが…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ても

Re: 外部インスタンスへのアクセスについて

#3

投稿記事 by ても » 9年前

みけCAT さんが書きました:
オフトピック
C++ではエントリポイントとしてvoid main()は使えません。
「このようなコード」と書いてありますし、main関数内のfuncが関数呼び出しではなくてプロトタイプ宣言なので、ただの擬似コードなのだとは思いますが…
すみません、仰る通り擬似コードです。main関数内のfuncにvoidが付いていたりvoid main()だったりするのは確認不足によるものです。コンパイルが通ったのでロクに確認せずそのまま載せてしまいました…

そして重ねて申し訳ありません、質問の内容が明確でなかったです。今回尋ねたかったのは『グローバルに定義していないインスタンスを、参照やポインタと言った引数を渡さず外部からアクセスする方法は無いだろうか』と言うものです。
独学でやっていて、ある日突然知らない方法を見つけたりする事もあるので、今回の事も実は自分の知らない機能でどうにかなったりするんじゃないかと思って質問した次第です。

かずま

Re: 外部インスタンスへのアクセスについて

#4

投稿記事 by かずま » 9年前

できないことはないけれど、.....

コード:

#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: 外部インスタンスへのアクセスについて

#5

投稿記事 by かずま » 9年前

ファイル "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: 外部インスタンスへのアクセスについて

#6

投稿記事 by かずま » 9年前

かずま さんが書きました:

コード:

void set(UNIT *p) { char s[32]; sprintf(s, "unigt=%p", p); putenv(s); }
"unigt=%p" を "unit=%p" に訂正します。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 外部インスタンスへのアクセスについて

#7

投稿記事 by みけCAT » 9年前

ても さんが書きました:今回尋ねたかったのは『グローバルに定義していないインスタンスを、参照やポインタと言った引数を渡さず外部からアクセスする方法は無いだろうか』と言うものです。
クラスに入れてメンバ変数を使うことによりグローバルにするのを避ける、とかでしょうか?

コード:

#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;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

djann
記事: 27
登録日時: 12年前

Re: 外部インスタンスへのアクセスについて

#8

投稿記事 by djann » 9年前

遊び心の探求をする質問だと受け取った・・・!

コード:

#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: 外部インスタンスへのアクセスについて

#9

投稿記事 by ても » 9年前

>かずま 様
インスタンスのアドレスを書き出して読み込む方法ですか。ちょっと発想に至りませんでした。目から鱗です
しかし、なんじゃあこりゃあ。こんなコード初めて見ます

>みけCAT 様
別のクラスにインスタンスを持たせる形だとhaveUNITの数だけUNITインスタンスが出来てしまいますね…
作らない場合は引数で渡す必要がありますし…

…これ例用に作ったコードが悪かったな

>djann 様
staticインスタンスのアドレスをリターンとな…って言うか関数ってこんな宣言できたのか…
if ( set ) これでnullか否かわかるのか…
一人でやってると知識が偏って困ります


djann様のstaticインスタンスを返す方法が一番やりやすそうなので、
とりあえずこの形で実装してみようかと思います
皆様ありがとうございました



しかし質問しておいてナンですが、素直に引数渡した方が判りやすそうですね…

閉鎖

“C言語何でも質問掲示板” へ戻る