堕天使の煉獄
2018-10
15
03:32:07
c++の闇は深い
今日もがりごりPG。
相変わらず文字コードがらみの自前stringクラスあたりで行ったり来たり。
この辺、はっきりとした正解というのもが無いので、好みの部分だったり、書きやすさだったりといった、つまらない部分でぐだぐだと悩んだりするぽ。
いまちょっと悩んでるのは、
class ustring final : public std::basic_string<uchar> { ... }
class ustring final : protected std::basic_string<uchar> { ... }
どっちにするか。ちなucharは
using uchar = char16_t or char32_tな感じで。
wchar_tと同じものを選択する前提で。wchar_tとノーコストで相互変換出来るほうがいいかなということで。
win環境だとchar16_tですね。
んで、このustringクラスはメンバ変数を持たず、また仮想関数も持ってないんですよね。
あるのは基底クラスの関数のオーバーロードとか追加機能の関数のみ。
そしてstd::basic_stringは仮想デストラクタを持っていないので、基本的にはprotected継承をするべきなんでしょうけど。(そもそも仮想デストラクタもってないクラスは継承するべきでないという考え方もある)
そもそも仮想デストラクタをもってないクラスを継承すると何が不味いかというと、基底クラスに暗黙のアップキャストが行われた場合、派生クラスのデストラクタが呼ばれない=メモリリークが起る。
てのが問題なわけで。
protected継承すると、基底クラスへのアップキャストを禁止出来るわけです。
が、今回のケースの場合、ustringからchar16_t(std::u16string)に暗黙変換出来ないのはちょっとヤなわけですよ。
中身のデータは、wchar_tとchar16_tのように型は違えど中身は全く一緒だし。
ustring str = u8"あいうえお";
std::u16string utf16 = str.data();
protected継承の場合はこのように基底クラスのdata()メソッド呼んでコピーしてやれば、アップキャストではなく単純に中身のデータのコピーになるので問題ないのですがやはり
std::u16string utf16 = str;
と書きたい。
これをするためにはpublic継承にしなくてはならない。
んで、いっぺん上にも書いたけど、このustringクラス。
「ustringクラスはメンバ変数を持たず、また仮想関数も持ってない」
んですよね。
実質サイズ0。仮想関数も持ってないので当然仮想関数テーブルも持っていない。
オブジェクトの実体のバイナリデータは基底クラスのそれと全く同一なわけです。
ググっても、「空の基底クラス」についての記述はあるんですが「空の派生クラス」については該当する記事は見あたらず。
とにかく盲目的に継承するなら仮想デストラクタ! と呪文のように唱えてる所ばかりぽこぽこと。
空の派生クラスの場合は仮想デストラクタ無しの基底クラス継承してアップキャストしても、問題ないように思うのだけど……
ググっても明確にそれを肯定も否定もしてる記事は見つからず。
唯一一件見つかったところは「問題は起らないけどやらない方がよい」と書かれているだけで、なにがどうしてやらないほうが良いのかは語られていない。
その辺、win環境のwchar_t=2byte 中身はutf16で
char16_tとwchat_tをreinterpret_castするのも、「問題は起らないけどやらない方がよい」と言うひともいるわけだし。
まあreinterpret_castはたしかにできれば使いたくないcastではあるけど。
気分の問題のレベル(あとものすごく特殊な状況において問題がでないともかぎらない危険性を孕んでいるのも事実だけど)なんだろうか。
そのへんで、「問題ないならつかっちゃえ」と「やっぱなんだか気持ち悪い」の2派が心の中で闘争中なのですよね。
空の派生クラスの非仮想デストラクタ基底クラスのpublic継承。
それで得られるのが、わざわざ.data()メソッドなしで直で代入とかできるだけという恩恵。
しかしコードがごちゃごちゃするのはいやだ。
んでもほんとに中身は同一だけど何にも問題無いの??
アップキャスト前後でもオブジェクトのサイズは同一だし、メモリのリークも起ってない。
問題ないから使っても良い物なのか。
そんな感じでモヤモヤ~。
そもそもこれって、派生ってより、アダプタってかんじなんですよねぇ。
言語機能としてこういうのあってくれるといいんですけどね。
アップキャストしても派生クラスのサイズが0なら派生クラスのデストラクタ呼ばれなくても問題ないっていう保証がほすぃ。
なんかc#かjavaにはそゆのあるらしい?
継承やめてメンバにstd::basic_string持つコンポジットパターンだと、メンバ全部自前で追加が苦行だしなぁ。
この問題で一番めんどくさいのが、いったん良しこっちにしようと決めたあとで、やっぱ問題あるらしいとわかって修正するとき。
この文字クラスはかなり広範囲にわたって使われる類のものなので、修正となると結構大変なんですよね。
んでも、やっぱ暗黙変換ほしいなーとおもうところに早速ぶちあたったりしてるんですよね。
std::regexとかのcharタイプを設定して使う系のライブラリとか。
まあ今現在std::regexはchar8_t、char16_t、char32_tどれも未対応ですけど。
そしてchar16_tは将来においても対応しないとか言われてたりしますけど。
SRELL (std::regex-like library)
ttp://www.akenotsuki.com/misc/srell/
char8_t、char16_t、char32_t対応版のstd::regex風ライブラリなんか導入していまのところ対応するつもりですけども。
その場合、受け渡しはchar16_tを使う事になるので、regex使う箇所に毎度.data()とか書いてられないなーと。
ていうかstd::basic_regex<wchar_t>でchar16_t←→wchar_tの変換しょっちゅう噛ましてるコード書くの面倒になって、どうせ今後もしばらく対応しないし、いまいち余所で使われてるという話を聞かないのでパフォーマンスとかどうなの? とおもっていたSRELLを本格採用してみるかとおもったところで、結局char16_t使えるようになっても、ustringから変換メソッドいるんじゃめんどくささはいっしょじゃねーか。ってなってたりして。
文字周りめんどくさ……。
んで平行してぼちぼち調べてるのが、多倍長整数ライブラリ。
文字周りとGUIまわりの部分ををいまはガリガリやってるのですが、それらの実地テストとして、簡単な放置ゲーム的なものを一本作ってみるかなと考えてたりして。
で、そこで多倍長整数てのは必要になるよなーと。
プログラムで普通に扱える一番大きな整数といえば、unsigned long long(符合なし8バイト)で1844京6744兆737億955万1615。
放置ゲーとかクリッカー系やったことある人なら判ると思うけど、京の位なんでまだまだようやく序盤抜けたかなぐらいの数字なわけで。
むかしちょっとやってた放置ゲームが最近スチーム版もあると知って懐かしくなって再開してたりするんですが、既に桁の数が80桁ぐらいになってるし。
(それでもまだ序盤ぬけてこれから中盤戦ってところっぽい)
で、そういう大きい数を扱うためには普通の変数一個じゃ収まらないわけですよ。
しかし、とっくにあるモンだと思ってたのですが、c++には標準では多倍長整数ライブラリ無い……_| ̄|○
perlにもrubyにもjavaにもあまつさえC#にもあるというのにっ。
まあc++の場合はパフォーマンス重視なところあるので、そのへんで昔から揉めてて決定的な物が出てきてない……って感じらしいです。boostには一応あるし、GNUとかLGPLライセンス付なのがうっとうしいGMPとかもあったりするのだけども。
いまのところ整数しか使う予定ないので、その手のライブラリは浮動小数とかほかにもいろんな機能いぱーいで、当然ソースもいぱーいで、整数部分だけちょろっと使いたいと思っても結局あれもこれも付いてくるってかんじで気軽に扱いづらかったりする。
そこで、機能をかなり限定すれば、自前でも十分用途には足るんじゃないかなと、車輪の再発明になっちゃう感じだけど考えて見たりしてたりで。
普通に思いつくのは基数1000にする1000進数とかかな。
999*999の結果が収まるサイズあれば十分なのでuint32あたりか。
一桁uint32で各桁もって、下の桁から順番に足してくの。
かけ算になると
「カラツバ法」
https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%A9%E3%83%84%E3%83%90%E6%B3%95
てのがつかえるっぽい。
関連項目にカラツバ法よりも高速とか書かれてる「ショーンハーゲ・ストラッセン法」高速フーリエ変換を使用しているって、なにげにフーリエ変換で音楽の波形編集とかでよくみる語なんだけど、フーリエ変換のウィキみたら、そっとじ……あ…頭がw
てか
うん、あんまりおいらには関係無いかもw
そんな感じでPGがりごり。
相変わらず文字コードがらみの自前stringクラスあたりで行ったり来たり。
この辺、はっきりとした正解というのもが無いので、好みの部分だったり、書きやすさだったりといった、つまらない部分でぐだぐだと悩んだりするぽ。
いまちょっと悩んでるのは、
class ustring final : public std::basic_string<uchar> { ... }
class ustring final : protected std::basic_string<uchar> { ... }
どっちにするか。ちなucharは
using uchar = char16_t or char32_tな感じで。
wchar_tと同じものを選択する前提で。wchar_tとノーコストで相互変換出来るほうがいいかなということで。
win環境だとchar16_tですね。
んで、このustringクラスはメンバ変数を持たず、また仮想関数も持ってないんですよね。
あるのは基底クラスの関数のオーバーロードとか追加機能の関数のみ。
そしてstd::basic_stringは仮想デストラクタを持っていないので、基本的にはprotected継承をするべきなんでしょうけど。(そもそも仮想デストラクタもってないクラスは継承するべきでないという考え方もある)
そもそも仮想デストラクタをもってないクラスを継承すると何が不味いかというと、基底クラスに暗黙のアップキャストが行われた場合、派生クラスのデストラクタが呼ばれない=メモリリークが起る。
てのが問題なわけで。
protected継承すると、基底クラスへのアップキャストを禁止出来るわけです。
が、今回のケースの場合、ustringからchar16_t(std::u16string)に暗黙変換出来ないのはちょっとヤなわけですよ。
中身のデータは、wchar_tとchar16_tのように型は違えど中身は全く一緒だし。
ustring str = u8"あいうえお";
std::u16string utf16 = str.data();
protected継承の場合はこのように基底クラスのdata()メソッド呼んでコピーしてやれば、アップキャストではなく単純に中身のデータのコピーになるので問題ないのですがやはり
std::u16string utf16 = str;
と書きたい。
これをするためにはpublic継承にしなくてはならない。
んで、いっぺん上にも書いたけど、このustringクラス。
「ustringクラスはメンバ変数を持たず、また仮想関数も持ってない」
んですよね。
実質サイズ0。仮想関数も持ってないので当然仮想関数テーブルも持っていない。
オブジェクトの実体のバイナリデータは基底クラスのそれと全く同一なわけです。
ググっても、「空の基底クラス」についての記述はあるんですが「空の派生クラス」については該当する記事は見あたらず。
とにかく盲目的に継承するなら仮想デストラクタ! と呪文のように唱えてる所ばかりぽこぽこと。
空の派生クラスの場合は仮想デストラクタ無しの基底クラス継承してアップキャストしても、問題ないように思うのだけど……
ググっても明確にそれを肯定も否定もしてる記事は見つからず。
唯一一件見つかったところは「問題は起らないけどやらない方がよい」と書かれているだけで、なにがどうしてやらないほうが良いのかは語られていない。
その辺、win環境のwchar_t=2byte 中身はutf16で
char16_tとwchat_tをreinterpret_castするのも、「問題は起らないけどやらない方がよい」と言うひともいるわけだし。
まあreinterpret_castはたしかにできれば使いたくないcastではあるけど。
気分の問題のレベル(あとものすごく特殊な状況において問題がでないともかぎらない危険性を孕んでいるのも事実だけど)なんだろうか。
そのへんで、「問題ないならつかっちゃえ」と「やっぱなんだか気持ち悪い」の2派が心の中で闘争中なのですよね。
空の派生クラスの非仮想デストラクタ基底クラスのpublic継承。
それで得られるのが、わざわざ.data()メソッドなしで直で代入とかできるだけという恩恵。
しかしコードがごちゃごちゃするのはいやだ。
んでもほんとに中身は同一だけど何にも問題無いの??
アップキャスト前後でもオブジェクトのサイズは同一だし、メモリのリークも起ってない。
問題ないから使っても良い物なのか。
そんな感じでモヤモヤ~。
そもそもこれって、派生ってより、アダプタってかんじなんですよねぇ。
言語機能としてこういうのあってくれるといいんですけどね。
アップキャストしても派生クラスのサイズが0なら派生クラスのデストラクタ呼ばれなくても問題ないっていう保証がほすぃ。
なんかc#かjavaにはそゆのあるらしい?
継承やめてメンバにstd::basic_string持つコンポジットパターンだと、メンバ全部自前で追加が苦行だしなぁ。
この問題で一番めんどくさいのが、いったん良しこっちにしようと決めたあとで、やっぱ問題あるらしいとわかって修正するとき。
この文字クラスはかなり広範囲にわたって使われる類のものなので、修正となると結構大変なんですよね。
んでも、やっぱ暗黙変換ほしいなーとおもうところに早速ぶちあたったりしてるんですよね。
std::regexとかのcharタイプを設定して使う系のライブラリとか。
まあ今現在std::regexはchar8_t、char16_t、char32_tどれも未対応ですけど。
そしてchar16_tは将来においても対応しないとか言われてたりしますけど。
SRELL (std::regex-like library)
ttp://www.akenotsuki.com/misc/srell/
char8_t、char16_t、char32_t対応版のstd::regex風ライブラリなんか導入していまのところ対応するつもりですけども。
その場合、受け渡しはchar16_tを使う事になるので、regex使う箇所に毎度.data()とか書いてられないなーと。
ていうかstd::basic_regex<wchar_t>でchar16_t←→wchar_tの変換しょっちゅう噛ましてるコード書くの面倒になって、どうせ今後もしばらく対応しないし、いまいち余所で使われてるという話を聞かないのでパフォーマンスとかどうなの? とおもっていたSRELLを本格採用してみるかとおもったところで、結局char16_t使えるようになっても、ustringから変換メソッドいるんじゃめんどくささはいっしょじゃねーか。ってなってたりして。
文字周りめんどくさ……。
んで平行してぼちぼち調べてるのが、多倍長整数ライブラリ。
文字周りとGUIまわりの部分ををいまはガリガリやってるのですが、それらの実地テストとして、簡単な放置ゲーム的なものを一本作ってみるかなと考えてたりして。
で、そこで多倍長整数てのは必要になるよなーと。
プログラムで普通に扱える一番大きな整数といえば、unsigned long long(符合なし8バイト)で1844京6744兆737億955万1615。
放置ゲーとかクリッカー系やったことある人なら判ると思うけど、京の位なんでまだまだようやく序盤抜けたかなぐらいの数字なわけで。
むかしちょっとやってた放置ゲームが最近スチーム版もあると知って懐かしくなって再開してたりするんですが、既に桁の数が80桁ぐらいになってるし。
(それでもまだ序盤ぬけてこれから中盤戦ってところっぽい)
で、そういう大きい数を扱うためには普通の変数一個じゃ収まらないわけですよ。
しかし、とっくにあるモンだと思ってたのですが、c++には標準では多倍長整数ライブラリ無い……_| ̄|○
perlにもrubyにもjavaにもあまつさえC#にもあるというのにっ。
まあc++の場合はパフォーマンス重視なところあるので、そのへんで昔から揉めてて決定的な物が出てきてない……って感じらしいです。boostには一応あるし、GNUとかLGPLライセンス付なのがうっとうしいGMPとかもあったりするのだけども。
いまのところ整数しか使う予定ないので、その手のライブラリは浮動小数とかほかにもいろんな機能いぱーいで、当然ソースもいぱーいで、整数部分だけちょろっと使いたいと思っても結局あれもこれも付いてくるってかんじで気軽に扱いづらかったりする。
そこで、機能をかなり限定すれば、自前でも十分用途には足るんじゃないかなと、車輪の再発明になっちゃう感じだけど考えて見たりしてたりで。
普通に思いつくのは基数1000にする1000進数とかかな。
999*999の結果が収まるサイズあれば十分なのでuint32あたりか。
一桁uint32で各桁もって、下の桁から順番に足してくの。
かけ算になると
「カラツバ法」
https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%A9%E3%83%84%E3%83%90%E6%B3%95
てのがつかえるっぽい。
関連項目にカラツバ法よりも高速とか書かれてる「ショーンハーゲ・ストラッセン法」高速フーリエ変換を使用しているって、なにげにフーリエ変換で音楽の波形編集とかでよくみる語なんだけど、フーリエ変換のウィキみたら、そっとじ……あ…頭がw
てか
実際には、ショーンハーゲ・ストラッセン法がカラツバ法やToom-3をのような従来の手法より性能が上回り始めるのは、2215 - 2217(10進法で10 000 - 40 000桁)同士の掛け算である
うん、あんまりおいらには関係無いかもw
そんな感じでPGがりごり。
Sun
Mon
Tue
Wed
Thu
Fri
Sat
01
02
03
■
■
台風よくくるな
04
■
■
遅々として
05
06
07
08
[体育の日]
09
10
11
12
13
14
15
■
■
c++の闇は深い
16
17
18
19
20
■
■
数式こわい
21
22
23
■
■
車輪~
24
25
26
27
28
29
30
31
total:2077069 t:77 y:504
■記事タイトル■
■年度別リスト■
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