堕天使の煉獄
2014-09
23
06:44:44
不毛……?
うーんうーん。
そろそろしんどくなってきた。
相も変わらずPGやってるのですが。
GUI機能的な文字列描画まわりテスト。
文字のアライメント付き表示(8方向+中央の9位置)とか
文字数が指定の範囲を超えたらスクロール表示とか。
そんでさらに、その文字列表示オブジェクトを
行の単位で扱えるリストビュー的なのとか。
行間のマージンの指定とかもあったり、背景の指定も出来たりみたいなの。
……。
クラスの実装はさておき、上の例を表示するのには
利用側からは、こんなかんじで記述して使うのですが……
なんかもう、多重継承にテンプレートに、さらにはクラステンプレートの継承とか
c++の用法的にはまともな使い方してるつもりなんですけどね。
ただの文字を表示するだけに、なんだか大げさになりすぎたかなぁ。
とかちょっと我に返り気味……。
んまあ、ここから新しい機能とか追加したりするのは
仕組み的に楽なんでしょうけども、
一年後とかにコレ見て、利用法の方がすぐにぱっと出てくるかと言えば……。
そういうところは、テンプレートとか使うと
かえって訳がわからなくなっちゃうような。
あと、c++の駄目なところを回避するのが
結構な足かせになっちゃってるのを、最近頓に。
まず、上のソース見てもらうとわかるのですが
オブジェクトの生成にはだいたいmakeという生成ヘルパーを使用してます。
コレの中身は単純に自分をnewしてshared_ptrにいれて返してるだけの物です。
そうしている理由というのが、単にstd::make_shared<Hoge>(...)とか
毎回書くのが面倒……というわけではなく、(それも無いわけじゃないけどw)
C#なんかの最近の言語と違って、
c++はインスタンスとポインタの両方の生成方法が任意に使えるのですが、
インスタンスで生成した物はポリモーフィズムが使えなくなっちゃうんですよね。
継承されたオブジェクトを親クラスに入れる事が出来る……というのは
ポインタ限定なんですよね。
(出来ない訳じゃないけど、する意味はない)
class HogeBase{...};
class Moge : public HogeBase{...};
で、
HogeBase* hoge1 = new Moge();
は、いいけど
HogeBase hoge2 = Moge();
だと、hoge2の中身はHogeBaseになってしまう
正確には、HogeBaseのコピーコンストラクタが呼ばれて
(上の例だとムーブコンストラクタかな?)実質
HogeBase hoge2 = HogeBase();
と同じ事になってしまう。
当然Mogeクラス独自のメソッドやメンバ変数は一切使えない。
スライシングと言う奴ですね。
なので、多態性を持たせようとおもうと、ポインタで生成させないといけない。
が、newしたらdeleteしないと、当然メモリリークしてしまう。
そうなると、必然的にshared_ptrに常に包む運用が現実的なわけです。
(スマポはポインタなので、多態性は普通につかえる)
で、そうなると、そもそもコンストラクタをprivateにしちゃって
makeメソッドからしか生成出来ない、つまりshared_ptrの形でしか
生成出来ないようにした方が都合がよいわけです。
が、しかし、ここでふぁっきんなのが、
そういう用途で使おうとおもうと
std::make_sharedが使えなくなっちゃうんですよね。
いや、回避方法はあるっちゃあるのですが。
通常の
std::shared_ptr<Hoge>(new Hoge);
にくらべて
std::make_shared<Hoge>();
で生成する事により、例外安全と、生成コストの軽減という恩恵がある。
が、std::make_sharedはprivateなコンストラクタが呼べないんですよね……。
回避するには、インナークラスを使った生成クラスを内部に持って、
そこで生成するとか、いくつか回避方法はあるものの。
実際のところ、make_sharedと通常の生成と、
そのコスト速度差はだいたい1.5倍~2倍程度らしいです。
毎フレーム大量に生成、消去する様な物の場合は
そもそもshared_ptrは向いてない、もしくはあろけーたを自作するなど
チューンが必要になったりするのだけども
今回のような一度生成したら、しばらく使い続ける様な物に関しては
最初の一回の生成のコストが多少増えたところで問題ない。
しかし、c++なんて言語をやってる輩からすれば
実行速度が速い! というのが矜持じゃないですか。
なので素直にmake_sharedが使えないというのは
「ふんぐぐぐぐぐっっっ……!!!(血涙)」
ってかんじなのですよ(ぉ
そんでさらに、スマポに包んで、もうあとは問題なしかと言えば問題はまだあって。
全部が全部shared_ptrにしてしまうと
浅いコピーと深いコピーを使い分ける必要も出てきたりで。
浅いコピーは、単純にメモリのアドレスのコピーだけ、みたいなの。
auto sp = std::make_shared<Hoge>(0,0);
//class Hoge() : m_pos(0,0){}とかになってるとおもいねぇ
auto sp2 = sp;
なんてやると、spとsp2のポインタが指すHogeクラスの実体は同じ物な訳です。
が、これだと都合が悪い時がある。
sp2->setPos(100,100);
なんてやった後、別の場所で
sp->pos();
とコピー元のほうをみると、
こっちもposの値は(100,100)になってしまうのです。
なぜなら、どちらも同じ実体を指している訳ですから。
解ってやってるときならともかく、
複製して、別の物を指していると思ったら、
同じ物という思い違いで思わぬバグになることもあるわけで。
そこで、深いコピー(ディープコピー)が必要になるわけで。
auto sp = std::make_shared<Hoge>(0,0);
auto sp2 = sp->clone();
とすると、
上のような事は起こらない。
cloneの中では新たにHogeクラスを新たにnewして中身をコピーするということが
行われている。
cloneした直後は、中身の値(オブジェクト自体がもってるメンバの値)は同じだけども
インスタンス(実体)は別物となる。
コピーするオブジェクトが、
値オブジェクトなのか(オブジェクトの中身が重要)
oop的なオブジェクトなのか(中身の違いよりも、どのオブジェクトなのかが重要?)
ディープコピーする意図というか意味を理解するには
対象のオブジェクトがどのような意図のオブジェクトなのかの理解が必要になる。
と、けっこう単純な話でもなかったりする。
そんでもって、clone関数は標準であるわけでなく、
自前で用意しないといけない。
上のソースコードの中でも
ラベルオブジェクトを一個だけ作って
ラベルリストに登録する際には、それぞれcloneしたものを登録してたりします。
この例の場合だと、
フォント、文字色、背景といった設定は複製して、
文字列だけ別のに変えたラベルを複製している感じです。
なんかいろいろとごてごて機能つけすぎると
生成部分が複数行になったりするぐらい糞長くなっちゃいがちなので
最初に一個ひな形的なのを作って
cloneで適時生成するようなほうのが楽ちんというのもあります。
がしかし、毎度コピーするたびに
コレは浅いコピーであるべきなのか、ディープコピーするべきなのか。
そしてディープコピーは普通に一回分の生成コスト+中身のコピーのコスト
が掛かるので必要なとき以外はするべきではない。
単純にみーんなスマポでハッピーというわけにも行かない、というかんじぽ。
んでまあ、何が言いたいのかといえば
単純なnewもつかえず、インスタンスも生成させない。
テンプレートでごてごて<>がついてる。
コピーにはcloneを使う。
なんか奇形なソースコードになってくなぁ……と。
どんどん、標準な機能が表から消えていき
独自の拡張関数ばかりになっていってしまい
ほんとこれ、1年後とか見たときに、すぐに使えるのだろうか?
もしくは、誰か他の人が見たとき
利用法がすぐに解るのだろうか? と。
仕様書が無いと使えない、学習コストがかかるライブラリ。
なんか微妙だなぁ。
一昔前に一部で話題になった
main.cppだけで200kb超えの
うんこスパゲッティーソースコードのアクションゲーム。
変数名も、一文字とかざら。
ヘッダファイル? 何それ?
意味をなさない記号の変数名の嵐。
みんなグローバル。
リソース(マップ)とかもソースコードに直接記入。
とか、おおよそ、
やっちゃいけないと言われることがすべて詰まった
恐ろしいソースコードなのですが。
だが動く。
普通にオープニングから複数面クリア、エンディングまである。
オブジェクト指向だとか設計だとか……
そんなんよりもただ、
「動けばいいんだよ」
という強烈なアンチテーゼな作品ですよね。
どっかの二丁拳銃の女海賊さんも言ってたっけ。
「こんなもんはな、撃てて、当たりゃいいんだよ」
と。
「汎用性を求める決定をした時、そのプロジェクトの失敗も決定する」
と書くと、マーフィーの法則っぽい?w
そんな感じで
ちまちまとオレオレライブラリ作りも不毛感がましてきて
末期的な感じだなーとか。
そろそろ、どんなでもいいからまともなゲームっぽいのつくらないとね。
以前つくったADV用のシステムも
今見れば噴飯もののソースコードだけども
ちゃんと用件みたして動いてるんだものなぁ。
中身がどれほど高度で精練されていても、
未完成ならばそれに価値はないよな。
んでもまあ、その課程でえた経験と知識……その分だけはまあ
無駄ではないのかもだけども。
そこで失った時間的損失に釣り合うのかと言えば。
そんな感じでぐんにょり中な最近。
そろそろしんどくなってきた。
相も変わらずPGやってるのですが。
GUI機能的な文字列描画まわりテスト。
文字のアライメント付き表示(8方向+中央の9位置)とか
文字数が指定の範囲を超えたらスクロール表示とか。
そんでさらに、その文字列表示オブジェクトを
行の単位で扱えるリストビュー的なのとか。
行間のマージンの指定とかもあったり、背景の指定も出来たりみたいなの。
……。
クラスの実装はさておき、上の例を表示するのには
利用側からは、こんなかんじで記述して使うのですが……
なんかもう、多重継承にテンプレートに、さらにはクラステンプレートの継承とか
c++の用法的にはまともな使い方してるつもりなんですけどね。
ただの文字を表示するだけに、なんだか大げさになりすぎたかなぁ。
とかちょっと我に返り気味……。
んまあ、ここから新しい機能とか追加したりするのは
仕組み的に楽なんでしょうけども、
一年後とかにコレ見て、利用法の方がすぐにぱっと出てくるかと言えば……。
そういうところは、テンプレートとか使うと
かえって訳がわからなくなっちゃうような。
あと、c++の駄目なところを回避するのが
結構な足かせになっちゃってるのを、最近頓に。
まず、上のソース見てもらうとわかるのですが
オブジェクトの生成にはだいたいmakeという生成ヘルパーを使用してます。
コレの中身は単純に自分をnewしてshared_ptrにいれて返してるだけの物です。
そうしている理由というのが、単にstd::make_shared<Hoge>(...)とか
毎回書くのが面倒……というわけではなく、(それも無いわけじゃないけどw)
C#なんかの最近の言語と違って、
c++はインスタンスとポインタの両方の生成方法が任意に使えるのですが、
インスタンスで生成した物はポリモーフィズムが使えなくなっちゃうんですよね。
継承されたオブジェクトを親クラスに入れる事が出来る……というのは
ポインタ限定なんですよね。
(出来ない訳じゃないけど、する意味はない)
class HogeBase{...};
class Moge : public HogeBase{...};
で、
HogeBase* hoge1 = new Moge();
は、いいけど
HogeBase hoge2 = Moge();
だと、hoge2の中身はHogeBaseになってしまう
正確には、HogeBaseのコピーコンストラクタが呼ばれて
(上の例だとムーブコンストラクタかな?)実質
HogeBase hoge2 = HogeBase();
と同じ事になってしまう。
当然Mogeクラス独自のメソッドやメンバ変数は一切使えない。
スライシングと言う奴ですね。
なので、多態性を持たせようとおもうと、ポインタで生成させないといけない。
が、newしたらdeleteしないと、当然メモリリークしてしまう。
そうなると、必然的にshared_ptrに常に包む運用が現実的なわけです。
(スマポはポインタなので、多態性は普通につかえる)
で、そうなると、そもそもコンストラクタをprivateにしちゃって
makeメソッドからしか生成出来ない、つまりshared_ptrの形でしか
生成出来ないようにした方が都合がよいわけです。
が、しかし、ここでふぁっきんなのが、
そういう用途で使おうとおもうと
std::make_sharedが使えなくなっちゃうんですよね。
いや、回避方法はあるっちゃあるのですが。
通常の
std::shared_ptr<Hoge>(new Hoge);
にくらべて
std::make_shared<Hoge>();
で生成する事により、例外安全と、生成コストの軽減という恩恵がある。
が、std::make_sharedはprivateなコンストラクタが呼べないんですよね……。
回避するには、インナークラスを使った生成クラスを内部に持って、
そこで生成するとか、いくつか回避方法はあるものの。
実際のところ、make_sharedと通常の生成と、
そのコスト速度差はだいたい1.5倍~2倍程度らしいです。
毎フレーム大量に生成、消去する様な物の場合は
そもそもshared_ptrは向いてない、もしくはあろけーたを自作するなど
チューンが必要になったりするのだけども
今回のような一度生成したら、しばらく使い続ける様な物に関しては
最初の一回の生成のコストが多少増えたところで問題ない。
しかし、c++なんて言語をやってる輩からすれば
実行速度が速い! というのが矜持じゃないですか。
なので素直にmake_sharedが使えないというのは
「ふんぐぐぐぐぐっっっ……!!!(血涙)」
ってかんじなのですよ(ぉ
そんでさらに、スマポに包んで、もうあとは問題なしかと言えば問題はまだあって。
全部が全部shared_ptrにしてしまうと
浅いコピーと深いコピーを使い分ける必要も出てきたりで。
浅いコピーは、単純にメモリのアドレスのコピーだけ、みたいなの。
auto sp = std::make_shared<Hoge>(0,0);
//class Hoge() : m_pos(0,0){}とかになってるとおもいねぇ
auto sp2 = sp;
なんてやると、spとsp2のポインタが指すHogeクラスの実体は同じ物な訳です。
が、これだと都合が悪い時がある。
sp2->setPos(100,100);
なんてやった後、別の場所で
sp->pos();
とコピー元のほうをみると、
こっちもposの値は(100,100)になってしまうのです。
なぜなら、どちらも同じ実体を指している訳ですから。
解ってやってるときならともかく、
複製して、別の物を指していると思ったら、
同じ物という思い違いで思わぬバグになることもあるわけで。
そこで、深いコピー(ディープコピー)が必要になるわけで。
auto sp = std::make_shared<Hoge>(0,0);
auto sp2 = sp->clone();
とすると、
上のような事は起こらない。
cloneの中では新たにHogeクラスを新たにnewして中身をコピーするということが
行われている。
cloneした直後は、中身の値(オブジェクト自体がもってるメンバの値)は同じだけども
インスタンス(実体)は別物となる。
コピーするオブジェクトが、
値オブジェクトなのか(オブジェクトの中身が重要)
oop的なオブジェクトなのか(中身の違いよりも、どのオブジェクトなのかが重要?)
ディープコピーする意図というか意味を理解するには
対象のオブジェクトがどのような意図のオブジェクトなのかの理解が必要になる。
と、けっこう単純な話でもなかったりする。
そんでもって、clone関数は標準であるわけでなく、
自前で用意しないといけない。
上のソースコードの中でも
ラベルオブジェクトを一個だけ作って
ラベルリストに登録する際には、それぞれcloneしたものを登録してたりします。
この例の場合だと、
フォント、文字色、背景といった設定は複製して、
文字列だけ別のに変えたラベルを複製している感じです。
なんかいろいろとごてごて機能つけすぎると
生成部分が複数行になったりするぐらい糞長くなっちゃいがちなので
最初に一個ひな形的なのを作って
cloneで適時生成するようなほうのが楽ちんというのもあります。
がしかし、毎度コピーするたびに
コレは浅いコピーであるべきなのか、ディープコピーするべきなのか。
そしてディープコピーは普通に一回分の生成コスト+中身のコピーのコスト
が掛かるので必要なとき以外はするべきではない。
単純にみーんなスマポでハッピーというわけにも行かない、というかんじぽ。
んでまあ、何が言いたいのかといえば
単純なnewもつかえず、インスタンスも生成させない。
テンプレートでごてごて<>がついてる。
コピーにはcloneを使う。
なんか奇形なソースコードになってくなぁ……と。
どんどん、標準な機能が表から消えていき
独自の拡張関数ばかりになっていってしまい
ほんとこれ、1年後とか見たときに、すぐに使えるのだろうか?
もしくは、誰か他の人が見たとき
利用法がすぐに解るのだろうか? と。
仕様書が無いと使えない、学習コストがかかるライブラリ。
なんか微妙だなぁ。
一昔前に一部で話題になった
main.cppだけで200kb超えの
うんこスパゲッティーソースコードのアクションゲーム。
変数名も、一文字とかざら。
ヘッダファイル? 何それ?
意味をなさない記号の変数名の嵐。
みんなグローバル。
リソース(マップ)とかもソースコードに直接記入。
とか、おおよそ、
やっちゃいけないと言われることがすべて詰まった
恐ろしいソースコードなのですが。
だが動く。
普通にオープニングから複数面クリア、エンディングまである。
オブジェクト指向だとか設計だとか……
そんなんよりもただ、
「動けばいいんだよ」
という強烈なアンチテーゼな作品ですよね。
どっかの二丁拳銃の女海賊さんも言ってたっけ。
「こんなもんはな、撃てて、当たりゃいいんだよ」
と。
「汎用性を求める決定をした時、そのプロジェクトの失敗も決定する」
と書くと、マーフィーの法則っぽい?w
そんな感じで
ちまちまとオレオレライブラリ作りも不毛感がましてきて
末期的な感じだなーとか。
そろそろ、どんなでもいいからまともなゲームっぽいのつくらないとね。
以前つくったADV用のシステムも
今見れば噴飯もののソースコードだけども
ちゃんと用件みたして動いてるんだものなぁ。
中身がどれほど高度で精練されていても、
未完成ならばそれに価値はないよな。
んでもまあ、その課程でえた経験と知識……その分だけはまあ
無駄ではないのかもだけども。
そこで失った時間的損失に釣り合うのかと言えば。
そんな感じでぐんにょり中な最近。
Sun
Mon
Tue
Wed
Thu
Fri
Sat
01
02
03
04
05
■
■
雨~
06
07
08
■
■
うぉいっ、君ぃ!?
09
10
11
12
13
14
15
■
■
やっぱりか……
[敬老の日]
[敬老の日]
16
17
18
■
■
糖分
19
20
21
22
23
■
■
不毛……?
[秋分の日]
[秋分の日]
24
■
■
スクラップアンドビルド
25
26
27
28
29
30
total:2076282 t:190 y:119
■記事タイトル■
■年度別リスト■
2024年
2024年12月(0)2024年11月(0)
2024年10月(1)
2024年09月(2)
2024年08月(1)
2024年07月(1)
2024年06月(5)
2024年05月(2)
2024年04月(1)
2024年03月(6)
2024年02月(4)
2024年01月(3)
2023年
2023年12月(3)2023年11月(1)
2023年10月(2)
2023年09月(3)
2023年08月(3)
2023年07月(3)
2023年06月(7)
2023年05月(8)
2023年04月(2)
2023年03月(1)
2023年02月(2)
2023年01月(3)
2022年
2022年12月(4)2022年11月(3)
2022年10月(1)
2022年09月(3)
2022年08月(3)
2022年07月(2)
2022年06月(1)
2022年05月(3)
2022年04月(2)
2022年03月(2)
2022年02月(1)
2022年01月(6)
2021年
2021年12月(8)2021年11月(3)
2021年10月(4)
2021年09月(6)
2021年08月(2)
2021年07月(1)
2021年06月(3)
2021年05月(2)
2021年04月(2)
2021年03月(3)
2021年02月(1)
2021年01月(4)
2020年
2020年12月(3)2020年11月(7)
2020年10月(2)
2020年09月(3)
2020年08月(1)
2020年07月(3)
2020年06月(7)
2020年05月(5)
2020年04月(8)
2020年03月(4)
2020年02月(2)
2020年01月(4)
2019年
2019年12月(1)2019年11月(1)
2019年10月(2)
2019年09月(1)
2019年08月(3)
2019年07月(2)
2019年06月(2)
2019年05月(2)
2019年04月(4)
2019年03月(1)
2019年02月(7)
2019年01月(1)
2018年
2018年12月(1)2018年11月(1)
2018年10月(5)
2018年09月(1)
2018年08月(5)
2018年07月(1)
2018年06月(1)
2018年05月(1)
2018年04月(2)
2018年03月(2)
2018年02月(1)
2018年01月(1)
2017年
2017年12月(2)2017年11月(1)
2017年10月(2)
2017年09月(5)
2017年08月(8)
2017年07月(2)
2017年06月(1)
2017年05月(1)
2017年04月(3)
2017年03月(5)
2017年02月(7)
2017年01月(8)
2016年
2016年12月(7)2016年11月(2)
2016年10月(3)
2016年09月(7)
2016年08月(8)
2016年07月(10)
2016年06月(17)
2016年05月(6)
2016年04月(8)
2016年03月(10)
2016年02月(5)
2016年01月(10)
2015年
2015年12月(7)2015年11月(7)
2015年10月(13)
2015年09月(7)
2015年08月(7)
2015年07月(5)
2015年06月(4)
2015年05月(5)
2015年04月(2)
2015年03月(4)
2015年02月(1)
2015年01月(7)
2014年
2014年12月(12)2014年11月(8)
2014年10月(4)
2014年09月(6)
2014年08月(7)
2014年07月(4)
2014年06月(2)
2014年05月(5)
2014年04月(4)
2014年03月(8)
2014年02月(4)
2014年01月(8)
2013年
2013年12月(15)2013年11月(8)
2013年10月(3)
2013年09月(3)
2013年08月(8)
2013年07月(0)
2013年06月(0)
2013年05月(0)
2013年04月(0)
2013年03月(0)
2013年02月(0)
2013年01月(0)
■レス履歴■
■ファイル抽出■
■ワード検索■
堕天使の煉獄
https://rengoku.sakura.ne.jp
管理人
織田霧さくら(oda-x)
E-mail (■を@に)
oda-x■rengoku.sakura.ne.jp