1 :
v(^・^)v :
2006/04/28(金) 09:52:50
STLつかうと一気に実行ファイルサイズが10倍に?!
>>10 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>11 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
#include <stdafx.h>
後死ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
13 :
デフォルトの名無しさん :2006/04/28(金) 11:29:41
きましたよ
結局 CUJ のリンクはそのままか。
CUJって何?
>>15 Effective with the March 2006 issue, the C/C++ Users Journal has merged with Dr. Dobb's Journal, which will now feature expanded C and C++ coverage.
ってことで、CUJはDr. Dobb's Journalと合併
>>5 のリンクも修正した方がいいんじゃないの、ということ
次スレで修正だな
typedef void (*Function)(void); typedef std::map<std::string, Function> _map; このようにして、std::string型をキーとして引数を取らないvoid型の関数を格納できますが ここで、格納したい関数の戻り値がそれぞれ違うものであったり 引数の個数や型がバラバラの場合でも同じmapに格納する方法がありましたら教えて頂きたいです
なんかboostでそんなんなかったっけ
>>17 関数呼び出し式の形が同じにできるのであればboost::functionが使える。
boost::anyで何とかなる希ガス
>>17 それ、取り出したときにどうやって使うの?
>>17 です。アドバイスありがとうございます。boost::functionとboost::bindでどうにかなりました。
これだけではあれなので、詳細を書かせて頂きたいと思います。
>>22 さんの鋭い質問で深く考えさせられました。取り出すというか、引数がバラバラなのにどうやって使うんだ、と。
結果的に、考え付いたのが
CApp p; std::map< std::string, boost::function0< void > > map;
map["aaa"] = boost::bind(&CApp::FuncA, &p, "aiueo");
このようにすることで、どんな引数の数、内容でもキー毎に固定できれば
map["aaa"](); と同じ呼び出し式を使う事ができ、
>>17 の目的は達成されました。boostすげえ。
では、長文すいませんでした。
rand()%100の場合、同じ数字が出ることはありますか?
あります
26 :
24 :2006/04/29(土) 21:01:44
>>25 ありがとうございます。
スレ違いですよね、失礼しました。
初心者スレで聞いてきます。
>>26 いやまてw 初心者スレで聞いてもまったく同じ答えだぞw
28 :
24 :2006/04/30(日) 01:44:20
>>27 あ、同じ数字を出さない方法が知りたいので初心者スレで聞いてこようかな、と思いましてw
エスパー的には、 srand((unsigned)time(NULL)); のことだと予言。
>>29 俺のエスパー能力だと、
0から99まで、100個の、重複しないランダムな乱数列が欲しいんじゃないかと。
まあ、0から99まで配列に入れてシャッフルしろと言うことだな。
>>30 なるほど。そっちの方があってそうだな。
0〜99までの値をランダムシャッフルでおkだな。
ランダムシャッフルのアルゴリズムは定番のがあるから
ググれば出てくるだろう。
このスレ、エスパー多いな。
シャッフルはstd::random_shuffleで事足りるとみた
35 :
24 :2006/04/30(日) 03:37:29
どうもありがとうございます。 srand((unsigned)time(NULL)); は使っています。 配列ですね。 分かりました。 皆さんスレ違いなのにどうもありがとうございました。
スレ違いってわけでもないが、 本当に質問したいことをはっきりさせるべきだと思われ。
37 :
24 :2006/04/30(日) 03:51:45
>>36 そうですね。
確かに説明不足で何が知りたいか分からない文章でした。
乱数 配列とランダムシャッフルでググったら両方知りたいソースコードが見つかりました。
本当にありがとうございました。
世の中にここまで自分の意志を伝えられない人間がいるってことが ものすごく不思議だ。 教育され損なうって恐ろしいことだな。
エスパーにならないと立派なSEにはなれません
>>39 それはクライアントに恵まれていないのです、オー人事でも無理です。
だけど実際にそういう目に遭うことはたまにあります orz
>>40 それは運がいいだけです。現実は、そんなクライアントばかりです。
もっとも近い整数へ変換する関数ってありますか 例 4.9->5 6.2->6
double value = 4.9; int answer = (int)(value + 0.5);
負の数の場合は気をつけろってことだろ。
素直に知っとけばいいじゃないか
>>45-46
48 :
デフォルトの名無しさん :2006/04/30(日) 23:21:53
#include <iostream> using namespace std; template <typename T> bool less(const T &ref1, const T &ref2) { return ref1<ref2; } int main() { cout << less<char>('A', 'B') <<endl; } これをg++でコンパイルすると、less undeclared (first use this function) とエラーになってしまいます。どこがいけないんでしょうか?
>>48 lessは標準ライブラリに定義されている(std::less)。
多重定義エラー。
>>42 四捨五入って言葉を知らないの?
それとも敢えて使ってないの?
負数の時、「もっとも近い整数」をどっちによせるかによる
そもそも、 0.5 にもっとも近い整数は一意に定まらないよな
>>48 g++は知らないけど'A'とか'B'とかをint型と認識してるのかな?
C++では文字定数はcharのはずなんだけど…。
VC++6ではちゃんとコンパイルできて動くね。
>>49 less undeclared(lessは宣言されていない)って書いてるじゃん。
多重定義エラーってのはなかろ。
>>48 とりあえず
-less<char>('A', 'B')
+less('A', 'B')
でも通らないか?
55 :
48 :2006/05/01(月) 00:37:01
less を aless とか適当に名前を変えてみたら通り、動きました。 また、::less() とスコープ演算子を付けてみたら通り、動きました。 うーん、やはり多重定義エラーなんでしょうか? このスコープ演算子をつけた場合、どちらのlessを見に行ってる のかなと悩んでいたんですが、自作の方のless()を見に行っている ようです。うーん。
56 :
48 :2006/05/01(月) 00:42:19
>>54 そのように書き直してコンパイルしてみたらどちらも
no matching function for call to 'std::less<char>::less(char, char)'
といわれますた。
どちらも?
58 :
48 :2006/05/01(月) 01:06:47
すみません。違うエラーメッセージをコピペしてしまった。 正しくは、 cout << less<char>('A', 'B') <<endl; これを cout << -less<char>('A', 'B') << endl; cout << +less('A','B') << endl; の各々でやった場合、どちらも 'less' undeclared (first use this function) と怒られますた。 おとなしくテンプレート関数名を変えときますです。 ありがとうございました。
-と+の扱いも次からテンプレに追加すべきだな、これは……。
クマー
namespace N { struct f; } using namespace N; int f(); int main() { return f(); } これでも :4: error: `f' undeclared (first use this function) だと。 ちなみに cygwin の gcc 3.4.4 ね。 エラーになるのはいいんだが、このエラーメッセージはひどい。
VC8でコンパイルすると、「あいまいなシンボルです」ってちゃんと言うね。
>>61 G++の3.4.6, 4.0.3は、
foo.c: In function `int main()':
foo.c:4: error: use of `f' is ambiguous
foo.c:3: error: first declared as `int f()' here
foo.c:1: error: also declared as `struct N::f' here
foo.c:4: error: `f' was not declared in this scope
やはりメジャーバージョンより高くないとダメだな>gcc
f()に適切なのが見つからないと、4行目のエラー出力処理に落ちていくんだろう。 no suitable `%s' in this scope にするといい具合いだと思われ。
MinGWバージョンアップマダーチンチン
68 :
デフォルトの名無しさん :2006/05/01(月) 23:26:29
質問です。 一年ちょっと前にC言語の本を読んでプログラムの勉強を初めて、自分でコードを書いて、 その次にアルゴリズム本等を読んで、またコードを書いて、 今はC++の勉強に取り組みつつコードを書いているという段階なんですが 次に買う本について相談があります。 標準ライブラリの使い方や、基礎的なアルゴリズムを解説している本ではなく、 クラスの上手な作り方、C++プログラミングの常識を勉強できるような本を探しています。 そこで C++ FAQ と Effective C++ に目をつけたのですが、まずどちらを買うべきか迷っています。 自分の希望としては、(どちらも難しい本だろうけれども)少しでも読みやすい方を買いたいのですが 何かアドバイスして頂けないでしょうか
70 :
デフォルトの名無しさん :2006/05/01(月) 23:36:33
Effective > C++ FAQ
C++ FAQとMore Effective C++は日本語訳が腐ってる。 Effective C++を買うか、これの3rdの日本語版(もうすぐ出る?) が出るまで待つか。C++ Coding Standardもなかなか良い。
>>68 CエキスパートがC++を業務で使い始めて半年間で蓄積したノウハウが全てEffectiveC++に書かれていた。
つまり、EffectiveC++はその位有用だと言うことだ。
73 :
68 :2006/05/02(火) 00:23:05
レスありがとうございます ぐぐって調べてみました。 Effective C++ 第三版 もう出てるみたいです。amazon に今日付けのレビューが一件だけ入ってました。 他の本にも興味はありますが、悩んでも仕方ないし 何か縁を感じたのでとりあえず Effective C++ にしておきます
Effective C++ 第三版は日本語訳がひどくないよな・・・ 明日でもちょっくら立ち読みして、良さそうだったら買ってくるか。 誰か既に突撃した人いる?
Effective C++第三版の訳者はAccelerated C++の人だから大丈夫だろ まぁ俺は改訂二版が手元にあるから第三版は買ってないので断言はできないが
禿本って何だゴラァ
"禿本 C++" で調べたら判った
禿本は正直薦めにくい 禿本を活用できるレベルの人は既に禿本を読んでいる 禿本を活用できるレベルでない人には、もっと適した本が一杯ある
C++FAQも実は隠れた名著であることはあまり知られていないようだな。 EffectiveC++が有名すぎて。
C++FAQってwebで公開されてなかったっけ?
「C++再考」もいいよ。 最新C++ではないけれど、設計の考え方が参考になる。
>>81 俺はその本で、引数付きマニピュレータの定義の仕方を初めて知った。
それから、テンプレートと関数オブジェクトの組み合わせとか、ぱっと見
は簡単そうだが、じっくり読むと深い内容まで突っ込んだ事が書いて
あるね。
著者がKoenig&Mooだからな… それぞれCFrontのテスタ、マネージャ。 初期のC++設計&処理系開発の中心にいた人たち。 「C++の設計と進化」のKoenigの登場回数と言ったら… 禿の次くらいにC++設計への貢献が大きいんじゃないか?
まずは、C++ Coding Standards を読むのがベストだと思う。 Exceptional C++ の sutter 氏と、Modern C++ Design の Andrei 氏が さまざまな書籍から要点をピックアップしてくれていて、読みやすい。 一通り読んだあとで、Effective や、Exceptional を読むとより分かりやすいし。
逆に最後に手元に置くのを C++ Coding Standards がいいんじゃないかな? あれ説明がないから、最初は辛い。
自分から情報を求める姿勢があるなら大丈夫じゃね
ていうかとっくに届いてる 中が2色刷りなのにびっくり 高いだけある(のか?)
近所の大型書店では 4月29日発売とは言っても、東京の問屋に卸すのが29日の場合は今日書棚にあるとは限らない、 GW明けまでずれこむ恐れもある、と言われたよ 梅田まで出て行ったら見つかったけど
Effective C++3版買った奴に聞きたいんだが、改訂2版持ってても3版買う価値ある内容?
内容変えてしまうならいっそ続編みたいな形で出してほしいな。 同じ書名で版が違うだけなのに内容がかなり違うとかなんか本として微妙。
>>91 俺もそこが知りたい。
改訂前の第一版を持ってる俺としては。
94 :
シャビ :2006/05/02(火) 21:38:22
仮想関数テーブルポインタを含んだクラスをまるごとfwriteやfread等できる方法はありますでしょうか? ファイルからデータ読み込んだ時に、仮想関数テーブルポインタが壊れないようにしたいのですが… 各メンバ別個に読み書きしたり、メンバを構造体にするのはなるべく避けたいので、何か良い方法があれば教えて下さい。
>メンバを構造体にするのはなるべく避けたい 構造体にしたほうがわかりやすいんじゃないかなあ。利用側としては。
>>94 Boost.Serializationはだめか?
char buf[10] = {0}; とかした場合、buf[1]〜buf[9]まで0で初期化される保証はあったっけ? 構造体の場合と同様に、初期値の指定が無い残りの部分は0で埋められると考えていいのかな?
>>97 その保障はある。
足りないところは0初期化される。
99 :
シャビ :2006/05/02(火) 23:23:15
>>95-96 サンクス!
Serializationについて調べてみる事にします。
普通は構造体にするのかな?
ハンドでガリガリ行きたいなら、 fprintfの値渡し書きして、scanfのパラメータ&の参照渡し機能使って読むって手もあるが、 環境が分からないから何出せばいいか分からないけど、シリアライズオブジェクト使うのがいいと思う。
scanf>fscanf
102 :
シャビ :2006/05/03(水) 00:38:23
ありがとうございます! 確かにfread、fwriteよりはずっと楽ですねー
あるstreamの一部分を別のstreamへ切り出したいんだけどいい方法ない? rdbuf()からいろいろいじってみたんだけど、頭は指定できてもケツが決まらくて難航中。 具体的な状況としては、複数のファイルがその行数と共に詰まってるアーカイブもどきから 一つのファイル分だけ取り出して、パーサーに渡そうとしている所。
104 :
デフォルトの名無しさん :2006/05/03(水) 03:01:07
>>103 行数で決まるんだろ。普通に書けるじゃないか。何が不満だ?
fmemopenみたいなのがほしいの?
質問なんですが、関数のリファレンスってどこを見れば良いんでしょうか? 例えば、ですけど、 std::getlineの引数にはどんな型が来て、戻り値の型がこうで・・・ みたいなことが知りたいんです。 Cのときはmanを参考にしたりしていたんですが、 何かリファレンス本を買った方が良いですかね?
>>109 libstdc++のmanをインストールして、
$ man 3 std::iostream
doxygenで生成しているからhtml版もあるよ。
>>112 おなじサーバで運用中(?)の swig.jp とか unittest.org もずっと死んだままス。つд`)
なんか渋チン、社会人になってからサーバのメンテを放棄してる?
>>115 捨てメアドでも晒してくれたメールで送るよ。
VS.NET で以下のソースをコンパイルしたら実行時にエラーが起きました。 #include <iostream> using namespace std; int sub( int* p_num ) { p_num = new int; *p_num = 10; cout << *p_num << endl; return 0; } int main() { int* p_num = 0; sub( p_num ); cout << *p_num << endl; // * を外してアドレスを表示すると 0 となる delete p_num; return 0; } 最初はどこで引っかかっているのか判りませんでしたが、今はとりあえず 呼び出し側の main 関数に p_num = new int; が反映されておらず 存在しないものを delete しようとしているからエラーが起きることが判りました。 しかし sub 関数の側では 10 という値が確かに表示されているし なぜポインタで渡してるのに呼び出し元に 10 が伝わってこないのかが判りません。 new 演算子で用意したメモリは delete で明示的に捨てるまで確保されたままだと思っていたのですが もしかしてこれが勘違いだったのでしょうか
118 :
デフォルトの名無しさん :2006/05/05(金) 00:41:35
上げてしまった。すまん。
確かに不勉強。
>>117 >なぜポインタで渡してるのに呼び出し元に 10 が伝わってこないのかが判りません。
なぜ渡されたポインタを new で潰してるのかが判りません。
>>117 自分が分かった部分だけだけど、欠陥が2箇所見つかった。
>int* p_num = 0;
&p_numに0x00000000が入ってしまっている。
intprep=0;
int* p_num = &prep;
こうダミーを使ってやれば解決する。
>int sub( int* p_num )
>{
>p_num = new int;
これは是非、デバッガを使って、intの前にブレークポイント置いて、ステップオーバでp_numの値に注目してもらいたいのだけど、
この関数は参照で、int*p_numでアドレスを受け取っている。
次にnewして新たにp_numにアドレスを割り当てている。この時点で受け取ったアドレスと内容はゴミとしてメモリ上に浮くことになる。
そして、main側(sub( p_num );を発した側)はアドレスが変わったことを知るすべもなし、ゴミのアドレスと値を参照することになる(元々の値)。
実行時、エラーがでなくとも、たまたま短かっただけで、新たなスタックがそこに侵食してくると、もしp_numアドレス参照すると、
AccessViolationかMemoryAssertionかなんらかのエラーがでると思う。
やっぱ、C関連やるにはデバッガ必須だね。 うまくいかなかったとき、デバッガなしだと、脳内妄想で終わってしまう。 自分もうやむやのまま進んで、何度も初歩に戻ったしなあ。
阿呆な質問かもしれませんが。。。 std::strlen等と、strlen等は同じなんですか? #include <iostream>としておけば、 Cだとそれぞれ別にヘッダファイルをincludeしておかないと使えない関数も含め、 ほとんどのCの標準ライブラリ関数が使えるようですが・・・ std名前空間のメンバである Cの標準ライブラリ関数と同じ名前の関数は、 Cの標準ライブラリ関数とまったく同じものだと考えて良いんですか? std::strlenと書いても、ただstrlenと書いても同じように動作するわけですが、 これはどういうことなんでしょうか? あと、試してみた中では数学関数はstd空間にないみたいで、 これはmath.hをincludeしないと使えないようですが、 なんでこんな風になってるんですかね?
>>125 コンパイラ書けよ。俺のコンパイラの挙動と違うぞ。俺のはVC8ね。
>>116 届きました。
本当にありがとうございました!
129 :
125 :2006/05/05(金) 01:21:13
>>127 すんません、gcc(g++)使ってまして、
gcc_selectの結果は
Current default compiler:
gcc version 4.0.0 20041026 (Apple Computer, Inc. build 4061)
なんですが。
>>125 #include <cmath> だろ。
131 :
125 :2006/05/05(金) 01:28:17
>>130 Cで#include <〜.h>として使っていたものに関しては、
#include <c〜>となるわけですね。わかりました。
132 :
125 :2006/05/05(金) 01:32:03
std名前空間のメンバになってる関数については、 自分の環境では#include <cstring>等々することなく std::strlenとか単にstrlenと言った風に使えてしまうんですが、 これは問題でしょうか?ちゃんと#include <cstring>とすべきですか? また、std::strlenという風に使うのと、単にstrlenという風に使うのとでは、 まったく同じことだと思っていいのかどうなのか分からないんですが、 その点についてはどうなんでしょうか?
>>132 あーそれどっかで問題になってたな。
std付けないと見えないはずなのに、見えてしまうという問題。
どこでだっけ・・・
>>125 >#include <iostream>としておけば、
>Cだとそれぞれ別にヘッダファイルをincludeしておかないと使えない関数も含め、
>ほとんどのCの標準ライブラリ関数が使えるようですが・・・
たまたま<iostream>内で間接的に#includeしてるだけで
使いたい関数があったらちゃんと対応するヘッダを#includeすべき。
>>115 のC++リファレンスが欲しいんですが、どなたかupして頂けませんか
136 :
125 :2006/05/05(金) 01:47:26
>>133 ,
>>134 ありがとうございます。
ということは、
使いたい関数があるときは
#include <cmath>なり、#include <cstring>なり、
きちんとincludeして、std::〜という形で使うのが正解、
ということですね?
ちなみに、includeするときにcmathとかcstringとか
頭にcが付いているってことは、
その動作はCの標準ライブラリ関数とまったく同じと考えても良いんですよね?
規格票も持ってない奴ばっかかよ・・・・
138 :
125 :2006/05/05(金) 01:51:45
持ってないです・・・阿呆な質問の繰り返しでごめんなさいorz
規格読めで済むならこんなスレいらなくね
>>137 おまえ、あれはコンパイラを作るヤツやC++の解説書を書くヤツなんかの為にあるもんだぞw
141 :
126 :2006/05/05(金) 02:00:20
>>140 「規格読め」はそもそも言った本人が読んだことなくて
しかも質問にきちんと答えられないときに使うセリフなんで
真に受けちゃダメよ
>>142 言われて悔しい思いをした経験がおありで?
144 :
140 :2006/05/05(金) 02:54:30
>>142 コンパイラ云々ではなくC++の仕様的にどうなのかって質問なら「規格嫁」が正論だろ。
コンパイラの挙動ではなくC++の厳密な仕様を気にするぐらいなら規格票を購入すべき。
規格票も持たず、基本的な仕様すら規格上でどうなってるかも知らないのに
部分的な仕様だけを知ろうとするのはナンセンス。
要するに、「規格票読め」は避けて、規格票の該当部分をそのまま コピペして、簡単な説明を付けろって事だな。 著作権の問題とかはどうなるのかはよくわからないが、少なくとも、 貼り付けた本人が「実は質問に答えられないのでただ言ってみた」 わけではない事がわかるだろう。
>>113 libstdc++もmanあるのね知らんかった
Thanks!
そもそも規格を読むだけでは分からないような質問が このスレでされたことは一度もないぞ
>>148 ウソつくな。そんな質問いくつもされてきたぞ。
で、そのたびに「スレ違い」というレスが返されてきた。
自他共に認める無知、あるいは、自分では一応知識があるつもりだけど それが本当に試される状況は怖いから避けたい人、 そういう人種が「そのくせ偉そうにしたい」時には便利ですよね<○○読め
152 :
113 :2006/05/05(金) 16:21:19
153 :
デフォルトの名無しさん :2006/05/05(金) 16:33:30
C か C++で正規表現をするにはどうしたらよいでしょうか。 サードパーティのは利用せず(?)に、標準のもので実現したいのですが。
標準だけでやりたいなら、自分で書くしかない。 boost::regexが次の標準に入る奴に近い。
156 :
153 :2006/05/05(金) 16:46:58
見ただけで理解できないのは普通。 とりあえず触って覚えろ。
158 :
153 :2006/05/05(金) 18:37:08
今boostのインストール中ですが、最終的に作るアプリをほかのPCで 動かしたいと課題を出した人が言うと思うので、自分で書こうと思います。 あとインストールに時間がかかるというのと、いくつかインストール方法の載ってる サイトを検索したけども、そこにある用語すら分からず正常にインストールできている か不明のため
boost ってテンプレートライブラリだから、 余計なもの入れなければ ヘッダだけあれば動くんじゃないの?
boost使っていようがいまいが、 他のPCでも動くと思うが。。。
boost::regex の使い方をサンプルで理解できないのに 自分でパーサを書くという意味?それは無茶があると思う。 boost を用いたプログラムを書いても、特別な dll 等は必要ないし そのままやった方が早いかと。
まぁ、boost が準標準ライブラリだとしても、初めて触る者にとっては 得体の知れないモノなわけで、そんなモノに頼りたくないって気持ちは わかるが騙されたと思って boost 使っとけ。
boost使うと実行サイズが大きいし、速度が遅いし、という難点があるけどね。
>>163 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>164 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
STLつかうと一気に実行ファイルサイズが10倍に?!
いいえ、3倍です。
168 :
デフォルトの名無しさん :2006/05/05(金) 20:29:32
棒読みw
169 :
側近中の側近 ◆0351148456 :2006/05/05(金) 20:30:23
>>167 (っ´▽`)っ
ついでに赤くなるんだよな?
Boostつかうとコンパイルが遅すぎ
>>170 君に取って置きの秘策をお教えしよう。
パ ソ コ ン グ レ ー ド ア ッ プ。
VC++6.0stdで最適化コンパイルできますか?
古いコンパイラでコンパイルできるかどうかは保証しない。
VC++ならプリコンパイルドヘッダとか使えば多少速くなるんじゃね?
>>170 まあ、ソースが全部ヘッダに含まれてるわけだからな・・・。
早く export 実装しろよー。
禿がもっと禿れば各ベンダーも実装してくれるだろうよ。
>>158 なんか変な流れでかわいそうなのでwマジレスしておくと
静的リンクしておけばDLLはいらんし、そもそもヘッダインクルードだけで使えるライブラリも多い。
ダイナミックリンクにしてもDLLを一緒に配ればすむ話だ。
filesystem系とかスレッド系とかunittest系以外はヘッダだけで大丈夫じゃなかったっけ
180 :
デフォルトの名無しさん :2006/05/07(日) 02:30:20
ff
質問で〜す 同名でconst、非constなメソッドがあったとして、 そのメソッドを非constなオブジェクトから呼んだ場合、 どちらのメソッドが呼ばれるのでしょうか? 具体的には下記のようなコードで、func2の中のa.hoge()は const、非constどちらのメソッドが呼ばれるのか? とりあえずvc7だと非constメソッドが呼ばれるようですが、 これってどの処理系でも必ず保障されます? class A { public: void hoge() const { cout << "const" << endl; } void hoge() { cout << "not const" << endl; } }; viod func1(const A &a) { a.hoge() // => const } viod func2(A &a) { a.hoge() // => not const ? }
non constに決まってるだろ constの意味を理解してから書けボケ
>>181 Overload Resolutionのルールによって、保障されている。
詳しく説明すると長くなるけど、
staticでないメンバ関数は、thisを隠れた引数として取るが、
このthisも、オーバーロードされている際のbest candidateを決定するにあたって考慮される。
さらに、thisはcv-qualifiersの影響を受けるので、constなメンバ関数では、thisはconst修飾される。
constなオブジェクトから呼び出した場合は、constなメンバ関数、
constでないオブジェクトから呼び出した場合は、constでないメンバ関数のほうが、
よりbest candidateになる。
×保障 ○保証
>>183 const なオブジェクトから呼び出した場合は const でないメンバ関数は
candidate にもならないんじゃないか?
186 :
183 :2006/05/07(日) 10:15:06
187 :
181 :2006/05/07(日) 10:15:46
>>183 ためになる解説どうもありがとうございました。
Overload Resolutionについて勉強してみようと思います。
>>187 あまり深く勉強しても、実際に役に立つことは少ないと思うけど。
こんなに複雑なのも、人間にとってより自然な挙動にしようと議論された結果だし。
//! boostのtype traitsを実装しようというなら、話は別だけど。
>>182 constの意味とか、この質問にはまるで関係ないじゃんw
あとあとまともな回答があっただけに、大恥さらしちゃったねww
>>181 189 名前: デフォルトの名無しさん [sage] 投稿日: 2006/05/07(日) 14:43:24
>>182 constの意味とか、この質問にはまるで関係ないじゃんw
あとあとまともな回答があっただけに、大恥さらしちゃったねww
お前の方が恥じ書いてるっての
constの意味は大いに関係あるだろ 途中でconst外されちゃまいっちんぐ というルールなわけだし
>>192 非 const なオブジェクトなら const メンバ関数も、非 const メンバ関数も安全に呼び出せる。
どっちでもよさそうだが、その場合にどっちになるのか?という質問だ。
const の意味は十分理解しているものと思われる。
詭弁君キター
char *c; *c = '\0'; と、 char *c = NULL; って同じ意味?
俺も違うと言いかけたが 必ずしも違うとは言い切れない気もしてきた
>>195 ,197
どう考えたら同じだと思えるの?
>>198 文字コードにASCIIを使っている場合。
>>197 もしかしてNULLと'\0'の違いがどーとか考えてないか?
char *c;
c = 0;
と、
char *c = NULL;
ならお前の悩みも解らなくもないが・・・
201 :
200 :2006/05/07(日) 22:00:15
あ、キャストせんとコンパイルエラーでっかな? 誤 char *c; c = 0 正 char *c; c = (char *)0;
いや、0はどんなポインタ型へも変換できる。
>>199 その前提で、もうちょっと変形すれば動作が同じになると思えなくも無いが、
やっぱり意味はぜんぜん違う。
ポインタの説明読んでると、ミスするとシステムを壊してしまう可能性があるらしいんですが みなさんミスしないでやれるんですか? ポインタ勉強したいけど怖くて・・・><
>>204 まともなOSが走っているマシンで実行するなら大丈夫。
安心してポインタいじれ。
1.例外拾えればアプリケーションがズッコケ 2.例外逃すとプロセスがぼよよーん 3.最悪はシステム(OS)が凍てつく
まともじゃないOSって具体的になんだ?OS/2とか?
MSX-DOS とか
Windows 1.0 〜 3.x 〜 9x
ぼよよーんにふいた
自分で throw した例外以外( 一般保護例外,ゼロ除算,等々 )は catch(...) でも拾えずに コアを吐く Unix/Linux のヘタレっぷりを初めて知った時にはワロタ。
>>213 catch(...) で一般保護例外を拾ってしまうのは、それはそれで問題なわけだが。
>>213 個人的に、そういう種類の例外は、環境依存の方法でキャッチすべきだと思っているんだけど。
まあ、VC++ならどういう例外が投げられてきたかを知る方法だけはあるから、まだましか。
>>216 できるできないの問題ならいいんだが、強制されてしまうぶんには
どっちが有利ともならないなぁ。
>>217 例外処理の使い方を考えれば強制されるという概念を持つ事は変だと思う。
が、その「強制された」としてなんか困ることや嫌なことが具体的にあるの?
俺はこの件に関しては Unix/Linux はダメダメと結論している( もちろん
そんな一点の問題で Unix/Linux 自身がダメダメと結論づけるようなつもりは
毛頭無い。 )が、そうでない意見があるなら聞いておきたい。
>>218 「C++の例外処理」「unixのsignal」「WindowsのSEH」を混同してませんか?
C++の例外風に処理を記述できるWindowsのSEHは便利だよね、というだけの話。
まぁSEHには「知識や権限に関わらず、早く例外を捕まえた人が処理できてしまう」
という問題があるため結局VEHが導入されたわけだが。
>>218 よく知らないんだが throw() と考えられる関数からも一般保護例外は飛んでくるよね?
ちゃんとそれ考慮して、スタックの巻き戻しができるようにコード生成してくれるの?
try{
std::auto_ptr<T> p(new T);
strcpy(0,0);
}catch(...){
// ここにくるまでに p の delete は行われるの?
}
行われるとしたら、とても非効率なコードが生成されてしまいそうなんだけど。
>>219 一応知ってはいるが、混同はあるかも知れん。が、結局どこがどう問題なの?
自分が知っている例外についてはそれぞれ型を明記してそれぞれに合わせた処理をして、
その他の例外がきたらまとめて処理する。この「その他の例外」に「unixのsignal」 or
「WindowsのSEH」が含まれることは全然welcomeだと思うんだが。
>>220 それはダブルフォールトになって落ちる。
これはまた別の問題だと思う。
223 :
222 :2006/05/08(月) 00:05:26
あ、適当なこと言った。 ダブルフォールトじゃなかったかも。 とにかく落ちる。
VC++ 2005 Express で↓のコード動かしたけど、キャッチできないお? #include <cstdio> int main() { try{ struct T { ~T(){ puts("~T()"); } } x; puts("causing access violation"); char* p = 0; *p = 0; }catch(...){ puts("catch(...)"); } }
コードが最適化で消えてるとか?
WindowsのSEHはそのままじゃC++のEHじゃ捕まえられないよ。 VC++なら_set_se_translator()使わないと自分で throw した例外以外 ( 一般保護例外,ゼロ除算,等々 )は catch(...) でも拾えずに Dr.WatsonをよぶWindows のヘタレっぷりを初めて知った時にはワロタ。
他のosだと捕まえられるのか?
>>224 コンパイルオプションを調べれ。
>>226 がなんか言ってるけど、そんなことしなくても拾える。
( まぁ、明示的か裏でやってくれるかの違いでしかないかもしれんが。 )
>>226 何をやっても拾えない Unix/Linux はヘタレ以下ってことでおk?
230 :
224 :2006/05/08(月) 00:43:36
>>228 /EHa にしたらキャッチできた。 ~T() も呼ばれたみたい。
でもデフォルトじゃないってことは、やっぱり何か問題があったっぽいな。
>>217 というわけで、強制じゃないってことだな。
それなら便利に使えることもあるだろう。
>>230 問題と言っても Unix/Linux で動かした時と同じ挙動にさせたいとか
そーゆー互換性の類の問題かも。本当のとこはどーなのか知らんけど。
>>224 VC7.1だと、/EHsでもキャッチできてしまう。
問題だったんだろうな。
>>232 SEHに対応してなかった頃のプログラムの挙動を変えないようにする為に1票。
>>221 記述が楽なだけで、出来ることも不便なところもsignalと大差ないでそ?
VEHなら強力で応用範囲が広いので Windows マンせーもわかるけど、
高々SEHは記述がラクってだけで unix はダメ風に言うのはどうか、と言いたかった。
237 :
229 :2006/05/08(月) 00:57:29
>>237 は低脳ということが判明した。
知らない環境に対して口を出すなよ。
>>236 catch(...)って記述だけで全部拾えるのは単に記述がラクって言うのとは違うとは思う。
全てのプログラマが Unix/Linux でのプログラミングに精通してるわけじゃないないんだから。
>>239 確かに簡単というか難しくないアプリ開発とかならそのとおりなんだけど、
signalさえわからん奴に勝手に拾われても・・・ってな話もあると思うよ。
結局SEHではそれが問題でVEHが出てきたわけだし。
窓使いなのでよく分からないのだけど、Unix/Linuxでシグナルがcatchできないってのは 特定の言語処理系の問題なの? それともUnix/Linuxのしくみ自体がそれを許さないってことなの?
>>242 いや別にLinuxにもUnixにも、それを不可能とするような制限は無いよ。
例えば HP C++ なんかではSEH同様の機構が実装されている。
あんまり欲しい人がいないせいか、gccに採用されてないだけ。
245 :
242 :2006/05/08(月) 01:25:23
>>244 サンクス。よかった、そりゃそうだよね。
それじゃ、そもそも
>>213 は「GCC(等の対応していない処理系の)のヘタレっぷりにワロタ」ってことなのかな。
246 :
237 :2006/05/08(月) 01:26:41
>>245 実際はそういうことなんだろうが、 OS の優劣と混同していると思われ。
cygwin の gcc でSEHを拾えるか試してみたんだけど拾えんかった。 なんかググってみたところ、SEHに対応させるパッチを作ってる人がいるみたいだけど gcc みたいにそれなりの頻度でバージョンアップがあり且つバージョンが変わったら ゴロっと中身が変わってしまうようなプログラムでパッチがあってもあんまりうれしくないなぁ。
>>230 > ~T() も呼ばれたみたい。
これ、例外の種類によっては、うまくいかないことがある。
特にコンストラクタの中で例外が起きた時。
だからSEHは強い例外安全じゃない。過信は禁物。
>>249 コンストラクタが完了しないとデストラクタは呼ばれません。基本です。
>>251 お前がぐれたのは、こういう物を使ったためだったのか。
int main() { Damepo moudamepo; moudamepo.mandokuse('A'); }
え?C++って正規表現すらろくに標準装備されてないの?ショボw
. ┌┬┬┬┐
.―――――┴┴┴┴┴―――、 ______________
|| ̄ ̄ ̄||  ̄||| ̄ ̄ ̄|| | ̄ ̄ヽ /
|| アヒャヒャ| | ||| アヒャ || |_∧ ヽ / では
>>254 を
||(・∀・)_| |・∀||(・∀・)|| | ) [ ] < 引き取らせていただきまーす
||_ ̄ ̄_|_|_/ | ̄ ̄ ̄.|| | ̄ ̄ ̄ || \_____________
l O| ―-.|O゜| 東京精神病|.|院 ニニ .||
|_  ̄口 ̄ l_l⌒l|____|.|l⌒l_||_|__| ブロロ-‥‥
`ー' ̄ ̄ ̄`ー' `ー' `ー'
>>256 いちいち他人の作ったもん探して、自分のソフトに組み込むのが嫌なんだよ
ほんとショボいなC++は。他人にだっこしながらでないと開発できないなんて
今年のGWはやけに長いな
>え?C++って正規表現すらろくに標準装備されてないの?ショボw >ほんとショボいなC++は。他人にだっこしながらでないと開発できないなんて
>>258 嫌だね。全部自分で作りたい
なんか、他人のもん使うってせこい感じで嫌
効率悪くても自分で作りたい
だからって、どのソフトでも標準である機能をわざわざ自分で作成するのも損した気がするし
やっぱ、C#かVBのほうがいいね
C#の正規表現もVBの正規表現も他人が実装したもんじゃね?
>>261 で、君が使っているコンパイラは「他人のもん」ではないのか?
で、boostが標準に取り込まれたらころっと態度を変えるのかね君は。
>261 だったらコンパイラから自分で作れば?
M$以外が作ったなんの保障もない糞ライブライリなんてイラネ
>>266 だからって、どのソフトでも標準である機能をわざわざ自分で作成するのも損
日本語も理解できねーのかよカス
けっきょく標準を策定した人間に対してはおんぶにだっこか
おまいら釣られすぎ
今年はGW直後から5月病患者が大暴れだな。
C++の盲点をついたら病気扱いかよw 都合の悪いこと言われるとみんな異常者か? ほんと異常者のおまえらの思考はとんでもないなw
正規表現が使えないくらいでオロオロすんな FSMの練習だと思って作ればいいじゃんよ ・・ところで盲点って何?
どこが盲点なんだ?C、C++と受け継がれる設計思想そのものだぞ。
正規表現使いたいだけで
>>251 みたいな英語のサイト行かないとだめだし
てか、そんなものがあるかどうか知るすべなんてないし
それに比べてVBはLIKEがある。簡単
C#ならregexがある。簡単
C++は標準ではまともな関数がない
どうやってみ探せばいいかもわからない。
説明サイトもない。書籍もない。誰が好きこのんでC++なんかやるんだよ
時代錯誤もいいところ
最初からそう言ってくれればよかったのに。 なかなか正しい意見だからC#勉強したほうがいいよ。
>>276 そのとおりだ
C#とかJavaとかオススメ
なに変な方向に盛り上がってんの? 「正規表現使いたいんなら正規表現ライブラリ使え」以上、終了。 じゃダメなんか?
いいよ。
全部自分で作りたいんじゃなかたのか
自分でプログラミング言語つくれ
boost等にあるよ C++ 正規表現で検索すれば出てくるのに
>>284 やっぱboostかよ
なんでVBに正規表現あるのに
C++にはないわけ?
C++使う奴は、VBじゃ文字列処理やポインタなど細かい処理ができないから
C++に来てるのに、正規表現もないってなんだそれ?
一体どういう奴を対象にしてんだよ!まったく
てか、どうせ、正規表現だけじゃなくて、ほかにもVBならあるのにC++にはない
関数とかが大量にあって、その度に、検索しまくって探しまくったりするんだろ?
あーめんどくせ
そりゃお前がVBから始めたってだけの話だろ 愚痴ならチラシの裏かブログへ
┏┳┳┓ ハイ. ┏┳┳┓ ┏┫┃┃┃池沼と遊ぶのは ┃┃┃┣┓ ┃┃┃┃┣┓ ここまで ┏┫┃┃┃┃ ┃ ┃┃┏━━━┓┃┃ ┃ ┃ 池沼 ┣┫ . ・∀・ ┣┫. STOP!┃ ┗━━━━┛┗┳━┳┛┗━━━━┛ ┏┻┓┃ ┏━┛ ┣┻┓ ┗━━━┫ ┗━┓ . ┗━━━┛
スレが伸びてると思ったら・・・なんだこりゃ?
また基地外か。
応用編: なんで C に複素数あるのに C++ や VB には(ry なんで x86 マシン語にはローテートあるのに C には(ry まあなんつーか、これが所謂「ヴビチュウ」という生き物か。
>>291 C++には複素数あるし、
ローテートも Intel C++ Complier とか使えば組み込み関数で提供されてるだろ。
組み込み型としての複素数が無いってことだろう。 まあ、処理系独自に組み込み型の複素数作って、 complex はそれを inline で使ってるだけ・・・ な実装な処理系もあるけどね。
忘れられた<complex>……。
組み込み型かよ、Stop! 池沼だな。
組み込み型なら専用の最適化がある可能性がある。
VBに正規表現あったっけ? .netの間違いじゃないか? それならC++も同じですが
>>276 >>281 VB や C# を話しにあげているなら、Visual Studio .NET 以降だろう。
なら、標準でついている ATL に正規表現ライブラリがくっついてる。
Microsoft 純正で、VCなら標準だ。文句ないだろ
自分で標準化委員会でも立ち上げて、 自分が使いたいものについてはすべて標準ってことにしちゃえばいいじゃない
組み込み型?ただでさえ基地外のように巨大な言語仕様になって しまったC++なのに、まだ肥大化させるつもりかよ。
おまえが基地外だから 基地外のように巨大に感じるだけ。
組み込み型は別に多くないが、 言語仕様は大きいのはまあ大きい。 もっと大きなのもあるけど。 より良い言語を作ろうとすると どうしても言語仕様がデカくなって、 それが為に理解できる人が減ってしまうのは 何か遣る瀬ないな。
・馬鹿の一つ覚え ・ありきたり という表現がぴったりくるな。
RVOの時代に組み込み型で最適化とはね。 標準化委員会の方向とは完全な逆方向だな。
「C++の言語仕様はさまざまな変更を経て複雑怪奇なものに〜」 ってよく聞くけどVBやJavaってそんなに楽なのか
キーワードを無闇に使い回ししたせいで 文脈毎に意味が変わったりする、って点では複雑だが まあコンパイラ開発者に比べたら利用者の流す汗と涙なんか 知れたものよね。
>>307 ・generic function系は、大抵適当な奴を選ぶ規則が複雑。
・Javaはinstance methodはvirtualのみ。
・templateの(部分)特殊化
・Cとの互換
Javaはなぁ・・・あれを使うことによって楽になるのは馬鹿だけだから。 天才、凡人、馬鹿、すべての層の開発コストが抑えられる言語・環境ではなく、 C++では「馬鹿お断り」だった領域に、馬鹿でも加われるようになる言語・環境なんだよ。 喩えるなら、Javaの利便性は人工呼吸器みたいなもの。 それによって助かる人もいるけど、健常者なら苦もなくやれるところを手助けしてるだけ。 健常者にとっては、それ使って生活するのは何かとうざったい。
Javaは多重継承がないのが耐えられない。 特殊化がないのも辛い。
多重継承禁止するなら mix-in は欲しいよね。
言語の機能として欲しいね。自分で書くんじゃなくて。
>>307 本格的なものをつくろうとするとそんなにラクでもない。
簡単なものを作る場合には C++ より楽なことが多い。
316 :
デフォルトの名無しさん :2006/05/09(火) 22:31:06
全角文字列(2バイト文字)をあるデリミタで(2バイト文字)分解したいと思ってます。 C言語のstrtok()みたいなものです。C++にこのような機能を持った関数はありますか? g++でコンパイルでき外部のライブラリは使わないという条件なのですが。
>>316 ワイド文字へ変換してwcstokを使ったらどうか?
wchar_t 使って wcstok とか?
2バイトずつ文字を拾うイテレータをでっちあげて find する。
>>317 ありがとうございます。それでできそうな感じです。
strtokを含めてC言語の機能みたいですがstringクラスみたいなC++クラス版は実装されてないんでしょうか?
322 :
デフォルトの名無しさん :2006/05/09(火) 22:41:07
ありがとうございます。 いろいろ手がかりができたので調べてみます。
wcstok を wstring に使うのはマズいなぁ。 wstring 使うなら、 find したり substr するなりして拾う事になるかな。 俺はそうやって strtok みたいなのを自分で実装して使ってる。
324 :
デフォルトの名無しさん :2006/05/09(火) 22:57:01
>>323 findでデリミタの場所探してsubstrでできそうですね
Cで正規表現なんてつかわないでしょ とっかしたパーサかけ
boost::tokenizerはどう?
そっか。ここは boost アリなんだったな。
このスレに標準C++限定などと言った縛りは無い。
>>329 VC6という糞コンパイラについて語ろうか。
C スレは厳しいからな。 ちょっとビクビクしてしまう。
334 :
デフォルトの名無しさん :2006/05/10(水) 02:25:39
typedef struct S S; struct T { S* S; }; VC++ 2005 Express の cl.exe (VC8?) だと通るこのコードが、 cygwin の gcc 3.4.4 ではエラーになりました。 > 2: error: declaration of `S*T::S' > 1: error: changes meaning of `S' from `typedef struct S S' gcc の言ってることはわからんでもないのですが、 規格としてはどっちなんでしょうか?( ill-formed? well-fromed? )
レベルの低い質問すいませんが "AABBAAACCCCAAADDDEEAAA" このような文字列を処理するにはistringstreamwを使用すればいいことは解ったのですが 今何文字目を処理しているかを知るには自分で数えるしかないのでしょうか?また 先を読みをしたい場合はどうすればいいのでしょうか?
>>335 文字列を処理するには string 使えばいいと思うんだけどね。
istream について、
何文字目ってのは tellg() とか gcount() とか使う。
読み出すには read() とか operator >> とか使う。
337 :
334 :2006/05/10(水) 02:47:41
後付になりますが、 typedef 無しで struct S; struct T { S* S; }; としても同様の結果になりました。 ただ、実際の問題は C のソースを C++ に持ってきたときに エラーになってしまうことがあるということなんで、ちょっと別件っぽいです。 S* S を struct S* S に変えると C でも2つの C++ コンパイラでも どっちでも通るので、タイプ量をケチるための typedef struct S S を 辞めるべきなのかな?と迷ってます。
338 :
335 :2006/05/10(水) 03:03:12
>>336 あ〜なるほどなるほど
ファイルから読み込んで、istreamにアタッチして読み込み
判別していくという感じになるのです。解りました。
もう1つ聞きたいのですがC++でこのような文字判別を行う場合
例えば'A'を判別するケースとして
C言語のようにif文無いし関数を用いて判断するべきなのか
それともoperator >>のような新しい演算子を作るべきなのでしょうか
>>337 S* S; の2つ目の S で問題が発生してるようだ。
何でもかんでも同じ名前にするのはやめとけ。
S* s; で通る。
VCだと、クラス名と変数名がかぶっても、できるみたいだな。 仕様を読んでみたら、typedefで意味を変えるな、とは書いてある気がする。 class Foo {} ; typedef Foo Foo ; //OK typedef int Foo ; //ERROR でもこの問題は、typedefじゃない気がする。 どっちにしろ、名前がかぶるといいことはない。 Foo Foo ; //VCではOK Foo & f = Foo ; このコードは、VCでは、 変数 Foo と変数 fに対して、&演算子を適用し、変数 Fooを代入する意味になるらしい。 変数 Fooを参照する、Foo &型の変数 fにはならないらしい。
>>338 string に読み込んで find() する。
typedef struct S S; の2つの S は名前空間が違うから問題ない。 これはよく言われる事だから確実かと。 で、S* S; の2つの S は名前空間同じなんじゃないかな。 VC++ で通るのは処理系独自の拡張?
343 :
335 :2006/05/10(水) 03:34:35
うーんそれだとちょっと意味が違ってきてしまいます 字句解析を将来するための事前勉強なので findを連発するのはふさわしくないと思うのですがどうなのでしょうか
>>343 最初に十分な情報を出さずに質問しておいて、答えが帰ってきた後に
自分の都合を小出しにして文句を垂れる。そんな人は嫌いです。
345 :
335 :2006/05/10(水) 03:42:24
申し訳ございませんでした。
>VC++ で通るのは処理系独自の拡張? 単にチェックしてないだけなんじゃないかという、 大胆な予想を思いついてしまった。
そういや struct T の内部だから、 S* S; の2つの S は名前空間違うな。 なら、通る方が正しいのか? まあ、そう何度も同じ名前を使うべきじゃないと思うから、 S* s; の方がいいと思うがな。
ドンブラコッコ、ウンコッコ
349 :
334 :2006/05/10(水) 03:59:23
親クラスCMaterialがCMaterial型のポインタNextMaterialを持ってて、CMaterialを継承したCBlockクラスがあるとき、CMaterialのメソッドを使ってNextMaterialをCBlockとしてnewする方法ない?
あるよ。
>>334 typedef struct S S;
struct T { ::S* S; };
そんなことは読んでます。
>>350 template < class T > class CMaterial {
CMaterial* NextMaterial;
public:
T* CreateNext() { return NextMaterial = new T; }
};
class CBlock : public CMaterial<CBlock> {};
/* または */
class CMaterial {
CMaterial* NextMaterial;
protected:
virtual CMaterial* Factory() const { return new CMaterial; }
public:
CMaterial* CreateNext() { return NextMaterial = Factory(); }
};
class CBlock : public CMaterial<CBlock> {
protected:
virtual CMaterial* Factory() const { return new CBlock; }
};
ふたつめのCBlockの宣言は class CBlock : public CMaterial { … だorz
>>355 ありがとう(_ _)
でもそれだと生成するオブジェクトがCMaterialならCMaterial、CBlockならCBlockしかNextMaterialに生成できないですよね?
CMaterial型のオブジェクトのNextMaterialにCBlockを生成するようなことはできないでしょうか。
358 :
デフォルトの名無しさん :2006/05/10(水) 13:16:12
CMaterial *CMaterial::CreateNext() { return new CBlock; }
>>357 template < class T > CMaterial* CMaterial::CreateNext() {
return NextMaterial = new T();
}
CMaterial mate;
CBlock blo = mate.CreateNext< CBlock >();
template < class T > T* CMaterial::CreateNext() { だった
>>359 そんな方法が!コンパイル通るならそれで行こうと思います。何度も有難う御座います。
>>361 まだ試してないのですがCMaterialの前にCBlockを先行宣言すればとおり・・・ませんか?
>return NextMaterial = new T(); を T *ret = newT(); NextMaterial = ret; return ret;
364 :
デフォルトの名無しさん :2006/05/11(木) 07:30:20
質問なんだが C++でクラス図とコードを相互変換できるソフトとか知らないか? できればフリーで。クラス図のモデリングが出来ればなおよし
スレ違い
367 :
デフォルトの名無しさん :2006/05/11(木) 14:45:44
質問します。 STLのVECTORを用いた構造体の配列に関するプログラムで typedef struct{ int a1,a2,b1,b2; }Mat; vector<Mat> Matrix; void func(Mat *dat){ dat->b1 = 3; dat->b2 = 5; } void main(void){ int i; for(i=0;i<10;i++){ a1 = 1*i; a2 = 2*i+3; } //--------------------------★1 for(i=0;i<10;i++){ func(&Matrix[i]); } //--------------------------★2 return; } とまぁこういうプログラムがあったとして(実際はもっと複雑な事やってるのですが) ★1の時にはしっかり値をセットできているのに、 ★2の時にはVECTOR配列Matrixのメンバ値全てが-8123456といったヘンな値をとるようになってしまいました。 また、関数の引数をポインタではなく構造体そのものにすると(func(Mat dat)とし、"->"の代わりに"."を使う)途中で例外エラー hoge.exe の 0x00424dd4 でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x4b55c568 を読み込み中にアクセス違反が発生しました。 が発生します。 このような時にしっかり値を構造体配列にセットするにはどう修正すべきでしょうか。 御教授下さい。
ファクトリ関数というのを作ろうとしています。 試しにVC++7で以下のようなコードを書いてみました。 今のところエラーも出ず、きちんと動いてるように見えるのですが こんな書き方で問題ないのでしょうか(主に、メモリリークが起きないかどうか) class Base{}; class Advance : public Base {}; // 戻り値なし・引数ありパターン void createv( Base* &rp_a ){ rp_a = new Advance; } // 戻り値あり・引数なしパターン Base* createb(){ return ( new Advance ); } int main() { // 基底クラス型ポインタ Base* p_b1; Base* p_b2; // オブジェクトを生成 createv( p_b1 ); p_b2 = createb(); // オブジェクトを破棄 delete p_b1; p_b1 = 0; delete p_b2; p_b2 = 0; return 0; }
>>367 値をセットするとかそういうところの問題ではありません。
vector は明示的に要素数を指定してあげなくてはなりません。
vectror<Mat> Matrix(10) とするか、main の頭でMatrix.resize(10) としてください。
基本知識が少し不安・・・
>>367 >実際はもっと複雑な事やってるのですが
最低再現するプログラムを貼りましょう
- Matrixのサイズは0でいいの?
- ★1のa1,a2ってなに?
>>368 Baseのデストラクタはvirtualにした方がいいよ
Advanceがそのままメンバ変数を持たなければ問題はないだろうけど
あるいは生のポインタじゃなくてboost::shared_ptr使うとか
>>369 vectorは動的にサイズを変更できると聞いていますが、要素数は指定しなければいけないのでしょうか。
何しろ格納するデータ数が未定なので、STLを使ってみたのです。
先ほど、要素数を vector<Mat> Matrix(0); と指定して
for(i=0;i<10;i++){
Matrix.resize(i+1);
a1 = 1*i; a2 = 2*i+3;
} //--------------------------★1
のように行っても直りませんでした。
>>370 最低再現するプログラム…
OPENCVで画像を読み込んである行列計算をしてその結果を放り込むプログラムです。
計算部分はデバッグを行い、ウォッチで値を確認して動作は確認したため貼らなかっただけです。
再現したい部分は
>>367 に書いた通りです。
Matrix.resize(10); for(i=0;i<10;i++){ Matrix[i].a1 = 1*i; Matrix[i].a2 = 2*i+3; } の写し間違いだよね? 人に質問できるレベルに達してないよ・・・
>>373 すみません、その通りです。少々慌ててました。
>>362 あのさ、
>>359 でいいなら(呼び出し側がNextMaterialにセットする型が分かってるなら)
CMaterial::SetNext(CMaterial* next) {
NextMaterial = next;
}
mat.SetMaterial(new CBlock);
でいいじゃん…
>>374 370は373と同じことを言ってるのに、372のようなレスをすることからも
かなり慌ててるのがわかる。
午後4時から研究室の発表とかいうのでなければ
まずはコーヒーでも飲んでくることをお勧めする。
つーかさぁ、Matの一時変数に代入してpush_back()すればいいじゃん。
…申し訳ありませんでした。本当の所を書きます。 void main(void){ int cnt=0; char buf[256]; char *tp; FILE *fp FolderPath1 = "csvファイル1のパス" FolderPath2 = "画像フォルダのパス" fp = fopen(FolderPath1,"r"); while(!feof(fp)){ Matrix.resize(i+1); fgets(buf,sizeof(buf),fp1); tp = strtok(buf,","); temp = atof(tp); Matrix[i].a1 = temp; Matrix.resize(i+1); fgets(buf,sizeof(buf),fp1); tp = strtok(NULL,","); temp = atof(tp); Matrix[i].a2 = temp; cnt++; //ここでデータ件数をカウントする }
>>375 全然気づきませんでした
それが一番スマートで楽ですね。そうします。
皆様ありがとうございました。
//main関数の続き //画像データを格納 char imgpath[512];//画像のパス char tempstr[32];//画像ファイル名 for( i=0 ; i<cnt ; i++ ){ //連番ファイル名の画像ファイルパスを作成する sprintf( tempstr, "%05d.jpg", i+1 ); strcpy( imgpath, FolderPath ); strcat( imgpath, tempstr ); //格納処理 IplImage *image = cvLoadImage( imgpath, -1 );//読み込み SetTex(image,&Block_Mat[i]); ←この関数の定義は次に書きます(main関数の前に定義してある) }
void SetTex(IplImage *img, BLOCK_IMAGE *dat) { int size = sizeof(dat->tex);//行列サイズ size = sqrt((double)size); CvSize r_size = cvSize( size, size );//リサイズ後の座標 IplImage *res_img = cvCreateImage( r_size, IPL_DEPTH_8U, 3 );//テクスチャ画像 cvResize( img, res_img, CV_INTER_CUBIC ); //テクスチャ作成 int w, h; for (w=0;w<size;w++) { for (h=0;h<size;h++) { //青 if(0 <= res_img->imageData[h * res_img->widthStep + w * res_img->nChannels]) dat->tex[w][h][2] = (GLubyte) res_img->imageData[h * res_img->widthStep + w * res_img->nChannels]; else dat->tex[w][h][2] = (GLubyte) (256 + res_img->imageData[h * res_img->widthStep + w * res_img->nChannels]); //緑 if(0 <= res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 1]) dat->tex[w][h][1] = (GLubyte) res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 1]; else dat->tex[w][h][1] = (GLubyte) (256 + res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 1]); //赤 if(0 <= res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 2]) dat->tex[w][h][0] = (GLubyte) res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 2]; else dat->tex[w][h][0] = (GLubyte) (256 + res_img->imageData[h * res_img->widthStep + w * res_img->nChannels + 2]); } } }
おいおい今度は丸投げかよw(ないよりはいいけど) 貼るのは「最低限の再現するプログラム」にしてくれよ その最低限を探す過程で大抵は自己解決するんだからさ
>>372 最低再現するプログラム
= コンパイルが通る完全なコードで、質問する実行時エラーが発生するコード
≠ 作成中のプログラム全体
必要十分な部分を抜き出すか、新たに同一の問題が起こるサンプルを書く。
その過程で、何が間違いか気づくことも多い。
要は、こういうことがしたいのか?
#include <iostream>
#include <vector>
struct matrix_t { int a1, a2, b1, b2; };
std::vector<matrix_t> matrixes;
void func(matrix_t& target) { target.b1 = 3; target.b2 = 5; }
int main() {
for (int i = 0; i < 10; ++i) {
matrix_t tmp;
tmp.a1 = 1*i;
tmp.a2 = 2*i+3;
matrixes.push_back(tmp);
}
for (int i = 0; i < 10; ++i) {
matrix_t& m = matrixes[i];
func(m);
std::cout << "[" << i << "] = (" << m.a1 << " " << m.a2 << " " << m.b1 << " " << m.b2 << ")" << std::endl;
}
return 0;
}
すみません、
>>378 のMatrixはBlock_Matに置き換えてください。
//構造体BLOCK_IMAGE
typedef struct{
GLubyte tex[64][64][3];
double a1;
double a2;
double b1;
double b2;
}BLOCK_IMAGE;
385 :
367 :2006/05/11(木) 16:25:34
皆様、お騒がせしました… 今一度頭を冷やした方がいいかもしれません。 整理して出直します…
↓試したけどちゃんと動いたよ。本当に頭を冷やした方がいいかも。 #include <iostream> #include <vector> using namespace std; typedef struct{ int a1,a2,b1,b2; }Mat; void func(Mat *dat){ dat->b1 = 3; dat->b2 = 5; } int main(void){ int i; vector<Mat> Matrix; Matrix.resize(10); for(i=0;i<10;i++){ func(&Matrix[i]); } for(i=0;i<10;i++){ cout << Matrix[i].b1 << Matrix[i].b2; } return 0; }
387 :
367 :2006/05/11(木) 17:46:19
頭を冷やしてきました。一つ一つ値を追いかけていき、値の狂いだした場所を突き止めたところ するとバグの起きていた場所が自分の想像していた場所とは違う場所にありました。 int size = sizeof(dat->tex);//行列サイズ size = sqrt((double)size); の部分で,sizeの値が構造体メンバのサイズではなく、構造体一個丸々のサイズが出力されていたことが全ての元凶でした。 間違っていると思われていた箇所は問題なく動いておりました… 自分のデバッグ力の無さを反省しながら首吊って死んできます
388 :
383 :2006/05/11(木) 18:44:17
漏れのコードは闇に葬られたか('A`)
すいません、終わったところで
>>368 お願いしてもいいですか・・・
無い。以上。
戻り値返す方はスマートポインタを返す様にすると 呼び出し側が戻り値を受けとらなくても安全かも まぁその時点でバグなんだけど
>>342 > typedef struct S S; の2つの S は名前空間が違うから問題ない。
> これはよく言われる事だから確実かと。
間違いです。
「C++設計と進化」の名前ルックアップのところが良くまとまっていると思います。
本を嫁はすぐ可能な事ではないのでよろしくない。 C だとそうだけど C++ だと違うとかいう類いのものなのかな。
394 :
デフォルトの名無しさん :2006/05/11(木) 22:31:02
おまいら頭悪スレ逝ってくれ
2つの S は同じ名前空間にあるはずなんだけど、その宣言の後、
プログラムに現れた S がどっちを指すか、規格できっちり決まっていない。
っていうのが
>>349 のリンク。
なるほど。
>>393 なぜだろう、ここで晒される本は全部持ってる。
持ってても斜め読みするだけじゃ、糞のカスにもならない。 手垢がついてボロボロになる位にまで読まなきゃ。
というかD&Eも読まずに何を言っているんだという感じだけどな。
禿本は持ちすぎて手の汗でカバー中央がグズグズだ
>>395 違うぞ。
>>334 のケースは決まってる。駄目。
name lookupのthe reevaluation ruleってやつだ。
Mike Millerは、その新しいやり方(this approach)にしても、
やっぱり駄目じゃん(but doesn't eliminate the incompatibility with C)と言っている。
mixiでkusakabeに聞けば良いんじゃね? 間違ってたら「ボケ」って言ってくれるよ。 正解は教えてくんないけどな
403 :
395 :2006/05/12(金) 01:57:39
>>401 俺は
>>334 が well-formed だなんて言ってないよ。
決まってないのは typedef struct S S の後に現れる S が
クラス名なのか typedef 名なのかってところ。
404 :
335 :2006/05/12(金) 02:05:08
char * dataっていうの中身が"HOGEHOGEHOGE"だったとして char *buf = data + 3; char *result = new char[4]; memcpy(resutl, buf, 4); こうすると、EHOGがresultにコピーされますがこのようなデータを <list>や<vector>内に格納してitするのはまずいですよね? ;
>>404 「このようなデータ」「itする」の意味がわからない。
エスパー的には iterate するってことだとおも
408 :
401 :2006/05/12(金) 08:36:43
>>403 ああ、そういうことね。スマン誤読した。
>>335 何を言ってるのかさっぱりわからん。研究室の先輩にでも聞いたらどうだ?
memcpyの第一引数のスペルミスといい、お前本当にサンプルコードで試してるのか?
書いてからエスパーが働いたが、もしかして、resultを、char*を要素にもつコンテナに格納してもいいかという質問か? それなら問題はない。ただし、delete[]を忘れないこと。
境界を出ると例外を投げてくれるiteratorってないですか? std::list<int> li; li.push_back(0); std::list<int>::const_iterator it(li.end()); ++it; // ここで例外を投げてほしい
std::list<int> li; li.push_back(0); std::list<int>::const_iterator it(li.end()); *it; // end()ならここで投げる予感 ++it;
operator++()が呼ばれるたびに、毎回範囲内かどうかテストするってことか? あんまりうれしい処理じゃないな。 ++it; if (it == li.end()) throw XXX; とでも書けばいいんじゃないの。
>>411 昔のプログラミング言語CLUみたいだな。
boost::iterator::iterator_facadeで、
std::list<int>::const_iteratorから生成すれば?
void increment()の中でcheckしてthrowするようにすればいい。
20行くらいで書ける。
415 :
411 :2006/05/12(金) 18:46:03
やりたいことは何個か先の値を見て条件分岐することです。
例えば三個先の値を見て分岐する場合
std::list<T> li;
std::list<T>::const_iterator it(li.begin());
...
if (boost::next(it, 3)->getHoge() == ...) { // 3個先の要素のgetHoge()の値で分岐させたい
}
else {
}
こんな感じになるわけですが、boost::nextでイテレータが三回インクリメント
されるときに、[li.begin(), li.end())を超えてしまうと未定義の動作になってしまいます。
かといって、
if (++it != li.end() && ++it != end() && ++it != end() && it->getHoge() == ....) { ... } // @
とするのはソースが読みにくくなり、また書くのも面倒でしかも使いにくいと思ったわけです。
インクリメントごとに境界チェックするのは
>>413 さんと同じようにうれしくはないのですが、
@のコードよりはマシかなと思った次第です。他に方法があればいいのですが・・・
>>415 ループ内で list<T>::iterator::next(3) なんてするくらいなら、
見た目は悪いけど 3つ先のiteratorも作って一緒に回した方が良いよ。
ごめんなさい。 ループじゃないんですね。
その目的で例外を使うのは得策じゃないなぁ。 正常動作中でも比較的頻繁に発生しそうじゃないか。 イテレータを3個進める関数を作るのが一番無難な希ガス。 #その関数の中は>415の(1)みたくなっちゃうけど。
419 :
デフォルトの名無しさん :2006/05/12(金) 21:20:31
質問です。 参照とポインタの大きな違いは何ですか? というか、参照>ポインタ なメリットってなんですか? ポインタのように振舞える?ってことはポインタで十分補えるってことですよね? 使いどころがよくわかりません。 見た目の違い・・・?
データベースのプログラム作ってみると分かるかもな
>>419 歴史的に言えば、演算子オーバーロードをスマートに書くために実装された。
例えばユーザ定義クラスHoge同士を
Hoge a, b, c;
c = a + b;
と書けるようにするには
operator+(Hoge& lhs, Hoge& rhs);
が必要になる。
これをポインタでやろうとすると、
(つまり operator+(Hoge
(´・ω・`)途中で送信しちまったい operator+(Hoge *lhs, Hoge *rhs) と実装してしまうと、 c = &a + &b; と書かなければいけなくなるけれど、 Cでは &a + &b はポインタの加算であって、演算子オーバーロードと意味が被ってしまう。
423 :
デフォルトの名無しさん :2006/05/12(金) 21:53:33
な、なるほど・・。 じゃぁ、オブジェクト指向にするために実装されたわけか・・・。 苦し紛れの friend 制約と似てる気がする。 ま、使っても使わなくてもどっちでもいいってことか。 データベースはちょっと作る機会が当分なさそうですな・・。
>>419 メリットどうこうよりも、
中身が絶対無いとダメな場合は参照。
中身が無い事(NULL)もありうる場合はポインタ。
この2つで使い分けると良い。
とりあえずconst参照渡しから使い始めてみるのがいいかと。
ポインタを使う場合よりスッキリ書ける。
>>423 その後色々使い方が出てきたけれどね。
例えば、「参照は必ず初期化されなければならない」という制約があるから、
引数のNULLチェックが必要なくなる。
void foo(int *p)
{
if (p == 0) return; // 必要
*p = 10;
}
void foo(int &p)
{
p = 10; // 特殊な例外を除いて、NULLではない
}
など。
参照をムリに使う必要もないし、ポインタだけで済ませることもできるけど
オーバーロードの例のように、ポインタであることを意識させたくない場合や
参照を使った方が便利になる場合は参照を使えばいいかと。
>>423 >じゃぁ、オブジェクト指向にするために実装されたわけか・・・。
オブジェクト指向とオペレーターオーバーロードは直接関係ない。
もうちょっとC++勉強すれば参照の良さがわかってくるよ。
ことC++に関しては後から追加された機能が多いからな そういう機能を「C++っぽいから」という理由で無理に使ってワケわからんプログラムを書くよりは 便利さを実感できるようになってから使った方がいい
428 :
デフォルトの名無しさん :2006/05/12(金) 22:04:49
ふむ、にわかプログラマじゃちょっと難しい使い方ですね。 もっと、経験を積んで再度参照の使いどころを検証してみます。 ありがとうございました。
429 :
デフォルトの名無しさん :2006/05/12(金) 22:11:38
VC++でプログラムしている学生です。 マインスイーパの画面を色を読み取って、 それをプログラムの中で行列にしたいのですが、 どういったコマンドを使えば良いのでしょうか? ・画面の読み取り方 ・画像から行列データの変換の仕方など 教えてください。
それってWindowsのAPI関係の話題じゃないのか? そっち行った方が良くね?
あ、すいません
432 :
デフォルトの名無しさん :2006/05/12(金) 22:27:18
コンパイラ : Borland C++Compiler 5.5 IDE : BCC Developer VBアプリからBCC Developerで作成したDLLを呼び出したいです。 VBのソースに書く装飾名が知りたいんですが、VC++がインストール されている環境でないと知ることはできないのでしょうか。
>>432 tlibでインポートライブラリからリストファイルを作成。
自作のDLLならextern "C"しとけば?
435 :
デフォルトの名無しさん :2006/05/12(金) 23:37:36
質問です。 あるクラスで構造体BBOXを宣言しました。 そして、そのクラスの中で、 BBOX GetBox(void){ return m_bbox; } のようにボックスを返すメンバ関数を作りました。 そして、別のクラスで呼び出そうとしたところ、 BBOX box; と変数を宣言したら定義されていないとされました。 BBOX構造体を宣言したクラスのヘッダファイルはインクルードしてあります。 なにが問題でしょうか?
>BBOX構造体を宣言したクラスのヘッダファイルはインクルードしてあります。 「BBOX構造体を宣言したクラス」のヘッダファイルをインクルードしたんだな? 「BBOX構造体を宣言した」ヘッダファイルをインクルードしたわけじゃないんだな?
437 :
デフォルトの名無しさん :2006/05/12(金) 23:46:42
>>436 そうです。
やはり、他のクラスでも使えるようにするには共通のヘッダで宣言するってことですか?
クラス内で宣言した場合はクラス内でしかつかえないのでしょうか?
そのクラスの名前::BBOX box;
439 :
デフォルトの名無しさん :2006/05/13(土) 00:04:36
>>419 この質問は昔からあるFAQだな…。
コピーコンストラクタとか、例外とか、深くわかってくると参照じゃないと非常に問題があることがわかってくるよ。
ていうかポインタってやつは言語仕様的にはマジ腐ってる。
でも参照も実は中途半端で、コンテナに突っ込んでおくとオブジェクトの生存期間の管理がややこしくなったりする。
生存期間、つまりdeleteするタイミングを任意にコントロールしたければ、腐っていてもポインタを使うしかない。
そんなわけでポインタも参照もなるべく使わず、C++/CLIのハンドル(^)を使うのが最強ってことで。
>>440 C++ 使ってるんなら、実行速度を無視して最強を決めるんじゃない。
>>419 参照は「初期化されずに使用されるポインタ」「(意図せずに)NULLを指すポインタ」
なんてのを排除しつつ見た目を多少整える程度の存在。
別の言い方をするなら、
指し示す先を「領域が確保され初期化されている既存オブジェクト(等)」に
限定したポインタのような存在。
>>441 昔はC++は遅いってよく批判されたものだけどね。
10年前はマイナーな言語だったのに、今は詳しい人がこんなにいるってのが、
おじさんには驚きですよ。いい時代になったものだね。
誰にも理解されなかったあの頃が懐かしい。
C++/CLIのネイティブコンパイラが現れる時代もそんなに遠くないでしょ。
ネイティブでガベコレってのはD言語でもやってるしね。
>>443 C++ のポインタが遅いとか、
>>440 が書き込まれた時点で C++ のポインタの変わりに
C++/CLI のハンドルが使える(しかもそうすることを推奨)とか、
そういうことを本当に信じてますか?
初学者に適当なこと言って惑わすのって面白いですか?
ポインタ演算はなんだかんだ言って高速でシンプルなイテレーションに使えるしな。 # ここで禿が言う「オブジェクト指向に過度に毒された人」はイテレータのクラスを作れ!とか言うんだろうが
>>443 ところでガベコレってなんで必要なのかいまいちわからんな
スマートポインタ使ってれば必要なくね?
>>446 D&Eの最新の邦訳を持っているなら、第-1章のxxviiiを参照するといいかも
>>447 情報Thanks!
ということはガベコレにもいいことがあるだなぁ
今度見てみます
C++エキスパーツなおまいらから見てDってどうよ
エキスパーツじゃないけど、C++にいくつかのライブラリとマクロを組み合わせれば
Dの優位性はあまり感じられない、というのが正直な感想。
DがC++に対して優位である証明として、次の比較があるけれど:
D vs その他の言語
http://www.kmonos.net/alang/d/comparison.html C++のように、ライブラリでの実装を推奨したとすれば、上記の比較表はかなり違ったものになる。
この比較は、標準ライブラリでの実装を否定し、言語仕様に組み込むことを善とする考えに基づいている。
その理由として:
言語の機能 vs ライブラリによる実装
http://www.kmonos.net/alang/d/builtin.html を挙げている。漏れには、これらの「利点」が、ライブラリでの実装を否定するほどのものではないように見える。
その他のDの機能も、C++でできることを、Dは少し簡易にできるというだけにしか見えない。
結論:C++で必要十分。
>>446 シングルスレッドなプログラムならスマートポインタでほとんど大丈夫。
でもコンテナにポインタを入れるときに面倒なことがおきがち。
マルチスレッドで、オブジェクトをスレッド間でやり取りするなら、
ガベコレは非常に欲しい。かなり楽になるよ。
>>450 Dの関数の入れ子やデリゲート、無名関数は欲しい。
でもtemplateはC++のがいい。これがあるから俺は他の言語へ移る気にならない。
言語を作るための言語ができれば最強じゃね
>>419 関数に巨大な構造体を引数として渡す時に値渡しではなくconst参照で渡して
パフォーマンスアップ、以外の使い方見たこと無いけどね
>454 > 関数に巨大な構造体を引数として渡す時に値渡しではなくconst参照で渡して それはconstポインタでもできる ってか,巨大な構造体を値渡しなんてCでもせんだろw
相談ごと VC6 で、 デバッグビルドではさくっと動くのに、 リリースビルドではさくっとこける。 て言う現象が起こったとき、 どこを疑えばいいのかどなたかご教授くださいお願いします orz
変数の初期化
458 :
335 :2006/05/13(土) 12:44:38
みんな細かいテクニックはどこから学んでるの? EffectiveC++とか?
459 :
456 :2006/05/13(土) 12:53:42
>>457 解決しました!
(初期化されてない関数へのポインタ変数を使ってたらしい)
ありがとうございました。
>>455 参照ならポインタと違ってわざわざ呼ぶ側が&演算子を使う必要が無くなる。
こと構造体(やクラス)では値渡しだと非効率と言うコンピュータの勝手な都合だから、
そんなポインタを使っていることを意識させないほうがよろしい。
461 :
デフォルトの名無しさん :2006/05/13(土) 15:31:29
コンピュータに都合なんかねえよ 応答速度やメモリ原価でイライラするのは結局人間の都合
コンピュータの特性と言えばよかったのにね☆
new をオーバーロードしたいのですがオーバーロードしたnewが呼ばれません… class A { void* operator new(size_t t) { void* mem; mem = malloc(t); return mem; } } class B : public A { int* i = new int; }
すみませんクラスBがあれですが気にしないでくださいorz
>>463-464 頭脳が間抜けか?
それがよばれるのは、class A および class Bをnewしたときだ。
それがしたいなら、グローバルなnewをオーバーロードしなければならない。
void * operator new(size_t size, std::nothrow_t const &) throw()
{
std::cout << "new called : " << size << std::endl ;
return malloc(size) ;
}
なるほど解りました、ありがとうございます。
>>466 あと、std::nothrow_tを引数に取らないnewをオーバーロードするときは、ちゃんと例外を投げておくこと。
とくにグローバルなnewをオーバーロードしたいなら。
厳密にまったく同じ動作をしたいなら、さらにset_new_handlerをトリッキーに使う必要があるけど、
そこまでするかどうか状況によると思う。
ありがとうございます。 もう1つ聞きたいのですが、 operator new[]の方をオーバーロードした時の中の処理は malloc(size);でもいいのでしょうか?
callocでないといけないとかと思ってたんですが、 すみません自己解決しました。
>>458 「細かいテクニック」って何のことだ?
その表現からは、「所詮は枝葉末節であり、仕事に関係しない・知らなくてもいい技法」というニュアンスを感じるが。
Effective C++では、設計・実装の「常識」は説明されているが、「小細工」の類は書かれていない。
Effective C++に書かれてる内容は理解してて当然じゃないと仕事ふれないよな…
std::string に pop_back がないのですが、どうすれば良いのでしょうか…?
[end() - 1] じゃだめなん?size()も一減らさないとあかんの?
477 :
デフォルトの名無しさん :2006/05/14(日) 01:00:21
#include <iostream.h> #include <malloc.h> struct KATA{ int ab; int cd; }; int MyFunction(int x, struct KATA *y) { y = (struct KATA *)calloc(x, sizeof(struct KATA)); if(y == NULL){ return(1); } for(int i = 0;i <= x -1;i++){ y[i].ab = 2; y[i].cd = 3; } return(0); }
478 :
デフォルトの名無しさん :2006/05/14(日) 01:00:48
void main() { struct KATA *y; cout << "MyFunctionの戻り値 = " << MyFunction(2, y) << endl; for(int i = 0;i <= 1;i++){ cout << "y[" << i << "].ab = " << y[i].ab << endl; cout << "y[" << i << "].cd = " << y[i].cd << endl << endl; } } 関数に作りたい構造体の数と、構造体変数へのポインタを渡して、 関数の中で、領域を確保して値を格納して、格納した値をmainで参照 したいのですができません。これはできないものでしょうか。
480 :
デフォルトの名無しさん :2006/05/14(日) 01:23:34
△ × void main()
482 :
デフォルトの名無しさん :2006/05/14(日) 01:36:48
>>478 int MyFunction(int x, struct KATA *&y)
それから、C++ では calloc より new とコンストラクタを使え
なお、479 は C++ スレで C の解説サイトへ誘導を試みてるアフォなんで (・∀・)ニヤニヤ しとけばいい
参照渡しやオブジェクトの初期化方法を差し置いて × と書いている理由も
おそらく根拠が C の仕様で、かなり重度に気が狂ってる模様
>>480 3.6.1 - Main function の 2 より。
"It shall have a return type of type int, but otherwise its type is implementation-defined."
485 :
デフォルトの名無しさん :2006/05/14(日) 01:41:31
>>484 なるほど、お前が英文が読めないことはよくわかった
>>482 479 の×の理由の根拠が C の仕様って、おまえも狂ってんじゃね?
なになに? void main() が OK とか言ってるやつがいるの?
488 :
デフォルトの名無しさん :2006/05/14(日) 01:44:19
489 :
デフォルトの名無しさん :2006/05/14(日) 01:47:31
________. | ・・・「ひでもん」? ||| | \____ __ ||| | )\ ∨ ||| 英 文. <⌒ヽ ヽ ||| \ ( ´ー`) ∧∧ |||_________V( 丿V^ ●Д゚,,) |,,| |,,| ヽ ( と ,) ノ ) | |〜 ∧ .し`J,,.  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ なんか、たった1行の英文が読めてない奴多いなー
MTGで鍛えた英文力でも大丈夫だったぜ
491 :
デフォルトの名無しさん :2006/05/14(日) 01:54:49
まあ欧米のネイティブど素人が読んでわかる文面でもないが・・・
So if one's compiler's documentation happens to say anywhere that main may have the return type void then main may indeed have the return type void and a program with void main() is a conforming program. ↓これをどう取るかで宗教論争
494 :
デフォルトの名無しさん :2006/05/14(日) 02:05:55
禿の所有物みたいに思ってる化石がまだいたか
>>494 必死だな。 ISO で決まってるんだからその指摘も的外れだが。
> See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1.
496 :
デフォルトの名無しさん :2006/05/14(日) 02:09:30
ISO の所有物みたいに思ってる化石がまだいたか
499 :
デフォルトの名無しさん :2006/05/14(日) 02:11:33
>>497 それならまだマシ
奴は ISO の文書が読めてない
500 :
デフォルトの名無しさん :2006/05/14(日) 02:12:11
仕事の憂さ晴らしなら雑談スレでしてほしいところだ
>>499 意味わからん。 ISO の文書読んだら、戻り値は int 以外無いだろ?
503 :
デフォルトの名無しさん :2006/05/14(日) 02:14:09
最初のレスで何に噛みついたかでカテゴリ1に分類されているわけだが
504 :
デフォルトの名無しさん :2006/05/14(日) 02:14:53
>>502 ほらな
484 を君は何と読んだんだい (ニヤニヤ
日本語が怪しい人がいますね
え……?
507 :
デフォルトの名無しさん :2006/05/14(日) 02:16:57
>>505 それは仕方ないよ、処理系定義という日本語を日本人全員が知ってるわけでもないのと同じ
問題はプログラム技術板で鼻息を荒くしてることであって
誰の鼻息が荒いの?
ちょっと頭の悪い方がいるようです
>>507 あれを「戻り値の型は実装定義」と読んでるようだな。
実装異存なのは main 関数の型だよ。
otherwiseの意味が若干とりにくいですけれどね
512 :
デフォルトの名無しさん :2006/05/14(日) 02:22:31
>>512 ここはひとつ、あなたの解釈を書いてみてもらえますか?
514 :
デフォルトの名無しさん :2006/05/14(日) 02:27:42
>>513 あっかんべー
どうしても教えて欲しければ有料だよ乞食さん
意味の通るところで改行するという定義に合わせるなら あの文章の前後の文もないとつらくないか?
>>512 の訳が知りたい。
>>510 以外のどういう解釈があるのかと。
int main()
{
std::cout << typeid(main).name() << std::endl ;
}
今時あっかんべーも無いだろう。釣りにしてもあからさますぎ。
518 :
デフォルトの名無しさん :2006/05/14(日) 02:38:45
しょうがないから JIS の訳を引用してあげる。 > 関数 main は多重定義してはならない。その返却値の型は, int とする。 > これを除いて,関数 main の型は,処理系定義とする。
鼻息野郎は逃げたようだな。いやよかった。
521 :
デフォルトの名無しさん :2006/05/14(日) 03:23:15
オブジェクトの初期化だの引数の渡し方だのを C の話でやろうとしたことを棚に上げて main の話に逃げ込んだのがどっちかは明らかだがな
まだいたのか、この超ロングヘアーのフサフサ
524 :
デフォルトの名無しさん :2006/05/14(日) 03:29:21
main には 「型」 があるそうだが、こんなのが型かよまったく extern "C++" typedef int f1(); extern "C" typedef int f2(int, char *[]); extern "C" f1* p1; extern "C++" f2* p2; extern "C++" int main() { p1 = &main; (*p1)(); } extern "C" int main(int, char *[]) { p2 = &main; (*p2)(0, 0); }
>>524 > main には 「型」 があるそうだが、こんなのが型かよまったく
そうだ。 C/C++ の関数には型がある。君はそれを知らなかったんだ。覚えておけばいい。
間違いを偉そうに撒き散らしたのを謝って反省するともっといいね。
526 :
デフォルトの名無しさん :2006/05/14(日) 03:52:47
>>525 言いたいことが通じてないようだが
int 以外の返却値を認めてない背景にある問題が
スタートアップモジュールとのスタック構造の一致にあり
それこそが型に他ならないと指摘している
オブジェクトの初期化だの引数の渡し方だのを C の話でやろうとした奴だからこそ
main の結合が処理系定義とか言う話にも何の疑問も感じないんだろうが
そういうレベルの輩と真面目に話しているつもりは最初からないんで
何が間違いかがあんたらとは認識ちがいそうだよ
527 :
デフォルトの名無しさん :2006/05/14(日) 03:56:53
>>525 俺に知らなかったと言うあんたは 524 のプログラム片に含まれる ill-formed を全て指摘できるのか
528 :
デフォルトの名無しさん :2006/05/14(日) 03:57:25
スーパークラスにサブクラス型のメンバを持たせたいのですが 方法ありませんか?どなたかよろしくお願いします。 class SuperClass{ ExtendClass* ec; }; class SubClass:public SuperClass{ };
見苦しいものだな 苦し紛れの言い訳とは。
530 :
デフォルトの名無しさん :2006/05/14(日) 03:59:05
>>528 実体を持たせようとするとサイズが無限になることくらいはわかるか?
やるならポインタで指すだな
531 :
デフォルトの名無しさん :2006/05/14(日) 03:59:45
>>529 自分が根に持っているものに疑問を感じたら態度違うさ
超先生がいるスレはここですか?
>>526 関数の型は、戻り値と引数リストで決まる。スタック構造の一致は実装の都合。
引数の渡し方については C の話で問題ない。
>>477 が誤解しているのは明らかに値渡しの理解。これを理解せずに
>>482 のようにコードを変更してうまくいったとしても、同じ間違いを繰り返す。
オブジェクトの初期化だのについては、君以外だれも何も言っていない。
534 :
デフォルトの名無しさん :2006/05/14(日) 04:03:25
言い負かすのに失敗したからといって、それがイコール自分の間違いとは認識しないことがある 527 をスルーで煽りに転じるだけな者に型を語られても説得力がないことに変わりがないように
>>527 main 関数のアドレス取っちゃだめですぅ
536 :
デフォルトの名無しさん :2006/05/14(日) 04:06:17
>>533 >関数の型は、戻り値と引数リストで決まる。スタック構造の一致は実装の都合。
違う
結合は明白に関数の型の一部である
gcc などで試した結果のみが根拠な者がそのような誤解をするのは当然
>引数の渡し方については C の話で問題ない。
よってこれも誤り
>オブジェクトの初期化だのについては、君以外だれも何も言っていない。
そのとおり、重要なことを放置したまま話が逸れていったんだよ
537 :
デフォルトの名無しさん :2006/05/14(日) 04:06:33
何かに似てると思ったらエンコリ翻訳ににてるのか
>>537 main 関数は多重定義しちゃだめですぅ
540 :
デフォルトの名無しさん :2006/05/14(日) 04:09:02
>540 レスがワンパターンになってるぞ。もう終わりか?
542 :
デフォルトの名無しさん :2006/05/14(日) 04:12:27
>>540 main の多重定義に付随していろいろ出てくるが、それも全部挙げさせるつもりか?
// 配列のテスト // #include <iostream> using namespace std; int main() { char c[10] = "あいう"; char *s = "abcd"; char ch[10] = "わをん"; cout << " s:" << s << endl; cout << " c:" << c << endl; cout << "ch:" << ch << "\n" << endl; s = (char*)c; cout << "c => s:" << s << "\n" << endl; cout << "現在のch:" <<ch << endl; cout << "現在の s:" << s << "\n" << endl; // @ for (int i=0; i<10; i++) s[i] = ch[i]; cout << "ch => s:" << ch << "\n" << endl; return 0; } 文字列を各配列に納めるテストをしていたのだけれど 目印@でのキャスト処理を for構文つかわずに s = (char*)c; のように簡略化できる方法ありますか?
545 :
デフォルトの名無しさん :2006/05/14(日) 04:18:48
>>543 ill-formed に対する処理系独自の解釈に起因する連鎖で出るエラーはいいよ
直接的に ill-formed な箇所がわからない者には説得力がないと言っているだけなんで
>>536 明白ってのは根拠があって言ってるのか?
規格を読む限りでは、戻り値型と引数リストの型が関数型の構成要素だよ。
非staticメンバ関数について型修辞子が追加される。
デフォルト引数や、例外仕様は含まれないことも明記してある。
リンケージについての記述は見当たらないが、 static つけたら型が変わられちゃ
困るんで、そんなものは関数型の一部ではない。
どうも「関数の型」が規格上に定義されたものだという前提が無いようだな。
> よってこれも誤り
「よって」が前の文と繋がってないよ。
> >オブジェクトの初期化だのについては、君以外だれも何も言っていない。
> そのとおり、重要なことを放置したまま話が逸れていったんだよ
どうでもいいから誰もタッチしてないんだよ。
548 :
デフォルトの名無しさん :2006/05/14(日) 04:23:24
>>546 static は型の一部ではない
extern "C" は関数の型の一部である
>どうでもいいから誰もタッチしてないんだよ。
どうでもよくないが、ここであんたに考えを改めてもらう必要もないんで放っておく
>>545 じゃぁ ISO の規格的にはもう無いと思うよ。君の脳内にはなんかあるみたいだけど。
550 :
デフォルトの名無しさん :2006/05/14(日) 04:25:29
551 :
デフォルトの名無しさん :2006/05/14(日) 04:27:30
>>530 すみません。コード間違えました。やりたいのは
class SuperClass{
SubClass* sc;
};
class SubClass:public SuperClass{
};
です。
>実体を持たせようとするとサイズが無限になることくらいはわかるか?
分かりません。でもポインタで指しているつもりです。
コンパイルを通したいのですが、どう宣言したら良いものか。
552 :
デフォルトの名無しさん :2006/05/14(日) 04:31:57
class BaseClass { public: virtual ~BaseClass(); }; class SuperClass{ BaseClass* pSubClass; }; class SubClass:public SuperClass{ }; とやっておいて、dynamic_cast とか class SubClass; class SuperClass { SubClass* sc; }; class SubClass : public SuperClass { }; のように不完全型を使うとか・・・
>>548 > extern "C" は関数の型の一部である
これは正しいようだ。 7.5.1 に書いてある。
ということは、
>>524 での p1, p2 への代入が関数型の不一致ってことか?
p1, p2 の宣言に付いてる extern "" は関数型には影響しないんじゃね?
↓こうなってればダメってのはわかるんだけどね。
extern "C" int (*p1)();
extern "C++" int (*p2)(int, char*[]);
554 :
デフォルトの名無しさん :2006/05/14(日) 04:52:36
>> 552 ありがとうございました。下の方法でうまくいきました。 ダイナミックキャストは勉強しておきます。
>>554 dynamic_cast 使わない方法をさがそうね。
dynamic_castってなあに?
558 :
デフォルトの名無しさん :2006/05/14(日) 05:10:25
>>553 うん、そこは影響しないように頑張るならこうだという意図で書いた
スタートアップがどうやって両方に対応するのかに対する疑問を提起するために
>>558 ん?スタートアップは両方に対応する必要はないでしょ?
>>558 じゃぁ >549 が不合格なのはなんで?やっぱりまだなんかあるの?
561 :
デフォルトの名無しさん :2006/05/14(日) 05:12:55
>>559 すくなくとも int main() と int main(int, char *[]) に対応できなければならない
562 :
デフォルトの名無しさん :2006/05/14(日) 05:14:15
>>560 結合指定が合ってるのを確認したうえで 「以上」 と言ってたならごめんよ
話についてこれてないのと見分けがついてなかった
563 :
544 :2006/05/14(日) 05:15:48
string (s = ch); とすることで解決出来たのですが <string> を include しなくても使えたので この string の扱いは basic_string で良いのでしょうか?
日本語がおかしければ正確に伝わらないのは当然
>>561 それ、両方 extern "C++" だから関係ないでしょ。
extern "C++" とは?
567 :
デフォルトの名無しさん :2006/05/14(日) 05:27:38
>>565 どちらか一方のみが extern "C" という実装もありうるし
main に結合指定を記述することも許されている
これは返却値のみについて int であることを強弁することが空疎であると主張する根拠の1つである
>>566 extern "C" と同様に使えるが、デフォルトと同じなのであまり使わない。
>>567 それを許可する処理系は、その定義を正しく処理する。
できなければ処理系の欠陥。処理系定義ってのはそういうことだ。
main の戻り値が int なのは規格で決まってる。
C++ で void main() が無効なのは変わらない。
570 :
デフォルトの名無しさん :2006/05/14(日) 05:48:28
>>569 正しく処理するように画策するのは曲がった話を通すためだろうがよ
1つの関数が extern "C" と extern "C++" の両方で同じ結合を持つなんて多重定義ができずかつ複数の型で定義できる関数だけだろ?
そのために main の型が処理系定義なのは結構だが、だったら「返却値を除く」必要性こそ処理系固有の事情によるはずで
引数の渡し方や動的記憶の使い方よりも優先するほどの重要度を持つ話ではないし
それしか指摘できない者がおこがましくも回答者面してたわけだ
571 :
デフォルトの名無しさん :2006/05/14(日) 05:51:13
関数とは名ばかりな特殊な規定の権化 >main
>>570 規格に文句言いたいなら勝手にすればいいが、ここで同意を求めるのはやめてくれ。
書籍関係のスレでぼろくそ書かれた著者か?
>>570 英語の一文を誤訳してたやつがおこがましくも回答者面しているわけだが。
576 :
デフォルトの名無しさん :2006/05/14(日) 06:15:10
>>572 あんたの話そらす腕は認めるよ、大したものだ
だがあいにくと文句の主たる矛先は規格ではなく 471 でな
残念だったな
577 :
デフォルトの名無しさん :2006/05/14(日) 06:15:41
576 訂正 s/471/479/
>>576 規格に従うつもりがあるなら、 void main() がダメなのぐらい素直に認めとけよ。
俺は >479 はまっとうな指摘だと思うけどね。
あんたがさんざん噛み付いてる main の話も、おまけでつけてるだけだし。
持論展開したいなら。 スレ立てして、最初に自分がどういう認識なのか全て書け。 気が向いた奴が相手してくれるだろ。
580 :
デフォルトの名無しさん :2006/05/14(日) 06:24:24
>>578 盲従はしないってだけさ
従う/従わないの2値的な考えしてる者には通じなさそうだが
ところで main に噛みついてるのは俺じゃないぜ
くだらねえつってるだけだ
581 :
デフォルトの名無しさん :2006/05/14(日) 06:26:17
>>575 C++ についてロクな回答できない奴よりまし
なんだい、あのコードに対してヘッダに main て・・・
582 :
デフォルトの名無しさん :2006/05/14(日) 06:32:30
OOP でございと言いながら main に固執してる奴ほど大事らしいけどな
>>477 参照好きの漏れが修正するとこうなる。こういう関数にはもっといいパターンがあるけど、そこは気にしない方向で。
#include <iostream>
struct KATA { int ab, cd; };
int MyFunction(int x, KATA*& y) {
y = new KATA[x];
if (!y) return 1;
for (int i = 0; i < x; ++i) {
y[i].ab = 2;
y[i].cd = 3;
}
return 0;
}
int main() {
using namespace std;
KATA* y = 0;
cout << "MyFunctionの戻り値 = " << MyFunction(2, y) << endl;
for (int i = 0; i < 2; ++i) {
cout << "y[" << i << "].ab = " << y[i].ab << endl;
cout << "y[" << i << "].cd = " << y[i].cd << endl << endl;
}
delete[] y;
return 0;
}
>>583 new の戻り値をヌルチェックしても意味無いよ。
おっと、しまった。議論を呼ぶことをしてしまった。 > KATA* y = 0; としていながら参照で渡しているのは酷かったな。MyFunction()のあたりに次のコメントを追記: // 引数 KATA* への参照は、null ポインタを指している可能性がある。右辺値としてアクセスする前に、必ず代入を行うこと
>>585 そんな些細なこと気にするぐらいだったら、「もっといいパターン」に書きかえるよな。
bad_alloc投げてくれるんだっけ。 あー寝起きはだめすぎるなー。つっこみどころ多すぎる...orz もう一眠りしてくる
もう二度と起きるなw
589 :
デフォルトの名無しさん :2006/05/14(日) 08:41:42
void mainは、 ・CはC99から適合、 ・C++はC++03でも駄目 ってことを知らない人がスレを混乱させてるな。
混乱?してないだろ?
>551 template<class T> class SuperClass{ voif foo() { static_cast<T>(this)->submethod() }; class SubClass : public SuperClass<SubClass>{}; だな。俺は
初心者のvoid main()にいちいち噛み付いて age厨と100レス近く論争するのを規格を遵守するって言うんですか
何でこんなに伸びてるんだよ
厨房は沸点が低いから
CreateInstance関数ってWIN32APIなんですか? それともCOMでしか使えない関数なんですか?
CoCreateInstanceは、COMヘルパーなWIN32API。 IClassFactory::CreateInstanceはCOMのメソッド
>>596 少なくともC++言語に関する話題ではないな
あの、そのあのそのごごめんなさい
600 :
デフォルトの名無しさん :2006/05/14(日) 21:10:38
C++でEJBみたいなことがやりたいんですけど、そういったツールはありますか?
低級の質問です(・ω・` 半径を入力すると円の面積と円周を出すプログラムを作りたいんですが \include<iostream> using namespace std; double main() {const double pi = 3.14; double hankei; cout << "円の面積と演習を求めます。" <<'\n'; cout <<"半径を入力してください: cin >> hankei; cout << "円の面積は" << hankei*hankei*pi << "です。" <<'\n'; cout << "演習は << 2*pi*hankei << "です。" ; <<'\n'; return 0; } このようにしたら エスケープシーケンスの使い方が正しくありません ';' が '<' の前にありません。 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 'cout' : 定義されていない識別子です。 定数が 2 行目に続いています。 ';' が、識別子 'cin' の前に必要です。 '0x3000': この文字を識別子で使用することはできません というエラーが出ました。「:」が「<」の前にないだのと良く分からないのですが何が問題なのでしょうか?
とりあえず色々間違っているのはわかるが コピペミスなのかもしれない \include double main "半径を入力してください:
\include<iostream> double main() cout <<"半径を入力してください: cout << "演習は << 2*pi*hankei << "です。" ; <<'\n'; ここまでバカなんだったらムリしてプログラムなんてするなよ
#include<iostream> using namespace std; int main() { const double pi = 3.14; double hankei; cout << "円の面積と演習を求めます。\n"; cout << "半径を入力してください:\n"; cin >> hankei; cout << "円の面積は" << hankei*hankei*pi << "です。\n"; cout << "演習は" << 2*pi*hankei << "です。\n"; return 0; } これでも駄目なんですが何がいけないんでしょう?
それだとどう駄目なの? エラーが変わってないなら変わってないと、 変わったなら新たなエラーの内容くらい書けよ・・・回答者に言語以外の頭を回させるな。
>>604 > cout << "半径を入力してください:\n";
> cout << "円の面積は" << hankei*hankei*pi << "です。\n";
全角スペースになってるぞ
>>604 そのソースをプリントアウトしたものを見ながら
新しい main.cpp ファイルに打ち直してみましょう。
それでコンパイルできたら、なぜコンパイルできるようになったのか考えながら首吊りませう
そもそもs/演習/円周/だと思うのだが。
>>610 どうでもいいが
初心者で検索すると将棋スレになってワロタwww
C++はvoid *禁止ですよね? そうすると型を無視したポインタの配列確保するときはどうすればいいのでしょうか? Intやcharや他の構造体がいっぱい入ってくる場合どのように書けばいいのでしょうか
>>613 別に禁止じゃないが。推奨すべき理由もないが、それが最良と判断したのなら躊躇わずに使えばいい。
>>613 べつに禁止されてないので型を無視したいのなら使えばいいっしょ
型を無視せずにいろんな型を突っ込むなら
RTTIでdynamic_cast使ったりとか仮想関数とか適当に
グローバルな new のオーバーロードをしていて、 処理の中では malloc でメモリ確保しているのですが どうやれば new と同じようにコンストラクタを呼び出せるのでしょうか?
>>613 プログラマにリスキーな手段を採る裁量を認めているのがC++の思想。
>>616 placement newすればいいんでね
>>616 確か勝手によばれるだろ?
明示的に呼び出したい場合は
char hoge[sizeof(hoge_type)];
new (hoge) hoge_type();
こんな感じで呼び出せる。
>616 オーバーロードできるのはoperator newであって、newはそもそもオーバーロードできない。
そうですかどうもありがとうございました。 Cのインターフェイスがvoid **になっていて果てさて どうしたものかと悩んでしまいました。教えていただきありがとうございました。
>>616 D&Eを嫁…といいたいとこだが、
Hoge *h = new Hoge();
というコードが実行される際の動作は、
1.sizeof(Hoge)のメモリがoperator newによって確保される
2.Hogeのコンストラクタが実行される
operator newはあくまでメモリを確保する役割しか持ってない。
あとは
>>619-620
void foo(){ static int a=0; a++; if(a==5)return; foo(); } みたいなコードを書いたとき、aは再帰で呼び出すたびに0になるの?それとも一番呼び出し元の最初だけ?
即レスサンクス やっと謎がとけた
virtualなメンバー関数は非仮想関数でオーバーロード禁止なのでしょうか? class B { public: virtual void F(); }; class D :public B { virtual void F();//これではなく、 void F( int );//このようなもの。 }
いえ〜い
630 :
627 :2006/05/15(月) 18:43:13
C++標準的コーディング技法って本を読んで、 そこに 「オーバーロードを悪いコードとして目立たせている理由に、1つは仮想関数をオーバーロードすることが望ましくないこと」 と書いてあったので気になったのですが・・
禁止ではあるが、望ましくはない。 それだけの話。
間違えた。 禁止ではないが、望ましくはない。 だ。
紛らわしいから止めとけ、ってだけのはなし
ぁぁ。別に禁じ手ってわけじゃないんですね。安心しました
禁じ手・・・かもしれないな。
個人でプログラム書いてて、絶対に他人が見ないならいいけど 他人と共有するときにそんなコード書いたら、「ああ、この程度か」って思われると思うよ。 少なくともEffectiveC++は読んでないなと。
effectiveC++に仮想関数はオーバーロードするなってありましたっけ?
連続すいません。
こんな安易な発想で実際にクラス書かないですけど、
>>627 のを
class D :public B
{
virtual void F();
virtual void F( int );
};
なら別に紛らわしくない?
横からすいません、 なぜ仮想関数をオーバーロードしてはいけないのか なぜオーバーロードさせたくない関数にvirtualを付けるのか 解説または、そのような記述のあるサイトがありましたら 教えて頂けるとうれしいです。
片方は B からの仮想関数で、 もう片方は D からの(仮想)関数となると、 紛らわしい。 まあそんだけ。
>>637 第38項「継承したデフォルトパラメータを再定義してはならない」というのならあるね。
それはちょっと違うなぁ。
>>637 Effective3版の33項(2版だと9項?)には、
「基底クラスのオーバーロードした関数が隠蔽される」って話があるけど、
するなとは書いてないから違うかな?
個人的にはとてもわかりにくい仕様だと思った。
>627 C++ STANDARDにこんなのあった。 10.3.3 [Note: a virtual member function does not have to be visible to be overridden, for example, struct B { virtual void f(); }; struct D : B { void f(int); }; struct D2 : D { void f(); }; the function f(int) in class D hides the virtual function f() in its base class B; D::f(int) is not a virtual function. However, f() declared in class D2 has the same name and the same parameter list as B::f(), and therefore is a virtual function that overrides the function B::f() even though B::f() is not visible in class D2. ] 可視性の観点からややこしいことになるみたいね。
>>639 オーバーロードとオーバーライドがごっちゃになってるだろ。
ごっちゃにでもなってなけりゃ、これの意味がわからない。 > なぜオーバーロードさせたくない関数にvirtualを付けるのか
>>639 仮想関数は関係ない。これは継承を挟んだオーバライドの問題。
親クラス(またそれ以上の先祖クラス)のメンバ関数と偶然名前が衝突した時、
子クラスのメンバ関数を呼んだつもりが、親クラスのメンバ関数を呼んでいた
なんてことになるを避ける為、継承を挟んだオーバーロードは親クラスのメンバを
隠蔽する決まりになってる。親クラスのメンバを隠蔽させたくない時は using を
使って隠蔽させたくない親クラスのメンバを指定する。
>>650 一行目の「オーバーライド」は「オーバーロード」の間違い?
652 :
650 :2006/05/16(火) 07:21:53
usingでベースクラスのをインポートすればOKじゃない?
普通に
>>627 みたいなこと俺やってるけど・・・
ていうかもう9時だorz
C++で書かれたオープンソースソフトウェアで有名なのって どんなのがありますか? 特にFirefoxとApacheはC++ですか?
自分でみてみりゃいいじゃん
Apacheは主にC FirefoxはC++
658 :
654 :2006/05/18(木) 00:45:12
>>658 いちばんまっとうな 655 には礼もなしか。
ワラタ
//Foo.hpp class Foo { public : //テンプレートなメンバ関数 //これはヘッダで定義 template <typename T> void f() { std::cout << typeid(T).name() << std::endl ; } //普通のメンバ関数 //これはヘッダ以外の別の場所(Foo.cpp)で定義 void g() ; } ; //Foo.cpp void Foo::g() { std::cout << "Foo::g()" << std::endl ; } //main.cpp int main() { Foo foo ; foo.g() ; foo.f(0) ; foo.f(0.1) ; } インスタンス化に必要な部分だけは、main.cppから見えているので、ちゃんとコンパイル&リンクができるのですが、 やはりこういう書き方はやめたほうがいいのでしょうか。 export ほすぃ……
>>662 inline にしたいのでなければ、とりあえずクラス外に移したほうがいいだろうな。
いつか export がサポートされるのを夢見て、 template の定義を別ファイルにわけて
// Foo.hpp の最後に
#ifndef COMPILER_SUPPOTS_EXPORT_KEYWORD
#define export /* removed */
#include "Foo_template.cpp"
#undef export
#endif
// Foo.cpp に
#if COMPILER_SUPPOTS_EXPORT_KEYWORD
#include "Foo_template.cpp"
#endif
とかいう話は聞いたことがある。メンドクサイ上にメリットの期待値が極小。
質問です。 namespace MyClass { class Exception{ Exception( Exception &E ); }; } というクラスを作っていたんですが、Exception( Exception &E )をException( const &E )に変えたところ、 throw Exception( "〜〜〜" ); と例外を出してるクラスほとんど(全部ではない)から Exception( class Exception &E )は未解決〜とエラーが出てしまいました。 ( Exception( Exception &E )と宣言してたときにはエラーは出てない ) で、そのエラーが出たクラス内に using namespace MyClass; と書き加えたところでなくなりました。 namespace MyClass { //ここにusing namespace MyClass;と付け加えたら出なくなった。←MyClass内なのに。 void Func(){ throw Exception( "〜〜〜" ); } } で、さらにその後、追加したusing namespace MyClass;を削除してリビルドすると、 未解決エラーが出なくなりました。 今は正常にリンクできるのですが、後味が悪いので質問させていただきました これはなぜなんでしょうか?
オブジェクトファイルの更新がうまくいってなかったんじゃまいか? 例えばそのヘッダをA.cpp, B.cpp, C.cppから参照していたとして、 constに書き換えた時、何らかの理由でA.cppのみ再コンパイルされてしまったとか。 そうすると、Aのオブジェクトはconstを引数に取るコンストラクタを参照しようとするけれど、 B,Cのオブジェクトファイルは今まで通りconstのないコンストラクタを参照しようとして、未解決エラー。 で、エラーが出たクラスに変更を加えたことで、B,Cのオブジェクトファイルも更新され、正常にリンクされるようになる。 (加えた修正には意味がなく、修正を加えたことで更新されたのが解決の原因) VC++のようなIDEを使っていればまず起きえない問題だけど、 もしMakefileでコンパイルを制御しているなら、各オブジェクトがヘッダの更新に対応しているかどうか 依存関係の記述を見直してみるといいかと。
666 :
655 :2006/05/18(木) 08:41:45
ところでBjarneはカタカナ表記だとビョーンでいいのかな?
ビョーン・ソレ・シランカットッテンチントンシャン
670 :
664 :2006/05/18(木) 18:28:56
>>665 返信ありがとうございます。
実はVC++使ってます(汗・・・
やっと正解が出たか
某氏がブジャーナ ストラウストラップって書いてたから 影響されて俺もそういってるけど、検索しても全然でてこねえな
とっさに発音できないからハゲでいいや。
とっさに発音することなんてあるのかよ
道ばたで出くわした時 「やあ、禿」なんて言うわけにいかないだろ
やあ、禿、C++0xにevalを導入する件、よろしく頼むよ。
や、友達にC++のことを話すとき 「ビャールネ・ストロヴストルップ氏が〜〜って書いてた。」 って言うよりは、 「ハゲが〜って書いてた。」 って言うほうが早いなと。
>>680 あんまりそんな事言ってると自分が偉くなって氏に直接会う機会とかで「ハゲ」って言いかねないからなぁ。
習慣って怖いし、「ハゲ」とか言ってると上司ににらまれたりもするし(w
>>681 前者 → ないないw
後者 → …もの凄い気まずかったが、何か?
STLに的を絞って勉強しようと本を探しているのですが、何かおすすめはないでしょうか できれば、必要な知識の解説&リファレンスが3:7ぐらいの割合で入っているものが欲しいです
>>683 解説:EffectiveSTL
リファレンス:>684のサイト
詳細情報:適当な実装
STLPortがいいんじゃね
WinXPでコンパイラはVisual C++ 4.0を使っているのですが #include <iostream> int main() { std::cout << "wake waka ran"; } をコンパイルするとエラーがでます。 1.インクルードファイルがオープンできないといわれるから, <iostream.h>にすると 2.戻り値が指定されていないといわれる。 だから return 0;をつける。 けれど 3.std識別子がクラス名ではないときます・・ なにが原因なのでしょうか
きついのが来たな...
>>688 <iostream>と<iostream.h>の違いはstd名前空間に入っているかいないか
(iostream.hはとっくにdeprecatedだけれど)
だからiostream.hにするならstd::をつける必要はない
というかVC4.0を使うぐらいならVC2005EEにした方が数百倍マシな気がするが…
std::をけして<iostream.h>にしたら問題なくコンパイルできました。 コンパイラですが,VC2005EEは使ったけれど使いにくかった(使い慣れていない)ので,アンインストしましたが, そうならもう一度入れてVC2005EEを使用することにします。 ありがとうございました。
692 :
デフォルトの名無しさん :2006/05/20(土) 19:54:06
しかもその事実上の標準にも適合してないし。
VC2005はなんか使いにくいというか、重くて、UIの色使い(?)に 抵抗感があるよね・・・ 一生VC2003と付き合っていくことになりそうだ
>>694 俺もVC2003から乗り換えた当初は「なんだこの分かりづらくてケバい色遣いは」と思ったが
しばらく使ってると慣れて、むしろ見やすく感じるようになった。
住めば都とはこのことか。
コンパイラだけ入れ替えてくれ。
2003も2005も、キーボードだけでクラスの頭出しが出来ないから 一生VC6と付き合っていくことに……なるのは嫌だな。なんで退化するのよ。
何を言ってるかわからんがインテリセンス? まぁいずれにせよスレ違いということで
いやインテリセンスじゃなくて、そこに飛ぶの。もの凄い便利よ。良く皆あれ無しでやっていけるなと思う。まぁスレ違いか。
>>699 右クリック→Go to definition じゃダメなの?
右クリックはコンテキストメニューキー、Go to definitionはGキーで代用できるから、
実質2回キーを押すだけで飛べるんだが、それじゃ不満なのかね。
別にマクロ組んでショートカット割り当てても同じだと思うが…
というかスレ違いだな、うん。
>>700 レスしてーw
違う、違うんだ!でもスレ違いだw
VC++2005にはマクロ機能が無い!!!。これ最悪。 スレ違いでごめん。
704 :
デフォルトの名無しさん :2006/05/21(日) 00:44:20
オーバーロードに関して質問です。 void f(int) {} void f(float) {} template<class T> void g(T) {} g(f); // 曖昧 これを g(なんとか); の呼び出しで解決する方法はありますか?
>>704 g(f<int>);とg(f<float>);でできたような。違ったらすまん。
>>705 f()はテンプレート関数じゃないように見えるんだが……。
どうやるんだろう。
708 :
705 :2006/05/21(日) 00:49:12
>>706 これはおおぼけをかましてしまった。
_| ̄|○
709 :
デフォルトの名無しさん :2006/05/21(日) 00:52:25
>>707 通りました。
一応確認ですが
g(static_cast<void (*)(float)>(f));
でvoid f(int); が void f(float)にキャストされてしまう心配は無いですか?
>>709 そんな無茶な変換をstatic_castが通すわけがない。
711 :
デフォルトの名無しさん :2006/05/21(日) 00:56:24
>g(f); // 曖昧 曖昧なのは本当はコンパイラのチェックのタイミングで PG の設計じゃないのにな
>>704 g<void (int)>(f);なんかはだめ?
static_castよりも少ない文字数だよ。
713 :
デフォルトの名無しさん :2006/05/21(日) 01:04:13
>>710 ありがとう御座います。
密かに
void (*p)(float) = f;
g(p);
しか無いのかなと思っておりました。
>>711 趣味でやっているもんでして
>>712 上の例はかなり簡略した例でして
実際のはfor_eachに渡すんで第二引数になってしまうんですよね。
第一引数を指定するのも面倒なんで
>>707 の方法で逝きます。
ありがとうございました
しかし、オーバーロードの利点がなくなりそうなコードだが……。
715 :
デフォルトの名無しさん :2006/05/21(日) 01:11:29
>>714 確かにそうなんですが destroy_int とか destroy_float ってやるのもどうかと思いまして。。。
当然中身はただ delete オペレータ読んでるだけじゃないっす。float 以外の型も増えそうな感じなんで。
テンプレートで出来ないのかと思ってやってみたけど、無理なのか……。 古き良きマクロでも使うしかないのかねぇ……。 template <typename T> void (T) make_f() { return static_cast< void (T)>(f) ; } template <typename T> void (*)(T) make_f() { return static_cast< void (*)(T)>(&f) ; } template <typename T> struct make_f { typedef ????……無理か…… }
具体的な用途は知らんけど、こんな感じにしたら? #include<iostream> using namespace std; template<typename T> struct g_impl; template<> struct g_impl<int> {static int do_it(){cout << "int" << endl;} }; template<> struct g_impl<float> {static int do_it(){cout << "float" << endl;}}; template<class T> void g(T) {g_impl<T>::do_it();} int main() { g(5); g(5.5f); }
>>717 for_eachに渡したいといっているんだから、
関数オブジェクトにすべきでは?
既に g(なんとか); の呼び出しで解決してないのでありますが…
汎用関数に,オーバーロードされた関数へのコールバックを 明示的なキャストなしで引き渡したい場合,確かに (operator()がオーバーロード/テンプレート化された)関数オブジェクトにするしか 方法がないとは思いますけれど,そうすると今度は関数オブジェクトを わざわざ作る手間とのトレードオフになってしまうんですよね.
template <typename T> struct destroy ; template <> struct destroy<int> { void operator () (int *p){ delete p ; } } ; template <> struct destroy<float> { void operator () (float *p){ delete p ; } } ; int main() { int * ptr_array[32] ; // for (int i = 0; i != 32 ; ++i) ptr_array[i] = new int ; std::for_each( &ptr_array[0], &ptr_array[32], destroy<int>() ) ; } そんなに手間かな? むしろ関数オブジェクトのほうが使いやすいと思うのだが。
722 :
721 :2006/05/21(日) 01:49:39
じつは特殊化を使う必要もなかったり……
C++の厄介なところはあれでも出来るこれでも出来るって所に有りまして・・・ 趣味でやってると時間の制限が無い分、あれこれ試してるだけで1日終わったり…。 今はなるべく、行数が少ない方が良いと思ってプログラムしております。 変更するのに時間掛からないんで。 どうでもいいですよね
>>721 >>722 関数オブジェクトクラスに型パラメータを持たせずに
済ませることすらできるようになりますね.
struct destroy{
template< class T > operator()( T *p ){ delete p; }
};
ただ for_each のような例なら関数呼び出し構文の戻り値の型を
全く必要としないのでその手間で済むんですが,一般には汎用関数内で
戻り値の型を必要とする場合がしばしばあるので,
そうすると戻り値の型計算をちゃんと書かないといけなくなるので.
(いわゆる Polymorphic Function Object)
725 :
721 :2006/05/21(日) 01:56:22
template <typename T> struct destroy
{
void operator() (T *p) { delete p ; }
} ;
オーバーヘッドが気にならないんだったら、
boostのsmart_ptrあたりをコンテナに放り込んだほうが楽そう。
>>723 禿曰く、「マルチパラダイム」らしいけど。
726 :
721 :2006/05/21(日) 01:57:49
>>724 それは思いつかなかった。
自分はまだ未熟かOrz
うは、トラックバックしてぇ
Effective STLに載っていたような気がする。
>>704 ,. -‐'''''""¨¨¨ヽ
(.___,,,... -ァァフ| あ…ありのまま 今 起こった事を話すぜ!
|i i| }! }} //|
|l、{ j} /,,ィ//| 『関数ポインタを返す関数をコンパイラに読ませたと
i|:!ヾ、_ノ/ u {:}//ヘ 思ったらいつのまにか自分では読めないコードがそこにあった』
|リ u' } ,ノ _,!V,ハ |
/´fト、_{ル{,ィ'eラ , タ人 な… 何を言ってるのか わからねーと思うが
/' ヾ|宀| {´,)⌒`/ |<ヽトiゝ おれも何をしたのかわからなかった…
,゙ / )ヽ iLレ u' | | ヾlトハ〉
|/_/ ハ !ニ⊇ '/:} V:::::ヽ 頭がどうにかなりそうだった…
// 二二二7'T'' /u' __ /:::::::/`ヽ
/'´r -―一ァ‐゙T´ '"´ /::::/-‐ \ 催眠術だとか超スピードだとか
/ // 广¨´ /' /:::::/´ ̄`ヽ ⌒ヽ そんなチャチなもんじゃあ 断じてねえ
ノ ' / ノ:::::`ー-、___/:::::// ヽ }
_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::... イ もっと恐ろしいものの片鱗を味わったぜ…
template<typename T>
inline void (*select_f())(T) { return f; }
g(select_f<int>());
730 :
デフォルトの名無しさん :2006/05/21(日) 06:06:45
>>724 をそのまま使うのだったらboost::checked_deleteを使えば良いと思う。
>>729 こういう風に調べたのだろうか……。
//関数ポインタ
typedef void (*ptr_type)(int) ;
//関数ポインタを返す関数
ptr_type foo() ;
//人間の読める文字列を得る。
std::cout << typeid(foo).name() << std::endl ;
//VC7.1だと、void (__cdecl*__cdecl(void))(int)
これを元にテンプレート関数へ
template <typename T>
inline
void ( *make_f(void) ) (T) { retuirn f ; }
将来、絶対に書きたくないし読みたくもないコードだ……。
733 :
デフォルトの名無しさん :2006/05/21(日) 18:24:15
>>732 ふつーに K&R でも読めばどうとでも・・・
K&R吹いた
>>735 あれを typedef 使って書き直そうとすると、 template のせいで意外と大変な罠。
脊髄反射してしまった。スマン。
738 :
デフォルトの名無しさん :2006/05/21(日) 20:58:36
>>734 関数ポインタを返す関数について K&R と C++ の相違を述べよ
K&R C との比較か?
>>738 違いはない。一人吹いたぐらいで突っかかるな。
741 :
デフォルトの名無しさん :2006/05/21(日) 21:57:51
「違い」 と、わざと曖昧な聞き方をしてみたが 返ってきたのは 739 程度
変な煽りあいは他所でやってくれ。
743 :
デフォルトの名無しさん :2006/05/21(日) 22:00:51
じゃ、おまえは二度と煽るなよ
744 :
デフォルトの名無しさん :2006/05/21(日) 22:39:11
はあ?何でだよwww意味不明すぎww 論理的思考のできない平成生まれが脊椎反射でレスてんじゃねーよwwww
745 :
デフォルトの名無しさん :2006/05/21(日) 22:50:07
脊髄による反射でレスできるならしてみろドアホ
カックン
カックン
>>738 C++にしかないtemplateと併用する場合typedefを使うとかえって面倒なため(>736)、
>729のような複雑な宣言を強いられるが、
Cであればtypedefですっきりした宣言にできる。
あんたはCでもtypedefせずに>729みたいに書いてるのか?
つかまさかK&Rに>729みたいな書き方を読めるようになりなさいって書いてあるんだろうか
749 :
デフォルトの名無しさん :2006/05/21(日) 23:08:39
>あんたはCでもtypedefせずに>729みたいに書いてるのか? まあ、そうだね 職場でもスタイルについては頻繁に議論するけど これに不満を訴える人はいないし
他所でやってもらえませんでしょうか?
>>749 後半はまったく意味を成していない件について
こんなことはできない? template<typename T> type { typedef T type; }; template<typename T> inline type<void (*)(T)>::type select_f {return f;}
>>752 できるだろうな。そのままじゃコンパイルできないけど。
struct つければいいだけか。いいね。
うんにゃ typename も要る
ああ、そうか。そうだな。
template <typename T> struct identity { typedef T type ; } ; template <typename T> inline identity<void (*)(T)>::typename type select_f() { return f ; } VC7.1ではコンパイルが通らない。 何かおかしいのかな。
typename identity<void (*)(T)>::type select_f() だろ? VC7.1で試してはいないが。
759 :
757 :2006/05/22(月) 02:04:37
そうだったOrz
760 :
757 :2006/05/22(月) 02:07:32
template <typename T> struct make_type { typedef void (*type)(T) ; } ; template <typename T> inline typename make_type<T>::type make_f() { return &f ; } こうしたほうがわかりやすいかな。
>>760 return &f;←このfはどこから?
763 :
デフォルトの名無しさん :2006/05/22(月) 06:21:18
>>750 ここで喧嘩売るあんたこそ一番の荒らしだよ
売ってもいない喧嘩を売ってると言い張るパターンは、 あらゆる難癖の中でも「自分がキレイなつもりでいる」分悪質だな。
765 :
デフォルトの名無しさん :2006/05/22(月) 06:26:44
と、メール欄で罵倒しておいて喧嘩売るつもりじゃなかったと言い張る腑抜けが申しております
766 :
デフォルトの名無しさん :2006/05/22(月) 06:27:12
そんなにここで暴れたいか
template<class T> void f(T); template<>void f<int>(int){....} template<>void f<float>(float){...}
>>765 ほら、喧嘩したいのは他ならぬ自分なのが丸わかり。
整合性が2ターン保たない人ってたまにいるんだよね :-)
>>704 の場合、f は g に対する visitor なので、
そのまま visitor として実装すればいいだけだろうと思うが。
function_traits でいちいち型を調べる必要も無い。
// STL のアルゴリズムに渡すためには、
// result_type を定義しないといけないので、
// とりあえず static_visitor から派生させておく
struct fx : public ::boost::static_visitor<void> {
template< typename T > void operator()( T val ) const {
// すでにある関数 f の呼び出し
f( val );
}
};
g(fx());
772 :
デフォルトの名無しさん :2006/05/22(月) 20:54:20
>>768 あんたが煽る限りいくらでもやり返すぜ
最後まで何か言う気なら結果は1つだ
std::auto_ptr<ChanStatus> TChanStatusPtr; この様に宣言されているスマートポインタをノーマルポインタに宣言し直すにはどうのようにすればいいのでしょうか?
ChanStatus *TChanStatusPtr; じゃないの?
>>774 即レス感謝です。ありがとうございました
>>772 ほんとに血の気が多いね。頭が悪いのに。
あ、ズバリ書くとまた煽られちゃうかもー(コワイコワイ
本当に他所でやってくれよ 質問しづらいだろ
778 :
デフォルトの名無しさん :2006/05/24(水) 00:29:06
ある本のC++のサンプルを見ていたら、 { if(なんちゃら) if(なんちゃら) if(なんちゃら) } ってあったんだけど、 { } ↑これなに? カッコだけでくくると何か特別な意味あるのかな? ただ、見やすくするため?
>>778 それだけ見るとあんまり意味は無い。
変数の定義があれば、スコープがひとつできることになる。
変数なくてもスコープになるんじゃないの? 意味ないのは変わりないと思うけど。
変数なくてスコープという意味が分からん。
782 :
779 :2006/05/24(水) 01:05:49
>>780 あーそうだな。書き直そう。
- 変数の定義があれば、スコープがひとつできることになる。
+ スコープがひとつできるので、変数の定義があれば何か意味があるかも。
スコープとは変数に対して使うもんだと思っていた ブロックの事を言っている?
784 :
782 :2006/05/24(水) 01:16:31
785 :
779 :2006/05/24(水) 01:30:04
>>783 などをふまえて、さらに書き直そう。
- 変数の定義があれば、スコープがひとつできることになる。
+ ブロックができるので、変数などの宣言があればそこでスコープが切れることになる。
786 :
デフォルトの名無しさん :2006/05/24(水) 01:46:04
中で何も変数は宣言していない。 ただ if(ほにゃらら) return FALSE; が3列ならんでるだけですね。 見やすくするだけなのか?あまり意味はなさそうですね。
while() { } とかだったりしてな。
説明のために一部分切り出したとか、誤植で1行目だけ飛んでるとかもありそう。 正直、778のレス内容だけでは何とも言いがたい。
{ if(なんちゃら) { T x = XXX; … if(なんちゃら) if(なんちゃら) } ってのがあれば、デストラクタ呼び出しが}で行われる。Cとの違い。
>>789 その例だと外側のBracesは要らない。
無い知恵絞った積もりなのだろうけど、その点に関してはCと違わない。
そんな深い理由じゃなくて、
>>787 の言うとおり、
if( どーたら )
{
if(なんちゃら)
...
}
とあったのが、何らかの理由で「if( どーたら )」
だけ削ったんじゃねーの?
>>790 >無い知恵絞った積もりなのだろうけど
やめろってば
>>789 > {
> if(なんちゃら) T x = XXX;
だとどうなの?
>>793 Cだと(C99でも)エラー。
C++だとスコープがif () の後の一文に限定される。
#だったと思う。
for (int i = 0; i < N; i++) { … } のiのscopeは結局どうなったの? if (i == N) { // not found はまずい仕様になった?
for (int i = 0; i < N; i++) { //iはここで使える。 } //VC6のような腐ったコンパイラだと、何故かここで使える。
VC6を叩いて優越感にひたる奴が急に増えたな 時代背景も知らずに
>>797 知ってても今となっては(今さら使うなら)腐ってるといえる
でもまあ今VC6を使ってるとかいう話なわけでもないのに
唐突にVC6のことを書くのは余分だな
VCとしては7以降でちゃんとその後の規格に合わせて対応してるし
>>795 規格としては
>>796 でいうVC6で採用されていたスコープルールとは
異なるものが採用された
class A { bool F(){ delete this; retrun true; } }; -- A *a = new A; a->F(); これあり?
標準ライブラリでもfacetとか、標準から離れればIUnknownの実装なんかで、 delete this;は当たり前のように使われている。
boost::intrusive_ptrなんか、我々がその辺を自前で用意するもんな。
tr1::shared_ptrには削除子があるのに、何故auto_ptrにはそれがないのでしょうか?
806 :
デフォルトの名無しさん :2006/05/25(木) 13:32:22
type_info::operator = type_info::before による型チェックを行ってるのですが、何故か照合できない型があります。 そして、別の型名なのに true になってしまう事もあります。 type_info による型チェックは信頼性が低いのでしょうか?
>>806 問題を再現する最低限のソースを貼ってみましょ
808 :
デフォルトの名無しさん :2006/05/25(木) 14:19:11
class FixObj : public Obj { contents... }; class Block : public FixObj { contents... }; class Step : public FixObj { contents... }; こういうクラス構造で・・・ bool test (const type_info& TYPE, Obj* OBJ) { return typeid(OBJ) == TYPE || typeid(OBJ).before(TYPE); } こういう型判定メソッドがあり・・・ Obj* obj = new Block; test(typeid(Block*), obj); こうしても結果がfalseになってしまいます。 しかし、dynamic_cast<Block*>(obj)では、NULLになりません。 何故なんでしょうか? ただ、Stepインスタンスはちゃんと照合できるのです。 環境はVisualC++です。何故なんでしょうか? type_info による型照合は信頼性が低いのでしょうか?
Objに仮想関数ないだろ
ポインタ渡しによるスライシングが起きている。 参照渡しにすれば問題なし。
811 :
デフォルトの名無しさん :2006/05/25(木) 15:18:36
>>810 おお、どうもです。しかし・・・・
bool test (const type_info& TYPE, Obj& OBJ) {
return typeid(OBJ) == TYPE || typeid(OBJ).before(TYPE);
}
として、参照渡しにして
Obj* obj = new Block;
test(typeid(Block), *obj);
としたら、照合はされたのですが、今度は
typeid(Step)でもtrueになってしまいます・・・・
しかも、ポインタ型だとどんなものでもtypeid(string*)でも、trueに
なってしまうのです・・・・
内部で勝手に、何かが共有(スライシング)されてるのでしょうか?
もうイライラして死にそうです・・・
>>811 うちはちゃんと動いてるようだけどなぁ
$ cat test.cpp && c++ -o test test.cpp && ./test
#include <iostream>
using namespace std;
struct Obj {virtual ~Obj () {}};
class FixObj : public Obj {};
class Block : public FixObj {};
class Step : public FixObj {};
bool test (const type_info& TYPE, const Obj& OBJ) {
// return typeid(OBJ) == TYPE || typeid(OBJ).before(TYPE);
return typeid(OBJ) == TYPE;
}
int main () {
{
Obj* obj = new Block;
cout << test(typeid(Block), *obj);
cout << test(typeid(Step), *obj);
}
{
Obj* obj = new Step;
cout << test(typeid(Block), *obj);
cout << test(typeid(Step), *obj);
}
cout << endl;
return 0;
}
1001
>>812 すみません。説明不足でした・・・・
実際のプログラム中では、「Obj*」データはコレクションクラスに格納されており、
Objを仮想基本クラスにした様々なインターフェースを、それぞれが実装してるのです。
その格納庫の中から任意のインターフェースを実装してるObj*データを
随時取り出して処理を行わせる流れにしてるのですが、そのインターフェースの
型チェックで上記のtest関数が上手くいかないのです・・・・
コレクションから取り出したObj*は、dynamic_castだと正確に照合できますが
typidチェックだと照合できなかったり、他の型でもtrueになったりしてしまうのです・・・
もうどうすればいいのか・・・
>>813 testに渡す前とtestの中で
type_info::nameを見てみれば?
815 :
デフォルトの名無しさん :2006/05/25(木) 17:04:15
>>814 それが「class Block」となってるんです・・・・
しかし、そのObj*データは、ポインタ型だとどんなものであっても
typeid(obj) == typeid(string*) || typeid(obj).before(typeid(string*))
これで true になってしまうのです・・・・
/GRオプションは?
817 :
デフォルトの名無しさん :2006/05/25(木) 17:26:19
画面上にある図形を与えられた座標を中心に円運動させるにはどうしたらいいのか どなたか知恵をかしてください。 ヒントは"三角関数をつかう"なんですけど... 式の立て方がわからないです
818 :
デフォルトの名無しさん :2006/05/25(木) 17:29:21
/GRはつけてます・・・・ まとめると Obj* pobj; として、それにBlockインスタンスを代入して typeid(pobj)だと、その「Block*」との照合が false となり、 typeid(*pobj)だと、「Block」だけなく同じ仮想基本クラスを持つ型(Step)と、 更に全ポインタ型(string*)との照合でも true になってしまうのです・・・ 何がなんだか・・・orz
>>817 座標(cx, cy)を半径rで回るとすると
int i = 0;
while (true) {
i = (i + 1) % 360;
double rad = (double) i * 3,14 / 180;
double x = cos(rad) * r;
double y = sin(rad) * r;
drawImage(cx + x, cy + y);
}
>>818 これの出力をコピペしてみて(文章による報告じゃなくて)
#include <iostream>
using namespace std;
struct Obj {virtual ~Obj () {}};
class FixObj : public Obj {};
class Block : public FixObj {};
class Step : public FixObj {};
bool test (const type_info& TYPE, const Obj& OBJ) {
cout << typeid(OBJ).name () << ' ' << TYPE.name ()
<< ' ' << typeid (string *).name ()
<< ' ' << typeid (int *).name () << endl;
return typeid(OBJ) == TYPE;
}
int main () {
Obj* obj = new Block;
cout << typeid (*obj).name () << endl;
cout << typeid (Obj).name () << ' ' << typeid (Block).name ()
<< ' ' << typeid (Step).name () << endl;
cout << test(typeid(Block), *obj) << endl;
cout << test(typeid(Step), *obj) << endl;
return 0;
}
>>819 アドバイスありがとうございますY(>_<、)Y
今からさっそく実行してみます!!
>>813 dynamic_castが使えるならdynamic_castでいいだろ。
>>820 わざわざどうもです。
class Block
struct Obj class Block class Step
class Block class Block class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * int *
1
class Block class Step class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * int *
0
結果は正確なのですが、上でも述べましたが
Obj* obj = への代入は、実際のプログラムの中ではコレクションクラスから
取り出したObj*データ(Blockインスタンスなど)なのです・・・
>>822 一つの希望クラスを指定してのtest関数だけなら、そうするのですが
実は、複数のtype_infoオブジェクトをvectorで渡して、その複数タイプの内
どれか一つを実装してるインスタンスを判別する為のmultiTest関数もあり
そっちがメインなのです。
ですから、何とかtype_infoで型チェックを行いたいのです。
trueになるのはbefore()のせいじゃないの?
>>815 beforeが判定するのはクラス継承関係じゃないよ(わかってたらごめん)
>>823 実行結果最後の行の0は
>>818 >typeid(*pobj)だと、「Block」だけなく同じ仮想基本クラスを持つ型(Step)
><中略>との照合でも true になってしまうのです・・・
の報告と矛盾してるようだけど
>>824 >>実は、複数のtype_infoオブジェクトをvectorで渡して、その複数タイプの内
type_infoオブジェクトはコンテナに入れてはいけないよ
Loki::TypeInfoなどを使いましょう
>>825 自分の認識ではbeforeは、そのインスタンスの全スーパークラス「だけ」との
照合で true になると思ってるのですが・・・・
違うのですか?
>>826 単純に、Obj* obj = new Block と代入するなら正確な結果になるのですが
実際のプログラムの中では、obj = iterator->second などと
コレクションクラスから代入してるのです。
>>827 正確には、type_info のアドレスをvectorに入れてるのですが
これでもまずいのですか?
830 :
825 :2006/05/25(木) 18:19:32
>>828 単にtypeidの配列をソートしたい場合とかに使う順序関係であって、
クラス継承とは無関係だと思ったけど…。
いざ探そうと思うとドキュメントが見つからない
int main(){ int i = 0; i = i++; printf("%d\n", i); } このようなコードを書いた際、C/C++では1が表示されますが C#で同じコードを書くと0が返ってきます。 演算子の優先順位を確認するとC#のほうが正しいような気がするのですが、正しいのはどっちでしょうか。 気になって夜も眠れません。
>>830 げー!!!
じゃあC++の標準ではスーパークラスをチェックする方法はないんですか?
MFCみたいに、クラス毎にマクロを記述するのはどうしても避けたいのですが・・・
インターフェースが多すぎて
833 :
831 :2006/05/25(木) 18:24:45
すみません。忘れてましたorz C/C++のコンパイラはVisual C++ 2005とgcc4.0.3で確認しました。 C#のコンパイラはVisualC# 2005で確認しました。
>>832 >18.5.1
>1. The class type_info describes type information generated by the
>implementation. Objects of this class effectively store a pointer to
>a name for the type, and an encoded value suitable for comparing two
>types for equality or collating order. The names, encoding rule, and
>collating sequence for types are all unspecified and may differ
>between programs.
>
>bool before(const type_info& rhs) const;
>
>5. Effects: Compares the current object with rhs.
>6. Returns: true if *this precedes rhs in the implementation’s collation order.
>>831 これは演算子の優先順位でなく、コンパイラの解釈上の問題のような。
シンプルに考えると1の方が正しい。iへの後置演算をキャンセルした
♯のアセンブルが正しいかどうかは、人によって意見が分かれると思う。
>>831 少なくともC/C++ではそれがどうなるかは未定義。
2つの副作用完了点の間に、2度も同一のオブジェクトに書き込むことになるから。
>>832 dynamic_cast<>すればいいだろ。
>>831 gcc3.3.5は-Wallで警告が出るね
839 :
831 :2006/05/25(木) 18:44:56
int main(){ int i = 0; i = (i++); printf("%d\n", i); } ちなみにこのように括弧をつけても共に同じ挙動を示します。
840 :
831 :2006/05/25(木) 19:06:25
さらに追加です。以下のコードで実行した場合の出力を書きます。 <C++> int main(){ int h = 0; int i = 0; int j = 0; int k; printf("%d ", h++); printf("%d ", i = i++); printf("%d ", k = j++); printf("%d\n", i); return 0; } <C#> static void Main(string[] args) { int h = 0; int i = 0; int j = 0; int k; Console.Write("{0} ", h++); Console.Write("{0} ", i = i++); Console.Write("{0} ", k = j++); Console.WriteLine("{0}", i); } 出力 <C++> 0 0 0 1 <C#> 0 0 0 0
>>831 だから未定義って言ってるだろ。
コンパイラによっても違うかもしれないし、
最適化オプションによっても違うかもしれないし、
鼻から悪魔が出るかもしれないし、
そんなコードは書いちゃいかん。
>>839-
>>840 副作用完了点って意味ワカンなかったらググれよ、屑。
なんかWin32APIスレにも同じような流れが
まちがえたスレ立てるまでもないだったw
日本語でおk
848 :
デフォルトの名無しさん :2006/05/26(金) 20:59:45
どこかのサイトに 「mainより先に処理を呼ぶ方法がある」 と書いてあって、 方法としては確か mainの書いてあるファイルと 同じファイルに無名namespaceで囲んだクラスを定義して・・・ 以下どうだったか忘れました ・詳しくはどうやるんだっけ? ・どうしてそうなるのか の二点が疑問なんですが、どなたかご存知の方いらっしゃいますか
>>848 >同じファイルに無名namespaceで囲んだクラスを定義して・・・
その後で無名namespaceでインスタンスをつくるとかかなぁ
>>848 ・適当なクラスのコンストラクタにmainより前で実行させたい処理を書く。
・そのクラスのインスタンスを静的変数として定義
全ての静的変数の初期化はmainより前で行われるのでmainの前で処理が行える。
ついでに言うと静的変数のデストラクタはmainの終了後に行われる。
851 :
848 :2006/05/26(金) 21:59:20
>>849 >>850 なるほど!
静的変数の初期化を利用するんでしたか
という事は
・mainより先に処理したいクラス定義はmainの書いてあるファイルと
別ファイルにしてはいけない
・mainより先に処理したいクラス定義は複数書くと順番は保障されない
という認識になるんですかね
あとは調べながら試してみます
ありがとうございました
852 :
848 :2006/05/26(金) 22:13:55
>>851 >・mainより先に処理したいクラス定義は複数書くと順番は保障されない
同一ファイル内なら書いた順番みたいですね
>>831 演算子の優先順位を確認するとC#のほうが正しいような気がするのですが
int main(){
int i = 0;
int n;
n = i++;
printf("%d\n", n);
}
これでどうなる? 0 がでるだろ、演算子の優先順位処理は正しく行われている。
もとの式
i=i++;
左のiにゼロが代入される
その後i++でiがインクリメントされて、printfに渡される、何が問題なのか不明だなw
グローバル変数とか静的変数のコンストラクタ/デストラクタに処理書くのって なんかメリットあるのか?正直デメリットしか思いつかないんだが。
855 :
デフォルトの名無しさん :2006/05/26(金) 23:07:55
>>854 cout の初期化を明示的に書かずに済むことくらいか
・・・これも怪しいが
>>854 Singleton系
allocatorの初期化
C++でthread-specific strageをやってくれるスレッドライブラリはないでしょうか?
boostにthread_specific_ptrとかあったような気がする
>>857 g++ならinfoみて
__pthreadとか
コードのある範囲内で、グローバル名関数へのアクセスを禁止したいのですが・・・ #include <stdio.h> namespace x { fread(...) { ... } xmain() { fread(...); fwrite(...); } } main() { fread(...); } 上のxmain()内でのfread()の呼び出しはx::fread()ですが、fwrite()の呼び出し先を::fwrite()でなく、エラーにしたいのです。何かいい方法はありますか?
>>860 名前の隠蔽を利用して、宣言だけをx名前空間の中に置いておけばいいんじゃまいか?
namespace x {
fread(...) { ... }
size_t fwrite(...);
xmain() {
fread(...); // x::fread
fwrite(...); // エラー:x::fwriteは定義がない
}
}
>>860 #define fwrite do_not_call
C++って初心者向きではないですよね?
>>863 わざわざそんな質問をするような暇人向けではない。
いや暇人向けかも 将来使う予定があるなら暇なときに習得するべし
ある意味じゃ初心者向けかもな 線形リストもコーディングできないような奴とか 配列の境界チェック怠ってBOF起こさせる奴とか
確かに STL の存在は大きいだろうね。
エラーメッセージも張らない莫迦はお断りだし環境依存スレに池。
870 :
デフォルトの名無しさん :2006/05/28(日) 23:25:59
テンプレートメタプログラミングについて お母さんの様にやさしく教えてくれるサイト・本等あったら教えてください boost,Lokiのソースを見てみましたが 「何の処理をしているか」はなんとなく分かるんですが 「なぜそうしているのか」かがいまいち汲み取れてないのが現状です
873 :
870 :2006/05/28(日) 23:34:04
>>872 なるほどソース読むよりまずはドキュメントを熟読せよと
英語なのでお母さんの様にやさしいかは不明ですが、
ますはチュートリアルから頑張って読んで見ます。
>>871 29800だろ?それが高いのはかなり前から推薦図書スレで既出
良書の上、絶版になったので高騰してる
>>870 Modern C++ Design(邦訳あり)
C++ Templates
C++ Template Metaprogramming
876 :
デフォルトの名無しさん :2006/05/29(月) 01:29:16
時々std::tr1 という名前空間をみかけますが、 TR1の名前空間は暫定的なものなんでしょうか C++0xになったらstdに格上げされるとか?
互換性の問題から、std名前空間になることはないと、思うんだけどね。 だいぶ仕様が変わっているから、そのままだと既存のコードが動かないし。
>>877 互換性のため、std::tr1を維持するのは構わないけど、(そのための'1'なんだから)
標準に入ったら、stdにも加わるに決まってるだろ。
private継承、protected継承について詳しく解説している書籍・ページはありますか? ExceptionalC++等で断片的な知識は得た物の、 言語仕様上の違いがいまいちハッキリ分からずに悩んでおります。
>>882 おkおk、書店で売っている大量の、
自称C++入門書とやらは、全部詐欺本だな。
規格票ひとつあれば、あんなものいらねーもんな。
アルゴリズムや特定のアーキテクチャ、ライブラリの解説書以外は不要だよな。
>>883 まあ必要かどうかということならそうだね。
教科書だけあれば参考書は必要ではない
だがあれば理解の助けになるので、意義はあるけどな
>>881 継承関係なしに private と protected の違いさえわかればいいと思うんだが。
>>885 例えばDerivedがBaseをprivate継承していたら
BaseのポインタにDerivedのポインタを代入できなかったりと
クラス内のアクセス制御とはちょっと違う制約があるからな
>>886 それも継承関係が private であることの結果でしょ?何が違うとも思わないな。
>>887 「クラス内からのみアクセスできる」と「ポインタが代入不可」にどうして違いがないのか理解できない
>>888 「クラス内からのみアクセスできる」ことによって
「クラス内からのみポインタが変換(代入)できる」ことになる。
前者が private の効果。後者はその結果の一つ。
エディットからコンパイルまで備えたフリーのエディタってありますか?
VC++2005EE
フリーなの?
フリーだよ
d。 ダウンロードしてみます。
d。 ダウンロードしてみます。
d。 ダウンロードしています。
897 :
デフォルトの名無しさん :2006/05/30(火) 19:17:23
d。 ダウンドードしています。
d。 ダウンロードしてきます。
900 :
ホアキン :2006/05/30(火) 22:34:33
ある2つのクラスを用意して、相互にもう一方のクラスをメンバとすることはできますか? 要するにこうしたいのです↓ class ClassA{ ClassB b; }; class ClassB{ ClassA a; }; よろしくお願いします。
そんな金太郎飴みたいなこと出来るわけねーだろアホが
>>900 どちらか一方或いは両方がポインタや参照などを持つようにするならば可能。
class a{ protected b{ any function() .... } } インナークラスBのインスタンスをクラスAで宣言する場合の記述方法を教えてください const a::b _b&; こんな感じだっけ?
>>903 インナークラス=ネストされたクラス
クラスAで宣言=クラスAのメンバとして宣言
として、
class A { class B {}; B b; };
こんな感じ。
B b;やるとg++4.1だとエラー出るんですよ 新しいg++だとダメみたいで正確な書式知りたいんだけど どなたか知りませんか?
>>906 エラーメッセージも貼らずに聞かれちゃぁ、エスパー募集するしかないねぇ。
class A { class B{ ... }; B &b; }; だったら出来るんじゃないの?
>>900 ちょっと興味深いコードだね。
しかし
>>900 のようにしてしまうとコンパイル時にサイズが決定できなくなる
っつーか無限大になっちまうから、ポインタや参照にする必要がある。
class B; class A{ B* b; public: A(); }; class B{ A* a; public: B() { a = new A; } }; A::A() { b = new B; } いくらコンパイル通るからってこういうことするなよ
イテレータには、ランダムアクセスや双方向アクセスなど5種類あるそうですが プログラマーが明示的に区別しなくても vector<int>::iterator p; の様に書くだけで、後はコンパイラが適切なものを自動で選んでくれるのでしょうか?
何かを大きく勘違いしちゃってるな
>>913 vectorの場合はランダムアクセスイテレータ。
そういう風にコンテナによって必然的に決まる。
コンテナとは関係ないイテレータでも、その目的によってやはり必然的に決まる。
template<typename T> class Hoge { friend T; }; こういうことをしたいのですが、VC++ 7.1ではこれでコンパイルできたのですが、 GCC 3.4.4ではコンパイルエラーになりました。試しにfriend class T;としてもだめでした。 もしかしてこんなことを標準C++ではやれないのですか?
917 :
デフォルトの名無しさん :2006/05/31(水) 23:28:29
型を返す関数ないかな vector<int> a; iterator(a) i = a.begin(); みたいな
918 :
デフォルトの名無しさん :2006/05/31(水) 23:52:16
>>916 C++標準 7.1.5.3 の 2
>《詳述型指定子》中の《識別子》は,名前検索によってその表すものを見つけ出す
>(これを,名前検索が解決するという。)。名前検索の処理は,3.4.4に規定する。
>《識別子》が《クラス名》 又は 《列挙体名》 と解決された場合,《単純型指定子》が
>その型名を導入するのと同じように,《詳述型指定子》は,その《識別子》をその
>宣言に導入する。
>《識別子》が《型定義名》 又はテンプレート《型仮引数》と解決された場合,その
>《詳述型指定子》は不適格とする。
>
>参考 したがって,《型仮引数》Tというテンプレートをもつクラステンプレートの中では,
>次の宣言は,不適格となる。
> friend class T;
>>917 auto i = a.begin();
ってのが標準化されるかも。
型推論ってやつ? C#に搭載されるという
>>919 C++0xに入ってるみたいだけど
まだ正式な規格になってないから「かも」レベルではあるか
そのautoってのはイテレータだけ?
923 :
デフォルトの名無しさん :2006/06/01(木) 00:05:09
>>919 それはすごいな
初期化子からオブジェクト自体の型を推論か・・・
いやふつーに a.iterator i = a.begin(); でもいいんだけどさ
たまーにコンパイラがアフォすぎって感じることあるんだよ
別に :: と . と -> の使い分けとかポインタの存在なんかそのままでいいんだけど
そういうところを受け入れたうえでもコンパイラのロジック自体の直交的に見えないところを整理して欲しい今日この頃でさ
>>923 まあ今でも関数templateの実引数から型を決定すること自体はやってるわけでさ。
>>923 関数テンプレートの型パラメータの省略だけじゃなくて、
クラステンプレートのコンストラクタの型パラメータの省略とか、
改善して欲しい所はたくさんあるね。
928 :
デフォルトの名無しさん :2006/06/01(木) 00:16:45
>>924 面白そうだな
じっくり読んでみるよ
thx!!
929 :
デフォルトの名無しさん :2006/06/01(木) 00:17:46
C++初心書のためのお勧めの本を教えてくださいm(_ _)m
しらんがな 他の言語は何かマスターしてるのか? アドバイスが欲しかったらちゃんと自分の状況を書け
C言語は初級〜中級レベルです。 わかりやすく解説してる良書、お勧め書はありますか?
B言語以来の予約語autoがついにリンケージ指定子の立場を追われるのか。 既存の予約語を使いまわす辺りがC直系らしいと思うが なんとまあ都合いい予約語が余ってたもんだなw auto。
933 :
デフォルトの名無しさん :2006/06/01(木) 00:31:44
省略不可になるだけで意味が変わるわけじゃあるまい
>>931 憂鬱なプログラマのためのオブジェクト指向開発講座
>>933 auto i = 1.0; が
Cでは、int i = 1;のこと。(BCPL以来のint(WORD型)の省略可能)
>>924 が規格に入ったC++ではfloat i = 1.0;になるんじゃないかな。
auto の仕様が変わった所で 誰も困りそうにないのが凄いな。
%cat auto.cpp int main(){ auto i = 0; return i; } %g++ -Wall auto.cpp auto.cpp: In function `int main()': auto.cpp:2: error: ISO C++ forbids declaration of `i' with no type
autoの仕様変わるの? auto i = 0; // type-specifier auto int i = 0; // storage-class-specifier type-specifier auto auto i = 0; // storage-class-specifier type-specifier 名前に意味ダブらすの得意だし>C++
だから、そもそも3番目はエラーだってば。 >cl auto.cpp Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86 auto.cpp(2) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
autoは初期化しようとした型にあわせて自動的に型が決定されるようになるんじゃなかったか? for (auto it = v.begin(); it != v.end(); ++it) { ... } 規格が確定するのが2008年頃としても、コンパイラがサポートするにはあと3,4年かかりそうだなぁ…
でもautoってださいよなww
autoの仕様が変更されたら、
>>939 の例はどうなるんだろう。
autoキーワードそのものが
>>941 の目的に特化されて、
>>939 の2、3番目はエラーになるのかな。
>>941 型推論はいくつかの関数型言語ですでに実装されてる機能だし
実装自体にもそれほど難しい点はないので3、4年ってことはないと思われ
というか、初期化子だけで型が決まるんだから関数型言語の型推論よりよっぽど簡単
>>943 禿のことだから必死に互換性を保つだろう、その点は大丈夫そうだ
# 3番目はそもそもエラーらしいけどナ (規格に当たってないから本当かどうかは知らん)
auto 単独なら型推論するけど、 auto の他に型を書いていたら その型になるとかいう仕様になるんじゃね?
どちらにせよauto autoの扱いが気になるな
static auto i = v.begin(); なんてのはちゃんと解釈されるの?
>>917 のようなのは、g++だと、今のところ、
vector<int> a;
typeof(a.begin()) i = a.begin();
で何とかなります。
>>927 のコンストラクタ呼び出しの冗長化で悩ましいので、typeof使ったマクロで処理してます。
まあ標準外れちゃうんだけど。>typeof
されるんじゃね?要は右辺値の型を見ればいいだけだから コンパイル時に決定できれば何でも大丈夫かと
>>924 のn1894.pdfによれば、
storage class 'auto'は廃止の提案です。
951 :
950 :2006/06/01(木) 11:05:22
間違えました。 storage class 'auto'の廃止じゃなくて、 storage class specifier 'auto'の廃止です。 「3.Proposed wording」のところ。 もちろん暗黙に指定した'auto' storage classはなくなりません。
もともと互換性のために残されてたようなもんだしな
このスレに、誰か auto の仕様変わったら困るって人いる?
954 :
デフォルトの名無しさん :2006/06/01(木) 13:13:29 BE:108696487-#
あるとすれば組み込み系とか? デフォルトでregisterなのを明示的にautoにしたいとか。
そんなコンパイラあるの?
autoじゃ最適化の抑止にはならんだろ。。
>>955 昔、組込用コンパイラでそんなのがあった。OptimizeC-86だったかな。
>>956 最適化を抑止というか、レジスタを別の用途(インラインアセンブラとか)に使いたいからとか。
そういうのは、処理系依存の利用方法だから、 規格からautoがなくなっても、今まで通りの処理系使うだけだな。 そもそもC++じゃなくてCっぽいし。
弊害も結構ありそうだと思うのは俺だけか? いやautoが無くなる事じゃなくて型推論が追加される事に関してだが。
const auto n = 4; const auto a = 6.3; const auto m = n * sizeof(a); auto a[m]; こんな奇怪なコーディングが可能になる、とかか? すまんあまり良い例(悪い例?)が思いつかない。
>>961 一番下の式は初期化式がないからアウトだな。
普通の型推論じゃなくて、 あくまで初期化式と同じ型にするだけなのね。
確かにイレテータとか書くのめんどいもんな vector<int>::itrator it = v.begin(); とか
大抵は typedef するけど、名前考えるのが面倒い。
boost::any ほぼどんな型でも格納できる
この手の関数オブジェクトをauto無しで書くと死ねる。 auto is_test = not1(bind2nd(std::ptr_fun(strcmp),"test")); std::cout << is_test("Test") << " " << is_test("test"); まぁ、多少の非効率を無視してboost::functionで誤魔化してもいいけどね。
autoなしで書くとどうなるのそれ?
>>968 std::unary_negate<std::binder2nd<std::pointer_to_binary_function<const char*, const char*, int> > >
boost::lambdaを使うともっと、ありえない型になるw
using namespace boost::lambda;
auto is_test = ! bind(strcmp,_1,"test");
と書いたとして実際の型は
using namespace boost::lambda;
using namespace boost::tuples;
const lambda_functor<lambda_functor_base<logical_action<not_action>,
tuple<lambda_functor<lambda_functor_base<action<3,function_action<3> >,
tuple<int (&)(const char*, const char*),const lambda_functor<placeholder<1> >,
const char (&)[5]> > > > > >
>>969 boostのlambdaをそんな風に使うコードなんて、autoがあったとしても読みたくない。
autoがあれば、今よりずっと手の込んだコードが書けるから大歓迎。 できれば新しい予約語にして欲しかったけどね。 // けどそっちの方が互換性に問題が出やすいかな。
autoは仮引数には使えないのかね? void func(auto n) { ... } templateとバッティングするから恐らく不可だろうなぁ…
>>972 新しいtemplateの表記法として採用されなくはないんじゃないのか?
これが採用されれば、生まれて初めてC++のコーディングで autoって打つことになりそうだw
でも結構前から予約語なんだな
C時代からautoには意味があったからな 今回の提案で意味が変わりそうってだけで
>>974 そういや C ではとりあえず auto を使ってみた事はあるけど、
C++ では使った事無いな。
bitwise copyってどういうコピーですか?
>>978 memcpyのようなコピー。単に全ビットの並びが複写されるだけ。
980 :
978 :2006/06/03(土) 15:42:29
>>979 理解できました。ありがとうございました。
恥ずかしながらはじめて聞いた シャロウコピーなら聞いた事あるけど
単純なコピーなのにwiseなのな
◆-wise 《名詞の語尾につけて》〜のように、〜の方向に、〜の点で、〜に関しては、〜的に、〜風に、〜の観点で
type-safeの意味について確認したいんですが、 int型にstring型を入れようとするとコンパイルエラーになる というのをtype-safeという、という理解で合っていますか?
#includeディレクティブについてなんですが #include <hoge> という書き方の他に #include "hoge" という書き方もあるようなのですがどこか違いがあるのですか?
>>985 検索方法がちがう。実際の検索方法はコンパイラ依存。
988 :
デフォルトの名無しさん :2006/06/04(日) 15:12:33
>>985 適当に説明する。
<>はシステム側からフォルダ探す。
""はユーザー側からフォルダ探す。
だいたいの""は分割コンパイルするときの関数定義やらグローバル変数
を入れとくヘッダー。要は自作ヘッダー。
ま、言っても、色んなコンパイラ使ったことあるわけじゃないから
詳しくはしらね。
989 :
デフォルトの名無しさん :2006/06/04(日) 16:45:11
「 :: 」と「 -> 」の意味が分かりません 教えてください
本に書いてある通り。
>>989 JavaとかC#の人?
::はスコープ解決、主に名前空間の中の名前にアクセスしたり、静的メンバにアクセスしたり。
->はポインタからの間接参照、p->xは(*p).xに等しい。
992 :
985 :2006/06/04(日) 17:53:58
>>988 ありがとうございます
ということは<>はSystem32フォルダとかから
ヘッダファイル探索するけど
""だとプログラムのカレントディレクトリから
探索を始めるということですね
まぁ「「だいたいは」」<>がライブラリのヘッダで""が自分で作ったヘッダだな
>>992 システムにもいろいろなシステムがある。
コピーコンストラクタみたいに オブジェクトのセマンティクスを考えて行うコピーとの対照で良く、 bitwise copyと言われる。 例えば、参照カウンタを持つオブジェクトへのポインタは、 bitwise copyするとオブジェクトの整合性を壊してしまう。
それよりも誰か次スレ立てろ
立ててみる
999 :
996 :2006/06/04(日) 21:51:57
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。