#define

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

#define

投稿記事 by zxc » 12年前

  少し進展があったかもしれないけど誤差の範囲・・・  vc2010に移行したりしていろいろつまずいたりしてました。来週の空いた時間にできるだけ進めてしまいたいなぁ。

  あるコードでTimes(n){・・・・・・}なんて記述がありました。多分n回{}内の処理を行うということなんでしょうけど、これってどうやっているんでしょうね。自分はfor(int i=0;i<n;i++)をdefineで置き換えたと思ってますが、ほかに方法があるんだろうか?「defineは分かりにくいバグを生むので、なるべく使わないほうがいい。C++では使わなくても良いように、色々提供されている」とかそんな話だったから、もしかしたらあるのかな。まぁ今のところはdefineでかくことになりますか。

  factoryパターンはやっぱり便利みたいだし使うべきだと思う。じゃあ誰がdeleteするの?ってことに・・・  消したいときにもdelete出来て、忘れた場合や面倒なときは、スコープから出たときにデストラクタでdelete、というのが一番良いんだろうか。ファイルストリームと似てる。 stateパターンの切り替えも悩む。マネージャーに頼むのが一番なのかな。だとするとマネージャーは今の状態を把握しつつ、すべてのパターンが見えるということか。

  まあ何にせよ、ひとつ完成させないと駄目ですね。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前

RE: #define

投稿記事 by h2so5 » 12年前

zxc さんが書きました:   あるコードでTimes(n){・・・・・・}なんて記述がありました。多分n回{}内の処理を行うということなんでしょうけど、これってどうやっているんでしょうね。自分はfor(int i=0;i<n;i++)をdefineで置き換えたと思ってますが、ほかに方法があるんだろうか?「defineは分かりにくいバグを生むので、なるべく使わないほうがいい。C++では使わなくても良いように、色々提供されている」とかそんな話だったから、もしかしたらあるのかな。まぁ今のところはdefineでかくことになりますか。
そういうのはマクロじゃないと記述できないですね。
zxc さんが書きました:   factoryパターンはやっぱり便利みたいだし使うべきだと思う。じゃあ誰がdeleteするの?ってことに・・・  消したいときにもdelete出来て、忘れた場合や面倒なときは、スコープから出たときにデストラクタでdelete、というのが一番良いんだろうか。ファイルストリームと似てる。
騙されたと思っていちどstd::shared_ptrを使ってみることをお勧めします。
スマートポインタは万能ではないですが、そういった悩みには答えてくれると思います。
VS2010なら何も導入せずに使えますよ。
zxc さんが書きました: stateパターンの切り替えも悩む。マネージャーに頼むのが一番なのかな。だとするとマネージャーは今の状態を把握しつつ、すべてのパターンが見えるということか。
マネージャーからは基本的に基底クラスのポインタしか見えません。

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: #define

投稿記事 by zxc » 12年前

  やはりマクロでの記述になりますか・・・  関数を引数にとろうとすると、関数ポインタを介するなどの回り道をしないといけないというのが、個人的に面倒でどうにかならないかと考えている部分の一つです。引数になる関数がさらに引数をとれば、冗長になりそうですし・・・。関数をオブジェクトのように扱うクラスを作るのも一つの手かもしれませんが、迷いますね。
  スマートポインタは失念してました。多分実際に使うことになると思います。delete使いたくなったらそのときに考えます。
  stateパターンは自分の認識が間違っていました。どんな状態が用意されているかは関係なくて、切り替える条件と、これから切り替える状態がわかっていれば十分ですね。

ISLe
記事: 2650
登録日時: 14年前

Re: #define

投稿記事 by ISLe » 12年前

zxc さんが書きました:関数をオブジェクトのように扱うクラスを作るのも一つの手かもしれませんが、迷いますね。
『関数オブジェクト』あるいは『ファンクタ』で検索すると幸せになれるかもしれません。

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: #define

投稿記事 by zxc » 12年前

  関数オブジェクトも一応は選択肢の一つとして考えてはいます。今回の困った部分は大きく分けて二つです。
・関数を引数にとりたい場合には、関数を関数オブジェクトに書き換えるという手順を踏む、もしくは多くの関数を初めから関数オブジェクトで記述することになる。
・処理を行うものを関数オブジェクトにするのは大歓迎だが、処理されるものに関数オブジェクトであることを強要するのは、処理が一般的であればあるほど避けたい。オーバーライドやオーバーロードも少々ややこしくなることが予想される。
  
  クラスの数が増えることとコード量の増加、手間、複雑化などのデメリット以上のメリットは、関数オブジェクトを利用した実装では、ほとんどないと考えています。
  今回は基本的にマクロも関数オブジェクトも使わない、Time(n)等の記述も諦める、というのが一番簡単だと思っています。

ISLe
記事: 2650
登録日時: 14年前

Re: #define

投稿記事 by ISLe » 12年前

zxc さんが書きました:・関数を引数にとりたい場合には、関数を関数オブジェクトに書き換えるという手順を踏む、もしくは多くの関数を初めから関数オブジェクトで記述することになる。
・処理を行うものを関数オブジェクトにするのは大歓迎だが、処理されるものに関数オブジェクトであることを強要するのは、処理が一般的であればあるほど避けたい。オーバーライドやオーバーロードも少々ややこしくなることが予想される。
関数を呼び出すこともできます。
zxc さんが書きました:  クラスの数が増えることとコード量の増加、手間、複雑化などのデメリット以上のメリットは、関数オブジェクトを利用した実装では、ほとんどないと考えています。
関数だと引数リストによって型が異なるので、呼び出す側と呼び出される側の両方の手間が必要です。
関数オブジェクトだとメンバが使えるので呼び出し側だけの手間で済みます。

CODE:

#include 
template 
void Times(int n, Function f) {
	while (n-- > 0) {
		f();
	}
}
void hoge(int i) {
	std::cout << i << std::endl;
}
void foo() {
	static int i = 1000;
	std::cout << i++ << std::endl;
}
int main(int argc, char *argv[])
{
	int i = 10;
	// ラムダ式
	Times(10, [&](){
		std::cout << i++ << std::endl;
	});
	// ローカルにクラス定義
	struct Hoge {
		int i;
		Hoge(int n) : i(n) {}
		void operator()() {
			// 既存の関数を呼び出す
			hoge(i++);
		}
	};
	Times(10, Hoge(100));
	// 既存の関数を直接呼び出す
	Times(10, foo);
	return 0;
}

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: #define

投稿記事 by zxc » 12年前

  思っていたよりも利用できる範囲が広く、複雑にならずにすみそうですね。defineで実装したものとは仕様が異なるので、使いどころも変わりそうです。defineとは選択、もしくはキーワードを異なるものにする必要がありますかね・・・  どちらも他にもなにやら考えなきゃいけないみたいです。