C++相談室 part43

このエントリーをはてなブックマークに追加
905デフォルトの名無しさん:2005/09/30(金) 17:38:48
宣伝死ねって事でいいんだろうか
906デフォルトの名無しさん:2005/09/30(金) 18:13:12
最初は愚痴の部分まで一気に書きかけたが、
誘導される前に自己誘導&自粛したってことで。
907デフォルトの名無しさん:2005/09/30(金) 20:44:40
愚痴の部分抜いたら初心者でもマトモな脳みそがあれば
自分で分かるような事を偉そうに書いただけになるんだが。
908デフォルトの名無しさん:2005/09/30(金) 23:10:12
長すぎ。3行で飽きて読むのやめた。
909デフォルトの名無しさん:2005/10/01(土) 00:48:25
>>901-908
全部自作自演って落ちなんだろ?
910デフォルトの名無しさん:2005/10/01(土) 05:52:26
>>901
コンストラクタ内で仮想関数を呼び出したときの動作については
規格中に記述があるよ。 12.7.3 がそう。
 D(void) : A() {v();}
ここでは D::v() が呼び出される。
そして D::v() は純粋仮想関数では無いので、
呼び出し自体に問題は無い。

偉そうな長文が間抜けだな。
911デフォルトの名無しさん:2005/10/01(土) 17:16:30
偉そうな奴は大抵間抜けだからな。
912デフォルトの名無しさん:2005/10/02(日) 02:05:03
メンバ関数ポインタのポインタをtypedefを使わずにどのように定義したらいいんでしょうか?

typedef void(*ClassName::Func)();
Func* f;
のFunc*をtypedefを使わずに定義したいんです。

単なるメンバ関数のポインタなら
void(ClassName::*f)();
でいいんですが....
913デフォルトの名無しさん:2005/10/02(日) 02:09:44
>>912
みずらくなるからやめれ
914デフォルトの名無しさん:2005/10/02(日) 05:03:17
std::string型の変数に"2.5"や"4.7"などの小数点を含む数字の文字列が格納されているのですが、
これを数字として扱って加減乗除するにはどうすればいいですか?
915デフォルトの名無しさん:2005/10/02(日) 07:33:08
こんな感じかな
std::string s = "2.5";
double x;
std::sscanf(s.c_str(), "%lf", & x);
916デフォルトの名無しさん:2005/10/02(日) 07:44:26
>>915
いい加減Cの呪縛から逃れろ。
>>914
boost::lexical_cast<double>(str)を使うか、std::stringstream s(str); s >> d;
などどやる。
917デフォルトの名無しさん:2005/10/02(日) 08:42:15
>>915
C流でやるならせめてstd::atof(s.c_str())にしてくれ。
918デフォルトの名無しさん:2005/10/02(日) 09:31:40
>>912
俺もそのままtypedef使えとは思うが、こういう手段を知っていても損はないと思う。
#include <iostream>
#include <typeinfo>

class ClassName {};
typedef void (*ClassName::Func)();

int main()
{
    std::cout << typeid (Func *).name() << std::endl;
}
919デフォルトの名無しさん:2005/10/02(日) 09:54:02
>>916
C++は両方とも糞重いのが難点
まあlexical_castも中でstringstream使ってるから当たり前だけど。
920914:2005/10/02(日) 10:49:27
>>915-916
ありがとうございました。お蔭様でうまくいきました。
921デフォルトの名無しさん:2005/10/02(日) 10:50:13
貧弱シンプルC路線で行くか重厚楽々C++路線で行くか
922デフォルトの名無しさん:2005/10/02(日) 10:51:29
それを好きに選べることがC++のいいところでもある。
923デフォルトの名無しさん:2005/10/02(日) 11:24:32
でも単なる変換ならatofのが早くて楽な罠。
sscanfは使わないけど。。
924デフォルトの名無しさん:2005/10/02(日) 18:06:18
大量にメモリを確保する予定がある場合、
配列で一気に確保するのと、ちまちま一つずつnewしていくのでは、どちらが確実なのでしょうか。
速さは問いません。

配列の方が無駄が無さそうですが、
素人目にはしかし、連続したメモリ空間が無いと失敗しちゃいそうなイメージがあります。
925デフォルトの名無しさん:2005/10/02(日) 18:13:54
>>924
どっちかと言うと、ちまちま一つずつのほうが成功しやすいだろうな。

ページングの効く環境であれば、物理メモリの
フラグメンテーションによる危険性はほとんど無視できるんで、
あんまり差は無いと思うよ。
926デフォルトの名無しさん:2005/10/02(日) 18:29:15
関係ないけどC++にとってatoiは標準ライブラリなの?
単に好みとしてC++の標準ライブラリだけを使いたくなるものジャン。
でもC++でatoiみたいなことするにはstrstreamに対して<<とか使うんでそ?めんどい
927デフォルトの名無しさん:2005/10/02(日) 18:31:22
>>926
じゃあなんでstdネームスペースがあるんだよって言いたくなる
928デフォルトの名無しさん:2005/10/02(日) 18:38:07
atoi
The return value is 0 if the input cannot be converted to a value of that type.
だれじゃこんな糞仕様にしたのは
929デフォルトの名無しさん:2005/10/02(日) 18:41:21
ごめん
930デフォルトの名無しさん:2005/10/02(日) 18:42:06
そんな時はstrtolですよ。
931924:2005/10/02(日) 18:58:41
>>925
用語を調べていたら遅くなってしまいすいません。
おかげでとても勉強になりました。ありがとうございました。
932デフォルトの名無しさん:2005/10/02(日) 19:25:07
Cに由来する標準ライブラリ関数を残らず再設計してリプレースしてほしい
933デフォルトの名無しさん:2005/10/02(日) 19:39:43
>>926
少なくともJIS X3014:2003では<c〜>もその他のヘッダも全く同列に扱われている。
もっとも<c〜>のほとんどはCの<〜.h>と同じと書かれているが。
934デフォルトの名無しさん:2005/10/02(日) 19:43:09
>>926
そんでもってstrstreamはほかとは別扱いで附属書D 互換性に載せられている。
935デフォルトの名無しさん:2005/10/02(日) 20:19:02
そりゃあstrstreamはdeprecatedだからな
936デフォルトの名無しさん:2005/10/02(日) 20:31:15
>>928
文句があるなら>930。
私ゃ妥当な仕様だと思うがね。
937デフォルトの名無しさん:2005/10/02(日) 23:44:16
そういや、strstreamは使った事ないな。俺がC++始めた時には既に
標準規格が決まっていて、strstreamは使わないでください、みたいな
事が書いてあったな。でもこれを使ってるプログラムはたくさんあるわけで、
過去との互換性に残すんでしょ?
938デフォルトの名無しさん:2005/10/02(日) 23:47:09
strstreamは規格化(?)されたときにすごく非難された、とは聞いたことがある。
んだからstrstreamを使ってるプログラムはほとんどないんじゃない?
939デフォルトの名無しさん:2005/10/02(日) 23:52:02
>>926はstringstreamを知った上でわざとstrstreamを出したのかな
940デフォルトの名無しさん:2005/10/03(月) 00:01:27
>>938
ISO/IEC 1482:1998の通り、標準規格が決まったのは1998年の事で、C++自体は
1985年頃からあるわけで、その13年間でdeprecatedなプログラムが書かれた可能性
はどうかな?

あ、そうか、STLそのものは1993年にC++への組み込みが提案され、1994年に正式
に取り入れられる事が決まったので、たった4年ほどしかstd::strstreamを安心して
使える時期はなかったんだね。
941デフォルトの名無しさん:2005/10/03(月) 11:34:47
>>910
その動作は10年前から知ってる。
…だからわざわざ絶対にまずい純粋仮想関数の場合と分けて
「微妙だ」と書いたんだが。

仮想関数がコンストラクタ内でだけは通常のようなオブジェクトの動的な型ではなく、
静的な型に従って呼び出されるというのは決して直感的に分かりやすい動作とは思えない。
(その呼び出しそのものは確かに動作として安全ではあっても、
その仮想関数からさらに仮想関数が呼ばれたりRTTIが利用されたりした場合の
動的な型と静的な型がどうなっているか考えると頭が痛くならないか?
多分このようにコンストラクタ内でだけ仮想関数の動作が「特別扱い」される仕様は
古いC++コードとの互換性のために残ってしまった仕様ではないかと思う。
そしてこの微妙な仕様のせいで純粋仮想関数をコンストラクタ内で呼ぶのは
呼ぶ相手がなくなるために具合が悪いわけだ。
純粋仮想関数のほうが歴史的には後でできた仕様だったからこうなったのだろうが。)

・・・なので絶対に必要なとき以外はやはり書かないに越したことはにと思うのだ。
(もっともその「絶対に必要な例」は中々思いつけないが。)
というわけで例に挙げたコードのように論理的には純粋仮想関数であるべきものを
コンパイルエラー回避目的でエラー例外を投げる仮想関数に書き換えるのは
決して必要に迫られて熟慮した結果というよりはやっぱり性質の悪い小手先の誤魔化しだと思う。
942謹んで訂正:2005/10/03(月) 11:40:10
>>941
・書かないに越したことはにと思うのだ→書かないに越したことはないと思うのだ
・決して必要に迫られて→ 必要に迫られて
943デフォルトの名無しさん:2005/10/03(月) 12:47:27
>>901
>こういうコードはC++では実行結果が不定になる。
>(分かりやすく言うと書いちゃだめ。)
>仮想関数のセットアップはコンストラクタの実行の
>どの段階で行われるか規格は敢えて厳密には決めていないからだ。
>仮想関数をコンストラクタ中で呼び出すことはそもそも微妙だが、
>特に純粋仮想関数の場合は深刻で、結果は不定だと明示されている。
>気の利いたコンパイラなら上掲のコードについてエラーを報告するだろう。

・初心者も読むスレッドでこういう嘘を平気で書き、なおかつ指摘されても訂正もしない
・他人のミスとも言えないようなミスはことさらに(誤りを含んだ)長文で指摘する
・しかも多分スレ違い。
944デフォルトの名無しさん:2005/10/03(月) 12:57:50
>>943
たぶん、得意げになりたかっただけだろ。
スルーで勘弁してやってくれ。
945デフォルトの名無しさん:2005/10/03(月) 13:43:37
>>941
恥をかきたくなかったら、最低でも、規格書のどこを読めば
そんな動作をするか、リファレンス先を書いておけ。

ま、この場合完全な嘘だから、リファレンス先などありはしないがな。
946デフォルトの名無しさん:2005/10/03(月) 14:39:13
>>941
D&E読め。
コンストラクタで仮想関数呼び出しでは派生クラスでオーバーライドしたほうの関数が呼ばれない理由がちゃんと書いてある。

ようするに派生クラスでオーバーライドした仮想関数の実装が
その派生クラスのコンストラクタが行われていることに依存していたら、
派生クラスのコンストラクタが呼ばれる前(== 基底クラスのコンストラクタの中)で、
派生クラスでオーバーライドされた仮想関数が呼ばれたらまずいことになる、
だからはコンストラクタでの仮想関数呼び出しでは派生クラスでオーバーライドした関数は呼ばれない仕様にしたと書いてある。
947デフォルトの名無しさん:2005/10/04(火) 00:53:48
>>941
この動作がいかに(マシンにとって)自然であるか理解していないのなら、
10年もの間、誤解していたことになるな。
948デフォルトの名無しさん:2005/10/04(火) 00:57:10
>>941は自我崩壊寸前です。
949デフォルトの名無しさん:2005/10/04(火) 01:27:04
>>941はJavaから入ったに違い無い
950デフォルトの名無しさん:2005/10/04(火) 01:44:15
>>941 ワロスwwwwnwっうぇwuwwwrwuwっうぇwwpwwwwwow
951デフォルトの名無しさん:2005/10/04(火) 03:12:06
さあ、そろそろ>>941の長文が飛び出すぞw
952デフォルトの名無しさん:2005/10/04(火) 03:31:20
晒し上げしていいの?
953デフォルトの名無しさん:2005/10/04(火) 08:32:32
ドゾー
954デフォルトの名無しさん
ここまで説得力の無い長文の言い逃れは久々に見たw