少し進展があったかもしれないけど誤差の範囲・・・ vc2010に移行したりしていろいろつまずいたりしてました。来週の空いた時間にできるだけ進めてしまいたいなぁ。
あるコードでTimes(n){・・・・・・}なんて記述がありました。多分n回{}内の処理を行うということなんでしょうけど、これってどうやっているんでしょうね。自分はfor(int i=0;i<n;i++)をdefineで置き換えたと思ってますが、ほかに方法があるんだろうか?「defineは分かりにくいバグを生むので、なるべく使わないほうがいい。C++では使わなくても良いように、色々提供されている」とかそんな話だったから、もしかしたらあるのかな。まぁ今のところはdefineでかくことになりますか。
factoryパターンはやっぱり便利みたいだし使うべきだと思う。じゃあ誰がdeleteするの?ってことに・・・ 消したいときにもdelete出来て、忘れた場合や面倒なときは、スコープから出たときにデストラクタでdelete、というのが一番良いんだろうか。ファイルストリームと似てる。 stateパターンの切り替えも悩む。マネージャーに頼むのが一番なのかな。だとするとマネージャーは今の状態を把握しつつ、すべてのパターンが見えるということか。
まあ何にせよ、ひとつ完成させないと駄目ですね。
#define
RE: #define
そういうのはマクロじゃないと記述できないですね。zxc さんが書きました: あるコードでTimes(n){・・・・・・}なんて記述がありました。多分n回{}内の処理を行うということなんでしょうけど、これってどうやっているんでしょうね。自分はfor(int i=0;i<n;i++)をdefineで置き換えたと思ってますが、ほかに方法があるんだろうか?「defineは分かりにくいバグを生むので、なるべく使わないほうがいい。C++では使わなくても良いように、色々提供されている」とかそんな話だったから、もしかしたらあるのかな。まぁ今のところはdefineでかくことになりますか。
騙されたと思っていちどstd::shared_ptrを使ってみることをお勧めします。zxc さんが書きました: factoryパターンはやっぱり便利みたいだし使うべきだと思う。じゃあ誰がdeleteするの?ってことに・・・ 消したいときにもdelete出来て、忘れた場合や面倒なときは、スコープから出たときにデストラクタでdelete、というのが一番良いんだろうか。ファイルストリームと似てる。
スマートポインタは万能ではないですが、そういった悩みには答えてくれると思います。
VS2010なら何も導入せずに使えますよ。
マネージャーからは基本的に基底クラスのポインタしか見えません。zxc さんが書きました: stateパターンの切り替えも悩む。マネージャーに頼むのが一番なのかな。だとするとマネージャーは今の状態を把握しつつ、すべてのパターンが見えるということか。
Re: #define
やはりマクロでの記述になりますか・・・ 関数を引数にとろうとすると、関数ポインタを介するなどの回り道をしないといけないというのが、個人的に面倒でどうにかならないかと考えている部分の一つです。引数になる関数がさらに引数をとれば、冗長になりそうですし・・・。関数をオブジェクトのように扱うクラスを作るのも一つの手かもしれませんが、迷いますね。
スマートポインタは失念してました。多分実際に使うことになると思います。delete使いたくなったらそのときに考えます。
stateパターンは自分の認識が間違っていました。どんな状態が用意されているかは関係なくて、切り替える条件と、これから切り替える状態がわかっていれば十分ですね。
スマートポインタは失念してました。多分実際に使うことになると思います。delete使いたくなったらそのときに考えます。
stateパターンは自分の認識が間違っていました。どんな状態が用意されているかは関係なくて、切り替える条件と、これから切り替える状態がわかっていれば十分ですね。
Re: #define
『関数オブジェクト』あるいは『ファンクタ』で検索すると幸せになれるかもしれません。zxc さんが書きました:関数をオブジェクトのように扱うクラスを作るのも一つの手かもしれませんが、迷いますね。
Re: #define
関数オブジェクトも一応は選択肢の一つとして考えてはいます。今回の困った部分は大きく分けて二つです。
・関数を引数にとりたい場合には、関数を関数オブジェクトに書き換えるという手順を踏む、もしくは多くの関数を初めから関数オブジェクトで記述することになる。
・処理を行うものを関数オブジェクトにするのは大歓迎だが、処理されるものに関数オブジェクトであることを強要するのは、処理が一般的であればあるほど避けたい。オーバーライドやオーバーロードも少々ややこしくなることが予想される。
クラスの数が増えることとコード量の増加、手間、複雑化などのデメリット以上のメリットは、関数オブジェクトを利用した実装では、ほとんどないと考えています。
今回は基本的にマクロも関数オブジェクトも使わない、Time(n)等の記述も諦める、というのが一番簡単だと思っています。
・関数を引数にとりたい場合には、関数を関数オブジェクトに書き換えるという手順を踏む、もしくは多くの関数を初めから関数オブジェクトで記述することになる。
・処理を行うものを関数オブジェクトにするのは大歓迎だが、処理されるものに関数オブジェクトであることを強要するのは、処理が一般的であればあるほど避けたい。オーバーライドやオーバーロードも少々ややこしくなることが予想される。
クラスの数が増えることとコード量の増加、手間、複雑化などのデメリット以上のメリットは、関数オブジェクトを利用した実装では、ほとんどないと考えています。
今回は基本的にマクロも関数オブジェクトも使わない、Time(n)等の記述も諦める、というのが一番簡単だと思っています。
Re: #define
関数を呼び出すこともできます。zxc さんが書きました:・関数を引数にとりたい場合には、関数を関数オブジェクトに書き換えるという手順を踏む、もしくは多くの関数を初めから関数オブジェクトで記述することになる。
・処理を行うものを関数オブジェクトにするのは大歓迎だが、処理されるものに関数オブジェクトであることを強要するのは、処理が一般的であればあるほど避けたい。オーバーライドやオーバーロードも少々ややこしくなることが予想される。
関数だと引数リストによって型が異なるので、呼び出す側と呼び出される側の両方の手間が必要です。zxc さんが書きました: クラスの数が増えることとコード量の増加、手間、複雑化などのデメリット以上のメリットは、関数オブジェクトを利用した実装では、ほとんどないと考えています。
関数オブジェクトだとメンバが使えるので呼び出し側だけの手間で済みます。
#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;
}
Re: #define
思っていたよりも利用できる範囲が広く、複雑にならずにすみそうですね。defineで実装したものとは仕様が異なるので、使いどころも変わりそうです。defineとは選択、もしくはキーワードを異なるものにする必要がありますかね・・・ どちらも他にもなにやら考えなきゃいけないみたいです。