STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
v(^・^)v
>>1 _ / ⌒)
_,. ‐'´ ̄ { ヽkュく
_, ィ^ヽ丶\\ `Y j>─‐┐
. \\ ィ ──ァ /〉 ,イ /i|\__\∠、 \ゝ. ハ. /
> > │ / // ///川、 \イじツ Yi \!イ廴ヽ./\
// ┴ ∠ _」 // ! ||ト|ゝハァュ一 ||j |三三三三三 \. /〉
o'´ _`ヘゝヽヘ.¨ f⌒>、ルじj三三三三三三ツヲ7/
`ヾ _>ド、ゞ .ノ ゞ==三三三 r'´1j│}ク'/ト
r===テミ 、 ヽ>、 ィvi|二ユ三_,/ メ'7´/三i
j /'´ ̄ ̄`¨ ┴┴'─ ¬! ´ _/三三j
/リ¬、_ __/-‐=イ三三三=i
//i^メミュ! 丶、__, ィY7フ´ / j三三三三!
/三⊆ミ‐=' \_, `' Yr──┴─ ¨´‐- ̄\ /三三三三|
/三三三三ヘ __/__厶_ /ヾ 、三三三|
/三三三三三三三三|  ̄ フ _ /_」j三三三j
//三三三三三三三三ハ / ` ¬''´三三/三三/
//三三三三三三三三三ノ / /三三三j三三/
//イ三三//三三三三三// _/三三//三 /
////三/ /三三三三 _/ 〈三三/ 〃//
16 :
989 :2006/06/05(月) 00:57:35
>>前スレ991 ありがとうございます なんとなくですが理解できました >JavaとかC#の人? そうです 普段使っているのはC#、Java、VB.NETあたりです
>>12 > STLつかうと一気に実行ファイルサイズが10倍に?!
>
> 環境によるだろ。
> 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
> ランタイムを使用するようにして使っているが、例えばstd::vectorを
> 使っても使わない時と比べ10Kほどしか増えない。
>
> すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
経緯を知らないので聞くが、このやり取りって何?
>>18 ども。流れ読んできた。
話が散逸していたのでうまく切りにくいが、
せめて↓はテンプレに入れた方がいい気がした。
(ノードベースコンテナならどうだとかツッコミ始めるとキリがないが)
part16の27から抜粋:
> STLはDLLに追い出せてないと思います。何せテンプレートで、コンパイル時
> にしかわからないものばかりのはずですから。
20 :
デフォルトの名無しさん :2006/06/05(月) 03:07:21
int や char 等であっても、非局所的な静的変数の初期化順序は、 未定義なんですか?
>>20 特に決まってないみたい。
一般的な実装ではプログラムイメージをメモリにロードした時点で
初期化が完了している。個々の順番とかいうのはわかんないね。
22 :
20 :2006/06/05(月) 10:16:20
>>21 良く判らないのですが、int や char、POD型なら main 関数前に参照しても
初期化されてるから大丈夫って事ですか?
>>22 main 関数前に参照って、どこでやるつもり?
グローバルオブジェクトのコンストラクタ("dynamic initialization"に含まれる)なら、
必ず POD の初期化("static initialization"に含まれる)の後に来るから大丈夫。
const int A = 20; const int B = A * 10; こういうのはどうなんだろう? #define の代わりとして const の仕様をわざわざ変えた以上、 これは期待通りに動くように(B が 200 になるように) 仕様で決められてるべきだと思うんだけど。
それのどこが静的変数?
cやc++は関数の引数に配列を直接渡せないって本当ですか?
なかなか、楽しい人が来たな
28 :
26 :2006/06/05(月) 13:36:04
C++ならテンプレートを使って配列を渡せるんだがな。
30 :
26 :2006/06/05(月) 13:42:27
>>28 そのページ、配列のサイズも自動で読み取るtemplateも書けることは
言及せず、サイズを指定する必要があると書いてるんだな
ともあれC++では、配列以外にも配列のようなもの(シーケンス)も
まとめて共通概念として使えるように整備されてるし、
すでに配列以外のテンプレート・コンテナが多数あるので
逆にCから引き継がれた「配列」がわりと邪魔だったりする。
std::vectorなんかが普通にいう配列みたいなポジションになってるので
これなら引数に普通に渡せるよ。
32 :
29 :2006/06/05(月) 13:52:17
>>30 例えば配列の要素数を返す関数はこうなる。
template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
でもまぁ、>31の言うように普通にvectorを渡せよって気もする。
static bool find(std::vector<int> const & foo, int ch)
{
std::vector<int>::const_iterator it = std::find(foo.begin(), foo.end(), ch);
return !(it == foo.end());
}
const int foo[] = {1, 3, 4, 6, 8, 10, 12};
std::vector<int> vfoo(foo, foo + sizeof(foo) / sizeof(* foo));
cout << func(vfoo, 2) ? "Found" : "Not found";
// ブラウザで直書きだから間違ってたらゴメン。
33 :
26 :2006/06/05(月) 14:21:09
local referenceってどういう使い道があるのですか?
>>34 ハンドルの獲得が主じゃないかね。
ポインタでも同じことはできるけど、ポインタよりも束縛が強い分、安心して使える。
36 :
デフォルトの名無しさん :2006/06/05(月) 16:35:28
1000行程度のサイズのファイルから1行ずつ読み込み、 それを又1行ずつコンソールに表示しておわり、というプログラム を書きたいのですが、以下のように書くと最後の行だけ2回表示されて しまいます。どう書けばよいか教えてください。 -------------------------------------------------------- #include <iostream> #include <fstream> int main() { std::ifstream ifs("test.csv"); std::string str; while (! ifs.eof()) { ifs >> str; std::cout << str << std::endl; } return 0; } -------------------------------------------------------- よろしくお願いします。
for (;;) { ifs >> str; if (ifs.eof()) break; std::cout << str << std::endl; }
#include <iostream> #include <fstream> int main() { std::ifstream ifs("test.csv"); std::string str; while (std::getline(ifs, str)) { std::cout << str << std::endl; } return 0; }
39 :
34 :2006/06/05(月) 16:46:30
>>35 すみません。ハンドルってのが何を指すのかわかりません
たとえば
int i;
int &j = i;
このときの j がハンドルですか?
そうだとするとこれのメリットがわかりません
結局iもjも同じものを指すに過ぎないのだから
2つも同じものを指すものが存在したところで
どんなメリットが生じるのでしょうか?
それとリファレンスはポインタよりも束縛が強い
とのことですが、束縛が強いとはどういう意味でしょうか?
ポインタみたいにリファレンスはそれを使った演算が出来ない点
をいっているのでしょうか?
長くなって失礼しました
>>39 例えば配列内の同じ要素に何度もアクセスする場合、
array[1][2][3] は *(array+1+2+3) のように、毎回位置を計算する必要があるだろ?
これを前もって
int& elem=array[1][2][3];
としておいて、その後の要素アクセスはelemを使うようにすれば位置計算が省ける、とそういう理屈。
ポインタでも同じことは可能だけれど、アスタリスクがついたり何かと見辛いのが難点。
参照は普通の変数と同じように扱えるから、比較的綺麗なコードになる。
もちろんこんな例はコンパイラの最適化でも同じような効果があるからあまり意味はないんだけども。
もうちょっと複雑になってくると重宝する。
コードが見やすくなるのもメリット。
多次元配列や複雑な要素アクセスは見辛いからな。
別名をつけておくことで、格段に読みやすいコードになる場合も多々ある。
その類で、シングルトンを使う際の省略にも使ったりする。
例えば
Hoge::getSingleton().method1();
Hoge::getSingleton().method2();
と書く代わりに、関数の先頭で一回だけ
Hoge& ref = Hoge::getSingleton();
のように取得しておいて、関数内では
ref.method1();
ref.method2();
みたく使えば見通しがいいコードになる。
IrrlichtEngineなんかはこういう記法を多用してたな。
Cだと直接触って欲しくないリソースを制限するのに使う ポインタを直接晒してクライアントに操作されちゃマズーなんで、 ハンドル経由で操作させる Win32APIとか
42 :
デフォルトの名無しさん :2006/06/06(火) 00:00:58
質問です。 struct A { int a, b, c, d, e, f; A(const A& x); A& operator = (const A& x); }; が有ったとします。で、コピーコンストラクタと代入演算子ですが、 c 以外のメンバーはビットコピーし、c だけ 0 に置き換えたいの出すが、 この場合、それぞれの定義で a = x.a; b = x.b; c = 0; d = x.d; e = x.e; f = x.f; か、 memcpy(...); c = 0; しか手っ取り早い方法はないですか?
cだけ0って時点で、なんか怪しい構造体だな。
>28 Cだって、コンパウンドリテラルがあるから直接配列渡せるはず
46 :
42 :2006/06/06(火) 01:07:00
>>43 ,45
あくまで例えなんで。また、もう一つ例えで
class X
{
public:
X(const X&);
X& operator = (const X&);
private:
・・・ // メンバー変数いっぱい
struct impl;
impl *pimpl; // impl にもメンバー変数いっぱい
};
全てのメンバー変数の複製を作る場合、
pimpl は特別な処理をしなきゃいけなくなりますよね。
そこでコピーコンストラクタと代入演算子を独自に定義したら、
丸々コピーしてくれるデフォルトのコピーコンストラクタと代入演算子が当然使えなくなる訳ですよ。
そうなると、Xの メンバー変数いっぱい をチマチマ代入しなきゃいけなくなるんで、
楽かつシンプルな方法はないかと考えていまして。
memcpyだとメンバーが単純なビットコピーじゃない場合に不具合が生じるし…
君はプログラム書かない方がいい。
予想で申し訳ないんだけど、 設計が不味いとしか思えない。
>>46 pimpl に、コピーの意味づけを加えたポインタクラスを使え。
>>35 ,41
ハンドルの使用と参照型の使い方は関係ないだろ。初心者を混乱させるな。
ところで、 C++ってjavaと比較してお仕事の絶対量って少ないのでしょうか? 求人を見るとjavaやphpばかりで・・・。
>>51 そんなことを知ってどうする?調査、統計しないと結論は出ないしね。
話を続けると C++ の話題から遠ざかるだろうから、これ以上は他所でやってくれ。
C++が使えるなら、JavaやPHPの習得なんて楽でしょ 時間があれば。
言語の習得は楽勝だろうね。 ライブラリはちと時間かかるが。
55 :
42 :2006/06/06(火) 02:34:07
>>47 ,48
有りそうな例を考えたつもりですが、結構変な例でしたか。
正直、ただ単にチマチマ代入文書くのが面倒なだけです。
a = x.a; b = x.b; c = 0; d = x.d; e = x.e; f = x.f;
と書くのも見栄えがあまり良くないと思ったもので。
>>49 それしかコピーコンストラクタと代入演算子内でシンプルに書ける方法が
なさそうですよね。
ありがとう御座いました。ねます。
>>50 C++FAQ 第2版 ローカルリファンレンスとは何か を参照。
クラステンプレートのfriend宣言についての質問です。 あるクラステンプレートMyClass用のoperator<<をオーバーロードしたいとします。 敢えてfriend宣言のtemplateを省略し、 template <class T> class MyClass { ... friend std::ostream& operator<<(std::ostream&, const MyClass&); }; template <class T> std::ostream& operator<<(std::ostream& os, const MyClass<T>& m) { ... } の形にすると「Undefined reference」となりコンパイルできませんが、 std::ostream& operator<<(std::ostream&, const MyClass<int>&) { ... } のように明示的な関数を定義しておけば正常にコンパイルされ、実行できます。 (non-template-friend警告は無視しています) なぜこのような差が生じてしまうのでしょうか? MyClass<int>のインスタンスを作った際に、MyClass<int>が実体化され、 friend std::ostream& operator<<(std::ostream&, const MyClass<int>&); の宣言が行われるかと思っていたのですが、もし宣言が行われているならば 最初の定義でマッチしないのは不自然に思えてしまいます。 実体化のタイミングがズレているのでしょうか? 長文失礼致しました。
template <class TT> friend std::ostream& operator<<(std::ostream&, const MyClass<TT>&);
Windowsプログラミングの初歩的なことについての質問なのですが、 環境: Windows XP SP2 VC++6.0(記述はC言語) 目的: 位置を自由に変更できるモーダレスなダイアログボックスを表示したい コード: WinMain関数内で、 DialogBox(hInstance, "MYDIALOG", NULL, (DLGPROC)DlgProc); と記述しています。 hInstance:アプリケーションハンドル MYDIALOG:自分でつくったダイアログの名称 DlgProc:ダイアログプロシージャ 結果: 実行するとなぜか位置が固定でタイトルに何も表示されないダイアログボックスが表示されてしまいます。 タイトルキャプションには「ダイアログ」と入力しているのですが。 どなたかアドバイスお願いします。
61 :
デフォルトの名無しさん :2006/06/06(火) 11:03:58
deleteしないとmainを抜けた後もメモリリークは残るんですか? もしnewとdeleteの途中でexitとかさせると、 それはメモリリークになりますか?
ISO C++的には環境依存です。 Windows, UNIX, Mac OS Xはメモリリークしないです。
>>57 こうかな?ウザイな。
template<class T>
class MyClass;
template <class T>
std::ostream& operator<<(std::ostream& os, const MyClass<T>& m);
template <class T>
class MyClass {
...
friend std::ostream& operator<< <T> (std::ostream&, const MyClass&);
};
template <class T>
std::ostream& operator<<(std::ostream& os, const MyClass<T>& m) { ... }
>>56 なんか用語としての意味があるの?
「ローカルリファレンス」と "local reference" どちらでググっても
C++ FAQ の目次しか出てこないから、何か勘違いしてるんじゃないの?
そんな平易な言葉に見たまま以上の意味を持たせるのはやめてほしい。
65 :
57 :2006/06/06(火) 11:49:04
>>58 言葉足らずで済みません、そうしなければいけないことは分かっているのですが、
敢えて省略した際の動作が不可解だったので質問させて頂きました。
>>63 確かにそれで通りますね…
といってもなぜそれで通るようになるのか分からず…(TT
もう少し勉強してみます。
66 :
59 :2006/06/06(火) 11:55:04
すみませんでした
>>65 gcc「non-template-friend警告て言うてるやん!無視すなや。もうあほかと」
for (p = s.end( ); p != s.begin( ) && *--p == c;); こんなコードみかけたんだけど for文ってfor(xxx; xxx; xxx) みたいに()の中は三つ項目がいるんじゃなかったの? 上記のコードが何をしているか説明して下さい
>>68 3つあるじゃん。3つ目は空っぽだけど。
やってることは
for(a;b;c){} と a; while(b){c;}が等価ってことで分かるっしょ
>>68 p という恐らくは何らかのコンテナの末尾から先頭に向かって、
全ての要素に c を代入している。
ちなみに for 文では空文が許可されている。
> p という恐らくは何らかのコンテナの末尾から先頭に向かって、 s だったorz
>>70 ==は代入じゃなくて比較なので
cと一致しない値を見付けるまでpを逆走させてる
73 :
68 :2006/06/06(火) 15:53:02
みんなありがとうございます こんなforの使い方もあるんですね すみませんあと一個聞かせて下さい for( int i = 0; i < 3; i++) { printf("%d\n", i); } このコードの実行順序は 1 i = 0 2 i < 3 3 printf 4 i++ 5 i < 3 6 printf 7 i++ 8 printf ... であっていますか?
74 :
68 :2006/06/06(火) 15:54:20
間違えたすみません > 8 printf 8 i < 3 です
C++やって一年以上経つのに privateメンバ関数をオーバーライドできる事に今気づきました VC++2005でできたんですが、これはもちろん標準C++の機能ですよね?
>>77 もちろん標準C++のうち。
メンバをオーバーライドするに当たって、その可視性は問われない。
でも仮想関数の場合は、そもそも仮想関数をprivateにするのは、どうかとは思うけど。
>>77 出来なかったら不便この上ないでしょ。
実装部分をメソッドとしてまとめられないし
>>78 >>79 ありがとうございます
privateメンバ関数を仮想にするのは
調べてみたところ「NVIイディオム」とやらに使用する場合があるみたいです
class A{
private:
virtual void Print(){ std::cout << "is A";}
public:
void CallPrint(){ Print();}
};
class B :public A{
virtual void Print(){ std::cout << "is B";}
};
A* a = new B;
a->CallPrint(); // "is B"と表示
漏れは class の中身書くときに、先に public 書いて後で protected、private と 続く感じなんだけど、みんなはどうしてる? >80 は逆みたいだね。やっぱりデフォルトが private だから?
>>81 それは宗教戦争になるからここでは触れない方が吉。
84 :
81 :2006/06/07(水) 01:57:51
すまん去るよ
>>83 どういう順番で実装するかは、お好みだし、宗教戦争になるかもしれんが
どう考えても public が先に決まるだろ?
でないと class になってる意味が無いような気がする。
だから話を蒸し返すなよ馬鹿w
>>39 int i = 0;
int j = 1;
int & r = i;
r = j;
r = 2;
としたときに、i, j それぞれに何が入るか分かっていれば、
> それとリファレンスはポインタよりも束縛が強い
> とのことですが、束縛が強いとはどういう意味でしょうか?
という言葉は出てこない気がする。
>>39 > 束縛が強いとはどういう意味でしょうか?
初期化時にどこを参照するか決められて、以後変えることはできない。
初期化しないことも許されない。
つーかローカルかどうかに限らず、参照はハンドルを表現するための手段なんだから 別に間違ってはいないだろ
91 :
68 :2006/06/07(水) 15:23:40
φ = 空
93 :
68 :2006/06/07(水) 15:35:27
>>92 空文だと文自体がないことになっちゃうから
空文じゃなくて空の式だといっているのですね
forの()の中の";"は空文(= ;)の";"とは全然違うから。 for (式opt; 式opt; 式opt) 式 だからさ。最後の"式opt"の後ろには";"ないし。
何とんちんかんな突っ込みしてるの?
>>94 しかもその中身もちょっと違う。
for (int i = 0;のように、ここで変数宣言できるよう、正しくはこうだ。
繰り返し文:
for ( for初期化文 条件opt ; 式 opt ) 文
for初期化文:
式文
単純宣言
>>96 for初期化文:
式文
単純宣言
これの意味がわからないです
擬似BNF記法かね
>>98 C/C++の規格ではそういう記法を使っている。
コンパイラによって通ったり通らなかったりするコードに困ってる。 C++の規格ではどっちが正しいのか教えてくれ。 std::ofstream fout; std::ostream *pout = fout ? &fout : &std::cout; std::ostream &out = fout ? fout : std::cout; gcc3.4.4だと両方通る。 VC8だと上が通って下が通らない。エラーメッセージはこんなん。 エラー1error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : private メンバ (クラス 'std::basic_ios<_Elem,_Traits>' で宣言されている) にアクセスできません。c:\program files\microsoft visual studio 8\vc\include\ostream581 なぜかヘッダーにエラーがあることになってるんだけど、&outの行を コメントアウトするとコンパイル通るからこの行のせいだと思うんだ。 C++の規格的にはどっちが正しい?
とりあえず、条件式にfoutを使うのはどうかと思うがどうか?
>>101 これはVC8でもコンパイルできた。
std::ostream &out = fout ? static_cast<std::ostream&>(fout) : std::cout;
条件演算子の結果の型を決める手順はきちんと規格書を呼んだわけではないが、結構複雑だと聞いたことがある。
>>103 ありがとう。castで通るとはね。
エラーメッセージとの関連性がまだ見えなくて気になるけど
gccでも通ったからひとまずこれで回避させてもらうよ。
typedef WCHAR TCHAR , *PTCHAR ; typedefが型の別名を定義するというのは知っていますが、 ↑のはどういう意味なのでしょうか?
>>106 TCHAR = WCHAR
PTCHAR = WCHAR *
108 :
106 :2006/06/08(木) 17:40:25
typedef std::multimap<std::string,std::string> Header; Header.insert( make_pair(key, value) ); cygwin上のgcc version 3.4.4では通ったんだが SolarisのCC 5.8では std::multimap<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string>>>::insert(std::pair<std::string, std::string>) と一致するものがありません. て言われる。なんでだろ?
とりあえずHeaderは型名な訳だが
int main(int argc, char **argv) { } Linuxのcのサンプルプログラムでよく 上のみたいな**argvってのを見かけるんですが どうしてポインタのポインタになっているんですか?
>>111 そういうあほな質問は別スレでやってくれないか
>>111 argvの利用方法を理解していればおのずと分かる。
この時期学校の授業でプログラミングやりだす学生が多いんだろうな
最近mainの引数の使い方覚えたような奴が釣られてるとしか思えない
その通りですが何か?
>>111 int main(int argc, char *argv[])
こうすると分かりやすいかもしれない(厳密に同じ意味である)
ようするに文字列の集まりを渡そうとしている
不気味なインターフェイスはCがそうだからだろう
ただいま〜今日は1日中眠かったよ… 解答うpしますね。 ちなみに環境はxyzzyです。 (defun _reverse (x &optional (y nil)) (if (null x) y (_reverse (rest x) (cons (first x) y)))) (defun _append (x y) (if (null x) y (cons (first x) (_append (rest x) y)))) (defun _length (x &optional (y 0)) (if (null x) y (_length (rest x) (+ y 1))))
質問なんですが、C++でワイド文字を使用するときwchar_tを使うということまではわかったのですが、 ワイド文字を格納して、それをcoutで表示させようとしてもアドレスみたいなのが出て、 ちゃんと表示されません。 C++では、wchar_tを使って格納した文字をどのようにしたら画面に表示させられるのでしょうか?
123 :
・∀・)っ-○◎● ◆toBASh.... :2006/06/09(金) 04:00:38
std::wcout << L"ワイド文字はwcoutに吐こうね" << std::endl; std::wcout << L"ちなみにwendlはねーよwwwwww" << std::endl;
124 :
・∀・)っ-○◎● ◆toBASh.... :2006/06/09(金) 04:06:00
あと、どうしても化ける場合のおまじないとか。 std::wcout.imbue(std::locale("japanese");
>>122 C:\Documents and Settings\Owner\デスクトップ\VC++\Sample_program\練習用\resnnsyuuu.cpp(14) : error C2065: 'wcout' : 定義されていない識別子です。
C:\Documents and Settings\Owner\デスクトップ\VC++\Sample_program\練習用\resnnsyuuu.cpp(14) : error C2297: '<<' : 不正な右オペランドです。
というエラーが出ました。どうしたらいいでしょうか?
>>125 コンパイラが wcout をサポートしているかどうか調べるといい。
このスレで聞いてもスレ違いだから気をつけて。
128 :
111 :2006/06/09(金) 08:08:09
こ、こんな屈辱を受けたのは、はじめてだ! おまえらもうゆるさないぞー
STLに関して「直交性が高い」とかいいますが どういう意味ですか?
ぐぐったら一発だった失礼しました
>>110 HeaderってBoostの?非標準なライブラリは使ってないぞ
まあこれは仮名なんで実際のソースはこの名前じゃない。
なんとなく原因は分かってきたので確信ついたら書くお。
>>131 いやだから、>109の1行目はHeaderを型宣言しているよな。
で、2行目は型のメンバを呼ぼうとしているよな。
例えばこうなら納得いくんだがな。
typedef std::multimap<std::string,std::string> Header;
Header header;
header.insert( make_pair(key, value) );
133 :
109 :2006/06/09(金) 11:22:36
>>132 あーそいうことね
すまそ、書き方不足でした。
ちなみに解決。
下の書き方だとgccでもCCでも通った。
typedef std::multimap<std::string,std::string> Header;
typedef Header::value_type Entry;
Header header;
header.insert( Entry(key, value) );
pairじゃなくてvalue_typeを使うのが標準ってことなのかね
『12:34:56』と入力した時、 hh=12 mm=34 ss=56 という様に代入するプログラムはどうやって書くんですか?
>>133 value_type は pair<string const, string> なんだが、これは
pair<string, string> から暗黙に変換できるはず。
この変換には pair のコンストラクタテンプレートが使われるんだが、
CC はそこ(メンバ関数テンプレート?)らへんで失敗してるんだろう。
>>134 まず自分で書いて、問題があればその問題を相談しろ。
がんばってedlinで書くw
139 :
デフォルトの名無しさん :2006/06/09(金) 13:24:19
c++で、intでは入りきれない変数のとき、 int64_tを使っているんですが、これでよいのですか? long long とかを使うべきなんですか?
多倍長整数クラスを使う
141 :
デフォルトの名無しさん :2006/06/09(金) 16:23:56
MFCで自作簡易HTMLブラウザって出来ますか????? 教えていただけると助かります。。。。。
143 :
デフォルトの名無しさん :2006/06/09(金) 16:27:05
>>139 そんなのどのぐらいの制度を要求されてるのかによるじゃんよ。
値が対数的に分布するような変数ならlong long使うより浮動小数点数にして係数調整したほうがいい。
>>141 IEの機能を読み込む形でかなり簡単に作れた気がする。
144 :
デフォルトの名無しさん :2006/06/09(金) 16:28:04
しまった 対数×→指数○
145 :
デフォルトの名無しさん :2006/06/09(金) 16:32:28
IEに依存する<基本クラスCHtml view>を用いたものは出来たのですが、 自作でのHTMLレンダリングエンジンを作りたいと考えています。
windowsで描画できるもんは何だって作ることは可能だ。
147 :
デフォルトの名無しさん :2006/06/09(金) 16:51:06
方法教えて(泣) 方法を求む!!!!!
>>147 どうにかしてコネクションを張る
↓
HTTPで必要な情報を取り出す
↓
取り出した情報を適切に解釈する
↓
解釈した情報を元に描画する
149 :
デフォルトの名無しさん :2006/06/09(金) 16:59:24
ありがとう御座います。 難しそうだけどプログラムを組みたいと思います。
(´-`).。oO(なにがわかったのだろう・・・無理なのだろう)
151 :
デフォルトの名無しさん :2006/06/09(金) 19:49:04
クラス内部に定義されたクラスを前方で参照することって出来ないんでしたっけ? void func(struct A::B& x) { ... } ←ここをどうにかしたい struct A { struct B { ... }; };
152 :
デフォルトの名無しさん :2006/06/09(金) 19:51:22
>>150 全くそのとーり〜
意味が分からんが・・・とりあえず流した。
153 :
デフォルトの名無しさん :2006/06/09(金) 20:12:36
class A :public hoge<A> { voif foo(); }; みたいな記述を見かけるのですが、 1 コンパイラはどういう順番でコレを解釈するんでしょうか? (Aの親クラスがhoge<A>で、Aの定義は・・ と無限ループしないか?) 2 どういう用途に使われるんでしょうか 3 この技法は一般的に何と呼ばれるんしょうか 解説したサイト等を探してるのですが、検索ワードが思いつきません・・・
>>153 1. とりあえず、hoge クラステンプレートの定義を読む。
この時点ではコンパイルされない。
2. とりあえず、A の定義を読む。まだコンパイルされない。
3. コンパイル中に A a; みたいな文が出てきて、
A が実際に必要な段階になったら、A と hoge<A> がコンパイルされる。
hoge の定義も、A の定義もすでに 1, 2 で読んであるから、
コンパイルする際も問題ない。
っと、
>>155 の 1,2,3 は、
>>153 の 1,2,3 に対応するんじゃなくて、
単純に評価の流れをおっただけの番号ね。
>>153 それを表す言葉はCRTP (Curiously Recurring Template Pattern)。
不思議な再帰の雛形様式ね 不再雛式と覚えればオケー
なのー
よし。「なのー」で俺の頭にインプットしたぞ。
自己言及的テンプレート
自慰式至射精テンプレート
163 :
・∀・)っ-○◎● ◆toBASh.... :2006/06/10(土) 02:23:18
Jane DoeのテキストビューコントロールをMFCとかWTLに移植してくれたら神認定
>>145
164 :
デフォルトの名無しさん :2006/06/10(土) 03:21:19
関数呼び出し演算子のオーバーロードをやってみようと思ってるんだけど、 なぜかコンパイルエラー・・・ どうしてエラーになるのかわからない・・・ 誰か助けてください・・・・ #include<iostream> using namespace std; struct myClass{ myClass(){} int operator()(){ return 9; } }; int main(){ myClass m(); int i; i=m(); cout<<i<<endl; } これで実行すれば9が出力されるプログラムのつもりなんだけど、 なぜかコンパイルできない。 i=m(); の行で、error: cannot convert `myClass' to `int' in assignment っていうエラーがでる。 m()でmyClassのoperator()が呼ばれてintの値を返してるつもりなのに。 なんで?
165 :
デフォルトの名無しさん :2006/06/10(土) 03:33:10
mainの最初の行が関数宣言だと思われている。 -myClass m(); +myClass m;
166 :
デフォルトの名無しさん :2006/06/10(土) 03:41:17
>>165 なるほどdクス!
てことは、こういう場合は無引数のコンストラクタを呼ぶときは()をつけちゃいけないってことなのかな?
質問です 次のようなコードを書きました void foo(){ try{ (処理1) }catch(bad_alloc){ (処理2) }catch(...){ (処理3) } } 処理1がなぜか失敗します。 その時何の例外が出ているのかよく分からず、 とりあえずbad_allocかなと思って例外を捕まえようとしたのですが、 どうもbad_allocでは無いようです 何の例外が出ているのか調べるにはどうすればよいのでしょうか ご教示願います
>>168 もし、その例外がSTLの例外だとするならば、
すべてのSTLの例外はstd::exceptionを継承しているから、
次のようにキャッチすればよい。
catch(std::excepption & e)
ここから環境依存の話になるけど、
VC++を使っているなら、SEHをキャッチしてしまったというのもありえる話。
VC8からは、最適化の関係で、
デフォルトではキャッチされなくなったけど。
あまり教えんなよ 164,166は悪戯をしたいだけの厨なのミエミエなんだから
172 :
151 :2006/06/10(土) 12:04:01
173 :
153 :2006/06/10(土) 17:02:10
>>154-162 質問に答えていただき、ありがとうございました
キーワードは抑えたので、詳しい事はWebの海で探してきます
175 :
168 :2006/06/10(土) 17:29:22
>>169 ありがとうございます
std:exceptionでぐぐって勉強してみます
うーむ・・・実際はstdio.hだけじゃないんですよね・・・stdioでもどれがくるのかわからない。 fopen()かもしれないし、_wcsicmp()かもしれない。 何のヘッダが来ても何とかできる方法はないでしょうか・・・???
プログラムの最初で変数をstatic宣言しとくと何かと便利 だとどこかで読みました。 しかし、どこが便利なのかわかりません。 例えばプログラムの最初の方で、 int i; とするのと static int i; とするのは何が違ってくるのでしょうか?
>>178 static の意味は使う場所でいろいろ変わるから、それだけじゃ比較できない。
static変数は便利どころか厄介な代物なので可能な限り使わないこと。 使わなければいけない理由がある場合以外には。
外部からexternされることを禁止するという意味では望ましいが autoで済むのなら済ましないさいなというところ。
コンパイル時の依存性を減らすために templateメソッドを実装ファイル内に記述 したいのですが、何か方法はありますか?
>>182 exportをサポートしたC++コンパイラを使用する。
>コンパイル時の依存性を減らすために >templateメソッドを実装ファイル内に記述 >したい まずこの前提条件が間違ってるから無理。 コンパイル時に依存できるからTemplateを使う。 おそらくTemplateを使う場所を間違ってる。
185 :
178 :2006/06/12(月) 08:41:13
どうもありがとうございます
>>179 もしよかったら使うメリットを具体例を挙げて
教えてもらいたいです
>>180 その使わなければならない理由を知りたいです
>>181 そういう効果があったんですね
>>185 今知らないのなら、使わなければならない理由なんて知らない方がいいよ。
そもそもここは初心者に手取り足取り教えるスレじゃないんで、どうしても知りたければ
適切なスレに逝っとくれ。
「何かと便利」って,なんだその理由w
どういうものかも知らないのに、 ・「何かと便利」と聞いたが何が便利か分からない。 その上、 ・これってどういう意味ですか? それに対して、文脈によって違うからと答えられると、 ・使うメリットを具体例を挙げて教えてもらいたいです。 まともな人間とは思えない。
static 変数の役割が知りたいなら入門書を読め。
190 :
デフォルトの名無しさん :2006/06/12(月) 11:27:05
質問させてください。 template <class data_t> class list { protected: data_t value; list *next; public: virtual data_t retrieve() = 0; }; template <class data_t> data_t stack<data_t>::retrieve() { data_t temp; list<data_t> *del; temp = next->value; ▲ del = next; ● next = del->next; ▲ } ▲の部分で、protected のメンバにアクセスできないという、コンパイルエラーになります。 同じ protected メンバの next にはアクセスできて、next->value にはアクセスできません。 何故でしょうか?
191 :
178 :2006/06/12(月) 11:35:52
スレ違いでしたか失敬 関数中で変数をstatic宣言するなら意味がわかるんだけど そのとき読んだやつでは static int i; int main(void) { ... } みたいにmainの前のグローバルスコープでstatic宣言されてて、 そこに宣言するなら別にstaticつけなくていいじゃんと思ってのでした で、このことの意味は別のソースからextern宣言されるのを防ぐため ということですね。どうもありがとうございました
>>190 ISO/IEC 11.5 Protected member access
: the access must be through a pointer to, reference to, or object of the derived class itself
193 :
デフォルトの名無しさん :2006/06/12(月) 16:01:58
今行列計算をしようとしているのですが、 標準の行列ライブラリだと0行0列から始まってしまい、 なおかつn行n列という定義ができないので不便で (というか計算不能で)しょうがありません。 これを解決するインクルードファイル等をご存知でしたら 教えてください。よろしくお願いします。
標準の行列ライブラリなんてねーよ。 boostでも使えば?
>>190 インスタンスが別だから。
protectedは継承先から継承元へのアクセス指定。
#define RETURNCODE "\n" //windowsでは"\r\n" なんて改行コードの違いを上みたいに書く人が意識するんじゃなくて システムに判断させたいんだけど何かいい方法ないかなあ? #ifdefとかよりもっと簡単な方法で。
>190 もう一つかぶせると、 自分(のクラス)の一部としてのみアクセスできる。 無理すればアクセスすることも出来るけど、お薦めはしない。
>>196 stdioのtext modeなら "\n"で統一されてるけどな
>>196 何だかんだ言って状況によるからな。
UNIXやMacは、text fileでは独自のやり方だけど、
networkなtext streamでは(例えばHTTP)共通の規則だから。
Windowsはそういう意味では常に\r\nでいいんだけど、
今度はfileを読み書きする時には、textかbinaryか明示し忘れるとまずいし。
# ISO C/C++的には明示しないのが悪いわけだが。
というわけであんまりいい方法、しかも一般的な方法はありませんよ。
text modeのやる気のないソースをみると 自前でやった方がいい気にはなるな あれだけのためにどれだけパフォーマンス落ちてるんだと
テキストモードなんてそもそもパフォーマンス悪いの前提でしか使わん
C++はパフォーマンスのために使うのにな
Winで改行コードがCRLFになった経緯って何だっけ?
タイプライターを模したからじゃないの?
>>204 MS-DOSから継承したから。
テキストファイル末尾のEOF文字は流石に継承しなかったが。
CP/Mはどうだったの?
CP/Mは改行はCRLF、テキストファイル末尾は128バイト単位のレコードを埋め尽くすまでEOFコード(0x1a)。
>>208 >テキストファイル末尾は128バイト単位のレコードを埋め尽くすまでEOFコード(0x1a)
これはなかなか面白いですね
CP/Mの改行コードは何に由来するんでしょうか?
あとMacは昔CRだったと記憶してますが OSXでもそれは変わらないのでしょうか? あとCRにしたのはなんでなんでしょね?
いい加減スレ違いなので自分でしらべてください
>>210 なんでかは知らんが
おかげでファイル読み込みのときに
LF, CRLF, CRの3種類のシーケンスのどれがきても
ひとつの改行と認識するコードを書かねばならなくなったりしてたよな
まあ今でもHTTPで引っ張って来るときはそんな感じだが
>>210 普段は CR で、ターミナルで UNIX コマンド使ってると LF 。
>>204 もともとASCIIでは、CRLFが行末。復帰(0カラム)+改行(次の行)。
^D(0x04)がEOT(End of Transfer)。(UNIXは端末からデータ終了に^Dはそのため)
UNIXの行末が、LFだけなのは、その方がプログラミングが簡単だから、
AT&Tベル研の人たちがそうした。
Macの行末(^M)は謎。CP/M, MS-DOSのテキストファイル末端(^Z)も謎。
AT&Tにいるようなできる人間でさえも、 プログラミングの煩雑さを嫌ってLFだけにしたのか。 なんだか希望が沸いてきた。
テレタイプとかテレックスの仕様ではなかったか? 印字位置が行末までいったり行送りで、 自動的で印字位置が先頭に戻り、1行改行したような記憶が... 詳しい人教えて。
^Z(EOF)はファイルサイズを管理していなかったファイルシステム上で、 クラスタ途中にあるファイルの終端を記録するためのもの。
^Z(\032,0x1A)は、 ASCIIではSUB(substitute character)なのに、 何故かCP/Mは^D/EOTを使わずに^Zにした…
^ZはCP/Mのファイル終端用で (CP/Mのファイルシステムはクラスタ数しか管理していない) MS-DOS初期はそれを引き継いだものの FATファイルシステムでファイルサイズがバイト単位で管理できるようになったため ^Zは不要になったけどな CP/Mとの互換性のために残ってたけど
いきなりで不躾ですが処理がどうしても思いつかずご相談させてください。 ユーザー関数の戻り値が帰ってくるまでの時間がランダムの 場合、その戻ってくる時間分だけ待機させるのってどうしたらいいでしょう? CheckISSError :ユーザー関数 for( i = 0 ; i < 15 ; i++){ iRet = CheckISSError( i ); if(iRet < 0){ エラーの場合の処理 } ::Sleep(700); } while文でぐるぐる回すのもおかしいですし。 現状では ::Sleep(700); をいれることでもたつきますが 正常に動作してます。
>>220 ユーザ関数が別スレッドで動作してるなら、
WaitForSingleObjectを使うといいんじゃね。
というかスレ違い。
>>221 スレ違い申し訳ありませんでした。
またスレ違いにもかかわらずご教授ありがとうございます。
早速試してみます。
ありがとうございました。
223 :
デフォルトの名無しさん :2006/06/13(火) 12:42:54
参照で入出力するvectorを作りたいのですが、下のプログラムではまずいでしょうか。 template <class T> class myvector { vector<T*> value; public: myvector() {} void add( const T& in ){ value.push_back( &in ); } T& get( const int& n ){ return *(value.at(n)); } }; int main(){ myvector<string> vec(); string s("hoge"); vec.add( s ); } これを実行するとmain()の最後のaddのところで request for member `add' in `vec', which is of non-aggregate type `myvector<std::string> ()()' のエラーが出ます。 どなたか教えてくれませんか。
>myvector<string> vec(); これが関数宣言とみなされているんだろう。
>>223 myvector<string> vec();
って関数宣言になってる気がするんだが
226 :
222 :2006/06/13(火) 12:59:13
>>224 ,225
どうもです。まだ慣れないもので。
その後 add() の引数を const T& から T& に変えたら
正常に動きました。ありがとうございます。
>>226 本当に関数宣言のままで動いたのか?
ともあれ add(const T& a)の中の vector<T*>.push_back(&a)は
constポインタは非constポインタには暗黙変換できないので
当然エラーになる。
228 :
222 :2006/06/13(火) 13:31:29
>>227 いえ言い方が悪かったです。
myvector<string> vec;
に直しました。
別のところで質問し、スレ違いと知りこちらにやってまいりました。 ユーザー関数の戻り値が帰ってくるまでの時間がランダムの 場合、その戻ってくる時間分だけ待機させるのってどうしたらいいでしょう? CheckISSError :ユーザー関数 for( i = 0 ; i < 15 ; i++){ iRet = CheckISSError( i ); if(iRet < 0){ エラーの場合の処理 } ::Sleep(700); } 現状では ::Sleep(700); をいれることでもたつきますが正常に動作してます。 WaitForSingleObjectを使用すればいいのでは?とご教授頂いたのですが どのように利用すればいいのかもわからない状態です。 何方かご存知の方 ご教授願えませんでしょうか?
すみません。書くところまちがえました。 申し訳ない
231 :
デフォルトの名無しさん :2006/06/14(水) 00:37:58
あるlibraryを使用しているんですが、 そのlibraryのclassは全てObjectというclassから派生したもので、 どのclassにもClone()が用意されています。 これらのclassをmemberに含むような自前のMyClass : public Objectを作る場合、 MyClassにもやはりClone()を用意してやって、 MyClassの(Objejctを継承している)memberは全てポインタにしてやって、 MyClass::Clone()の内部はそれぞれのclassのClone()を使用して複製して行くのが一般的でしょうか。 それとも、単にMyClass::Clone()の中ではそれぞれのclassのcopy constructorを使って、 複製を行うのがいいものなのでしょうか。 場合によって変わる、というものなのかも知れませんが、 指針があれば教えて下さい。
そのClone()の実装が、new コピーコンストラクタと同じかどうか調べれば? 同じなら、MyClass::Clone()をコピーコンストラクタで実装すればよいし、 違うなら、メンバのClone()を律儀に呼び出す必要がある。 でも、そもそも、MyClass::Clone()を実装する必要が本当にあるの?
233 :
231 :2006/06/14(水) 01:45:40
>>232 Clone()の実装は、内部でsaveとloadをしているようでした。
Object::Clone()のみが実装されていて、
派生classは全てObject::Clone()を利用しているようです。
なので、MyClass::Clone()を自分で書く必要はないみたいです。
# そこらへんが複雑でちゃんと読めてないんですが。
# 派生classの.hと.cxxとは別に、saveとloadを実装させるためのtoolがある。
ここです。
ttp://root.cern.ch/root/html/TObject.html 派生classのoperator=とかは、全て内部でCopy()を呼び出している。
# Clone()がsaveとloadから複製する関数で、Copy()はmemberを逐一複製している。
# このClone()とCopy()が両方ある理由も分かっていないんですが。
>でも、そもそも、MyClass::Clone()を実装する必要が本当にあるの?
これってのは、castまわりでClone()が必要な状況になれば実装すれば良いという事でしょうか?
使われる可能性がないうちは、特に実装しなくてよいということ?
classのmemberをポインタにするかどうかの判断は、
実行時にnewしたいかどうかだけで決めるものですか?
234 :
デフォルトの名無しさん :2006/06/14(水) 02:01:16
C言語をやろうと思い導入しました ですがうまくいきません ------ ビルド開始: プロジェクト: C, 構成: Debug Win32 ------ コンパイルしています... Cプラス.cpp .\Cプラス.cpp(4) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません ビルドログは "file://d:\My document\Visual Studio 2005\Projects\C\C\Debug\BuildLog.htm" に保存されました。 C - エラー 1、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ========== となってエラーになります
ファイル名に日本語を使うところが漢だな
そりゃ拡張子がcppじゃC言語にはならない罠。
238 :
232 :2006/06/14(水) 03:13:20
>>231 ちょっとドキュメントやらソースやら読んでみた。
まず押さえてほしいのは、このフレームワークはファイルシステム上にオブジェクトを保持するということ。
だから、オブジェクトをファイルに読み書きするメソッドはすべてのクラスで必須。
具体的な読み書きは、それぞれのクラスで定義されたメソッドStreamer()でやってる。
ここまでOK?
Copy(TObject &)は引数として与えられたオブジェクトにthisをコピーする。
それぞれのクラスできちんと定義してやる必要あり。
使う側は引数としてthisと同じクラスのオブジェクトを、
利用者の責任で用意して渡す必要がある。
(続く)
239 :
232 :2006/06/14(水) 03:14:44
(238の続き) Clone()はthisのコピーを作って返す。フツーのC++プログラムなら、 こいつもそれぞれのクラスできちんと定義する必要があるのだが、このフレームワークでは、 Streamer()を利用して、thisにファイルに書き出しておいて、それを読み出すことでコピーを作る、 というトリックを使っている(このトリック自体は、永続化フレームワークではよく使われる)ので、 Clone()の定義自体はTObjectのやつを使い回すことが可能になっている。 つまり、それぞれのクラスでClone()を定義する必要はない (TNamedみたいに、TObjectの振る舞いを変えたい、という事情がない限りは)。 さっきの「MyClass::Clone()を実装する必要が本当にあるの?」は忘れてクレイ。 上に書いた理由から、Streamer()はそれぞれのクラスで定義することが必要だし、 Clone()は定義する必要はない。 > classのmemberをポインタにするかどうかの判断は、 > 実行時にnewしたいかどうかだけで決めるものですか? これも関係ない。混乱させたならスマソ。 このフレーワークの他のクラスでやってるみたいに、ポインタじゃなくてOK。 以上、思ったよりも長文になった。関係ない人には申し訳ない。
240 :
232 :2006/06/14(水) 03:41:03
×Streamer()を利用して、thisにファイルに書き出しておいて、それを読み出すことでコピーを作る、 ○Streamer()を利用して、thisをファイルに書き出しておいて、それを読み出すことでコピーを作る、 一番肝心なところで・・・orz
241 :
231 :2006/06/14(水) 05:40:07
>>240 詳細にどうもです。
ソースは理解していないけど、何をしているかが分かりました。
参考にして書き書きします。
242 :
232 :2006/06/14(水) 08:06:59
フレームワークの設計(というか実装というか)には いろいろ気になる部分もあるが、何とか頑張ってホスイ。
template < int X > class Foo { //ストリーム演算子をfriend宣言 template < int X > friend std::ostream & operator << ( std::ostream & out, Foo<X> const & val ) ; private : //実際の出力は、このメンバ関数が行う。 void print( std::ostream & out ) const { out << "private!" ; }; } ; template < int X > std::ostream & operator << ( std::ostream & out, Foo<X> const & val ) { val.print(out) ; return out ; } int main( ) { Foo<1> f ; std::cout << f << std::endl ; } 上記のコードを、VC8でコンパイルすると、 >C2593: 'operator <<' があいまいです。 と言われてしまいます。 どうも、friend宣言も関数の定義と解釈しているようなのですが。 Barton and Nackman trickを使えば、なんとか意図通りのことができるのですが、 これは仕方がないのでしょうか?
>>243 template < int X >
class Foo;
template < int X >
std::ostream & operator << ( std::ostream & out, Foo<X> const & val ) ;
template < int X >
class Foo
{
//ストリーム演算子をfriend宣言
friend std::ostream & operator << <> ( std::ostream & out, Foo const & val ) ;
245 :
243 :2006/06/14(水) 12:57:42
>>244 >operator << <>
この <>とはなんでしょうか?
>>245 friend に指定している名前がすでに宣言された template であるとコンパイラに
認識させるための表記。また関数テンプレートの引数を、関数引数から
推測させる場合の省略表記。この場合は2番目の引数 Foo<X> から推測される
<X> の省略。
この friend が関数テンプレート operator << の X による特殊化を指すようになる。
やりたいことはこれで OK ?
関数テンプレートの宣言を事前に行わないと、文法エラーになってしまうので、
ウザイけど前方宣言が必要。
247 :
244 :2006/06/14(水) 13:28:45
>>246 なるほど。
そういう意味での<>だったのですか。
friendでも使えるとは知りませんでした。
operatorで使っていたので、なんだかまったく別の文法のように考えてしまいました。
248 :
244 :2006/06/14(水) 13:45:41
もうひとつだけ。
>>244 のコードは、
Nontype Template Parameterのときだけコンパイルエラーになるのですが、
何故でしょうか。
>>248 詳しく調べてないけど、 VC がバグってんじゃね?
ちなみに cygwin gcc 3.4 だと最初のコードでも
テンプレート仮引数名の重複さえ直してやればコンパイルはできた。
全部の特殊化に対する friend 指定になっちゃうと思うけど。
間違えましたOrz
みんなすげーな、おれわけわからん。
255 :
デフォルトの名無しさん :2006/06/14(水) 18:06:18
自動生成されるcopy constructorって、 memberのcopyにはoperator=が使われるんですか? それとも、copy constructorが使われるんですか?
>>255 コピーコンストラクタに決まっているだろ。
>>255 operator=を定義しておけば自動生成のコピーコンストラクタで使ってくれるのか、という問いなら、
「そんな気の利いたことはやってくれない」が答えだな
258 :
255 :2006/06/14(水) 19:20:23
259 :
デフォルトの名無しさん :2006/06/15(木) 04:50:05
相談させてください。 class base { virtual base* this_p(void) = 0; }; class derived : public base { derived* this_p(void) { cout << "derived called" << endl; return this; } }; class derived2 : public derived { int value; derived2* this_p(void) { cout << "derived2 called" << endl; return this; } }; で、 base* p = new derived2; p->this_p(); // これは"derived2 called"を出力 p->this_p()->value; // これはエラー となる理由を教えてください・・・。
>>259 derived::this_p()にvirtualを付けないと、それ以上探してくれない。
261 :
259 :2006/06/15(木) 05:21:37
>>260 ゴメンなさい。259のコードはvirtualが抜けてました。
derived* this_p(void)にvirtual付けても結果は同じであります('A`)
pがderived2*じゃなくてbase*だから。
RTTIというのは、文字通り実行時に働くからじゃないのかな。 pの型は、class base *なわけで、これにはとvalueはない。 たとえばこんなコードだったら void f( base & p ) { std::cout << p->this_p()->value ; } int main() { derived d ; //dにはvalueがない f( d ) ; } C++
間違えた。 p.this_p()->value メンバ変数のアクセスへRTTIは働かないから、 こういう使い方は間違いなのではないかと思う。
265 :
243 :2006/06/15(木) 06:33:38
あれから考えていたのですが、Barton and Nackman Trickも捨てがたいです。
前方宣言も必要ないし。
多少面倒でも、
>>244 のようにすべきなのでしょうか。
template < int X >
class Foo
{
//Barton and Nackman Trick
friend std::ostream & operator << ( std::ostream & out, Foo<X> const & val )
{
val.print(out) ;
return out ;
}
//こっちは厳密に言うとBarton and Nackman Trickじゃないかもしれないけど、よりジェネリックに。
/*********
* template < typename CharType >
* friend std::basic_ostream<CharType> & operator << ( std::basic_ostream<CharType>, Foo<X> const & val) ;
* { val.print(out) ; return out ;}
*************************/
private :
//実際の出力は、このメンバ関数が行う。
void print( std::ostream & out ) const { out << "private!" ; };
} ;
>>265 そっちだと ADL でしか見つからないことになる。それで問題なければそっちでいい。
ダメなケースを探してみたけど、あんまり思い当たらない。おおかた問題無いと思うよ。
268 :
259 :2006/06/15(木) 11:17:25
>>264 > メンバ変数のアクセスへRTTIは働かないから、
納得しました。
どうもありがとう〜。
269 :
243 :2006/06/15(木) 12:21:12
>>267 ADLでしか解決できないのは知っていますが、
演算子のオーバーロード、特にストリーム入出力のためのシフト演算子に対して、
ADL経由でない使い方というのが思い浮かばなかったので、
特に問題ないだろうと思っています。
しかし、なぜNontype Template Parameterのときだけ曖昧になるのか理解できず。
ちなみにvirtual methodはRTTI抜きでも働くから
その辺誤解のないように。
そう言う意味では、
>>264 のレスはおかしい。
>>269 g++では問題なくコンパイルが出来るから、VCのバグかね
>>269 つ friend std::ostream & ::operator << ( std::ostream & out, Foo const & val ) ;
「<>」と「::」のことか?
273 :
272 :2006/06/15(木) 13:47:05
ごめん、勘違いしていた。 結論はnontype template parameterの時はADLがうまく働かないだけ
274 :
243 :2006/06/15(木) 13:53:45
すると、VC8のバグであると認識していいのでしょうか。 だからといって、どうしようもないのですが。 結局、workaroundということで対処するしかないのかな。
規格上はnon-type駄目ってことはないみたい。
276 :
デフォルトの名無しさん :2006/06/15(木) 16:36:37
class MyClass { private: OtherClass* mP; public: SetP(OtherClass* p) { mP = p;] }; みたいにメンバーにポインタを渡したい場合、 OtherClass* p = new OtherClass; SetP(p); delete p; のように外でdeleteされてしまうと困るときってあると思うんですが、 pが外でdeleteされない、もしくはdeleteされても対処出来るようにするには、 どういう風にすればいいんでしょうか。
ポインタを使っている以上諦めるしかない。
>>276 OtherClassのコピーではだめ?
同じOtherClassの「あるオブジェクト」を参照したいのだったら、
スマートポインタ的なことをしたほうがいいかと
>>276 MyClassの中でも外でも一貫してboost::shared_ptrを使え。
場合によってはstd::auto_ptrで十分かもしれないが。
280 :
276 :2006/06/15(木) 18:04:11
>>277-279 ありがとうございます。
自分の場合でどれがいいかを検討してみます。
>>276 実はOtherClassは固有の名前をcharで持っていて、
単純にコピーすると名前もコピーされて重複するのが嫌なので、
ポインタで渡す事を考えていました。
コピー後に名前を変更するのを手動でするのも面倒だし、
だからと言って関数内に記述して自動で名前が変えられてしまうのも気持ち悪いしと思って。
そういう場合は、やはりポインタで渡してやって、
固有の名前を必ず持つようにしておくもんでしょうか?
281 :
276 :2006/06/15(木) 18:05:09
×実はOtherClassは固有の名前をcharで持っていて ○実はOtherClassのインスタンスは固有の名前をcharで持っていて
>>280-281 > 実はOtherClassは固有の名前をcharで持っていて、
ここ以下さっぱり意味がわからん。
よくわからんが 名前をコピーしないコピーコンストラクタなりを書けばいいんじゃね?
VC++6.0使ってるんですけどDIRECTXSDKのバージョンによっては(最新?) SDKが使えないようなことをどっかで見たようなきがするんですけど 最新のやつでも問題ないですか?MSのページ見たけどよくわからん
>>284 すれ違い。 DirectX でスレタイ検索しろ。
286 :
284 :2006/06/16(金) 02:05:03
わかりましたー
C++の言語仕様はいくらかマスターしてきたように感じます(60%くらい?) しかし、標準ライブラリがまだまったく勉強できていません。(Cの標準ライブラリは一応ひととおり勉強しました) C++標準ライブラリについて勉強できる良質なサイトや標準ライブラリのリファレンス的なサイトを紹介して下さい。 MSDNライブラリCDを持っていますが、これは一応Visual Studio.NET用文書中に標準ライブラリの部分もあるのですが、かなりおざなりです。(C標準ライブラリの方も・・・) ARMには何も載ってないし・・・
半日例外について学んでいたのですが、結局C++では、 stlのexceptionだけ無難に使っておけばOKみたいな感じなんでしょうか と、わざとアホっぽく書きましたが、いや実装よりの話となると、どれも(どこも)曖昧で…
>>291 作るものによるが、レイヤーがはっきりしている様な場合(例えばフレームワークとビジネスロジックとか)は、
ちゃんと例外クラスを作って、誰がどのレイヤーの例外をキャッチするかなどを決めておかなと、
困ったことになるかもねー。
もちょっと書くと、通信クラスの例外がアプリケーション層まであがってきても困ったりする。 そんな感じかな。
294 :
291 :2006/06/17(土) 22:29:20
>>292-293 レスありがとうございます
今までentityの例外は、boundaryやcontrollerが処理する(entityはエラーとか気にしない)みたいな意識でした。
つまりentityの例外はentityで処理しろ、みたいな認識で良いのでしょうか。
それなら狭い範囲で収まるわけで、独自の例外クラスが多くても混乱無さそうですね。
はい、そんな感じです。 基本は、受け取っても処理できない場所まで例外を上げるな、です。致命的な例外で、アプリケーションを 終了するしかないようなクリティカルなものは別ですが。 私も例外に関しては今でも試行錯誤で、それほどえらそなことは言えないのです。 お互いに頑張りましょうね。
296 :
291 :2006/06/17(土) 22:58:24
いやー、適当にstd::exception投げまくって、最悪、エントリーで一つcatchしとけば 良いかなぁとか思ってました。危ない危ない。 お付き合い感謝、丁寧にありがとうございました。
297 :
デフォルトの名無しさん :2006/06/17(土) 23:03:01
ClassNameがクラス名で、そのクラスはintを引数にとるコンストラクタをもつとして ClassName c(1); と ClassName c=ClassName(1); って全く同じ意味なんだっけ?
例外クラスを継承するといいことがあるかもよ。 FooExceptionとDerivedFooExceptionがあったときに、それをキャッチする層で同じ処理するなら FooException&でうけて、別々に処理するならそれぞれキャッチするとか。 ただ、これが「良い」やりかたなのかどうかは俺は知らない(無責任)
>>293 ユーザーには通信でエラーが発生したことを伝える必要があることを考えると、
通信クラスの例外がアプリケーション層まであがってこないと困る、とも言えないか?
うん、そういう場合は、上位が理解できる例外クラスを再送出するようにしてる。 なんて言ったらいいかなー、「生」の例外はあげちゃだめってこと。そうしないと、上位レイヤーが 下位レイヤーの詳細を知ってなんらかのアクションを起こさないといけないから。
302 :
デフォルトの名無しさん :2006/06/17(土) 23:37:49
>>299 それどういう意味?
どっちの場合もコピーコンストラクタは呼ばれないみたいだけど?
#include<iostream>
using namespace std;
struct myClass {
int p;
myClass(int i){p=i;}
myClass(const myClass & m){
cout<<"COPY CONSTRUCTOR IS CALLED"<<endl;
p=m.p;
}
};
int main(){
myClass mc1(1);
myClass mc2=myClass(2);
cout<<mc1.p<<endl;
cout<<mc2.p<<endl;
}
というプログラムで、出力は
1
2
で、COPY CONSTRUCTOR IS CALLEDっていう文字列は出力されなかったけど。
>>301 それをするには、下位レイヤー自身がすべての実装を知っていることが必要だが、
インターフェースを規定して実装を置き換えることができるようなモジュールでは
そうはいかないよね?
>>302 後者では意味上はコピーコンストラクタが呼ばれるが、
コンパイラがコピーを省略することを許されている。
コピーコンストラクタが private になってたりすると差が出る。
305 :
デフォルトの名無しさん :2006/06/17(土) 23:51:01
>>303 すみません、質問の意味が良く分かりません。
下位レイヤー自身は、自分が直接使用するものの詳細は当然知っていますが、誰から呼ばれるかは
知りません。
>>306 あーごめんよ。コールバック関数とか、そういうのの話ね。
ostream に対して汎用的なモジュールを作ったとして、
そこにファイルが渡されるかネットワークストリームが渡されるか
さらには未知のデバイスが渡されるかわからないとき
再送出をどうするかってこと。
>>307 んー、コールバックは関係ありません。
その例でいえば、ストリームを処理するクラスがあるときに、それを呼び出すレイヤーに、ファイル系や
ネットワーク系の例外を直接なげちゃ(あるいはキャッチせずにそのままじゃ)駄目ですってことです。
何のために「ストリーム」という抽象化をしたのかわからなくなります。
どうもうまく話がかみ合わない気が・・・。
ああ、やっと
>>303 の意味がわかりました。
あるinterfaceには(あるいはそれと同じレイヤー全部のinterfaceには)、それ専用の例外クラスを定義し、
そのinterfaceを実装するコードが使用するところから上がってきたexceptionは、必ずcatchし、
その専用の例外クラスをthrowするようにする、ということです。
>>309 やっぱりそうなるかね。面倒だからそのまま外まで飛んでいくようにしたほうが
コーディングも文書化もとっても楽なんだけどね。
発生したエラーの詳細が失われないように工夫も要りそうだ。
面倒だけど、ここらへんが妥協点だと言われれば納得もできそう。
今度なんか作るときはそんな感じに設計してみるよ。つきあってくれてありがとう。
いえいえ、こちらこそありがとうございました。 私も日々勉強です。システム全体の例外・エラー処理って本当に悩ましいですよね。ではー。
例外処理と抽象化は無関係だ
個々の事例を挙げてしまうと、結局ケースバイケースってなことになるな。 どっちが優れてるとか、どっちが劣っているとかないから、好きなようにしる。
言語c++ 文字列xの中に文字aが含まれる個数(含まれない場合は0)を返す関数 int abc(const char x[], int a) を作るという問題なんですがわかる方よろしくお願いします。 文字列にaが何個入っているかを表示するプログラムです。
そもそも問題がCで十分だし……。
>>318 int abc(const char str[], int a) { return static_cast<int>(std::count(str, str+strlen(str), a)); }
int abc(const char x[], int a){ return std::count(&x[0], &x[std::strlen(x)], char(a)); }
ケコン
セクス
ニンシン
ハラキリ
ダタイ
イシャリョウ
ナリキン
330 :
243 :2006/06/19(月) 12:06:48
流れを変えてみる。 VC8はこれでコンパイルが通る。不思議……。 template < int Parameter > class Foo { public : //これでは通らない。 //template < int AnotherParameter > //friend std::ostream & operator << ( std::ostream & out, Foo<AnotherParameter> const & val ) ; //template < int AnotherParameter > //もしくは単純に template < int > friend std::ostream & operator << ( std::ostream & out, Foo<Parameter> const & val ) ; private : //これは言うまでもなくprivateなメンバ関数 void print( std::ostream & out) const { out << "Private!" ; } } ; template < int AnotherParameter > std::ostream & operator << ( std::ostream & out, Foo<AnotherParameter> const & val) { val.print(out) ;//友達なのでおkらしい return out ; } int main( ) { Foo<1> f ; std::cout << f << std::endl ; }
本当に初心者な質問ですいません。 class A { const char *buf; public: A():buf("buffer"){}; }; この"buffer"はクラス変数になるのでしょうか? コンストラクタ終了後、死んだスタック上にある。とかそのようなこと無いですか?
ならない。
STLportか。
strstream Str; などと宣言したStrに Str << "ABC"; などと文字列を格納したあと、このABCをクリアしてバッファを初期状態(pcount()が0を返す)ようにしたいのですが、どのような手順を踏めばよいのでしょうか? ご存じの方いらっしゃったらご教示ください。
stringstream使いなよ。strstreamはobsolete。 Str.str("");
ありがとうございます。 使っているライブラリ関数がstrstreamを引数に要求するので仕方なくつかっているのです(^^;
じゃ、使っているstrstreamに独自拡張がない限り諦めるしかない。
酷いライブラリだな。 それはともかく、streastreamをnewするようにして、 初期状態に戻したくなったら、新しいのをnewし、 それから古いのをdeleteするようにしたらどうだろう。 それとももしかしてboost.optionalはコピー不可の型にも使えた?
340 :
デフォルトの名無しさん :2006/06/20(火) 23:04:24
引数に取るならiostreamの参照かポインタで事足りると思うんだけどなぁ。 どういう設計してるんだか。
>>339 こちらのアイデアでいこうと思います。
ありがとうございます。
しつもーん #undef LABEL #define LABEL (1) をマクロ関数とか使ってLABELを一回しか書かないで実現することできる?
実装依存じゃね? #undef が要らなくて #define で上書きできる実装もあった気がする。
class A { public: A(){} A(int n) {} }; class B {} int main(void) { B b(3); } このコードをコンパイルすると const int から class Bに変換することはできません とエラーになりますが C++ではコンストラクタは継承されないの?
>>344 仮にAのコンストラクタが使われてしまったら、
B固有の初期化が出来なくなっちまう罠
されないよ
C++”では”っていうか、コンストラクタが継承される言語なんてあったか?
348 :
デフォルトの名無しさん :2006/06/21(水) 02:49:23
>>344 継承されない。C++には多重継承があるから、
どの基底クラスのコンストラクタを呼べばいいか決められない。
B でコンストラクタを定義してないから、 B() : A() { } // デフォルトコンストラクタ B(const B& b) : A(b) { } // デフォルトコピーコンストラクタ が自動的に作られる。 それ以上は自分で書かないといけない。 そういうエラーが出るのは、 B(int) がないのでコピーコンストラクタを呼ぼうとしてるから。
>>350 コピーコンストラクタを呼ぼうとしてるわけじゃないよ。
AとBに何の関連もない様に見えるのは気のせい?
class B に B::B(int hoge) がないですね。コンパイラも困っているみたいです。
幻の継承を見た!
新しいC++の仕様なのかもね 「直後に定義されたクラスは直前のクラスを暗黙的に継承する」とか
>>351 ということは、
>const int から class Bに変換することはできません
は B(int) がないよというエラーなのか?
変な書き方するもんだな。
>>356 暗黙の型変換を考えれば自然なエラーメッセージだと思うが
const HOGE& hogeとHOGE const& hogeはどう違うのか教えて下さい。 constスレで調べようと思ったけど、ぐぐってもスレタイ検索しても見つからないorz
360 :
343 :2006/06/21(水) 16:24:25
なんかいろいろ勘違いしてたみたいです。 あざっした!
int ((* a) [10]); int * (b[10]); a=b; とすると error: cannot convert `int*[10]' to `int (*)[10]' in assignment というコンパイルエラーになるんだけど、 int ((* a) [10]); と int * (b[10]); ってそれぞれどういう意味なんでしょう?
>>361 a は int の配列(要素数 10 )へのポインタ。
b は int へのポインタの配列(要素数 10 )。
>>361 int*[10] は(intへのポインタ)の配列
int(*)[10]は(intの配列)へのポインタ
int *a[10];
int (*b)[10];
int x =123; // int
int y[10] = {456}; // intの配列
a[0]=&x; // intへのポインタを格納
b=&y; // intの配列へのポインタを格納
printf("%d,%d", (*a[0]),(*b)[0]);
結果
123,456
364 :
363 :2006/06/23(金) 13:28:29
遅かったか orz
365 :
363 :2006/06/23(金) 13:30:28
しかもaとbが逆だ orz
367 :
287 :2006/06/24(土) 15:53:22
368 :
358 :2006/06/24(土) 16:20:35
>>359 亀レスですが、どうもありがとうございました。
369 :
369 :2006/06/24(土) 17:11:37
>>369 亀レスですが、どうもありがとうございました。
370 :
370 :2006/06/24(土) 17:54:01
>>371 亀レスですが、どうもありがとうございました。
>>370 どう見ても兎レスです。
本当にありがとうございました
void traverse_queue(queue *q, int (*callback)(void *)){ list *l; for (l = q->head; l; l = l->cdr) callback(l->car); } とあるところでこんなコードみかけたんですが callbackって何でしょうか? 上記はコード全体の一部なんですが、コード全体を見渡しても callback型に関する定義はどこにも見当たらないのです そのコードは string.h stdio.h stdlib.h をインクルードしてましたがその中にも当然そんな定義ないし・・・
schemeのソースっぽいね。 型はint (*)(void *)じゃん。 「intを返し、引数がvoidポインタの関数」 という型でしょ
callbackは型じゃなくて仮引数名だね。
型は
>>373 さんの通り。
>372 そのソースのcallbackは、その関数を書いた奴がつけた引数の名前。 引数の型は>373、じゃちょっとおかしいな 「intを返し、引数がvoid*の関数、へのポインタ」
>>373 「……」へのポインタである引き数callback
378 :
デフォルトの名無しさん :2006/06/25(日) 03:13:49
(*callback)()って呼び出すもんだと思ったら 普通の関数形式で呼べるんだな...
すいません、クラスのことで少し質問させてください。 たとえば以下のようなクラスをつくったとします。 class abc{ private: int a; public: void xyz(abc k){ int i = a; int j = k.a; } } この場合、関数xyz内でのaへのアクセスは問題なく、k.a は引数のprivate変数なので アクセスできないものと思っていたのですが、コンパイルも問題なく通りました。 メンバ関数が自身のクラスを引数にした場合、 そのprivate変数にはアクセスできるものなんですか?
381 :
デフォルトの名無しさん :2006/06/25(日) 10:18:03
すいません。どなたか教えて頂きたいのですが、 class A class B を定義したとして、 classAの中で、メンバ変数として、 @ B b A B* b @とAのどちらかで定義したとします。 これらの違いがはっきり判りません。 Aの定義方法の場合、 class A のメソッドの中で、 b = new B(); と定義する事で、右辺で確保されたメモリ空間のアドレスが、 bに代入され、その後、bはアドレス参照により、 class B のメンバ変数やら、メソッドなどを使用できる(アロー演算子を使って)、 と思うのですが、 @の定義方法の場合、 b.メンバ変数 = メンバ変数の値 b.メンバ関数 などで、new しなくても使えると 思います。 そうすると、@の定義方法の方が簡単でよいと思うのですが、一般的には、 あるクラスが、あるクラスをメンバ変数としてもつ場合、Aの方法が正解 だと思います。この違いは一体なんなのでしょうか?
>Aの方法が正解だと思います。この違いは一体なんなのでしょうか? 正解だと思った根拠を聞こうか。
383 :
デフォルトの名無しさん :2006/06/25(日) 11:10:10
>>382 Aの方が正解というのは、他の方のソースを拝見すると、
クラスの中で他のクラスを持つような場合、
ポインタ変数として宣言し、コンストラクタで、new
デストラクタで、deleteしているので、こちらが
一般的なのかな?と思っています。
もし、Aのようにポインタ変数ではなく、@のような
宣言方法ですと、どのようなタイミングで、メモリ確保
が行われるかも判りません。ポインタ変数ですと、
new されたときに確保できるのは判るのですけれども。
説明が分かりにくくて申し訳ありません。
384 :
デフォルトの名無しさん :2006/06/25(日) 11:13:31
些細な質問で申し訳ありませんが while (n!=i) のような文の!とはどんないみなのでしょうか?
>>384 そこで"!"だけ抜き出すな。"!="で1つの演算子だ。
>>383 二つのクラスが一蓮托生なら1でもいいんじゃないの。
AとBの寿命が違うならポインタにしとくべきだとは思う。
間違ってたら突っ込みヨロリ。
俺も寿命の問題(確実に分かりやすい)が一番重要だとは思うけど、 でかいプロジェクトが多いもんだから、ヘッダ重ねてコンパイル時間が長引くのがいやで、常に(2)を採用しているな これはこれで定型文書くのが面倒なんだが
>>384 !は否定の意味。Notね。
!=だと、not equal
>>383 俺はメンバクラスにするのならば@だけど。deleteし忘れると困るし、
極力使わないですむような実装にしてる。
390 :
デフォルトの名無しさん :2006/06/25(日) 12:18:27
>>386 回答の方ありがとうございます。
確かに、
>>381 で@の宣言方法ですと、deleteしなくても、class A のインスタンスが、
スコープから外れると、class A のデストラクタ→ class B のデストラクタ
という風になり、同じタイミングでメモリから解放されるということですね。
もし、class Aが保持する、class B のインスタンスを自分の好きなタイミング
で開放したい時などは、Aの宣言の方がよいということですね。
あと一つ疑問なのですが、皆さんは、あるクラスで、別クラスの
インスタンスを持ちたい時は、どのような判断で、@、Aの宣言を
使い分けているのでしょうか?また、@、Aの各宣言の、長所、短所
など教えて頂けたらありがたいです。
>>387 ちなみにコンパイル時間変わる?
Bがインターフェースでない限り同じな気がする・・が、良い方法があるのだろうか。
>>387 うちの場合はコンパイル時間よりもバイナリコンパチビリティが保てることの方が重要だな。
今のバイナリに変更部分だけコンパイルして開発作業ができれば
全体のビルドは時間がかかっても平行でやっておけばいいのだ。
@の欠点は、class Aがclass Bの定義に依存してしまうということ。 具体的には、class_a.hはclass_b.hをincludeしなくてはならず、class Aには 全く変更が無くてもclass Bが変更されるとコンパイルの必要が出てくる。 Aの形式にしておけば、そのような依存関係を断ち切ることが出来る。 具体的には次のようにやる。 class B; class A { ... B *b; }; なぜ依存しないほうがいいかというのは、そのうちわかってくると思う。
394 :
デフォルトの名無しさん :2006/06/25(日) 12:28:11
>>387 >> 389
質問を書き込んでる間に、回答してもらいありがとうございました。
なるほど、やはり、deleteのタイミングさえ気を付ければ、@、A
であまり変わらないということですね。
大変勉強になります。
>>387 さんに回答して頂いた内容で、
「でかいプロジェクトが多いもんだから、
ヘッダ重ねてコンパイル時間が長引くのがいやで、
常に(2)を採用しているな
これはこれで定型文書くのが面倒なんだが
」
とありますが、私もプロジェクトがかなり大きいので、
お聞きしたいのですが、上記の意味は、
クラスをメンバ変数で宣言する際に、ポインタ変数で宣言
するとコンパイル時において、何か利点などあるのでしょうか?
395 :
393 :2006/06/25(日) 12:31:57
>>393 は、class Bが標準のクラス(というと語弊がありそうだが)以外の場合の話。
STLのクラスを使う場合などは@の形式を使う場合が多い。
>>392 ヘッダのコメント修正されただけで、全コンかかってむかつくことないの?w
397 :
デフォルトの名無しさん :2006/06/25(日) 12:41:58
>>391 >>392 >> 393
またまた、質問を書いている時に回答して頂いて、
ありがとうございました。
以下のようにポインタ変数で宣言すると、
class B;
public class A{
B* b;
}
bはもともとクラスBのアドレスを入れる変数なので、
クラスBの処理の内容までは知る必要がなく、Bの型さえ知って
おけばメモリ空間へどれだけメモリを確保すれば良いのかが
判る。というような感じですね。
しかし、もし以下のような宣言方法だと、
class B;
public class A{
B b;
}
B自体のクラスの中身をしらないと、メモリ空間を確保できない
ので、class A はclass B に依存してしまうということですね。
何か頭がすっきりしました。
本当に皆さんありがとうございました。
>>391 class Aのヘッダでclass BのヘッダB.hをインクルードせずに>393のようにする。
実際にBにアクセスするA.cppでB.hをインクルードすれば、AはBにアクセスできる。
Aを使うCモジュールでは、B.hがインクルードされないので、
class Bの変更でCは再コンパイルされない。←これが>393の言うソース依存関係を断ち切ると言うこと。
その必要もない。←これが>392の言うバイナリコンパチビリティ
>>391-392 実装段階じゃあまり効果はないが、宣言を良く弄る段階ならもう劇的に変わる。
要するに波及を一切シャットアウトできるわけだ。
最初からある程度完璧な設計を捻出できたり、
あるいはヘッダの依存をきっちり区切れる自信があるなら、必要ないかもな。
って、もう皆が詳しく書いてくれてるな。
private部分をpublic部分と分離しない(実装仕様もひとつのヘッダに宣言する)ところじゃ、 そりゃもう天と地の違いがありますな。
401 :
デフォルトの名無しさん :2006/06/25(日) 13:05:07
>> 398 >> 399 >> 400 回答ありがとうございました。 皆さんは、どのようにしてそのような知識を得るのでしょうか? 私はまだC++を仕事で使うようになり、1年ですが、まだ、本などを 読んだりして勉強しながら仕事を進めているのですが、 今回、皆さんに回答して頂いたような事は本には載っていません。 もしかして、実際に、VC++などで、デバックを行い、メモリウィンドウ などで、値を確認しながら、勉強されているのでしょうか? 本当に質問が多くて申し訳ありません。
402 :
382 :2006/06/25(日) 13:16:37
>>401 取り敢えずEffectiveC++くらいは読んだと思っていいのかな?
だとしたら後は実践あるのみだろ。
ちなみに漏れは、>381だけでは一概に言えないので適材適所で使い分けているとしか言えない。
403 :
379 :2006/06/25(日) 13:31:32
C++でメンバ関数をメソッドとかいう呼び方をするのはちとどうかと。
別に問題ない。 言語によって呼称が違うだけで、意味するところは同じ。 つまんないことにこだわらない方がいいよ。
仮想関数がメソッドだよなぁ。 普通のメンバ関数はメンバ関数だ。 つまんないことってw C++作った人がそう言ってるのに、 それを知らずに我を通すのも何だかな、と思う。 まぁ日本人的にどうなのかは知らんがw
>>404 public methodとか普通に言うけどなぁ。
パブリックなメンバ関数っていちいち言ったりしてる?
意味が通じれば何でもいい
>>406 仮想関数は、virtual functionだけど。
まぁ日本人的にはメソッドなのかも知らんがw
>>401 いや、載ってる。よく見かける話。
君がまだそのような本を読んだことが無いってだけの話だから、
そのうち読むことになるだろう。
412 :
禿 :2006/06/25(日) 14:44:07
俺、サブとスーパーじゃ意味がわからんから、 ディライブドとベースにした。
別名がメソッドならそれでいいじゃない。
>>411 英語を話す人としゃべったことないみたいだね
>>411 厳密に言うと、C++の文脈で言うメソッドとメンバ関数・仮想関数では
レイヤーが違うということであって、仮想関数のことをメソッドと呼ぶ
のではない。
>>415 それはあなたの常識?
それとも日本の常識?
それとも世界的な?
正直どこの馬の骨とも知れない匿名の個人の意見より、
どこかのサイトに書いてあることの方が信用できます。
なのでソースを貼って頂けると。もちろん書籍でも可です。
418 :
415 :2006/06/25(日) 15:43:10
>>416 常識かどうかは知らない。
C++ではメソッドをメンバ関数という手段で実現するのだが、仮想関数を使う場合には、
あるオブジェクト(インスタンス)のメソッドがメンバ関数で実現されているかどうかは
わからない。その意味で、
>>411 のURLには、
A virtual member function is sometimes called a method.
と書かれている。
何が真実か知りたければ、調べてください。
メソッドが概念で、C++ではその概念がメンバ関数で実装されてるって意味じゃないか? メソッドがオブジェクト指向用語だとすると仮想関数じゃなきゃメソッドって言わないのかも >仮想関数を使う場合には、 あるオブジェクト(インスタンス)のメソッドが >メンバ関数で実現されているかどうかはわからない。 この説明はよく分からんけど。 メンバ関数以外で実装されたメソッドってどんなんだ?
420 :
415 :2006/06/25(日) 16:15:15
>>419 >メソッドが概念で、C++ではその概念がメンバ関数で実装されてるって意味じゃないか?
そうです。それを私は「レイヤーが違う」と表現しました。
>メソッドがオブジェクト指向用語だとすると仮想関数じゃなきゃメソッドって言わないのかも
どのような論理でそうなるのですか?
>この説明はよく分からんけど。
メンバ関数とは、あるクラスで定義された関数のことです。
>>411 のURLには
>member function - a function declared in the scope of a class. A member function
>that is not a static member function must be called for an object of its class.
と説明されています。
また、あるオブジェクトから見たときのメソッドが、そのオブジェクトのクラスで定義された
メンバ関数ではない場合があるという意味です。
421 :
415 :2006/06/25(日) 16:21:08
とまぁ、どこの馬の骨ともわからない私と会話しても、意味が無いのでしょうね。 Netには、member functionとmethodについて、C++の黎明期に議論された痕跡などが ころがっているはずなので、真実が知りたいのならお調べになってください。
422 :
デフォルトの名無しさん :2006/06/25(日) 16:26:26
http://www.open-std.org/jtc1/sc22/wg21/ News 2006-06-24: The C++ Standard Library Issues List (Revision 43) is available (.tar.gz)
News 2006-06-24: C++ Standard Core Language Issues List (Revision 42) is available, also committee version
知らないうちに friend T; が有効になる予定になってた。
しょうもな。 通称メソッド、正しくはメンバ関数。 それ以上でも以下でもない。
規格ではmember functionの事をmethodとは一切呼んでおりません。
要するに class A { public: virtual void hoge() {...}; }; class B :public A { public: virtual void hoge() {...}; }; Aにとってのhogeは「メソッド」で、Bにとってのhogeは「メンバ関数」ってことか? クラスCがBを継承してhogeをオーバーライドしたら、Bにとってもhogeは「メソッド」に変わるわけかw バカじゃねーの?w
>>426 馬鹿はお前。
仮想メンバ関数の別名がメソッドだなんて、どこから沸いた話だ
関数なんて全部メソッドで十分ですよ。
なんつったっけこーゆーのは。 骨髄反射?
┏┳┳┓ ┏┳┳┓ ┏┫┃┃┃ スレ違い雑談は┃┃┃┣┓ ┃┃┃┃┣┓ ここまで.┏┫┃┃┃┃ ┃ ┃┃┏━━━┓┃┃ ┃ ┃スレ違い ┣┫ ・∀・ ┣┫ END ┃ ┗━━━━┛┗┳━┳┛┗━━━━┛ ┏┻┓┃ ┏━┛ ┣┻┓ ┗━━━┫ ┗━┓ ┗━━━┛
>>425 Bjarne Stroustrupはvirtual member functionのことをmethodだと言ってますが。
このグダグダな展開、もう見飽きたよ
英語よく読めないからわかんないけど 海外のメーリングリストでもこんな議論ってやってるの?w
>>436 あっちは匿名がほとんどないから、ここまで恥ずかしい展開にはならない。
くだらんことで議論すんなよ。
メーリングリストで匿名って日本人も普通やらないと思う。 というかメールではやらないだろ。
>>437 はぁ?C++作った奴が仮想関数をメソッドと呼ぶっていてるんだろうが
>>442 >呼ぶっていてるんだろうが
餅搗け。さもなくば帰れ。
つまり、こういうくだらないことに自分の知識を披露せずには いられない馬鹿が多いってことですな。
最近、巧妙な釣りがはやってるみたいだな。 さっきも宿題スレで「低レベル関数を使えという指示がありました」という コメントに「関数にレベルなんかあるかw」とつっこみを入れた奴がいたけど、 みごとに数人が釣られてた。 俺は最近はやってるこの手の釣りは、だれか一人がやってるんじゃないかと睨んでる。 そういうわけで、困ったチャンは相手にしないほうがいいんじゃないかといいたいわけだ。
議論してる奴らのどいつも結局自分の言葉で説明できてないな。
>>445 >>425 が、わざわざ「規格では」って断ってるだろ。
あと、 stroustrup が何故 "sometimes" と挟んでいるのか考えろ。
君は都合の悪いところを読み飛ばす癖があるみたいだな。
450 :
449 :2006/06/25(日) 18:16:51
おまいら近頃カルシウムが足りてないようですよ
禿げに電話して聞いてみたら?
規格の話なんか誰もしてないのに規格を持ち出す規格厨ウザス
ここはム板で言語系スレ。 規格になじめない人さようなら〜。
そうそう、だから、VCつこてるやつは今すぐ捨てようなw
>>455 VC捨てたら、ICCがうごかんやんけ!
規格厨はうざいよなー いつも規格では、規格ではでんでん言ってるのに 実際のコーディングはうんこ
>>457 それは規格を持ち出すのがうざいんじゃなくて
うんこなコーディングがうざいだけ。うんこ厨とでも呼べ。
禿の記述の意図は、 従来の多くのオブジェクト指向言語、例えばsmalltalk, Objective-Cでは、 virtual member functionと同等のものがmethodと呼ばれていた、 くらいのことだと思います。 以前からclass method/object methodと言われた時期があったから、 禿の書き方はちょっとどうかと思うんですが、まあいいじゃないですか。
>>458 規格を知らない奴とは仕事をしたくないな
ここで議論してる奴はリアルで自分の周りの奴に説法してくれよ 多分ウザがられると思うけど
俺は規格を尊重するし、たまには規格書を読んだりもするが
>>461 みたいなことを言う奴は、理想論ばかり言って
現実からかけ離れたコードを書きそうだから、
一緒に仕事をしたくないな。
つい最近C++の言語的な話をしているときに、同僚が「メソッド」と言ったの で、サクッと無視して自分は「メンバ関数」と言ったのを思い出しました。一 瞬微妙な空気が流れた。どっちでもいいよ……。
コミュニケーション能力のない奴だなぁ。 俺は相手が「ワーニング」と言えばそう言うし、「ピング」と言えばそう言うよ。
>>465 メンバ関数のことは別にどうでもいいが、そのWikiページの説明はアレだな。
「右手:左手の反対の手のこと」
「左手:右手の反対の手のこと」
みたい?
>>468 C++の言語的な話をしてる時はメンバ関数だろ。
みんな呼称のレベルで話してるけど、 結局両者の本質的な違いってなに? それがないなら不毛な議論だと思うけど。
>>471 >結局両者の本質的な違いってなに?
「俺は」視点の違いだと思ってる。
メンバ関数→C++用語
メソッド→OO用語
>>471 あるけど、ここまでのスレの中に答えはもう出てる。
お前らどんだけ話をるーぷさせれば気が済むんだよ
>>471 C++の用語には「メソッド」は無い。
以上。
私、勘違いしてました。 ・オブジェクト指向においてオブジェクトの振る舞いを定義するのがメソッド ・C++ ではオブジェクトの振る舞いをメンバ関数として記述する ってところなのかな?
お前が勘違いしてようがどうしようが関係ない。 いつまで話をループさせれば気が済むんだ。
>>476 お前は馬鹿か?
virtual member function == method
つってんだろ
>>472 ちょっとちがう。
メンバ → C用語
仮想 → Simula用語
メソッド → Smalltalk用語
ちなみに、C++は仮想関数の概念をSimulaから拝借している。
で、C++の仮想メンバ関数は、Smalltalkのメソッドに相当するってそれだけの話なような…。
ちなみにJavaはSmalltalkの用語(メソッドとか、スーパー/サブクラスとか)を拝借している。
OOはあまり関係ない(ストラウストラップのオブジェクト指向なのにメソッドなJavaの例もあるし…)。
強いて言えば、メソッドはケイのオブジェクト指向、仮想関数はストラウストラップのオブジェクト指向。
ttp://d.hatena.ne.jp/sumim/20040525/p1
for (int i = 0 ; i < 3 ; ++i) {} みたいな感じでループ変数の加算時の記述を 「++i」 としているソースばかりですが、 これは 「i++」 でも同じですよね?どうして皆そろいもそろって ++i と統一しているのでしょうか? 単なる慣習? それとも明確な理由があるの?
>>479 お前こそ、ちょっと違わないか?
「メンバ関数→C++用語」は結局のところ、お前の定義でも正しんだろ?
メソッドだって、由来がどうあれ、C++のことで議論してる時にメソッドって言ったら
普通はOO用語としてのそれであって、Smalltalk用語のそれじゃないだろ。
へえ、だからC++プログラマは無駄が多いんだ、納得。
++i の理由については、Effective C++にも書いてあるだろ。
じゃi++と++iって書いたときの違いは何?
T &operator ++() とT operator ++(int)の違い
効率だよ効率!最適化コンパイラなら同じコードを吐くかもしれんけど。
揃いもそろって読解力ない奴ばかりだな。
>>480 をもう一度ちゃんと嫁
まさかとは思うけど 演算子の前置・後置による実行順序のこと言ってんの?
むしろ
>>491 =493が
皆の言ってる意味を理解していないんだよ。
>>480 全員が全員、同じ理由ってわけではないだろうけど、たとえば・・・
C++には演算子オーバーロードがあるから、自作のクラス(イテレータとかね)に
独自のインクリメント演算子の動作を実装するという経験をしている人間も多い。
で、++hogeは通常「何らかの意味で"自身をインクリメント"して"自身の参照を返す"」のに対し、
hoge++には「"自身のコピーを作って"から"自身をインクリメント"して、"コピーを値で返す"」
という動作をさせることが多く、これは前置と比べると明らかにコストがかかっている。
そういうコーディングを経験していると、「前置でも後置でも意味的には変わらない」状況下では、
ほとんど手癖として「前置を選んでおく」習慣が身に付く。
別の言い方をするなら、operator++(int)の実装を経験すると、前置と後置を「同じようなモノでしょ」
と抽象的に同一視する気が(完全にとは言わないけど)失せてしまう。
ちなみにこの習慣の結果、「後置は後置でなければならない理由が無い限り登場しない」
という法則がソースコード内に生まれるので、ほんの僅か可読性も上がるかもしれず、
そっちの理由でも習慣はより強固なものになっていく。
・・・なんて背景が考えられるね。いやまぁ要するにこれ、俺のケースなのだけど。
漏れも漏れも
固定概念って恐いな
自分も前置を可能な限り使っているけれど、 興味本位で、VC8のコンパイラの吐くコードを見てみたら、 Hoge x ; ++x ; x++ ; どちらもインライン展開すると、同じコードになっていた。 まあ、戻り値を使っているわけではないし、 後置インクリメントは、単に自分自身のコピーをとっておいてから、 前置インクリメントを呼び出すという実装だったから、当然かもしれないけど。 でもやはり、前置を使う。 Cで後置が多かった理由は何だろう。 K&Rのコードに、主に後置が使われているからかな。
>>498 スタックについて考察してみればわかるよ。
500 :
499 :2006/06/26(月) 11:58:09
ちなみに
>>495 のような解釈は、演算子のオーバーロード自体を
C++で記述するからこそ発生する矛盾というか、要は後置インクリ
メントと前置デクリメントは、C/C++の性質によるものじゃないという
ことだね。
>>480 その場合はどちらも同じ。
まぁ世の中広いから、違うコードを吐くコンパイラがあるやもしれんが。
一方、クラスで++の演算子オーバロードしたときに、後置演算子だと
効率の悪い場合があるから、そのような場合は特に理由がない場合は
必ず前置演算子を使っておくのが吉。
結局とのところ
>>480 で++iとするのは「単なる慣習」でしょう。
>>480 インクリメント演算子でここまでに説明があったことは、オブジェクト指向の問題じゃ
なくて、単にC++の事情だから間違えないように。
ちなみに、純粋なオブジェクト指向言語と呼ばれているRubyには、インクリメント
演算子は存在しない。
for(i=0;i<10;i++) printf("%d",i); for(i=0;i<10;++i) printf("%d",i); 両方やってみればいいじゃん
>503 何がやりたいのかわからん
馬鹿が沸いた
イテレータだと後置の方が効率イイヨ
ほんと、このスレの住人は、聞きかじりの知識で議論モドキをするのが好きだねぇw
下手な突っ込みも読み飽きた。
510 :
506 :2006/06/26(月) 16:54:50
ばっちゃが言ってたから
511 :
506 :2006/06/26(月) 17:08:17
今調べたら前置の方が良いね
はいはい、もうどっちでもいいよ
constで確保される領域って、バッファオーバーフローとかでも破壊されないの?
どうしても演算子オーバーロードの話に持って行きたがる馬鹿
かといって他の話が出てこないんじゃなぁ。出せないんだろうけど。
なんで?前置後置は
>>499-500 に回答が書いてあるじゃない。
大昔ってか、今でもあるんだけど、CPUの機械語にスタックを実現する為の
前置デクリメントと後置インクリメントがあった、つか、あるんだよ。
で、大昔は、Cの最適化がタコだったから、++iと書くよりi++と書いた方が
より最適化されたし、i--と書くより--iと書く方がより最適化されたってことだよ。
しかし、本当にプリデクリメントとポストインクリメントの歴史を知らなかったのか?
やっぱり、最初にアセンブラをやらせるべきなのかなあ。
なんだろう。 釣りなのかなぁ。 釣りなんだろうなぁ。
まとめると、
>>480 で++iと書くのは「単なる慣習」であって、i++と書いても同じこと。
ただ、その慣習になったのは理由があって、それはC++の演算子オーバーロードに関係がある。
はい、これでこの話終わり。
なんで喧嘩してんのかわからん
>>480 のループはぶっちゃけ今ではどっち使ったって同じ
でも前置が使われることが多いのは何故か → 慣習的なもの
なぜそういう慣習が生まれるのか → まぁいろいろありまして
このへん一致した意見なんじゃねーのか
521 :
520 :2006/06/26(月) 19:44:29
ああ、かぶった いや一点違うところが 演算子オーバーロードはあくまで、慣習を生み出した原因のうちの一つだと思うよ
つまり、どうしても演算子オーバーロードの知識を自慢したい馬鹿の為に話がこじれた、と。
演算子オーバーロードの知識って何?
なんだろう。 釣りなのかなぁ。 釣りなんだろうなぁ。
__ __ n _____ _____ ___ ___ ___ | | / / / / / | /__ __/ [][] _| |_| |__ _| |_ | |. / / /⌒ヽ/ / / ̄ ̄|. l / / | _ | |_ レ'~ ̄| | | / / ( ^ω^ ) / /. / / | |___  ̄| | / / / /| | | | / / ノ/ / ノ /  ̄ ̄ / \__| | |  ̄ /_ / | |_ | |. / / // / ノ / / ̄ ̄ ̄ |_| |__| \/ | |/ / ⊂( し'./ / / |. / | ノ' / / | /. し' ./ /  ̄ ̄ ̄  ̄ ̄
>>520 >なんで喧嘩してんのかわからん
「・・・でも同じですよね?」に答えようとせず、演算子オーバーロードの話を
持ち出してくる馬鹿が多いから。
>>501 で初めて「同じ」という解答があった。
初めてまともなコメントしたのが
>>495 。
それ以前のコメントはクズ。
527 :
デフォルトの名無しさん :2006/06/26(月) 20:02:43
だせぇな、AA貼ってまで煽るならageだ!漢ならageダロ?
526=495
529 :
526 :2006/06/26(月) 20:07:24
>>528 いや、俺夜中に馬鹿を煽ってた書き込みしてた奴だから
>>529 わかってんだったら、煽らずに回等してやれよw
馬鹿迷惑な話だ
>単なる慣習?それとも明確な理由があるの?
に対する回答が
>>482 じゃん
>>495 なんかよりも前に「同じ」回答が出てるのに
それが理解出来ずに
>>483 ,490,491,493を書いたんだろ?
>>495 でやっと理解できたものの引っ込みがつかないんで以降も
>>497 ,503,505,507,512,515と馬鹿みたいな一行コメントを繰り返したんだろ?
全角の引用符使ってる人って、どのスレでもちょっとアレだよね
1分41秒
535 :
526 :2006/06/26(月) 20:26:50
>>532 お前も馬鹿発言した中の一人なんだろう?
その発言番号の中で夜中以外では
>>515 が俺だから。
まぁぶっちゃけると
>>501 も俺な。自作自演って奴だw
釣り師乙。
どっちもどっちだな。 くだらんことに時間使うな。
いずれにせよ、C++使うなら
>>495 は理解しておけ。
おまえら「メソッド」の時もくらだんことであーだこーだ言ってた奴らだろ。 ウザいよ
ハァ?言語も指定せずになにいってんだこいつ
( ´д)ヒソ(´д`)ヒソ(д` )ヒソ(ここはC++スレだよなあ)
っつか、お前に聞いてないし、粗探しならよそでやってくれ
適当な奴も多いけど、しっかりした書き込みしてくれる人もたまにいるから 2ちゃんやめられないんだよな
例外のことで悩んでいます。 例外の効果的な使い方が今一ピンとこないため、自分が書くコードでは一切 使わないようにしています。基本的には戻り値でエラーを返して、無理な場合は アウトパラメータを使うようにしてます。STLが出す例外はトップレベルでcatchしてます。 そんな私なんですが、Exceptional C++という書籍に、例外のことが詳しく載っていると いう情報をWebで見ました。私は田舎に住んでるので、近所の書店にはありませんでした。 また貧乏なため気軽にネットで買うということも出来ません。 この本は買う価値がありますか? また、内容について簡単に教えてくれたらうれしいです。
氷のような冷たさだな。空気読めよ。 俺はその本持ってないから答えられんけど。
>>545 amazonで中身検索できる本だから目次と一部みられるところから判断してみたら?
>>545 基本的にはGuru of weekの内容をまとめ、
そこに出された問題の解答を著者が詳しく解説したもの。
なので、英語を読むのを厭わないなら、GoWの原典
ttp://www.gotw.ca/gotw/ を一通り読めばだいたいの内容は網羅できる。
(MoreExceptionalC++まで含めて)
細かな説明や一般的な解答が欲しければ本を買うしかないが。
急速にスレの質が低下してまいりました
もとからでしょ
>>545 「例外を勉強したいならExceptional C++」という認識は正しい。
が、この本は例外を懇切丁寧に扱ってはいる
(例外の解説に1章/50ページを費やしている)が、
例外を専門に扱っているわけではない。一応勘違いがないようにってことで。
もっとも、C++の例外処理に特化した本てのはないんだけどね。
例外の章の内容は、ざっと書くと
「例外中立とは」「例外保証とそのレベル」「RAII」「やってはいけないこと」
「例外安全なコードの書き方」「テンプレートとの関わり」てな感じかな。
例外を知りたい・知る必要があって、GotW原文はちょっと... と思うなら、
十分買う価値があると思うよ。
少なくとも例外目的で他の本に手を出すぐらいならこの本を先に読むべきだろう。
あと、例外処理だけじゃなくてエラー処理も概観したいというなら、
C++ Coding Standardsもお勧め(これもあまり安い本じゃないけどね)。
エラー処理と例外の解説に1章/20ページを費やしている。
ただ、この本はC++全体を幅広く扱った本なので、手取り足取りな解説は載っていない。
>>553 全然「不測の事態」じゃないじゃんw
俺、そういう使い方嫌い。
戻り値と例外のどっちにするかで喧嘩が起こりませんように。
いつまでたってもnewbieは毎年発生するからね。 永遠の話題なんだと思うよ。
そういえば、throws節(というのかな?関数宣言の後ろにくっつけるやつ)は 明記しないほうが良い(してはいけない?)というのをどこかで見て、それが どこだったか忘れて探したけど見つからないことがあったんだけど、誰か 知ってる人いますか?
>>557 Exceptional C++に書いてあったような気がしたが、記憶が定かではないorz
>>557 例外仕様のことか?
アレは確か例外仕様を定義しても、守れる保証が全然ないし、
守れなかったら double fault で即死するからメリットより
デメリットのほうがでけぇよって話だったと思う。
>>557 C++ Coding StandardsのChapter 75にAvoid exception specificationsってのがあるが
それのことじゃまいか
>>558 項目15.の3. page59-60
索引では「例外仕様」だね
562 :
557 :2006/06/27(火) 00:11:25
みんなありがと。 早速明日(ってもう今日か)調べてみる。
>>545 先にEffective C++の第三版読め。
>>554 確かに不測の事態の説明には向いてないね。ErrorとかExceptionとかRuntimeExceptionとか、
例外クラスに継承関係を作っとくと便利というのを説明したかったんだけど。
>>557 Mingwのg++限定かもしれないが、以前runtime_errorを継承したHogeExceptionというのを作って、
void hoge() throw(HogeException); というメソッドを定義したら、
catch(runtime_error)では受け取れず、catch(HogeException)でしか受け取れなくなった。
継承関係は無視されるみたいでツカエネとか思ったよ。
>>556 ふつー、catch(runtime_error&)だろ
>>567 挙げられてるケースでは状況が変わらないと思うよ。
569 :
513 :2006/06/27(火) 11:31:58
>>514 >いやそういうもんじゃない。環境依存。
環境によってはconstエリアが絶対に破壊されない場合もあるのですか?
いや、何でこんなこと気にするのかって言うと、変数値以外の全ての領域をconstにすれば
どんなバグが含まれていようと落ちないプログラムが作れるのかなと妄想したもんで。
もちろん中の値は壊れたまま動きつづけるようになって使い物にならなくなるんでしょうけど
>>569 例えば組み込み系でconst用セグメントをROMに配置する場合、破壊されないヨ
バグの原因は、バッファオーバーフローだけじゃないだろ。
572 :
513 :2006/06/27(火) 12:09:54
>>570 なるほど、そういう環境もあるんですね〜T。hxです。
>>571 領域を破壊するバグの一つとしてバッファオーバーフローを挙げてみました。
オーバーフローとかでも桁あふれしてもあふれた分無視とか・・・はっ
昔ファミコンでそんな動きを見たことがあるような気がしてきた。
マリオの裏面とか
>>572 たとえconst領域が変更できなくても
RAMにあるリターンアドレスや関数ポインタは変更され得るので
そこが狂ったときはコードでない場所にジャンプしてあぼん。
バッファオーバーフロー攻撃はこれを巧妙に改ざんして
用意したコードにジャンプさせるわけだしな。
関数ポインタはC++で仮想関数を含むクラスインスタンスを作れば
vtblとして山ほど作られるのでヒープ上でも攻撃しやすいよな。蛇足だけど。
>>569 >もちろん中の値は壊れたまま動きつづけるようになって使い物にならなくなるんでしょうけど
プログラムの場合、そういうのを「落ちる」っていうんじゃないかな。
いいえ、そういうのは「暴走」といいます。
>>569 で、特定の変数領域以外すべてread onlyなプログラムにおいて、
read onlyな領域に何かを書き込もうとした場合どうするんだ?
普通なら保護例外吐いて死ぬが。
578 :
513 :2006/06/27(火) 17:51:27
>>574 なるほど・・・要するにconst領域は安全でもconst領域への入り口が破壊される可能性があって、
入り口は必ずconstの外に必要なものって事かな。
無知だからSEのエスパー能力を働かせてみたよ(´・∀・`)間違ってそうだけど
>>577 >read onlyな領域に何かを書き込もうとした場合どうするんだ?
read onlyな領域が物理的に書き込めない環境の話なのでその質問は答えるのは無理。
>>574 さんの回答で妄想は妄想のままということでケリがついたっぽいのでこの辺で退場しまふ。
c/c++で zipファイルを解凍するライブラリって何がよろしいですか?
OS
orz OSは?
582 :
579 :2006/06/27(火) 18:58:15
OSは、Windowsです ごめんなさい><
zlib
>>574 関数ポインタはC++で仮想関数を含むクラスインスタンスを作れば
vtblとして山ほど作られるのでヒープ上でも攻撃しやすいよな。蛇足だけど。
↑のあたり説明してるサイトない?
dlmallocとかでの関数ポインタの書き換え攻撃は知ってるけど、
vtblを利用したのは初耳だ。おせーてくれ
質問です こういうコードを書くとアクセス違反で例外が出されるようです CFoo *pFoo=0; // ヌルポ pFoo->foooo(); // メンバ関数にアクセス そこでこのようにtryブロックで囲んでみたのですが、catch(...)でキャッチ出来ません なぜでしょうか?catch(...)はどんな例外でも捕まえられると思っていたのですが違うのでしょうか また、アクセス違反の例外はcatch(?) の?の部分に何と書けば捕まえられるのでしょうか? どうかお願いします try{ CFoo *pFoo; CString str = pFoo->m_str; }catch(...){ printf("catch sita"); }
586 :
585 :2006/06/27(火) 19:20:33
間違えた、下のはこうです try{ CFoo *pFoo; pFoo->foooo(); }catch(...){ printf("catch sita"); }
>>585 環境はVC2005かg++だと思うんだがこいつらはWindowsのSEHをC++のEHでcatchできない。
>>587 ありがとうございます
SEHとEHの違いを良く分かって居ないようなのでもう少し勉強してみます
zlibってパスワード付のZIPって無理なんですか? 対応してるのってあります?
スレ違い
>>589 標準C++以外のライブラリの相談なら、環境依存スレなどへどうぞ。
>>587 一応書いておくと、Visual C++ 2005でも/EHa使えば、SEHをcatch (...)で捕まえられる。
>>588 基本的にcatchで捕まえられる例外は、誰かがどこかでthrowした例外だけと思え。
class A { private: struct B { int i; }; public: B& hoge() { return b_; } private: B b_; }; A a; a.hoge().i = 0; // ここ A::Bはprivateなのですが、VC++2003ではエラーになりませんでした。 これは言語的に正しいのでしょうか? 正しいのだとしたら、どう解釈したらいいのでしょうか?
内部へのハンドルを返すAが悪いって事で
「海水がしょっぱいのはなぜか」という質問に 「飲むな」と答えるほど的外れな回答。
というレスが的外れなわけだけど、的外れを指摘する的外れレスって 指摘すると必ず怒り出すんだよね。 さあ困った。
,. ---=ニニ==、 ,.-ヲミ´ \ ///イ ,.-ヽ ////イ´ イ´⌒ヽ ,.イノ//彡 ,.-⌒`ヽ / /匁、 /三三三 / ィ刄、 ー'´ Y !三三三彡 ィf‐―'´ ヽ ヽ、 乂 ト三三彡イ ´ ノ 、 r ) ハ ヽ `トミ三三ネ、 ゝ '´ ', ) (ヽ、三ト、川 ,.ィ ´ ̄ラソ ! Y⌒厂ソ )ノ! ( f―ニニ‐' ! /.///| | 人_ ヽ `ー―' ,' { !| | | ト、く へ ) / / ///// ハ _,イく`、 _.ノ( |(//////////ハヽ \`ー―、  ̄ ̄ ,. ハ ))ノ///////ノヽヽヽ \  ̄ ̄ ̄ ̄ヽ \ ハージ・マッターナー [Herge Mattuner] (1941〜1999 アメリカ)
public, private, protected などは識別子の可視性を制御するだけであって、 その識別子によって定義される対象の可用性を制限するわけではないから。 ですよね
C++ カプセル化 でグーグルといいお
頭の悪い議論ばかりしてると、本当に頭が悪くなっちゃいますよ(^^;
基底クラスのprivateなtypedefを 派生クラスでpublicにする時もそうなんかな
struct B { int i; }; という記述は、 class B{ public: int i; }; と等価だから、 いいんじゃねーの?言語的に。 変数 i は public だし。 メソッド hoge も public だし。
この場合Bの可視性は影響しないって事?
Bの可視性とは関係ないって事。
つうかAは実際Bを隠蔽してないよな
607 :
デフォルトの名無しさん :2006/06/28(水) 00:11:09
C++ Primer について質問したいことがあります。 このたび第三版を読み始めたんですが、P67あたりに、 メンバ変数名はアンダーバーで始めるのが普通である (第二版まではメンバ変数の取り扱いに set get を使っていたが実は効率が悪いことが判明した)、 というような一節がありました。これがいまいちピンと来ません。 メンバ変数名が m_value で値の取得は getValue() の様にするのが常識だと思っていたのですが この本が言わんとしてるのは class num { private: int _value; public: void value( int NEW_VALUE ); // 値の書き込み int value(); // 値の取得 }; という感じでメンバ関数をオーバーロードしてクラスを作れということなんでしょうか? 普段こんな感じでコード書いてる方っていらっしゃいます?
名前の隠蔽でんでんがあるから_つけろって俺は覚えてたけど 俺間違ってるな・・・
>>607 統一されていれば好きな物(コーディング規約で指定されている場合は指定されているもの)を使えばいいだけの話。
m_XXX / getXXX()が常識ということは一切ないから、変な誤解はしないように
>でんでん もしかして: うんぬん
>>607 データメンバ名とget-set系メンバ関数名の話に限らず、
命名はスタイルの問題なんで「これが普通」とか「これが常識」といった
普遍的なものはない。自分の手に馴染むものを選べばいいんでは。
というか俺ルールを初心者に刷り込むのはどうかと…
まあ変に悩ませないって点ではいいのかもしれんが。
614 :
608 :2006/06/28(水) 01:11:23
>でんでん
class B
{
public:
void v(){puts("めがっさ");}
};
class D :public B
{
public:
int v;
};
D d;
d.v(); //error
こんなの。こういうの避けるために_つけると思ってた
ごめん。
>>607 とまったく関係ないわ。すまん。マやめる。
アンダーバーを先頭につけてはいけません。
>>607 の例なら問題はないけどな
無用な混乱を避けるためにも、アンダーバーを避けるか、
末尾につけるようにするのが妥当か
>>585 ぬるぽに -> した時点で未定義動作。何が起こるかわからない。
移植性に価値があるのなら catch(...) で問題が検出できると思わないほうがいい。
アンダーバーを先頭につけるのは、予約されてなかったっけか?
>>619 グローバル名前空間での識別子として予約されてる。
どっかのスコープの中では宣言しても衝突しないことになる。
だからといって使っていいかというと、混乱の元なのでやめたほうがいい。
しかもアンダーバーの次が大文字だと、グローバルスコープかどうかに関わらず予約されていたり、 色々面倒な規則があるしな。 中にはマクロでスコープを無視してくるお行儀の悪い実装もあるし、 使わないに超したことはないっていうだけ。 でも先頭に付けた方が見やすいっちゃ見やすいんだよな。
アンダーバーの次が小文字ならOKだお 17.4.3.1.2に明記されているし、GoF本でも使っている。 メンバに m_ なんか付けるより、よっぽどクールだお! …と、周りに説明するのに疲れたので、最近は諦めてる。
単に人望が無いだけだろう
人望でコードスタイルは変える気は起きないなあ コーディング規約でも作って義務化しないと
void mf( int _value ); こんなことやってる俺はダメ?w
後ろに付ければ問題ないのに、何で前に付けるんだろう?
武勇伝武勇伝、武勇伝伝ででんでん♪
>>629 そうしてる(してた)のをどこかで見たからで、後ろ派より前派が多かったんでしょう。
あくまでも、その人が見た範囲でだけど。
サフィックスは認識しづらいしな
メンバ変数にサフィックスもプレフィックスも使わない俺は少数派?
>>630 どうやってメンバと非メンバを区別してるの?
this->foo foo
そのスタイルは昔2,3回見たことがあるけど、最近は見ないな。 今見ると何となくPHPっぽくも見える。
うおっまぶしっ
>>631 最初が小文字ならローカル
大文字ならメンバっておれのコードは見難いですかそうですか
変数名に大文字は抵抗ある
637 :
デフォルトの名無しさん :2006/06/28(水) 21:48:46
g_number とか変数名のソース読む気になれん
命名規則とかインデントとか議論すると、不毛な宗教論争に発展するのは目に見えているのに……。 といいつつ自分も晒し //空白を空けて、typename(classはどうしても必要なテンプレートテンプレートパラメータにしか使わない) template < typename T > class Foo //クラス名の先頭は必ず大文字。 { private : //デフォルトに頼らず宣言しておく。 int x_ ; //メンバ変数には、アンダーバーを末尾につける。 } ; //関数名の先頭は小文字。 //K&R形式のインデントは、個人的に嫌いなので使わない。 void func( Foo const & val ) //やはり、空白を入れる。 { int x ; //セミコロンの前にも空白を入れる。 x = 1 + 1 ; //演算子の間にも空白を入れる。 }
突っ込みたいけど突っ込まないぞ!釣られないぞ! コーディングなんとかスレってあったよね、そっちいけばいいんじゃない?
>>639 の心の声:「この俺のすばらしいコーディングスタイルを見れば、みんな絶賛せずにはいられないハズだ。」
みんなの心の声:「キモ杉wつか自己顕示欲丸出しでウザイ」
皆の心の声:「ふーん」
スタイルの善し悪しはスレ違いだから何とも言わないが (個人的には空白の開けすぎで見辛いように思える) > typename(classはどうしても必要なテンプレートテンプレートパラメータにしか使わない) classがどうしても必要になるテンプレートパラメータってなんだ? templateの仮引数中ではtypenameとclassは同義じゃねーの?
>>646 template<template<typename>class U>
class A{};
>>647 ああなるほど。
「typenameの代わりにclassを使わなければいけない場合がある」と勘違いした。
class A { int b; public: A( const int i )b(i){}; }; constで受け取って、constじゃないのに入れるっておかしい? いまいち、constの有効利用法が解らないんですが・・・
>>650 とりあえず散歩して来い。川の堤防の上とかジョギングするのもいい。
とにかく一度頭をリセットするんだ。
>>650 その場合、const int iはコンストラクタ中でiが不変であることをコンパイラに伝える意味しかない。
#つまり、間違ってコンストラクタ中でiに代入することを防止するということ。
別に渡す側にとっては何の関係もない。
あとコンパイラの最適化がしやすくなるかも (といっても、最近のコンパイラは賢いから、変わらない事も多いけど)
>>650 参照渡しとコピー渡しとプリミティブタイプあたりの関係を勉強した方がいいと思う。
>>650 C++全体でいうと、constはオブジェクトが不変であることを表明するというという
使い方がある。仮引数にconstを付ければ、そのメンバ関数内ではその引数の
オブジェクトは不変だし、メンバ関数にconstを付ければ、そのメンバ関数呼び出しで
オブジェクトが変わらないことが保障される。
constなメンバ関数から、constでないメンバ関数は呼べない(コンパイル出来ない)から、
知らないところでオブジェクトがいつの間にか変わっているということがない。
ただし、メンバ変数をmutableで宣言するとconstなメンバ関数内でも変更可能になる。 この効果的な使い方は・・・ググって。
ひとつ言い忘れた。 constなオブジェクトからはconstなメンバ関数しか呼べない。 意味的に不変であると宣言したオブジェクトは、コンパイル出来ないという 物理的な壁でもって、不変であることが保障される。
constを変数につけるのに意味がある場合は、char*とか参照で渡す場合に意味がでるって感じですか? あと演算子のオーバーロードとか。 ビット的定数性と概念的定数製も読みましたけど、これが必要と思えない...
mutableが必要になる場面はたまーーーにあった。 constなメソッドが要求されるのだが、メンバ変数を変更したいとき(そのままやん)。 概念的普遍性が必要になったことはないが、必要な人は必要なんだと思う。
クリティカルセクションがメンバにある場合に使った事ある。
クラス内にキャッシュ機構を持たせる時に使いました
漏れはそのオブジェクトが描画済みかどうかのフラグだけ 外に出したくなかったんでmutableにしたことあるな。
パフォーマンスや統計情報を測定するためのメンバ変数の書き換えとかで使いました。
テストでstubクラスを作ったときに、constなメンバ関数で内部情報を更新するために使いました。
mutable なんて知らなかった… thisポインタをキャストしてたよ。 mutableって何と読むの?ミュテーブル?
mutableを使ったら、彼女ができました。 本当にありがとうございました。
mutableでガンが治りました。
次はexport使えばお金持ちになるよ。
>>669 exportを使ったら、
物凄くマイナーな国の通貨と、
物凄くマイナーなジャンル(ピザデブ)の彼女ができました。
675 :
デフォルトの名無しさん :2006/06/30(金) 01:52:55
std::map<double, hoge*> var; var[1.] = new hoge; ってするとして、varはdestructorでどうやって扱えばいいの?
for (std::map<double, hoge *>::iterator it = var.begin(); it != var.end(); it++) delete it->second; これでおかたずけかな
まあ、そのうち面倒になって std::map<double, boost::shared_ptr<hoge> > var; とかやりだすんだが。
678 :
675 :2006/06/30(金) 02:11:29
C++ではあるクラスのコンストラクタから同じクラスの別のコンストラクタは呼び出せない とCマガのバックナンバーに書いてありました しかし #include <iostream> #include <string> class Base { Base() { Base("aaa"); } Base(std::string message) { std::cout << message << std::endl; } }; int main(void) { Base b; return 0; } とするとちゃんとaaaと表示されます どういうことなの?
>>679 言語仕様で呼び出すことが禁止されているわけではない。
コンストラクタの実行中はまだthisポインタが確定していない。
その状態で別のコンストラクタを呼び出した際の動作は未定義。
だいたいの処理系ではthisがヘンな値を指したままBase(std::string message)が呼び出されるけど
その例ではthisを一切必要としていないから、”たまたま“うまく動いているように見えるだけ。
thisを必要とする処理、たとえばメンバ変数への代入なんかをするとアウト。
>>679 Base("aaa") という式は Base() で初期化中のオブジェクトに対して
Base(string) を呼び出しているわけではなく、 Base(string) によって
初期化された Base 型の一時オブジェクトを得ることになる。
デストラクタにも出力を置いて試してみるといい。出力には this も加えると
わかりやすいだろう。
>>680 どこから出たデマだ?
>>680 コンストラクタの中から普通にメンバ関数呼べるわけだし、
this がないわけないだろ。
仮想関数は Base のものになっちゃうが。
>>682 確かにメンバ関数呼び出しもコンパイルできるし、 this も有効な値を持っているが、
コンストラクタの中では初期化が完了していない状態だということには気をつける必要がある。
メンバ変数への代入が出来ないコンストラクタって・・・
>>683 コンストラクタの実行中はコンストラクトは完了していない。
もったいぶって書くほどのことか?
>>661 ,663
そうか
mutableを使えばいいのか
ありがとう
うん? bを生成中に、一時オブジェクトを生成しただけだろ。 コンストラクタ(だけ)を呼び出しているわけではないと思うのだが。
>>679 そのデフォルトコンストラクタは、
Base() {
Base unused("aaa");
}
とほぼ意味だから。
コンストラクタで、別のコンストラクタを呼び出すには、
Base() {
new (this) Base("aaa");
}
みたいに、配置newを使うしかない。ただ、コレを使うと
初期化リストとか怖いことになるかもしれないので注意
>>679 ↓こうしたことと同じ。コンストラクタ内の一時変数ができるだけ。
Base(){
Base hensu("aaa");
} // ← 変数hensuが解放されて終わり。
デストラクタ(this->~Base())みたいに、this->Base("aaa")で呼べればいいのにとか思ったんだけど、
コンストラクタってクラスメソッドと同じ扱いっぽいから無理みたいだね。
691 :
デフォルトの名無しさん :2006/06/30(金) 15:15:18
vector <struct TAG>は出来ますが、 vector <classのTAG>はどうなんでしょう? 性能うpするにはclassよりstruct?
693 :
691 :2006/06/30(金) 15:32:50
いや、根本的な勘違いしてると思ってなければ事故解決するさ。 std::vectorでstructは今まで使ってたけど、 classにしたらどうなるか教えてでつ。
695 :
デフォルトの名無しさん :2006/06/30(金) 15:41:46
質問です。 ヘッダファイルなどで class CHoge; と書いておくと、CHogeはクラスなのだと認識してくれるので、その下で CHoge* pHoge; なんて書いてもOKですよね。(実際にCHogeのclass定義などが後に存在していたとしても) それと同じ理屈で、 enum HOGE { TEST=0 }; と「後に宣言される」HOGEを認識させることはできないでしょうか? イメージ的には enum HOGE; // HOGEはenumですよと宣言 HOGE hoge; // HOGE型を生成 //実際にはその下のほうでHOGEの中身を定義 enum HOGE { Test=0 }; です。 enumは所詮intなので、可能そうかなと思うのですが…。
できません
enum のサイズは、その含んでる値を元に、 処理系依存に決定されるんだったはず。 だから、サイズが分からないという扱いになって、無理。
>>696-697 すばやいお返事ありがとうございます。
残念。ダメですか。
enumの分割宣言とかできたらよかったのですけど…。
仕方ないのでint変数として作ることにします。
ありがとうございました。
699 :
デフォルトの名無しさん :2006/06/30(金) 16:59:05
質問させててください "特定のクラスにだけ継承を許す"というクラスは作成できるでしょうか 全ての関数が純仮想関数なインターフェースクラス(以下IClass)を定義したのですが、 他の人は、そのインターフェースクラスを継承するのではなく それの一部に機能を実装したベースクラス(以下BClass)を継承してもらいたいのです friend登録の逆思想で、IClass側に「私はBClass以外には継承されない」と制限をかけさせることはできないでしょうか
>699 コンストラクタをprivateにしてfriendすれば?
701 :
デフォルトの名無しさん :2006/06/30(金) 17:08:13
そこまでしてIClassを作りたいのはどうしてなのでしょうか?
>>699
> friend登録の逆思想で 自分でここまで書いてて答えにたどりつけないところがすごいな つか、概念的にインターフェースじゃないよな、そのクラス
703 :
デフォルトの名無しさん :2006/06/30(金) 17:20:46
>>700 あ、なるほど。ありがとうございます。
>>701 IClass.hの更新はもうない(ようにしている)のですが、BClassの更新(変数の追加)はまだまだありそうなのです。
変数の増減の度に、この.hを読み込んでいる全ファイルがリコンパイルというのはよろしくないなと思いまして。
思いっきり pimpl の適用事例に読めるなぁ
705 :
デフォルトの名無しさん :2006/06/30(金) 17:55:45
>>704 ありがとうございます。pimplというのは聞いたことのない単語でしたが、調べたところ実に今回の解決にマッチしそうでした。
導入をテストしてみたいと思います。
今この質問に答えててふと思ったんだが、ClassはCHoge。InterfaceはIHoge。 じゃあabstractクラスはみんなどうしてる? AHogeか? ハンガリー使わないって意見は別問題として。
CHoge。
実体が作れないのにCHogeって気持ち悪くね?
俺はIHogeにするかな。
インターフェースクラスってのは、少しでも実装が書いてあったらダメなのかね? virtualじゃない(オーバーライドしないことを前提とした)実装が書いてあってもよさそうなもんだけど。
>>706 インターフェイスにはI付けるけど、
クラスにはC付けない派。もちろん抽象クラスにも付けない。
>>710 インターフェースを提供するクラス、って意味だから、
共通のインターフェースを提供してさえいれば、
実装の有無はあまり関係ないと思ってるが。
Javaのinterfaceは位置づけが微妙だな
別問題を承知で ハ ン ガ リ ー 使 わ な い
>710 つNVI virtualが一切無いけど、 protectedなメンバ変数を利用してインターフェイスを名乗らせたりもした。
>>713 だよな、やっぱり逆ポーランドじゃないと。
最近、目がぼやけてポーランドとボーランドの区別がつきにくくなってきた。
ABCにだけIを付ける。 Cは一切付けない。
WinFX のネーミングルールでは、 インターフェースには I を付けるべきだが、 クラスには C 付けんな。ってどっかに書いてあった気がした。 あとアンダースコアも使うなとか。 ところでWinFXってなに?外国為替証拠金取引か?って感じだが。
>>718 WinFXはWin32APIの置き換えとなるはずだったもの。
今では、置き換えされず、名前も単に.NET Framework 3.0になることが決定済み。
>>716 昔から、MSゴシック/MS明朝とも、濁点と半濁点の区別、付けづらいよな。
その点Macで使われてたOsakaは区別付けやすかったんだが、
そのMacも最近を標準フォントをヒラギノに替え、
やはり濁点と半濁点を区別しづらくなった。
#include <list> class Hoge{ int* pointer; public: Hoge( int n ){ pointer = new int(n); } //Hoge( const Hoge& hoge ){ pointer = new int(*hoge.pointer); } ~Hoge(){ delete pointer; } }; int main(){ { std::list<Hoge> list_hoge; list_hoge.push_back( Hoge(777) ); } return 0; } 実行するとスコープを外れた時に、メモリのエラーが出ます。 コメントアウトしてあるコピーコンストラクタを有効にすれば問題は無いのですが、 それよりlistに挿入する度に、一回コピーが発生するのがどうにも無駄で。 実体ではなくポインタのリストにすれば良いのは分かるのですが、 管理の手間を省くために出来れば、実体のリストにしたいところです。 このままの形式で、挿入時にコピーを発生させずに済む方法があれば、教えて頂けないでしょうか。
pointerを共有可能なスマートポインタにする
>>721 >実体ではなくポインタのリストにすれば良いのは分かるのですが、
>管理の手間を省くために出来れば、実体のリストにしたいところです。
boost::ptr_list
か
boost::shared_ptr <Hoge>をlistに入れるとか
しかし折角のlistが、実質的にほとんど iterator->func() ではなく (*iterator)->func() みたいな記述になっちまうのは、妙な話だよな
>>724 ptr_listにすれば前者の書き方でいけるだろ
>>725 ああいや、スタンダードなのにこれか、みたいな
ptr_listがあるだろ。
728 :
721 :2006/07/01(土) 23:26:05
皆さんありがとうございます。 ということは実体でlistを使うと言うことはほとんど無いんですかね。ちょっと不思議な感じもしますが。 boostの使用も検討してみます。
>>727 いやだからptr_listはSTLじゃないだろ、くどいな
STLのコンテナはすべてコピーベースです
そういやshared_ptrはC++0xに盛り込まれるけど、pointer containerはどうなるんだろう?
>>731 どこでもboostが使えると思うなよw
shared_ptrをコンテナにぶっこめばいいから要らないんじゃね?
>>724 boost::indirect_iteratorもある。
皆で特定の何かの評価をしているのに、〜もあるだろって奴が増えたな 関係ないがコピーベースって言葉、初めて聞いたな
>>738 環境によるだろ。
俺はVC6で極力Boostを使用するようにして使っているが、
例えばVC8を使っても使わない時と比べ10K個ほどしか「〜もあるだろ」が増えない。
1万個も増えるのか
たった1まんこじゃねーか もっとよこせ
#ifndef UNIT0_H #define UNIT0_H namespace Unit0 { //クラス、関数宣言 } using namespace Unit0; #endif こんな感じでヘッダファイル内の宣言を丸ごとnamespaceで囲んで問答無用でusingするのって問題ありますか?
何のためにnamespace Unit0で囲ったの?
問題あるなし以前にそういうことをする動機を聞きたいものだが ソースファイル内なら十分意味があると思うが そちらに関しても普通は無名名前空間を使うのが筋だし
745 :
742 :2006/07/02(日) 13:20:08
使い回しの別のコンパイル単位とクラス名とか被った時の保険です。(*‘ω‘*)
>>741 お前、「年齢=彼女が居ない期間」だろ?
1まんこで十分だ、沢山あってもウザイだけだぞ。
>>745 using namespace Unit0;
これをヘッダじゃなくてソースファイルに書くようにしたら?
>>745 Unit0::hoge;
べた打ちが吉と視た。
質問なんですが、双方向リスト構造でソートを行う場合、理想的なソート方法はなんでしょうか?
まあ、某Win32用アプリケーションフレームワークで実際にこんな使われかたしてるので‥‥(*‘ω‘*) #ifndef SystemHPP #define SystemHPP namespace System { //ここに宣言 }/* namespace System */ using namespace System; #endif// System
>>742 ,750
ヘッダで using namespace は曖昧さという危険性を
回避不能な形で強制的に埋め込む行為。禁止一択。
>>750 その某フレームワークとはおそらくATL/WTLのことだろうが、
それらは、特定の名前のマクロを定義することによってusingディレクティブを行わないようにすることができる。
>>742 ,750
エラーの場合に勝手に警告ダイアログとか出しやがる、
うんこライブラリに気持ち的に似ている感じがするので、
できればusingは辞めてほしい。
>>753 BCBのVCLも同じことやってたな。
マクロを定義すると…ってとこも同じ。
名前空間が無かった時代の名残かな
va_argなどva_xxxにはANSIバージョンとUNIX互換バージョンが あるみたいなんですが windowsな環境ではどちらを使えばよいのですか? ANSIバージョン?
>>757 よくわからんが、 ANSI なり ISO なりのほうが移植性が高いといえるんじゃないか?
>>757 たぶん「UNIX互換バージョン」と呼ばれているのは、
標準Cに入る前の古いヤツの事ね。
<varargs.h>←これが古い頃のヤツ。
<cstdarg>←これが新しいヤツ。(Cでは<stdarg.h>)
760 :
101 :2006/07/03(月) 23:31:04
【初心者歓迎】C/C++室 Ver.28【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1149815331/933-935 これ見てやっと原因把握。VCとg++の挙動が全然違う。
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/2241.txt VCだと
D:\>ref.exe
Test Constructor 1 : this=0012FF60 : a=3
Derived Constructor 1 : this=0012FF60 : a=3 : b=4
Test Constructor 1 : this=0012FF5C : a=2
0(Test) or other(Derived) : 1
Test Copy Constructor : this=0012FF54 : a=3
Test Copy Constructor : this=0012FF6C : a=3
g++だと
$ ./a
Test Constructor 1 : this=0x22eeb0 : a=3
Derived Constructor 1 : this=0x22eeb0 : a=3 : b=4
Test Constructor 1 : this=0x22eea0 : a=2
0(Test) or other(Derived) : 1
>>101 のエラーはコピーコンストラクタが動くせいで
privateメンバに触ってるぞってメッセージだったらしい。
ということで解決というかなんと言うか。まあ参考までに。
素人でスマンけど、なんで
>>101 でコピーコンストラクタが動くんだろう?
参照に代入してるとこ?
バグだから。
>>760 >std::ostream &out = fout ? fout : std::cout;
そこは↓こうしたらVCも通るかも。
std::ostream &out( fout ? fout : std::cout );
#gccとVCの違いはRVO(Return Value Optimization)絡みな希ガス。
あかん。VC8でSTLport5.0.2を入れても、
>>760 と同じ結果になる。
当然
>>101 はコンパイルできない。エラーメッセージは次のような感じ。
だいたい同じ事だろう。
c:\stlport-5.0.2\stlport\stl\_ios.h(131) : error C2248: 'stlp_std::ios_base::ios_base' : private メンバ (クラス 'stlp_std::ios_base' で宣言されている) にアクセスできません。
c:\stlport-5.0.2\stlport\stl\_ios_base.h(217) : 'stlp_std::ios_base::ios_base' の宣言を確認してください。
c:\stlport-5.0.2\stlport\stl\_ios_base.h(48) : 'stlp_std::ios_base' の宣言を確認してください。
コンパイラでのこの診断により関数 'stlp_std::basic_ios<_CharT,_Traits>::basic_ios(const stlp_std::basic_ios<_CharT,_Traits> &)' が生成されました。
with
[
_CharT=char,
_Traits=stlp_std::char_traits<char>
]
>>760 こんなの見つけたよ。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446 rvalue を使うとコピーによる一時オブジェクトが必要になるらしい。
struct B { B(); private: B(B const&); };
struct D : B {};
int main()
{
B const& x = 0 ? B() : D();
}
でも
>>760 や
>>101 の例では両方 lvalue で片方がもう一方の
ベースクラスになる場合だから一時オブジェクトは要らないはず。
VC はなぜか rvalue として処理してしまってる気配がする。
で、 rvalue として処理された場合は一時オブジェクトなんで
結果で非 const 参照は初期化できないはずなんだけど、
VC ではなぜか以下略
>>766 つまり d が Test の参照に変換できて、その参照が d に直接結合も可能。
その結果 d が t に合致するように変換できたっつーことで
第2演算対象と第3演算対象が同じ型の時のルールが適用されて
結果は Test の左辺値になる。勿論コピーはされない。
これが規格上の動作ってことでいいのかな。
lvalueが要求されているところで、 コピーコンストラクタ呼び出しがあるって時点でアウトだろ。> VC++8
>>768 「規格上」なんだから回りくどいの当たり前。
つか
>>766 と
>>767 の内容は別物だぞ?
>>766 は
>>760 がDefect Reportに載ってるどのケースに当るか、
VCはそれをどのように処理するかについての話だが、
>>767 はlvalueだと一時オブジェクトが要らない理由の説明。
ほんっとくどいなこいつ
くどいついでに、
>>760 >
>>101 のエラーはコピーコンストラクタが動くせいで
> privateメンバに触ってるぞってメッセージだったらしい。
iosは、コピーされるとまずいから、
コピーコンストラクタをprivate宣言してあるだけ。定義なし。
>>101 見た瞬間に気付くように。
・・・くどいんじゃないくて焦点がズレてるな。
つうか、ただのアホだろ
vectorが空の時、 vector<...> v; ... @ if (!v.empty()) { for (auto it = v.begin(); it != v.end(); ++it) { .... } } と A for (auto it = v.begin(); it != v.end(); ++it) { .... } は同じですか?
馬鹿な質問多いな
>>775 後者のほうが無駄なコードがなくていいんじゃないの?
>>775 イタレータは問題ない。
emptyの時、v[n]するとまずい。
わからんとは驚き
いや。質問とは無関係の回答してたから何の話をしてるのかと。
[]使ってアクセスする場合はemptyチェックが必要ってことだと思われ。
784 :
デフォルトの名無しさん :2006/07/05(水) 22:19:10
継承は継承でも「実装の継承」と「仕様(インタフェース)の継承」は別物らしいと 最近認識したのですが、webで断片的にページを読んで調べていてもいまいちよく判らないです そこで、何ぞ詳しく説明してる本がないかと思ったのですが どなたか心当たりはありませんでしょうか
EffectiveC++
質問です Hoge hogehoge{ {hogehoge_a, hogehoge_b, hogehoge_c}, {hogehoge_a, hogehoge_b, hogehoge_d}, }; ↑これっを↓みたいに置換できないでしょうか? それかコンパイル時に↑みたく展開できるような宣言方法はないでしょうか。 #define HOGEEEE (hogehoge_a, hogehoge_b}) Hoge hogehoge{ {HOGEEEE, hogehoge_c}, {HOGEEEE, hogehoge_d}, };
#define HOGEEEE hogehoge_a,hogehoge_b Hoge hogehoge{ {HOGEEEE, hogehoge_c}, {HOGEEEE, hogehoge_d}, }; でいけない?
Mingwのstd_vector.hのswapですが void swap(vector& __x) { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); } /// See std::vector::swap(). template<typename _Tp, typename _Alloc> inline void swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) { __x.swap(__y); } これでどうして中身の置き換えになるのか読み解けないです・・・ 分かる人教えてけろ。
struct A { void swap(A& x) { std::swap(this->i, x.i); } int i; }; inline void swap(A& x, A& y) { x.swap(y); } と同じ事。
>>788 中身がswapされるんじゃない。中身を挿しているポインタ、個数カウンタ、
アロケートされた領域、の3つが交換される。
>>789 ,
>>790 inline void
swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) のことを
std::swapと勘違いしていたようです。
どうも、お騒がせしました。
ああstd::vectorのメンバ関数ね。shrink-to-fitによく使われる。
また出た。聞いても居ないことをぺらぺら喋る、最近覚えた知識を披露したい厨様が。
またしてもカスほど自己顕示欲が強い法則発動
ただの質問箱ってのはつまんないから、 ネタフリがあったほうがいいかもしれない。
boostの質問もここでおkでしょうか?
>>796 つ[boostスレ]
簡単な質問なら初心者スレでもいいかも知らん。
なんだアサヒのイメージ向上作戦か
>>799 それを言うならこうだろ↓
ああアサヒのメンバ関数ね。イメージ向上作戦によく使われる。
質問です template < class T > struct F { template < class T2 > void Func( T2 ); template <> void Func( int i ); }; こういうクラスがあって、T2を取る関数を書く場合 template < class T > template < class T2 > void F<T>::Func( T2 ){...} でコンパイル通るのですが、2番目のintを取るように特殊化したものを template < class T > template <> void F<T>::Func( int i){...} とかくと C2244:関数の定義を既存の宣言と合致させることができませんでした となって通りません。どのように書けばいいのでしょうか? VS2003.netを使用してます
たしか外側を特殊化しないと内側は特殊化できないという規則があったような気がする。 規格書読んでみればわかるという回答でも無責任だしな、すまん。
単純にインライン化すればコンパイルできるんだが、なんでだろうな。 こんな難しいことやろうとしたことが無いから、わからん。 template < class T > class F { public: template <class T2> void Func(T2 a) { } template<> void Func(int i) {} };
void Func( int i ); 〜 template<class T> void F<T>::Func(int i) {〜} やりたいのはこういうこととは違うの?
>>805 わかんないなら口を出すなよ恥ずかしいな
using namespace std; はusing ディレクティブ using std::cout; はusing宣言 で合ってる?
7.3.3 The using declaration [namespace.udecl] using-declaration: using typenameopt ::opt nested-name-specifier unqualified-id ; using :: unqualified-id ; 7.3.4 Using directive [namespace.udir] using-directive: using namespace ::opt nested-name-specifieropt namespace-name ;
>>807 お、これでコンパイルできた。
だけど、実際にインスタンスを作製して、メンバを呼び出すとき
F<int> f;
f.Func(100);
f.Func<int>(100);
f.Func<>(100);
どれを呼び出しても、
template < class T >template < class T2 > void F<T>::Func(T2)
こっちが使われるみたい。
>>801 template < class T >
struct F
{
template < class T2 > void Func( T2 );
void Func( int i );
};
じゃだめ?
>>811 それだとテンプレートの明示化とは違った、普通のメンバになるから
呼び出すときに
Func(int)を呼び出すときは
f.Func(100);
Func(T2)を呼び出すときは
f.Func<>(100);
と使い分けなくちゃいけない。
>>812 引数がintかint以外かでディスパッチしたいだけなんじゃないの?
f.Func(100);
f.Func(100.0);
で呼び分けるだけじゃダメなのかい?
814 :
812 :2006/07/09(日) 20:06:49
>>813 すまん、俺が勘違いしてたみたいだ。
確かに、それでうまくいきますね。
ってことは、template 関数の特殊化って何のためにあるんだろうと。わからなくなってきた。。
半年ROMることにするorz
C++の企画書(日本語)ってどこかで手に入れられると聞いたのですが、 どこで手に入れられるのでしょうか?
JIS
JIS X3014で適当に調べろ。後は知らん
winでcygwinのgccで以下のコードを gcc -lstdc++ a.cpp とすると /cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccfRcOaV.o:a.cpp:(.text+0xd): undefi ned reference to `std::basic_string<char, std::char_traits<char>, std::allocator <char> >::size() const' /cygdrive/c/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ccfRcOaV.o:a.cpp:(.text+0x60): undef ined reference to `std::basic_string<char, std::char_traits<char>, std::allocato r<char> >::operator[](unsigned int) const' とずらずらとエラーが出ます #include <string> #include <iostream> int main(void ) { std::string s = "a"; std::cout << s << std::endl; } gccのバージョンは gcc --version gcc (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125) Copyright (C) 2004 Free Software Foundation, Inc. どこがまずいのでしょうか?
>>823 gcc a.cpp -lstdc++
g++ a.cpp
825 :
823 :2006/07/10(月) 01:49:10
最近C++を勉強しなおしてるんですが、 ODR (One Definition Rule)違反とやらは namespace{int val;} template<typname T> class A { void foo(T t) { val = 0;} }; テンプレートクラスAが実体化する時に valが外部リンケージを持たないのでヤバイよ っていう認識でいいんですかね
>>826 なぜそうなる?
定義の重複は許しませんよっていうルールだ。
その例は確かに違反だが、 template に限ったルールじゃない。
ついでに、その例で val は外部リンケージ持ってるよね?
>>827 レスありがとうです
templateはあくまで例なんですが、
他の翻訳単位から実体化する時にvalを参照する場合、
翻訳単位毎に違うvalを参照する→ODRの原則に違反
という認識でいいのかなと思って
思い切り言葉足らずでしたね
>ついでに、その例で val は外部リンケージ持ってるよね
すいません。static int val;と書く予定がコピペ間違えました
template<typename T, size_t N> size_t NumberOfElements(T (&)[N]) { return N; } 配列の要素数を取得するこんなの、標準やboostにありますか?
----------a.h---------- template <class T> class A { public: typedef T type; type f(); private: type data; }; ----------a.cpp-------- #include "a.h" template <class T> type A<T>::f() { return data; } このコードをコンパイル(VC7.1)しようとすると a.cpp(4) : error C2143: 構文エラー : ';' が 'A<T>::f' の前にありません。 a.cpp(4) : error C2501: 'type' : 識別名を宣言するのに、型が指定されていません。 というエラーが出ますが理由がわかりません。 typedefを使わずにtypeをTに変えるとコンパイルできます。 エラーの理由を教えてください。
A<T>::type
833 :
デフォルトの名無しさん :2006/07/11(火) 16:04:59
c++用のgetopt的なライブラリって無いでしょうか? 手軽に使えるものがあるといんですが。。
>>833 boost::program_options
835 :
831 :2006/07/11(火) 16:15:33
>>832 ありがとうございました。
a.cppの4行目を
typename A<T>::type A<T>::f()に変えたらコンパイルできました。
VC6で for ( int i = 0; i < 3; i++ ) { } このコードは以下と等価ですが int i; for ( i = 0; i < 3; i++ ) {} このバグとも思える仕様はVC7や8 では直っているのでしょうか?
>>836 VC8では直ってる。
VC7は知らん。
839 :
837 :2006/07/11(火) 16:29:56
>>830 boost::size
ただし、Boost.Rangeの一部だから、コンテナに使うとメンバのsize()を呼ぶなどという具合で、適用できる幅が広い。
>>840 それ今もひきずってんの?
838の
>VC8では直ってる。
はスコープのデフォルトを直したってことかな
簡単なコード書いてコンパイルしてみればすぐわかるんじゃないか?
>>842 VC8はデフォルトで/Zc:forScopeが指定された状態になっている。
846 :
838 :2006/07/11(火) 16:59:38
俺様の言うことが信用ならんということか。 だったら最初からこんなところで聞くなヴォケ
てことは VC7では直ってなくて VC7.1ではデフォルトでは直ってないがオプション指定で回避可能 VC8直ってる でOK?
std::vectorやstd::map等のコンテナにはswapメンバ関数がありますが これは例外を投げない事は保証されているのでしょうか?
VC6 でも /Za でそのスコープに関しては直せる。 ほかに多くの問題が出るので、実質使えないオプションだけど。
>>848 VC7.1では/Zc:forScopeなしでfor文の外でも使えるけど、
外で既に同名の変数が宣言されていたらそっちを優先するようになった。
例えば
void func() {
int i;
for(int i;;) {
}
}
これはVC6だと宣言がダブってるってエラーが出てコンパイルできなかった。
852 :
851 :2006/07/11(火) 18:40:28
ミスった。正しくは -外で既に +ローカルスコープのどこかで
>850 #include <windows.h> しなければ何ともないぜ。
アラインメントが指定できなくなるのよねぇ。
>>849 Sequence (std::vector, std::deque, std::list) については保証されています.
AssociativeContainer (std::[multi]set, std::[multi]map) に関しては,
要素比較の関数オブジェクトのコピーコンストラクタが例外を送出しない限り,
swap も例外を送出しないことを保証しています.
856 :
849 :2006/07/11(火) 19:45:16
>>855 ありがとうございます。
比較関数オブジェクトで思いついたんですけど
アロケータが異なる場合も保証されないと思うんですけどどうなんでしょ?
>>856 >アロケータが異なる場合も保証されないと思うんですけどどうなんでしょ?
「異なる」の意味が少なくとも2つ考えられるんですけれど,どっちでしょうか?
「型が異なる」場合の話なら,そもそも異なるアロケータ型を指定された
コンテナ同士は swap が定義されていないですし,
「オブジェクトが異なる」場合の話なら,標準の範囲では
コンテナに対して指定するアロケータのオブジェクト各々が
異なる状態を持つことを明示的に禁止しています.
858 :
849 :2006/07/11(火) 21:46:46
>>857 「オブジェクトが異なる」場合の話です。
VC++2003付属のSTL見たら、アロケータを比較して別の処理してたので。
>コンテナに対して指定するアロケータのオブジェクト各々が
>異なる状態を持つことを明示的に禁止しています.
知りませんでした。
じゃあ何故コンストラクタでアロケータのインスタンスを取るようになっているのか
と思ったりするんですが。
>>830 先日 boost で提案されてた。 VC6 でも使える実装とか、いろいろこねくりまわしてたが、
結局どうなったかわからん。少なくとも現時点では含まれていない。
>>857-858 異なるアロケータインスタンスは禁止されているわけじゃない。
ライブラリの実装に対してそれらをサポートすることを要求していないだけ。
しかしサポートしようとすると難しい問題が発生するので
現存するほとんどの実装ではサポートされていない。
最近 STLport で条件付だがサポートされたらしい。
862 :
859 :2006/07/11(火) 23:35:53
>>861 あーごめん。見逃してた。先日提案があったのはコンパイル時定数って話ね。
みっともないなぁ。この知識披露厨は。
864 :
デフォルトの名無しさん :2006/07/12(水) 03:09:31
x個の要素のそれぞれの出現確率に従って、 y個の要素をランダムに選び出す高速な方法ってないでしょうか。 例えば、各アルファベットの出現確率に合わせて y個のアルファベットを選び出すような感じです。 累積ヒストグラムを作ってやる方法位しか思いつかないんですが、 もっと高速な方法は無いでしょうか?
C++の洋書のclassesって項目の中に post-construction て単語があるんだけどこれはどういう意味ですか? コンストラクタに関するうんぬんの後の処理って意味?
文脈によると思いますが、クラスの説明のところなら、メモリアロケートして、 インスタンスにvirtual tableの設定などをした後ってことだと。 その後、ユーザ定義コンストラクタのコードが実行される。
>>867 普通に、「コンストラクタ実行後」ってことじゃないの?
new 演算子について質問です。 通常、 class X* ptr = new X(); という感じでインスタンスを作成してから delete ptr; でメモリ開放します。ですが、 new X(); という形で作成した場合は、どうやって開放すればいいでのしょうか? よろしくお願いします。
>>870 言ってる意味がよく分からないが、
newした結果をどこにも格納していない場合は明示的に解放はできない。
オブジェクトがdelete this;で自身を解放するようになっていない限り、リークする。
>>870 delete new X(); でおk
セクションごとに区切られていないiniファイルを 読み込めるような関数ってありますか? もしくはGetPrivateProfileString()でセクションを意識しなくてもいい方法があれば 教えてください。
Visual Studio .NET 2003 で作業をしています。 プロジェクト名:TEST1 データセット名:TestDataset1 新しい項目の追加で「データセット」を追加し、テーブルDatasetTestを作成しました。 この時点でビルドをしてもエラーは出ないのですが Form1(デザイン)でdatasetを追加する時に [型指定されたデータセット]にチェックを入れ作成したデータセットを指定し ビルドすると、自動生成されたTestDataset1.hの public: __delegate System::Void Test1RowChangeEventHandler(System::Object * sender, Test1::TestDataset1::Test1RowChangeEvent * e); 部分で「\test1\TestDataset1.h(57): fatal error C1004: 予期しない EOF が見つかりました。」 とエラーになります。 ヘルプ等を見てもどうして突然エラーになるのか分かりません。 宜しくお願いいたします。
C++とmanaged C++は別物
877 :
874 :2006/07/12(水) 15:26:36
申し訳ないです。
878 :
867 :2006/07/12(水) 16:35:50
>>868 ありがとう
そっか、コンストラクションは構築だから単純にクラスを作った
あとでよかったのか。で、そのあとにコンストラクタが起動する・・・と
>>878 コンストラクションのあとにコンストラクタが起動する・・・っておかしくね?
そうだな。頭がおかしいな。
>>881 あーごめん。見逃してた。そうだな。頭がおかしいな。
883 :
878 :2006/07/13(木) 11:06:50
すみません 結局post-constructionの意味は クラスのインスタンスが作成されて そのインスタンスのコンストラクタ が実行されたあと ってことですか? それともインスタンスが作成されて、 コンストラクタが実行される前のこ とですか?
文脈でどちらかわかるだろうが。
誰も言わないけど、現代英語で "post construction" っていうと公共事業や 建造物や設備等の構築後の運用・管理のことを指しますよ。 いかにC++の本でも、定義等も無しでいきなり出てきたんなら たぶん間違いなく100%こういう意味で使ってると思うけど。
>>867 そもそも"C++の洋書"とは何という本なのか
なにも補足せずにそう書いたということは禿の原書?
つか、文脈でわかるだろ
いや、推測はできても確信は持てないので・・ で、禿なら邦訳あるんだから、センテンスが特定できてるんなら どう訳されてるか見ればいいんでないのかと
つか、その不明な単語が初出の段落読めばわかるだろ、普通。
>>883 英語に限らず、文脈を無視して、
単語の意味が一意に決まると考えていると、
文章読解うまくいかないよ。
母国語では自然とやっているんだけど。
国語辞典だって意味は何項目も書いてあるでしょ。
Cygwinみたいに、UNIXのAPIをWIN APIにかぶせたりして、 WINDOWSで使えるようなツールって、ほかにありますか?
>>891 スレ違い。
すれ立てるまでもない質問は〜というスレッドがあるはずなんだが、
ちょうど 1000 行ったところみたいだな。
>>893 ありがとうございます!
いってみます。
ヘッダに関数を書くとインライン関数になってサイズが大きくなるから使うな と某所で書いてあったんですが、どういう意味でしょうか? .hファイルに関数定義を書いてると#includeしてその関数呼び出すところは 全部インラインになるってこと?まじ?
>>896 インライン展開されるか否かはコンパイラの御心次第。
コンパイラによっては、別ソースの関数でもインライン化してくれるかも知らん。
サイズを問題にするなら、コンパイルオプションを併用するのが無難。
#そしてその話題はスレ違いなので以下個別環境向けスレでどうぞ。
バカが即レスすると見当違いも甚だしいとい見本ですな
>>896 インライン関数になるかどうかは inline と明示するか、
クラス定義内でメンバ関数の定義まで書いてしまうかで決まる。
ヘッダに書いたからインライン関数になるわけじゃない。
サイズが大きくなるっていうのは言い訳で、
ほんとはなるべくヘッダに実装を晒すべきじゃない
ってことが言いたいんじゃないかな?
効率を求めない限りはインライン関数なんて
積極的に使うもんじゃないしね。
最近のコンパイラはinlineつけなくてもメンバ関数じゃなくてもインライン展開するからなぁ。
>>899 >効率を求めない限りはインライン関数なんて
>積極的に使うもんじゃないしね。
kwsk
>>900 >最近のコンパイラはinlineつけなくてもメンバ関数じゃなくてもインライン展開するからなぁ。
リンク時コード生成?まだまだ一般的じゃないような
>>900 詳しくも何も、そのまんまだよ。インライン関数はヘッダに定義を晒す必要があるから、
関数の中身を変更したときは使ってる側の再コンパイルが要ることになるだろ。
中身を書くためには追加でヘッダのインクルードが必要になったりするしね。
ヘッダの依存関係はなるべく小さいほうがいいでしょ?
static void foo() { ... } int main() { foo(); } は、大抵のコンパイラならインライン化することない?
>>900 は別にしったかじゃないでしょww
知らなくて聞いただけなんだから
>>897 はバカ無能クソ低脳カス知ったかだけど
>>904 コンパイラの勝手だ。 foo() の中身にもよる。
それが大抵のコンパイラで事実だとしても、それに依存した
コーディングをしていいわけじゃないし。
>>897 はどこが間違ってるの?
だいたい合っていると思うんだが。
俺もそんな間違ってないと思う
>>907 単体では間違っていないが、質問への返答としては見当違い。
それはお前が897だからだろ。バカ丸出しですな。
大体あってる。 違うという奴は、ほのめかしではなくて、きちんと指摘しろ。
913 :
897 :2006/07/15(土) 14:41:22
まぁ、>899の方が無難な回答だろうね。
確かに漏れの回答はベクタが違う。
それを指して馬鹿だ無能だ低脳だとまぁ言いたい放題だこと。
>>901 iccの場合、オブジェクトモジュール内にインライン展開用の情報を埋めておいてリンク前に
プロシージャ間最適化している模様。
但し,gccも含めて>904のケースはコンパイル時にインライン展開してしまう。
#ついでに末尾再帰のループ化とか。
>>913 「見当違い」と指摘されて「ベクタが違う」と言い直すのが見苦しいな。
スレ違いだと自分で言っていたのに、勝手に特定のコンパイラの話まで持ち出すし。
これではさすがに知識披露厨と罵られても仕方がない。
>>914 ウザいな、お前。
どこがどう見当違いなのか、具体的に指摘しろ。
出来なければ消えろ。
>>914 これは酷いな。
>>909 は「指摘」なんかじゃなくてただの「言いがかり」。
「勝手に」持ち出したんじゃなくて聞かれたから答えた。
途中から読んでもこんくらいのことすぐわかる。
頭大丈夫?
919 :
918 :2006/07/15(土) 14:55:12
>>918 「クラス定義外」別ファイル
「」が抜けた…
register が意味なくなってるのと同様に、 inline もあんま意味ないの?
boostが付けてるから付けておけみたいな まあ転送関数だよ、程度の意味にしか使ってないな
昨日「ポインタのポインタってポインタのアドレスのことですよね?」議論に 関わってただろ。
>>920 ヘッダに関数の定義を書けるという効果があるから、
ヘッダだけの簡易的なライブラリを作るのに使える。
だめ?
そもそも、記述場所がヘッダファイルかどうかを インラインにするかどうかの判断基準に入れてるコンパイラなんてあるの? もちろんそうするのは勝手だろうが、 (順序でなく)記述場所によって意味が変わることになってしまうのは・・
場所の問題じゃなくて、 リンカに頼らなくても、定義を利用できるかどうかの問題だろ。 中間コードを利用してリンカでinline展開するコンパイラもあるけどね。
とうとう無駄に歳食ってる事実だけを武器にし始めたw
#include <iostream> class Session {}; class SessionFactory { public: Session Create( ); Session* CreatePtr( ); void Create(Session*& p); }; Session SessionFactory::Create( ) { Session s; return(s); } Session* SessionFactory::CreatePtr( ) { return(new Session( )); } void SessionFactory::Create(Session*& p) { p = new Session( ); } static SessionFactory f; // The one factory object int main( ) { Session* p1; Session* p2 = new Session( ); *p2 = f.Create( ); // Just assign the object returned from Create p1 = f.CreatePtr( ); // or return a pointer to a heap object f.Create(p1); // or update the pointer with the new address } このコードc++cookbookのサンプルコードなんだけど p1 = f.CreatePtr()で新しいSessionがnewされて 次にf.Create(p1)でまた新しいSessionがnewされてるけど このままじゃメモリリークしないですか?
します
普通にリークするな。
メモリリークも糞も…すぐにmain()が終わってるし。 Factoryの使い方を説明しているだけのコードだろ。 小さいことにこだわるな。
> すぐにmain()が終わってるし そういう問題じゃない気がするが
class C { public: void setHoge(@) { ... } A getHoge() { ... } private: tr1::shared_ptr<Hoge> hoge_; }; このようなクラスがあったとき、@とAはHoge*かtr1::shared_ptr<Hoge>の どちらにするのがいいのでしょうか? Aはユーザーが誤ってdeleteできないようにtr1::shared_ptrを返す べきとは思うのですが
>>936 get出来ないのがいいと思う。
access用のinterfaceを用意して。
free()と違ってdeleteはデストラクタを呼ぶ。 だからmainが終わるからと言って呼ばなくて良いことにはならない。 そう書くと、今度は931のSessionにはデストラクタがないとか言われそうだけどさ。
ひょっとして、プログラム終わる前にdeleteして廻れって言いたいのかな?
質問をさせてください。 当方、C/C++の開発をやってみようと思って、いろいろサイトを見て回ったのですが、 統合開発環境が沢山ありすぎ、 どれを使ったらよいのかわかりません。 お勧めなものや、一般的に普及している統合開発環境ってありますでしょうか。
WindowsならVC EE一択。 Unix系ならeditor + Makefile。 Macは知らん。
>>942 デストラクタに重要な動作があれば必須かと。
ほほう。
で、
>>931 のコードには、その重要な何かがあると?
一番のオススメはComeau
>>944 早いレスありがとうございました。
申し訳ありません、詳細を記述しておりませんでした。
当方の環境はWindowsXPです。
Windows系なので、一択といえるものがあり、安心しました。
VCとはVisual C++のことだと思うのですが、EEとは何の略称なのでしょうか?
Express Edition
>>940 コードをちゃんと嫁
読んでも分からんのなら勉強しろ
mainで解放していようがいまいが、
>>931 のクラスと使い方ではリークする
ありがとうございました。 早速Visual C++ Express Edition についていろいろ調べてみようとおもいます。
ちょっとVCEEについて調べてみたのですが、 「ゲーム作成ができない」という表現がございました。 まず、当方のやりたい事を記述していなくて申し訳ありませんでした。 ネットゲームでのツール(オートログイン、経験値時給表示、キャラ自動操作等) を作成してみたいと考え、C/C++の開発を行おうとおもっています。 ゲーム作成とネットゲームのツール作成は 確かに異なりますが、私のやりたいことはVCEEにて可能なのでしょうか
>>950 じゃあ、ソースを呼んだお前が
>>931 のクラスと使い方の問題点でも
指摘すればいいんじゃね?
>>952 基本的に何でもできると思うよ。
平易か困難かは別問題だが。
まぁ自力で調べる力はあるようなので心配はいらないかもな。
Express Edition って Win32 SDK がなかったり、 色々なのが欠乏してたと思う。
>>955 それは別途Platform SDKをダウンロードすればよいだけ。
>メモリリークも糞も…すぐにmain()が終わってるし。 すぐにmain()が終わってるから所詮サンプルコードって意味じゃね 「main()が終わる前にdeleteすればちゃんと動く」とは誰も言ってない気が
Express EditionはMFCが使えないってことくらいか その手の人に言わせると使えてしまうらしいが
structとclassの違いって structはデフォルト公開子がpublicで classはprivate っていうだけですか? 例えばC#ではstructはスタックにclassはヒープ っていう違いがあるけどC++ではどうなのでしょうか?
>>959 それだけ。全く違いは無い
one keyword, one functionality.ということで
自分はstructが好きだが
Boostを見るとみんな好みで使ってるようだな
>>939 >>access用のinterfaceを用意して
kwsk
963 :
959 :2006/07/16(日) 18:39:22
>>960 >>961 了解。ありがとうございました
ところで
one keyword, one functionality
とはどこが出典の格言でしょうか?
それとどういう意味ですか?
一つのキーワードは一つの機能と対応すべし
って意味だと思うんですが、
もともとstructがクラスとしての機能を果たしえたのに
名前的な対応のためにclassキーワードが追加された
とかいう背景でもあるのですか?
>>952 普通なら頑張れと言うところだが、升(チート)作りが目的なら寧ろ頑張るな。
別にMFCでGUIを作るわけじゃなさそうだからそれこそVC2005EEで充分だとは思うが。
今更なんだろうが、
>>964 升がチートの略表記なのね。1/3圧縮か。おもしろいなあ
>>963 Cとの互換性のためにstructではディフォルトがpublicになっているが、
オブジェクト指向のデータの隠蔽という概念からすれば、ディフォルトがprivate が望ましい。
だから新たなキーワード class が必要だったんじゃない?
c++coding standardの項目24 「常に内部の#includeガードを書こう 決して外部の#includeガードを書いてはいけない」 の中に以下の文があるのですが、理解できません。 「 昔の本に提唱されていた古臭い外部の#includeガードを 使うのはやめよう。 #ifndef FOO_H_INCLUDE_ #include "foo.h" #define FOO_H_INCLUDE_ #endif 外部の#includeガードは冗長で、現在のコンパイラでは時代 遅れである。また、インクルードする側とヘッダーファイルが ガード名について合意していなければならない。 これにより密接な結合が生じ脆弱になる。 」 文章中の「インクルードする側とヘッダーファイルがガード名について 合意しなければならない」とは具体的にどういう状況なのでしょうか?
>>967 その例では foo.h の中で使われるインクルードガードが
FOO_H_INCLUDE_ である必要がある。 foo.h が勝手に
インクルードガード変えたりすると破綻する。変更に対応しようとすると
FOO_H_INCLUDE_ を使ってる箇所を全部置換してまわる必要がある。
>>66 ほか
D&Eに何かないかとざっと探してみたが、classという言葉をSimulaから持ってきたということは書いてあったけど、
そもそもstructではだめだったのかということを直接的に書いているところは見当たらなかった。
強いて言えば4.4の中、「シンタクスは重要だ」とかが関係あるかな。
structとclassについて書いてあったのはこれくらい。
---3.5.1の後半の要約
しかしそれではなぜ私はstructとclassを別の概念にすることを選ばなかったのだろうか?
私の意図は、概念を1つにすることだった。ルールを二つにしてもそんなに困らなかったかもしれないが、
しかし単一概念のほうが、各機能の円滑な統合化と単純な実装を可能にする。
概念を一つにしなければ、"伝統的なCスタイルのプログラミング"から"抽象データタイプ"へ、
そしてさらに"オブジェクト指向プログラミング"への、円滑で斬新的な移行はできない、と感じていた。
結局のところ、こういう考え方が、実用ツールとしてのC++の成功のためにきわめて重要だったのではないだろうか。
インクルードファイル側でFOO_H_INCLUDE_によるインクルードガードをしてたらアボーンだな。
972 :
968 :2006/07/16(日) 23:35:14
>>970-971 外部インクルードガードって、ヘッダ内のガードを外でも検査するガードのことじゃないの?
確かに
>>967 で #include の後にもう一度 #define しているのは辻褄が合わないな。
どうも勘違いをしているのかもしれない。
そう思って今一度 Google に聞いてみたが、
>>967 の例がおかしいんじゃないかと思った。
だから、
>>967 の
#ifndef FOO_H_INCLUDE_
#include "foo.h"
#define FOO_H_INCLUDE_
#endif
みたいなインクルードのしかたは頭悪すぎ、って話でしょう
Mozillaじゃ普通にやってることだが?
そらMozillaの頭が悪すぎってだけだろ。
ヘッダ自身が自身のインクルードを「ヘッダ内部」でガードするべき、ってことでしょ ヘッダ外部にガードを委託するべきでない、と
977 :
967 :2006/07/17(月) 00:19:04
質問の仕方が悪かったです
すみません
本では内部インクルードを以下のように定義しています
---foo.h---
#ifndef インクルードガード名
#define インクルードガード名
//ここにヘッダファイルの中身を書く
#endif
で、この内部インクルードは置いておいて、
>>967 のような外部インクルード[のみ]を使う方法について、
どうしてインクルードする側とインクルードされるヘッダ側に
インクルードガード名についての合意が必要なのかが
わからないのです
たとえばa.cppで
#ifndef FOO_
#include "foo.h"
#define FOO_
#endif
としてガード名をFOO_としてfoo.hをインクルードするとき、
foo.h側は別にガード名FOO_を知らなくても何も問題が
ないじゃないかと思ったのです
一体どこらへんが合意なのかと
>>968 さんの回答が理解できません
上記の例ではfoo.h自体はインクルードガードをしていないのです
foo.h自身がするインクルードガードを内部インクルードガードと
呼んでいる様なのです
>>977 外部インクルードガードのみを使う場合でも、すべての箇所で
同じガード名を使わないと意味ないから、ガード名について
妙なスコープでの統一が要るようになるのは確かだな。
何も問題がないとは言えないだろう。
翻訳が腐ってるとか、そんなオチだったりして。
俺はこういうことかと思った。 foo.hは次のようになっていて、 #ifndef FOO_ #define FOO_ /* ... */ #endif hoge.cppは次のようにする。 #include "bar.h" //ここで既にfoo.hはインクルードされているかもしれない #ifndef FOO_ #include "foo.h" #define FOO_ #endif hoge.cppはそのまま"foo.h"をインクルードすると、 大量の空行を読み込むことになる。それを気にするほどメモリがないから、 予めhoge.cpp側でFOO_が定義されているかどうかを調べるという具合。 で、hoge.cppのようなことはやめようというのが件の記述ではないか?
>>977 あとね、外部インクルードガードの効果は、 #ifndef によって結局は無駄になる
ヘッダファイルの(ある意味物理的な)読み取りによるオーバーヘッドを避けるのが
よくある使用意図であって、外部インクルードガードだけを使うことなんて無いと思うよ。
この意図で多く使われるようになったが、コンパイラの実装によって
内部インクルードガードのパターンを認識してファイルの読み取り自体を
スキップするようなこともできるから、結局外部インクルードガードは無駄になる。
>>979 多分それが正解。今手元にないから確かめられないけど、『大規模C++
ソフトウェアデザイン』に載ってた話。
で、理由がちょっと違ってて、大規模プロジェクトにおけるコンパイル時間を
短縮するために、external include guardも書きましょう、という話だったと思う。
10年前の本だからね。コンパイル時間も数時間、あるいは10時間を超える
ようなこともあたりまえだった。
だけど今では、external include guardを書かなくても、プリプロセッサが
読み込んだヘッダファイルを覚えていて、たとえ二重にインクルードしても
ディスクアクセスが発生しなくなったから、というのが理由だったと思う。
多分、多分で恐縮だけど、こんな話だったと思う。
982 :
981 :2006/07/17(月) 01:30:18
・・・と980を読む前に書いたのでした orz
そろそろ次スレが要りそうだ。 以下は次スレの準備に使わせてほしい。 相談は次スレが建つまで待ってくれ。
テンプレの更新をしようとしたんだけど、いくらか気になったことがあったんで相談。
反対意見があれば言ってほしい。ただし肯定意見や埋まりそうな気配があれば
以下の要領でさっさと建てるんであしからず。
>>6 ISO の規格を参照するなら open-std のサイトからダウンロードできる
最新のドラフトが pdf 内でリンク貼られててすごく見やすいと思った。
こっちがあれば怪しい kuzbass のやつはリンク削除してもおk?
CUJ へのリンクは更新してみようとしたけど、新しいとこは何か
見にくいサイトになってるんで要らないかも。削除おk?
[Dr. Dobb's Journal | C++ (was C/C++ Users Journal)]
http://www.ddj.com/dept/cpp/ cppll のリンクも確認のために見てみたけど、リンクに使われてる
バーの背景が見にくくて嫌だった。こっちも要らないかも。削除でおk?
>>11 実際の関連スレは多すぎ、 Boland C++ や C++ Builder のスレも復活してるし。
もう「スレタイ C++ で検索してくれ」でいいかな?
それでも Boost スレと GCC スレはヒットしないから、別途リンク貼る。
ATL/WTL は削除するつもり。
その方針でいいんでない?
>>983 リンク先のリンク先を流し読みしたところ、次のような記述がありました。
> I wrote a quick script to add redundant guards to all the source code
> and did a full build again. The number of includes reported by the compiler
> went down to 10,568 (from over 15,000). That means that there were about
> 5,000 redundant includes in a full build. However, the overall build time
> didn't change at all.
>
> Result: Zero. Apparently Visual Studio .NET 2003 (and probably most of
> the major compilers) does a pretty good job caching those includes by itself.
これは数百ファイルからなるプロジェクトをVS .NET 2003でビルドするときの
話なんですが、のべ15,000回を超えるincludeが、”冗長”guard(=external
include guard)をすることによって、10,568回に減ったそうです。
ところが、フルビルド時間は全く変わっていない。
このことから、VS .NET 2003ではincludeファイルの読み込みをうまくキャッシング
してるのであろうし、他のメジャーなコンパイラもそうであろうと結論付けています。
『大規模C++ソフトウェアデザイン』という書籍は、当時かなりのインパクトを 業界にもたらしたんだと思う。 俺もこの本を読んだときに、脊髄に電気が走った記憶がある。 ただ、今となってはどんな内容だったのか思い出せないが・・・。
GNUのautoconfでは、 config.hの中で外部インクルードガード風のコードが多用されています。 インクルードガードのように二度読み込むのを防ぐんじゃなくて、 プラットフォームの違いを吸収するのが目的だけど。 こういう目的以外には外部インクルードガード「風」はほとんどないんじゃないかと思います。
>>992 どうして外部インクルードガード風のコードが
プラットフォームの差を吸収できるのか
もうちょっと
kwsk
992じゃないけど クロスコンパイル環境を作りたくて glibcを直してたときに見たなー 実際に見た方が早いよ
995 :
993 :2006/07/17(月) 16:11:58
>>994 わかりました
これから見てみます
理解できなかったら次スレで質問させて下さい
埋めるべ
あっ、埋めよう
同志社
同志社
魑魅魍魎
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。