5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

C++相談室 part64

1 :デフォルトの名無しさん:2008/11/01(土) 21:32:27
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part63
http://pc11.2ch.net/test/read.cgi/tech/1217008269/

2 :デフォルトの名無しさん:2008/11/01(土) 21:33:19
■基本■
ググレカス
http://www.google.co.jp/

3 :デフォルトの名無しさん:2008/11/01(土) 22:47:59
STLつかうと一気に実行ファイルサイズが





なぜ今たてる

4 :デフォルトの名無しさん:2008/11/02(日) 00:52:16
下のjavaのコードをC++にしようと思ったんですが、コンパイルエラーが出てしまいます。こういうとき、C++ではprotectedの代わりに何を使えばいいんでしょうか?あきらめてpublicなのかなぁ。
[Main.java]
abstract class A { protected abstract void foo(); }
class B extends A {
    protected void foo(){System.out.println("foo!");}
    public void bar(){pa.foo();}
    public void set(A p){pa = p;}
    private A pa;
}
public class Main { public static void main(String[] args) { B b = new B(); b.set(b); b.bar();}}
$ javac Main.java; java Main
foo!
[protected.cpp]
#include <iostream>
class A {
protected://public:とすれば問題無し
    virtual void foo()=0;
};
class B : public A {
protected:
    void foo() {std::cout << "foo!" << std::endl;}
public:
    void bar() {pa->foo();}
    void set(A* p) {pa = p;}
private:
    A *pa;
};
int main() { B b; b.set(&b); b.bar(); return 0;}
$ g++ protected.cpp
protect.cpp:4: error: ‘virtual void A::foo()’ is protected
protect.cpp:10: error: within this context

5 :デフォルトの名無しさん:2008/11/02(日) 09:51:03
>4
なんで、A を継承してるのにさらに A を内部に持とうとしてるの?

6 :デフォルトの名無しさん:2008/11/02(日) 10:46:50
<<5
Strategyみたいなことをしたいんじゃね?

<<4
インターフェースなのに公開しないというのが不思議だけど
どうしてもfooを呼ばれたくなければAの方をpublicにして、
protected継承すればよいと思う

7 :デフォルトの名無しさん:2008/11/02(日) 13:32:00
まだ早いだろw

8 :デフォルトの名無しさん:2008/11/02(日) 22:43:03
>>4
それ、Javaでもprotectedだから見えるのではなく、
同一パッケージのデフォルトアクセスのおかげで見えているだけだぞ。
BとAを別のパッケージに置くとJavaでもエラーになる。

9 :デフォルトの名無しさん:2008/11/03(月) 10:09:46
ubuntu上で開発しているのですが、自分で作った共有ライブラリを使うときに、
実行ファイルとライブラリを同フォルダに置いても、ライブラリがありませんと言われます。
LD_LIBRARY_PATHにカレントディレクトリをセットすれば動くのですが、毎回セットするのも
面倒で、だからといって/usr/libなどを汚したくもありません。
何か良い方法はないのでしょうか?


10 :デフォルトの名無しさん:2008/11/03(月) 10:20:47
/usr/local/lib か或いは全く別のディレクトリを決めて、そこに入れるようにすれば?

11 :デフォルトの名無しさん:2008/11/03(月) 10:26:20
>>10
やっぱりそれがいいのかな
自分が作った共有ライブラリを放り込むフォルダ作って、
パスを通しておく方法でいってみます。

12 :デフォルトの名無しさん:2008/11/03(月) 12:40:29
前スレが残ってるじゃん

C++相談室 part63
http://pc11.2ch.net/test/read.cgi/tech/1221144557/

13 :デフォルトの名無しさん:2008/11/03(月) 13:03:55
フォルダじゃなくてディレクトリと言ってね。

14 :C++嫌いな人:2008/11/03(月) 18:59:04
C++の便利な機能って
コンストラクタ、デストラクタ、メンバ関数、ポリモフィズム、
以外に何かあります?

テンプレートって使いどころが今一不明

15 :デフォルトの名無しさん:2008/11/03(月) 19:00:53
必要がないと感じなければ使わない自由があるのがC++

16 :デフォルトの名無しさん:2008/11/03(月) 19:33:08
全然答えになってない
流石C++スレ

17 :デフォルトの名無しさん:2008/11/03(月) 19:49:51
個人的にはテンプレートなしでのC++はありえない

18 :デフォルトの名無しさん:2008/11/03(月) 21:28:07
reallocよりはvectorのresizeのほうが便利だ。
テンプレートで要素の型を指定するから適宜よろしくやってくれる。

qsortよりはsortのほうが便利だ。
比較関数の引数がvoid*でないだけでも随分便利に感じる。
ソート対象と比較対象で要素の型を間違えれば警告やエラーになる。
まあエラーメッセージがわけわかめなのは御愛嬌。

19 :デフォルトの名無しさん:2008/11/07(金) 02:55:24
同じインターフェースの中で、
型によって異なる動作をさせたい時に使うのがポリモーフィズムで、
異なる型に同じ動作をさせたい時に使うのがテンプレート。

20 :デフォルトの名無しさん:2008/11/07(金) 03:20:55
>>19
同じ動作をさせたい時にテンプレート?
動作が同じなら普通にその動作を書けばいいだけじゃないの?

21 :デフォルトの名無しさん:2008/11/07(金) 03:25:44
同じアルゴリズムを適用したい時、かな。
>>20
型が違うので同じ処理には渡せない。
同じ処理をソース上複数書くと保守性に欠ける。

22 :デフォルトの名無しさん:2008/11/07(金) 05:33:09
>>21
それは同じ基底クラスから派生させてポリモーフィズムで解決することもできるだろ。

23 :デフォルトの名無しさん:2008/11/07(金) 08:12:54
>>22
テンプレートでやった方がスマートだよ。

24 :デフォルトの名無しさん:2008/11/07(金) 08:38:14
プリプロセッサで…いやなんでもない

25 :デフォルトの名無しさん:2008/11/07(金) 08:53:03
>>23
具体的に、何が良いのか言えるかな?
「スマート」とかいうあやふやな価値観でヘッダの依存関係を強制されるのは受け入れがたい。

26 :デフォルトの名無しさん:2008/11/07(金) 10:26:26
効率。

27 :デフォルトの名無しさん:2008/11/07(金) 20:52:20
そもそも、>>19がポリモーフィズムとテンプレートを並べていることに疑問を感じる。
ある種のポリモーフィズムを実現する1つの手段としてテンプレートがあるというのが自分の認識。

28 :デフォルトの名無しさん:2008/11/07(金) 21:10:53
ここまで「ジェネリクス」という言葉無し。

29 :デフォルトの名無しさん:2008/11/07(金) 21:35:32
ポリモフィズムは、is a だろ。
インタフェースとか継承とか使って、クラスA B Cが同じように見えて、同じように扱える。
使う側はABCの実装なんか気にすること無い。それぞれが勝手によろしくやってくれる。

で、ジェネリクスは template<typename T> G だろ。型 T を引数で渡すんだ。
型による違いは T を使う側、つまり G が面倒見なきゃならんのだな。
クラス X Y Z で G<X> G<Y> G<Z> とか。X, Y Z はお互いの違いなんて気にすること無く同じ機能を使える。
G が勝手によろしくやってくれる。

ところが T は型なんだ。つまり class なんだ。ってことはポリモフィズムが使えるんだ。
T をインタフェースにして、A B C がインタフェースを実装してたら、G は楽になるよな。
わざわざ場合わけする手間が省ける。A B C は同じ手続きを提供しているわけだから。

A B C が自分自身に関する情報を共通の手段で G に提供する。
ジェネリクス G は A B C のポリモフィズムを利用して、
さらに高レベルな手続きや機能を、A B C に付加するんだな。

そんなこんなで STL であり Boostなんだろうな。

30 :デフォルトの名無しさん:2008/11/08(土) 03:25:50
静的ポリモーフィズムというのもあってのう・・・

31 :デフォルトの名無しさん:2008/11/08(土) 14:55:16
コンパイル時ポリモーフィズムとも言う。
元々は関数のオーバーロードなどを指したけど、異なる型に対するテンプレートの実体化もある意味オーバーロードだからな。

32 :デフォルトの名無しさん:2008/11/10(月) 23:50:57
OOPの用語と区別できるように、
Interface -> Concepts
Inheritance -> Refinement
ってSGIのドキュメントに書いてあった。

33 :デフォルトの名無しさん:2008/11/12(水) 18:34:20

error LNK2019: 未解決の外部シンボル
"int __cdecl import_features(char *,int,struct feature * *)"
(?import_features@@YAHPADHPAPAUfeature@@@Z) が関数
"void __cdecl readfeatures(void)" (?readfeatures@@YAXXZ) で参照されました
とかいうエラーがでるんですけど、
どういうことをここではいってるんですか?


34 :デフォルトの名無しさん:2008/11/12(水) 18:46:35
未解決な外部シンボルが関数で参照されているということを表しています。
恐らくは、readfeatures()で呼んでいる筈のimport_features()が見つからないのでしょう。

35 :デフォルトの名無しさん:2008/11/12(水) 18:48:43
リンカでエラーになるってことは、大抵は宣言はあるんだけど定義がない関数が呼ばれたってこと。
宣言と定義が微妙に食い違ってて別物扱いされてるとかな。

36 :デフォルトの名無しさん:2008/11/12(水) 18:50:49
とりあえず前スレ使いきろうな

37 :デフォルトの名無しさん:2008/11/12(水) 19:43:17
だからって無理に前スレで
このスレにレスしなくても

38 :デフォルトの名無しさん:2008/11/12(水) 23:41:47
親子関係にあるクラスで、クラスParentがChildを複数持っているとします
Parentのコンストラクタ内で複数のChildを生成します。

ここで、ChildからParentの情報を参照したくなったので、
ParentへのポインタをChildに持たせ、コンストラクタでParentへのポインタを渡そう思ったんですが、

Parent::Parent() : child1_(new Child(this)),child2_(new Child(this)) //←これはヤバス?{}

デバッガで覗くとあやしげな値が入っていて、どうやら無効なポインタぽいです
まだできてないインスタンスのポインタを持ってもしょうがないって事ですかね

こういう場合うまいこと子クラスに親の参照を持たせる方法ってないですか

適当にInit()関数とか用意して、そこで全ての子に親への参照を持たせるのが手っ取り早いのですが
子が親への参照を持ってない状態ができてしまうのと、
Parentクラスの利用者に余計な手間を強制してしまうのでイマイチな気がします

39 :デフォルトの名無しさん:2008/11/12(水) 23:44:38
コンストラクタでもthisは有効だが、それ以前に相互参照なので気持ち悪い。

40 :デフォルトの名無しさん:2008/11/13(木) 00:11:07
俺だったら、親クラスのコンストラクタで子供なんか作らない。
必要になったときに作る。

41 :デフォルトの名無しさん:2008/11/13(木) 00:11:18
>>38
Childのコンストラクタで、渡されたParentオブジェクトをアクセスするのはNG
参照を憶えておくに留め、Parentのコンストラクト後にならいくらでもアクセスしてOK

>>39
Parentのスーパークラスに依存しているのかもしれない。
その場合は相互参照ではないね。

42 :デフォルトの名無しさん:2008/11/13(木) 04:20:02
本体ではもちろんthisポインタは有効だけど、初期化リスト中でも有効だっけ?

43 :デフォルトの名無しさん:2008/11/13(木) 09:25:02
有効でなければ初期化リストでインスタンス変数の初期化ができないだろ。

44 :デフォルトの名無しさん:2008/11/13(木) 09:53:27
有効じゃないぞ
値が変更されないだけ


45 :デフォルトの名無しさん:2008/11/13(木) 11:06:21
error LNK2001: 外部シンボル
""int __cdecl import_features(char *,int,struct feature * *)"
(?import_features@@YAHPADHPAPAUfeature@@@Z)" は未解決です。
MfSift.obj
というエラーが出るんですけど、何が原因なんだと思いますか?
ヘッダに宣言、別ファイル.cに定義をしています。
他のソリューションでは動いていたんですが、このソリューションにコピペしたら
このエラーが出るようになり、困っています。


46 :デフォルトの名無しさん:2008/11/13(木) 12:09:22
関数import_featuresの宣言にextern "C"つけろ

47 :デフォルトの名無しさん:2008/11/13(木) 12:11:46
.c に定義をしている?
もしかしてそれを .cpp から呼び出そうとした?

48 :デフォルトの名無しさん:2008/11/14(金) 12:56:10
double numer, denom;
// ...
numer / denom;
としたときに,0除算の例外が起きるときは denom == 0.0 が常に true になるときだけでしょうか?
それとも denom == 0.0 が false のときでも上記の除算で0除算の例外が生じる可能性はありますか?

49 :デフォルトの名無しさん:2008/11/14(金) 14:04:39
普通は例外なんて飛ばずに無限大が返ってくるだけだろ

その辺の挙動を何とかしたいならアーキテクチャのマニュアル嫁

50 :デフォルトの名無しさん:2008/11/14(金) 17:33:19
偉そうなこと言って使えねー奴ばっかだな。

51 :デフォルトの名無しさん:2008/11/14(金) 17:40:51
スルー汁

52 :デフォルトの名無しさん:2008/11/14(金) 18:03:36
DLLの扱いについてなんですが、
Aというプログラムのヘッダで、
#include hoge/hoge.dll
として、hoge.dllを読み込み、
ProgramA.dllを作成したとします。
そしてこのProgramA.dllを全く別のディレクトリに入れて動かすことを考えているのですが、
この際、
hoge.dllは必要になりますか?
また、必要だとしたら、ProguramA.dllのあるディレクトリにhogeを作って、その中にhoge.dllを入れる必要がありますか?

53 :デフォルトの名無しさん:2008/11/14(金) 18:05:02
DLLの扱いについてなんですが、
Aというプログラムのヘッダで、
#include hoge/hoge.dll
として、hoge.dllを読み込み、
ProgramA.dllを作成したとします。
そしてこのProgramA.dllを全く別のディレクトリに入れて動かすことを考えているのですが、
この際、
hoge.dllは必要になりますか?
また、必要だとしたら、ProguramA.dllのあるディレクトリにhogeを作って、その中にhoge.dllを入れる必要がありますか?

54 :デフォルトの名無しさん:2008/11/14(金) 20:11:20
> #include hoge/hoge.dll
C/C++ の #include ディレクティブを正しく理解するほうが先です

55 :デフォルトの名無しさん:2008/11/14(金) 20:18:31
バイナリを#includeするという発想はなかった
コンパイルしたら何が起こるんだろう
こえー

56 :53:2008/11/14(金) 21:47:34
あ、そういやそうですね(汗
vs2005の設定で読み込ませるだけです。

57 :デフォルトの名無しさん:2008/11/14(金) 21:48:55
C++/CLIはちょい特殊だから別扱いしないとだめ。
同じDLLでも.NETのアセンブリはだいぶ性格が違うから。

58 :デフォルトの名無しさん:2008/11/14(金) 23:27:29
#include </dev/tty>

59 :デフォルトの名無しさん:2008/11/15(土) 02:25:01
ttp://www.kmonos.net/alang/d/2.0/declaration.html
ここで説明されているD言語のtypedefのような,強いtypedefと同等のことをするにはどうするのが簡単でしょうか?
Boostなどの利用を前提とされても構いません

60 :59:2008/11/15(土) 02:57:37
うおー,ごめんなさい
BOOST_STRONG_TYPEDEF
ってのがありました…

61 :デフォルトの名無しさん:2008/11/15(土) 23:17:00
>>60
それは数値型でだけしか意味を成さなかったような記憶が

62 :デフォルトの名無しさん:2008/11/17(月) 23:30:13
namespace内のクラスを前方宣言しようと思ったんですが、

(namespace fugaのFooクラス)

class fuga::Foo; //これだとコンパイルエラー

namespace fuga{
class Foo; //これならおk
}

class Hoge{
fuga::Foo* f_;
};

なぜなんでしょうか


63 :デフォルトの名無しさん:2008/11/17(月) 23:40:58
>>62
そういうもんです、としかいいようがないやね

64 :デフォルトの名無しさん:2008/11/17(月) 23:42:48
>>62
::は名前空間解決をするのであって
名前空間を生成するわけじゃないから

65 :デフォルトの名無しさん:2008/11/18(火) 00:09:06
visual studio2008のコンパイル方法がどっかに載ってたと思うんですけど
どこか分かる方教えて下さいませ。

66 :デフォルトの名無しさん:2008/11/18(火) 00:10:33
>>65
visual studio2008のソースって流出してたっけ

67 :デフォルトの名無しさん:2008/11/18(火) 00:16:58
>>66
ん?

68 :デフォルトの名無しさん:2008/11/18(火) 00:18:34
コマンドラインからコンパイラを起動するって意味か?

69 :デフォルトの名無しさん:2008/11/18(火) 00:18:52
遠まわしに失せろと言われてるんだよ

70 :デフォルトの名無しさん:2008/11/18(火) 00:22:48
>>65
http://msdn.microsoft.com/ja-jp/library/52f3sw5c.aspx
ここに載ってる

71 :デフォルトの名無しさん:2008/11/18(火) 00:24:56
http://msdn.microsoft.com/ja-jp/library/z7kx322x.aspx
Visual C++ C/C++ プログラムのビルド

72 :デフォルトの名無しさん:2008/11/18(火) 00:32:37
>>70
ありがとうございます

73 :デフォルトの名無しさん:2008/11/18(火) 20:12:42
Visual C++ 2008 Express Editionで流体の数値解析を行っています。
暫定的なプログラムが出来上がり、ビルド→デバッグなしで開始、と実行出来たのは良いのですが、
結果出力用のファイル名をscanfで受け取るように変更し、ファイル操作等を行っているところでおかしくなってしまい、
最終的には初めの上手く動作していたソースコードに新たにprintf文を付け加えただけで上手く動かない状態となってしまいました。

アルゴリズムはSIMPLEという半陰解法を用いており、未知数である圧力、速度をループ計算で解くというものです。
ループ内で、各回の収束判定変数の推移をprintfで出力していますが、これは正常に動作して16回のループで終了します。
新たなprintf文を加えると、この変数が2ループ目から#QNAN0となってしまい、圧力、速度を得ることができません。
このprintf文はループ内においても、その外側のmain文中においても同様です。
stdio.hに問題があるのかと思い、改めてscanf文を入れてみたところ、特に問題はありませんでした。
しかしputs("")では同様に異常が見られます。

収束判定用の変数には何も関与していないのに、こんなことがあるのでしょうか。
プログラミング環境の問題かとも思いますが、何か情報があれば力を貸していただきたいです。


74 :デフォルトの名無しさん:2008/11/18(火) 20:15:59
何かの変数の初期化を忘れてるとか (たまたまいい具合に初期値が入っていて偶然動いていた)

75 :デフォルトの名無しさん:2008/11/18(火) 20:35:11
どうせscanfでスタックの破壊でもしていると予想

76 :デフォルトの名無しさん:2008/11/18(火) 21:09:58
書き込みありがとうございます。
>>74
初期化せずに扱っているものはないと思います。
>>75
現在scanfは用いていないのですが、スタックの破壊は具体的にどういう現象がおきていそうなのでしょうか。

77 :デフォルトの名無しさん:2008/11/18(火) 21:10:33
スタックの破壊 の検索結果 約 239,000 件中 1 - 10 件目 (0.27 秒)

78 :デフォルトの名無しさん:2008/11/18(火) 21:11:56
scanf スタックの破壊 の検索結果 約 3,230 件中 1 - 10 件目 (0.19 秒)

79 :デフォルトの名無しさん:2008/11/18(火) 21:15:43
スタック破壊は怖いぞー
一見何も関係なさそうな変数がいつの間にかぶち壊れてるからな

80 :デフォルトの名無しさん:2008/11/18(火) 21:24:41
デバッガ使えばすぐわかると思うぞ?

81 :デフォルトの名無しさん:2008/11/18(火) 23:03:47
取り敢えず、そのprintf()の周辺だけでも貼ってみたら?

82 :デフォルトの名無しさん:2008/11/18(火) 23:58:59
>>73
デバッガ使えるなら、問題の変数の値がQNANになる所で
ブレークしかけておけば原因がすぐわかると思うよ。

83 :デフォルトの名無しさん:2008/11/19(水) 12:25:56
>>77-78
スタックの破壊については昨日調べました。

>>81
参考になるか分かりませんが、プログラムの概略を載せます。

1   int main(void){
2      grid();               //格子を切る関数
3      init();               //初期値を代入
4      while(sorce>sormax){
5         cal_U();         //それぞれ速度U、V、Pを計算する関数
6         cal_V();
7         cal_P();
8         sorce = maxof3(resorm, resoru, resorv);      //maxof3()は3数の最大値を返す
9         printf("%lf %lf %lf %lf\n", sorce, resorm, resoru, resorv);
10      }
11      output();            //結果を出力
12   }

だいたいの流れはこのような感じです。
11行目以降はprintfを入れても問題なく走ります。

デバッガのことは知らなかったので、とりあえず今Visual C++ Express Editionのデバッグ機能を使ってデバッグをしてみました。
2行目にprintf("aiueo.\n");と入れてステップインで一行ずつ実行していくと、これまでと違い、このprintf文も実行され、ループも問題なく回っています。
これは何を意味しているのでしょうか…。

84 :デフォルトの名無しさん:2008/11/19(水) 13:16:30
グローバル変数でデータのやり取りしているならどこかの関数で同名のローカル変数を定義しているんじゃないの。
ていうか関数間のデータのやり取りにグローバル変数使うのヤメロ。

85 :デフォルトの名無しさん:2008/11/19(水) 18:30:29
デバッグモードに変えたりprintf入れたりした影響で挙動が変わったんだろうな

しかしひでープログラムだな
ローカル変数を知らないのか?

86 :デフォルトの名無しさん:2008/11/19(水) 20:51:15
>>85
流れであって実際のコードじゃないです。
ローカル変数に見えているのは実際にはファイルのstatic変数なんです


87 :デフォルトの名無しさん:2008/11/19(水) 20:58:23
BCBを持っていればCodeGuardの出力したログファイルを
ロダに上げてもらえば一発でバグの原因が分かるんだが・・・

88 :デフォルトの名無しさん:2008/11/19(水) 21:05:29
>>87
CodeGuardはいい機能と思っているが
いま、バカのC++を使ってるのってほとんどいないだろ。

VS用CodeGuardやVS用CodeGuardもどき ってないのか?

89 :デフォルトの名無しさん:2008/11/19(水) 22:23:30
>>86
83のコードにローカル変数なんか一つもないじゃないか
てか変数壊してるかもって話なのに変数定義省略するとかふざけてるのか

やっぱりわかってないのね
とりあえずCの勉強し直すのをお勧めする

90 :デフォルトの名無しさん:2008/11/19(水) 22:47:59
>>89
聞いているのは、どうしたら問題の部分を発見できますかじゃないのか?
問題箇所発見方法を聞いているのであって、(トンでもないプログラム構成だろとは想像できるが)
文法、コーディングスタイルは聞いていないと思う。それにCの勉強し直すのをお勧めする じゃ
ある意味的外れだろ(ググれカス的かな)
問題箇所部分の推定すら出来てない状況じゃ、かなりな部分のコードさらさないと駄目な気がする。

91 :デフォルトの名無しさん:2008/11/19(水) 23:28:41
%lf が1つ多いとかいうオチなんじゃないか?

92 :デフォルトの名無しさん:2008/11/19(水) 23:53:10
printf("%lf %lf %lf %lf %lf\n", sorce, resorm, resoru, resorv);
で、コンパイル通るんですか? 試してないですが、通らないですよね
で通った場合、最後の%lfは何を(どこを)表示するんですか

93 :デフォルトの名無しさん:2008/11/19(水) 23:57:11
>>92
スタック上の適当なデータを勝手にIEEE実数だと仮定して読んだ積もりになる。
しかも、恐ろしいことに%fを生で使っているので数百桁出力することも有り得る。

94 :デフォルトの名無しさん:2008/11/20(木) 00:04:37
×%lf
○%f

C++ はまだこうだな。
そして、printf のフォーマットまでチェックするコンパイラもあるけど、
全くチェックしないコンパイラもある。

まあ、ログ入れると動くっていう変なバグは大抵スタックを破壊してる。
スタックを破壊する原因は、
・ 配列のインデックス計算にミスがあり、配列外の領域に書き込んだ
・ 配列のインデックスに未初期化の変数を使って、配列外の領域に書き込んだ
・ ポインタの演算にミスがあり、予期しない領域に書き込んだ
・ 未初期化のポインタを使用し、予期しない領域に書き込んだ
など、色々あるが、どれも原因特定には地道な作業が必要だ。

95 :デフォルトの名無しさん:2008/11/20(木) 00:08:02
まあ基本的にスタックを破壊してるから、
ローカル配列変数の扱いにまずいところがないかチェックだな。

96 :デフォルトの名無しさん:2008/11/20(木) 00:20:57
>>93-94
>全くチェックしないコンパイラもある
ガクガクブルブル、信じられな
それはprintf系だけで話で、
自分で関数f(a,b,c)を作り、たとえば、これをf(a,b)とか、f(a,b,c,d)とか書くと
この場合は全てのコンパイラーでエラー絶対に起こりますよね? 起こらないのあったりして

97 :96:2008/11/20(木) 00:25:27
天下のVisual C++ 2008はチェックしてないってこと!?
なんか、orzです。

98 :デフォルトの名無しさん:2008/11/20(木) 00:26:56
>>96
C++では通常有り得ない。Cで未宣言の状態で関数を呼ぶ場合は、大いに有り得る。
まぁ、C++でもprintf()の例で判るように可変個数引き数(...)があればチェックされないが。

99 :デフォルトの名無しさん:2008/11/20(木) 00:30:55
printfのフォーマットって言ってるから

可変引数は普通チェックされないけど
printf系とかだけ、第一引数の内容と残りの引数の整合性を見てくれるコンパイラがあることを言ってるんじゃないの?

100 :96:2008/11/20(木) 00:39:35
>>98
ありがとうございます。CでもC++で(.cpp拡張子つけて)コンパイルすることにします。
ただ、printfは引数の数チェックしていないと覚えておかないといけないですね。
そうしないと、printfが終わった時点でまだ使うスタック変数を失う可能性がありますね。

101 :デフォルトの名無しさん:2008/11/20(木) 00:42:05
>>100
>そうしないと、printfが終わった時点でまだ使うスタック変数を失う可能性がありますね。
何を仰っているのかよく判りませんが、なにやら勘違いをなさっているとお見受けしました。

102 :デフォルトの名無しさん:2008/11/20(木) 00:44:01
void* p;
printf("%x", p);

だと警告が出る(vs2005)

printf("%p", p);

は当然でない

103 :96:2008/11/20(木) 00:46:54
あ、可変個数引き数(...)関数はですね

printf,sprintfでも変数は可変個数引だから、チェックなしは当然かな

104 :デフォルトの名無しさん:2008/11/20(木) 00:47:53
寧ろ、チェックしてくれていると考えるんだ。

105 :96:2008/11/20(木) 00:53:40
>>101
どう、勘違いしていると思っているんですか?

>>102
printf("%p %d", p); じゃどうですか?


106 :デフォルトの名無しさん:2008/11/20(木) 00:58:19
>>105
printf()の使い方をどう間違えたところで、ローカル変数がおかしくなるなんてことは(%nでも使わない限り)有り得ない。
それはさておき、「スタック変数」なんて妙ちきりんな言葉を使いなさんな。

107 :デフォルトの名無しさん:2008/11/20(木) 01:00:12
>>83
もしかしてcal〜とかmax〜の関数の中で配列使ってないか?
使ってるなら配列に値を代入する直前にインデックスをprintfして
配列のサイズを超えた値になってないか確認してみ。
俺の予想では、そんだけグローバル変数が多いところを見ると、
きっとインデックスもグローバル変数になってて、
初期化もせずに使い、2回目以降のループで死んでるとみた。

108 :デフォルトの名無しさん:2008/11/20(木) 01:06:27
C++だと
for(int i=0; i<MAX; i++)
がその類のミスを除く常套句として使えるな
多言語だとforかforeachで書くループがwhileになってるFORTRANを逐語訳して死んでるのはたまに見るな

109 :デフォルトの名無しさん:2008/11/20(木) 01:24:00
Fortranからの移植だと、判定を<=にしてしまったり、
index-1するのを忘れる可能性がw

110 :デフォルトの名無しさん:2008/11/20(木) 06:54:06
しかしSingle Pass Rangeに対応させようと終端チェックを!=で行う実装では無限ループする
<>比較演算子だとRandom Access Traversalを要求するからのう

111 :デフォルトの名無しさん:2008/11/20(木) 16:00:10
ATLのCFindFileみたいに、UNICODEのdefine状態に応じて、メソッドの
FindNextFileA と FindNextFileW を内部で自動的に切り分けているような
クラスを使う時に、MBCSとUNICODE両方に対応するコードは
どうやって書いてる?

#ifdef UNICODE
#define FindNextFile FindNextFileW
#else
#define FindNextFile FindNextFileA
#endif

は邪道??

112 :デフォルトの名無しさん:2008/11/20(木) 16:07:54
それは常套手段だね

113 :デフォルトの名無しさん:2008/11/20(木) 16:09:21
それでいいと思うけど、それはWin32APIの関数と同名だから、自分でその#ifdefを書く必要はないよ。

114 :111:2008/11/20(木) 16:18:24
>>112
そうだよね。
ただ、クラスのメソッドだけと取り上げてdefineすると、
インテリセンスに違和感ない?
ドット打っても、こんなメソッドねーYO!なのにコンパイル通る不思議。
保守で胸やけしそう。
みんなこんなもんなのかな。

>>113
メソッド名に流用しても平気?
流用が気持ち悪いなら _FindNextFile とかにしようかな。


115 :デフォルトの名無しさん:2008/11/20(木) 16:20:46
>>114
コンパイルできるという点では平気。あとは好みの問題。
ちなみに、ATL/WTLではUNICODE切り替えに関して全面的にWin32API用の#ifdefを流用している。

116 :デフォルトの名無しさん:2008/11/20(木) 16:21:20
_から始まるトークンは使ってはならない。

117 :111:2008/11/20(木) 16:27:51
>>115
ほぉー!そうなのか。
勉強になりました。ありがとう。

>>116
なんかそれ以前誰かにも言われたな・・・
互換性の為に残してあるとか。
そういえば今だに _ の意味がよく理解できてない俺は所詮VB厨

_ と __ との違いとか意識して使ってる?

118 :デフォルトの名無しさん:2008/11/20(木) 16:45:03
1.グローバルスコープにあり、_で始まる識別子
2._で始まり、英大文字が続く識別子
3.__を含む識別子

以上は処理系のために予約されており、ユーザが使うことは規格違反になる。

119 :デフォルトの名無しさん:2008/11/20(木) 16:48:18
めんどくさいから、自分は1と2をまとめて_で始まるのは駄目と簡略化して覚えている。

120 :デフォルトの名無しさん:2008/11/20(木) 18:10:19
>>106
105は、たぶんprintfとscanfを混同しているのだと思う。
スタック変数というのは確かに変な用語だがw

スレも、あまりに自然な流れで話題が scanf→printf へ移ってるからな

>>105
とりあえず俺からできるアドバイスは、
そのようなバグは、対処療法的に直すというよりも、プログラムの書き方を改善すると
自然に治るというパターンの方が多い。急がば回れ。
とりあえず、そのstatic変数を、*すべて* ローカル変数と関数の引数にすること。
数値計算のプログラムだったら、static変数なんかいらないだろ

121 :デフォルトの名無しさん:2008/11/20(木) 18:41:09
>>120
>>105と元祖質問者>>73は別人だろ
105=96と元祖質問者>>73の書き方はだいぶ違う。


122 :デフォルトの名無しさん:2008/11/21(金) 00:50:35
struct God {
 int foo, bar, hoge;
 int a, b, c, d, e, f, g;
 unsigned char h, i, j, k, l, m, n;
 double piyo, piyopiyo, baz, foobar;
 int x, y, z;
};

int main() {
 God god;
 Foo(&god);
 Bar(&god);
 Hoge(&god);
 FooBar(&god);
 Baz(&god);
}

と書いて満足されるかもしれない恐怖。

123 :デフォルトの名無しさん:2008/11/21(金) 01:17:50
#define retrun return
#define cahr char
#define unsinged unsigned

124 :デフォルトの名無しさん:2008/11/21(金) 01:21:22
retrunはときどき普通に変数名に使うから困る

125 :デフォルトの名無しさん:2008/11/21(金) 02:41:25
勝手にすればと言う気持ちも半分あるが
変数名retrunはやっぱ普通に困るよ

126 :デフォルトの名無しさん:2008/11/21(金) 14:45:44
C++の例外って
std::bad_alloc
以外に何がありますか?
例外一覧が乗っているサイトとかありますか?


127 :デフォルトの名無しさん:2008/11/21(金) 14:55:50
別に飛ばす気になればどんな型だって例外で飛ばせるが。

128 :デフォルトの名無しさん:2008/11/21(金) 14:58:31
c++標準の例外です。

129 :デフォルトの名無しさん:2008/11/21(金) 15:00:07
自己解決しました。
標準例外でググったら見つかりました
ttp://www.geocities.jp/ky_webid/cpp/library/027.html


130 :デフォルトの名無しさん:2008/11/21(金) 15:00:35
std::exceptionで検索

131 :デフォルトの名無しさん:2008/11/21(金) 15:09:09
例外にぬるぽってないんですか?
ぬるぽは、何でcatchしたらいいんですか?

132 :デフォルトの名無しさん:2008/11/21(金) 15:12:53
>>131
ない、つーか無効なポインタ参照しちゃっても例外投げない

133 :デフォルトの名無しさん:2008/11/21(金) 15:16:45
ぬるぽアクセスは未定義動作です。
つまり、何が起きるのか (例外が発生するのか、シグナルが発生するのか、
何事もなかったかのように動作し続けるのか、鼻から悪魔が出るのか)、
C++の規格では定義されていません。

134 :デフォルトの名無しさん:2008/11/21(金) 15:40:30
try{
int* p = 0;
*p = 100; // SNT(スーパーぬるぽタイム)
}catch( int e ){
printf( "%d exception\n" , e );
}catch( std::exception e ){
printf( "exception(%s)\n" , e.what() );
}catch( ... ){
printf( "misc exception\n" );
}
一応、misc exception って出るんですお

135 :デフォルトの名無しさん:2008/11/21(金) 15:44:06
Releaseだと出ないPO
げにおそろしきぬるぽ

136 :デフォルトの名無しさん:2008/11/21(金) 16:16:16
>>134
そういう変なものを例外で受け取れてしまうのはWindowsだけ(構造化例外)

137 :デフォルトの名無しさん:2008/11/21(金) 16:21:25
ポインタが壊れていると、 SIGBUS とか SIGSEGV のようなsignalが送られるOSもあるし。


138 :デフォルトの名無しさん:2008/11/21(金) 17:47:56
例えばポインタがメモリマップトのI/O領域を指していると
ポインタを出リファレンスしたりするとI/Oには読むだけで
動作するものもあるので、鼻から悪魔としか言えない

139 :デフォルトの名無しさん:2008/11/22(土) 03:38:26
ある初期化関数を呼ばないといけない処理をラップしたクラスを作るとします

たとえばWindowsのコモンコントロールを使うには
InitCommonControl()を事前に呼んでおく必要があります

class hoge{
public: static once_init(){ legacy_global_init(); }
};
hogeを使うユーザが明示的にonce_initを呼ぶ決まりにしておけばいいだけの話なんですが、
なるべく初期化関数を呼ぶ必要がない様にしたいです

そこで、翻訳単位内に
struct static_initializer{ static_initializer(){ legacy_global_init(); } };
というクラスを作って静的なインスタンスを作成し、
namespace{ static_initializer s_inst; }
自動的に初期化させる様にしました。

他の翻訳単位の初期化関数に依存する時はまずそうですが、
その他気をつける事はありますか?

というかこういう処理をするのはどうするのがセオリーなんでしょうか


140 :デフォルトの名無しさん:2008/11/22(土) 03:45:28
コンストラクタが初めて呼ばれたときだけ実行するとか?

class hoge{
static int x;
hoge() {
if (x == 1) {
x = 0;
legacy_global_init();
}
}
};
hoge::x = 1;



141 :デフォルトの名無しさん:2008/11/22(土) 03:48:42
静的オブジェクトは初期化の順序が保障されないから、あまりそういう用途で使わないほうがいい。
精々、互いに無関係な変数の初期値設定くらいだろうな。

複数のコントロールをまとめて一つの単位として扱いたいなら、ビルダーパターンとか、ファクトリとかのクラスを作って
そのクラスの初期化関数を一発呼ばせる。それくらいはさせるべきだろ、

ユーザーがコントロールの初期化の前に何かやりたいと思ったときにそれが出来ないんじゃ困る。


142 :139:2008/11/22(土) 03:50:40
>>140
そちらの方が初期化が遅延されるので、hogeクラスを全く使わない時には
初期化関数が呼ばれないので無駄が無くていいですね

マルチスレッド環境で気をつけないといけないですが

143 :139:2008/11/22(土) 03:53:36
>>141

>ユーザーがコントロールの初期化の前に何かやりたいと思ったときにそれが出来ないんじゃ困る。
確かにこの視点は抜けてました
ユーザの自由度はなるべく下げたくないですね

デザインパターンですか
ちょっと勉強してきます

144 :デフォルトの名無しさん:2008/11/22(土) 11:11:57
VS2005 C++です
仮想関数から、基底クラスのメンバー変数を参照する、クールな方法を教えて、もらえませんか
基底クラスには、そのメンバー変数に対する、アクセッサー(set/get関数)は、実装しているのですが
当たり前のことですが、基底クラスで、その、メンバー変数をセットしたものは、派生先の、基底クラスから、
呼び出しても、コンストラクターが、呼び出されだけで、初期化されたメンバー変数しか、取得できません(当然のことですが)

基底クラス、派生クラスに関係ない、普通に、C言語タイプの関数を定義して(クラスを定義しないという意味です)
そこで渡す方法とか、有ると思うのですが、2ちゃんねらー諸兄のテクニックを、伝授してください、長文スマソ。

145 :デフォルトの名無しさん:2008/11/22(土) 11:13:26
×当たり前のことですが、基底クラスで、その、メンバー変数をセットしたものは、派生先の、基底クラスから、
○当たり前のことですが、基底クラスで、その、メンバー変数をセットしたものは、派生先クラスから、
すみません

146 :デフォルトの名無しさん:2008/11/22(土) 11:36:19
>>144
こうか? 普通に取得できるようだけど
class Base {
private: int foo;
public: Base() : foo(0) {}
int GetFoo() { return foo; }
void Bar() { foo = 42; Hoge(); }
virtual void Hoge() = 0;
};
class Derived : public Base {
public:
virtual void Hoge() { cout << GetFoo() << endl; }
};
int main() {
Base *p = new Derived();
p->Bar();
}

147 :デフォルトの名無しさん:2008/11/22(土) 11:36:39
>>144
意味が分からん。クールとか無理。
とりあえず自分で書いたコードでも見せてくれないか?

148 :デフォルトの名無しさん:2008/11/22(土) 11:56:10
長文が問題なのではなく悪文が問題だな。
意味がわかりづらい上に、なんだその西村京太郎みたいな読点。

149 :デフォルトの名無しさん:2008/11/22(土) 11:56:21
protedted「お困りのようですな」

150 :デフォルトの名無しさん:2008/11/22(土) 11:58:18
何かの暗号じゃね?

151 :デフォルトの名無しさん:2008/11/22(土) 15:22:24
VS2005 WindowsSDKで
エディットボックス内の背景色の変更の仕方がわからない。

とりあえず、色を指定してブラシを変更して再描画命令出してみたけど書き換わらないんだけどどうすればええん?

152 :デフォルトの名無しさん:2008/11/22(土) 15:27:33
オナニードロー

153 :デフォルトの名無しさん:2008/11/22(土) 16:30:36
WM_CTLCOLORかWM_CTLCOLOREDITをマップ

154 :デフォルトの名無しさん:2008/11/22(土) 16:59:06
>>153
WM_CTLCOLORでブラシの設定はさせてみたけど変わりませんでした

155 :デフォルトの名無しさん:2008/11/22(土) 17:43:09
int配列をenum配列にキャストしたいんですが、何かいい方法ないでしょうか?
テンプレート使って要素1つ1つキャストするクラス作ろうとしたんだけど、
テンプレートってenum型はダメなのね。。

enum HOGE {
  A = 0;
  B = 1;
};

HOGE hoge[] = { 0, 0, 1, 1 };
// ↑暗黙キャストされないからエラー

156 :デフォルトの名無しさん:2008/11/22(土) 18:00:24
>>154
hDC弄るんじゃなくて、返り値にヒープに作ったブラシハンドルを返すんだ

157 :デフォルトの名無しさん:2008/11/22(土) 18:24:56
どうしてもintで初期化しなければいけないのか。
enumの使い方が間違ってないか。

158 :デフォルトの名無しさん:2008/11/22(土) 18:27:26
>>155
HOGE hoge[] = { A, A, B, B };
でいいんじゃないか?

159 :155:2008/11/22(土) 20:25:34
>>157
>>158
うーん、やっぱ使い方がおかしいか。
配列初期化するときだけはintで書いた方がわかりやすいんだけど、
それはそれで別途変換コード書いたほうがいいか。
どうもありがとう。

160 :デフォルトの名無しさん:2008/11/22(土) 21:14:34
vitrual関数のメリットが良くわからない。
継承したクラスのメソッドを置き換えるってイメージなんだけど
何でわざわざ別の処理に変更させるの?



161 :デフォルトの名無しさん:2008/11/22(土) 21:22:26
デザインパターンを勉強するといいよ

162 :デフォルトの名無しさん:2008/11/22(土) 21:25:11
>>161
了解。
一応ググってみたけれどけどもう少し解りやすい
メリットを提供して頂けると僥倖。


163 :デフォルトの名無しさん:2008/11/22(土) 21:31:05
動物がワンと鳴いたりニャーと鳴いたりするためです

164 :デフォルトの名無しさん:2008/11/22(土) 21:35:37
int hoge[] = { HOGE::A, HOGE:;B}; とかで

165 :デフォルトの名無しさん:2008/11/22(土) 21:45:18
>>162
全然関係ないですが"僥倖"って言葉初めて知りました
でも、明日には忘れてそうです><

これが、クールな表現なんだな。

166 :デフォルトの名無しさん:2008/11/22(土) 21:49:57
すみません、感動のあまり上げてしまいました。
その上、本来カキコする内容すら忘れてしまいました。orz

167 :デフォルトの名無しさん:2008/11/22(土) 21:50:44
>>160
一個の雛形で色々出来ると便利だから

168 :デフォルトの名無しさん:2008/11/22(土) 21:54:58
>>167
ひな形?


169 :デフォルトの名無しさん:2008/11/22(土) 22:03:14
突っ込んだらいけないんだろうか?
http://www.google.co.jp/search?hl=ja&q=vitrual&lr=&aq=f&oq=

170 :デフォルトの名無しさん:2008/11/22(土) 22:47:38
DLLからico読み出すってどうすればいいんですか?

171 :デフォルトの名無しさん:2008/11/23(日) 00:43:26
void* と関数ポインタは互換性がないらしいですが、
では任意の関数を格納できるポインタはどう宣言すればいいでしょうか

一応

int bar(int i){ cout << "bar arg = " << i << endl; return i + 2; }
//関数ポインタに入れて
void (*fp)() = reinterpret_cast<void(*)()>(bar);
//取り出して
int (*fp_arg1)(int i) = reinterpret_cast<int(*)(int)>(fp);
//実行する
std::cout << "return value = " << fp_arg1(3) << std::endl;

とむりやりキャストしてみると一応動きます

172 :デフォルトの名無しさん:2008/11/23(日) 00:48:19
> void* と関数ポインタは互換性がないらしいですが、

そうなの? 「互換性」がどういう意味か分からないが、キャストは出来ると思うが。
メンバ関数ポインタは無理だけどね。


173 :デフォルトの名無しさん:2008/11/23(日) 00:56:27
>>172
関数ポインタから void* へキャストできることも多いけど、移植性の面では避けたいところ。
C++98,2003 では確かにできないことになっているし、次の改訂で変更が入るものの
"conditionally-supported behavior" とかいう微妙な扱いになってる。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#573

174 :デフォルトの名無しさん:2008/11/23(日) 00:57:56
sizeof(X*)はXがvoidかデータ型なら同じになることが保証されてるけど
関数ポインタはその保証がない
もしかしたらvoid*より大きいかもしれない

175 :171:2008/11/23(日) 01:08:15
boost::functionがその手の処理をやってそうなので
今ソースを見ているんですが、心が折れそうです

176 :デフォルトの名無しさん:2008/11/23(日) 01:10:40
テンプレートを変態的に使うと、void*間のキャストは避けられるぜ。


177 :デフォルトの名無しさん:2008/11/23(日) 01:13:04
>>174
> sizeof(X*)はXがvoidかデータ型なら同じになることが保証されてるけど
いや、それは無いだろ。

178 :デフォルトの名無しさん:2008/11/23(日) 01:20:01
察してやれ・・・・・・・・

179 :デフォルトの名無しさん:2008/11/23(日) 01:37:36
>>177
ごめん、そんな保証なかった

>>171
5.2.10.6
関数へのポインタは、別の関数へのポインタに明示的に変換することが出来る。
ある関数の定義で用いられた関数型とは異なる関数型へのポインタを介して関数呼び出しを行った結果は、未定義とする。
型"T1へのポインタ"の右辺値から型"T2へのポインタ"(ここでT1及びT2は、関数型とする)へのポインタ変換の結果は、
それを元の型に戻すと元のポインタ値に戻ることを除いて、未規定とする。

これ読む限り、関数型同士ではreinterpret_castし直せば戻ることが保証されてるみたいだから
void (*)()にでも格納すればいいんじゃね

180 :171:2008/11/23(日) 01:43:44
>>179
なるほど

元のシグネチャでちゃんと取り出せば、
とりあえずは何の関数ポインタに格納しておいてもいいんですね

void(*)()に入れておきます

ありがとうございました

181 :デフォルトの名無しさん:2008/11/23(日) 01:44:54
ファンクタもテンプレートもあるんだから、そんなことすんなってことですね。


182 :デフォルトの名無しさん:2008/11/23(日) 13:12:22
関数ポインタとデータポインタのサイズが違う事があるのは、
例えば MS-DOS のミディアムモデルやコンパクトモデルだな。
このあたり知ってれば互換性が無いのは当然の話と分かる。

183 :デフォルトの名無しさん:2008/11/23(日) 13:13:32
DSPだとハーバード・アーキテクチャが多いから
データポインタと関数ポインタはビット幅が違うこともあるよ

184 :デフォルトの名無しさん:2008/11/23(日) 13:17:26
Cの話題になってしまうが
printfのフォーマット文字列に、関数ポインタ用の%pが無いのは規格の不備ではないかと思っている

185 :デフォルトの名無しさん:2008/11/23(日) 13:19:43
そういやそうだな。
流石にメンバポインタはどう表現していいものか分からんから
無くても仕方が無いとは思うが・・・。

186 :デフォルトの名無しさん:2008/11/23(日) 17:23:04
>>182
i8086 を持ち出すならデータポインタ同士、関数ポインタ同士でもサイズが違ったりするだろ

187 :デフォルトの名無しさん:2008/11/23(日) 17:56:40
すいません、私、MS-DOSって全然使ったことがないんですけど
それを語ることの出来るってことは、このスレにはおじちゃん世代が
かなり居るってこと?おじちゃん世代ってもう現役PGじゃないですよね

188 :デフォルトの名無しさん:2008/11/23(日) 18:50:56
MS-DOSは20代でも知ってるだろ・・・

189 :デフォルトの名無しさん:2008/11/23(日) 18:51:40
>>186
near ポインタと far ポインタは標準じゃないし・・・。

190 :デフォルトの名無しさん:2008/11/23(日) 20:21:18
>>187
「自分で興味があるから小さい頃から触ってた人」と
「他に何も出来ないから専門学校を出て職業コーダーになった人」の違いですよ。

191 :デフォルトの名無しさん:2008/11/23(日) 20:25:03
MS-DOSって確か1981年ぐらいに出たと思ったし
未だにVistaでもDOSプロンプト積んでるんだからおぢいちゃんとかおぢちゃん世代って言われる筋合いねぇっていうか
未だにバッチ処理させるのに使ったりするし、今現在「定年まで勤めたプログラマ」は存在しない

192 :デフォルトの名無しさん:2008/11/23(日) 20:28:51
>>190
その前者はいつまで現役でプログラミングしてるもんなんだろ
当然,やりたい仕事ができるかぎりは引退までなん?

193 :デフォルトの名無しさん:2008/11/23(日) 20:38:48
むしろコーダーの将来のほうが心配ですけどね。
どちらもまだ20代でしょうけど。

194 :デフォルトの名無しさん:2008/11/23(日) 20:47:28
プログラミング云々ではなく「MS-DOSを触った経験」について言うなら、
Win3.1以前のユーザーなら誰しも少なからずDOSに触れたことがあるはずだから、
たとえば小学校の真ん中くらいに、最初に買って貰ったPCに入ってたのがWin3.1、
なんて人は、DOSの使用経験があってもまだ20代の半ばくらいだね。

>>190が言いたいのはそういうこと(年齢よりは本人の"PC歴"に依存する)では。

195 :デフォルトの名無しさん:2008/11/23(日) 21:12:34
MS-DOSとコマンドは違うとするのか?
それとも同じとしているのか?

厳密に言うなら、Win2000以降はDOSプロンプトじゃないんじゃない?

196 :デフォルトの名無しさん:2008/11/23(日) 21:15:52
>>192 
自分では現役でいたくても、会社が強制引退にするのがほとんど
フリーには多いのかもしれないが、40代で主業務がプログラミングなのうちでは
ほとんどいないな

197 :デフォルトの名無しさん:2008/11/23(日) 21:31:52
今は、コマンドプロンプトだな。MS-DOSじゃない。
そもそも、16bitコマンドってまだVistaでも動くのか?

198 :デフォルトの名無しさん:2008/11/23(日) 21:35:35
エミュレータ積んでるから無問題

199 :デフォルトの名無しさん:2008/11/23(日) 21:36:47
>>197
動くけど、16bit用の日本語のデータが無いから日本語使うプログラムは動かないし
最初のWindows向けに書かれたプログラム何も弄らなくってもVistaで動くものもあるっていう・・・

200 :デフォルトの名無しさん:2008/11/23(日) 21:47:27
MS-DOSってソフトで直接I/Oいじることが可能だったはず
そんなことをしているソフトもほとんどVistaのコマンドプロンプトで動くのか

201 :デフォルトの名無しさん:2008/11/23(日) 21:48:48
コマンドプロンプトって debug ってうってみそ。
ハンドアセンブルできるよ。

202 :デフォルトの名無しさん:2008/11/23(日) 21:50:21
そういえばMEは9x系だから一応MS-DOSプロンプトだよな。見たこと無いけど。
98SEとかはまだ現役なところもあるって聞くし。

それと、自作暦が数年以上あるような人は
BIOSのアップデートとかで(無意識かもしれないが)
DOSに触ったことがある人も居るだろう。

だから何だと言われればそれまでだが。

203 :デフォルトの名無しさん:2008/11/23(日) 22:02:47
>>200
というか仮想メモリの概念がない
OS含めて全プロセスが同じアドレス空間を共有する

204 :デフォルトの名無しさん:2008/11/23(日) 22:08:25
EMM386が火を噴くぜ

205 :デフォルトの名無しさん:2008/11/23(日) 22:20:20
おじちゃん多いなら
CP/M-80、FLEX、OS9 とか使ったことあるよな

206 :デフォルトの名無しさん:2008/11/23(日) 22:24:00
今 flex とか言うと、flashの話になっちゃうよw

ちょっと前に「flexって知ってる?」って聞かれて
「yacc/lexのlexのgnu版のflex?」って答えて恥かいたw

207 :デフォルトの名無しさん:2008/11/23(日) 22:46:28
>>200
vistaはもう保証外のはずだけど
9x系のDOSプロンプトは、リアルモードじゃなくて仮想86モードで動いてた(>>204で)。
で、その場合はI/Oは全てトラップされて9xのカーネル内でエミュレートされて
正常に動くようになっていた。
もちろん、単純にI/Oを発行しなおしても調停等が無ければ正常に動くわけ無いので
それをうまく動かすために、MSは個別対応等多大な努力をしたと聞く。
ビデオやディスク等BIOSを使うのが普通だったものはともかくとして、
サウンド関係なんかはI/O直が普通だったので相当苦労したらしい。

208 :デフォルトの名無しさん:2008/11/23(日) 23:10:34
>>206
俺はflexと聞くとflexlmを思い出す

209 :デフォルトの名無しさん:2008/11/24(月) 00:17:20
>>205
アセンブラM80、リンカL80、ライブラリアンLIB80

  aseg
  .z80
  org    100h

まずこれで始めたよな。

210 :デフォルトの名無しさん:2008/11/24(月) 00:38:05
BASICの次にハンドアセンブルだろ、JK。

211 :デフォルトの名無しさん:2008/11/24(月) 00:46:49
>>207
それどころか、9xだとWin32アプリからもIOできて、DOSアプリ同様トラップして処理される。
自分がやったのは直接ディスクアクセスで、使ったのはint割込だったけど。

212 :デフォルトの名無しさん:2008/11/24(月) 09:18:01
Win32APIスレでやれ

213 :デフォルトの名無しさん:2008/11/24(月) 09:37:37
すいませんあそこはちょっと・・・

214 :デフォルトの名無しさん:2008/11/24(月) 10:19:32
C++、WindowsSDKでGUIソフトウェアを作ってるんですが、ショートカットキーってどうやって実装すればいいんですかね?

215 :デフォルトの名無しさん:2008/11/24(月) 10:26:41
キーボードアクセラレータでググれ

216 :デフォルトの名無しさん:2008/11/24(月) 10:30:41
>>215
できた、ありがとう

217 :デフォルトの名無しさん:2008/11/24(月) 18:22:41
class clsA{
public:const int a;
};
class clsB{
public:clsA ca;
};

上記のような2つのクラスがあります。
この場合、clsBのcaのaの定数を指定する場合、どのようにしたら良いのでしょうか。
教えてください。

218 :デフォルトの名無しさん:2008/11/24(月) 18:24:03
clasB.clasA.a

219 :デフォルトの名無しさん:2008/11/24(月) 18:31:28
すみません。出来ませんでした。
後だしですみませんが、コンパイラはVC++2008です。

220 :デフォルトの名無しさん:2008/11/24(月) 18:33:27
>>219
どうやったら、どうなったのか書けよ。
読んでるほうはエスパーじゃない。

221 :219:2008/11/24(月) 18:36:10
そもそも何処に記述したら良いのか分かりません・・・

222 :219:2008/11/24(月) 18:37:14
あー、すみません。今思ったら質問の仕方が悪かったですね。
clsBのcaのaの値を設定したい、ということです。

223 :デフォルトの名無しさん:2008/11/24(月) 18:37:36
class clsA{
public:const int a;
clsA( const int a ) : a( a ){ ; }
};
class clsB{
public:clsA ca;
clsB( const int a ) : ca( a ){ ; }
};
int main( void ){ clsB b( 10 ); std::cout << b.ca.a; return 0; }
こういうことか?

224 :デフォルトの名無しさん:2008/11/24(月) 18:38:12
>>221-222 >220

225 :219:2008/11/24(月) 18:40:23
>>223
正にそれを求めていました!ありがとうございます。

226 :デフォルトの名無しさん:2008/11/24(月) 18:52:55
エスパー乙

227 :デフォルトの名無しさん:2008/11/24(月) 19:11:51
>>223
clsA( const int a ) : a( a ){ ; }
の;をとったらコンパイルエラーは直りますか?

228 :デフォルトの名無しさん:2008/11/24(月) 19:14:07
>>227
>>220
どんなコンパイルエラーか書けよ

229 :デフォルトの名無しさん:2008/11/24(月) 19:26:14
どんだけゆとりかよ。>227
ここに出て来るaはどっちがどっちのaなのか調べろよ。コンパイラも混乱するわ。

C++なんてトラップの多い言語使わずにPythonとか使っとけ。


230 :デフォルトの名無しさん:2008/11/24(月) 19:33:18
>>228
これ
エラー:E0000、あなた嫌い
でつ

231 :デフォルトの名無しさん:2008/11/24(月) 20:52:31
>>228 >>229
でもあなたは;をとったらどうなるか
意味はわかっているのですか?

232 :デフォルトの名無しさん:2008/11/24(月) 20:55:40
>>231
とっても増やしても変わらないよ

233 :デフォルトの名無しさん:2008/11/24(月) 21:01:23
>>232
それはどういうことですか?
分かりやすく教えてください

234 :デフォルトの名無しさん:2008/11/24(月) 21:32:47
;はその行の終わりを示すんだからあろうがなかろうが変わらない
何も無い関数の中に;つけておくのもここ何も無くて終わるよって人間の為だし
;の有無でかわるか?って聞く前にコンパイル通して試してみろよと。

頭の中でコンパイルできないなら、機械を使え、機械に使われるなバカ

235 :デフォルトの名無しさん:2008/11/24(月) 21:57:21
つか#include<iostream>と>>223でコンパイルできるんだが
Visual C++ 2008 Express Editionで確認した

236 :デフォルトの名無しさん:2008/11/24(月) 22:40:12
>>234
> ;はその行の終わりを示すんだからあろうがなかろうが変わらない
行の終わりは改行だと思うのですが?

> 何も無い関数の中に;つけておくのもここ何も無くて終わるよって人間の為だし
そういう人は何も無い関数の中に;がないと何か続きがあると思うのでしょうか?


237 :デフォルトの名無しさん:2008/11/24(月) 22:55:35
>>236
> 行の終わりは改行だと思うのですが?
いいえ。

> そういう人は何も無い関数の中に;がないと何か続きがあると思うのでしょうか?
そういう人を探して訊いてみればいいと思います。

238 :デフォルトの名無しさん:2008/11/24(月) 23:07:04
セミコロンが行の終わり?

バカとバカががっぷりよつに組んでるようにしか見えん。

239 :デフォルトの名無しさん:2008/11/24(月) 23:12:43
あーではいつもの厳密な定義をお願いします

240 :デフォルトの名無しさん:2008/11/24(月) 23:19:23
厳密な定義が欲しけりゃ仕様書を読むのが早い

241 :デフォルトの名無しさん:2008/11/24(月) 23:19:52
>>237
> > 行の終わりは改行だと思うのですが?
> いいえ。
では行の始まりだというわけですね?

> > そういう人は何も無い関数の中に;がないと何か続きがあると思うのでしょうか?
> そういう人を探して訊いてみればいいと思います。
では>>223の人に訊いてみてください

242 :デフォルトの名無しさん:2008/11/24(月) 23:20:22
>>238
> バカとバカががっぷりよつに組んでるようにしか見えん。
同感ですね。

>>239
> あーではいつもの厳密な定義をお願いします
いつもの?

243 :デフォルトの名無しさん:2008/11/24(月) 23:21:35
>>241
> では行の始まりだというわけですね?
いいえ。

> では>>223の人に訊いてみてください
意味不明です。

244 :デフォルトの名無しさん:2008/11/24(月) 23:24:24
>>240
> 仕様書
別名「馬鹿には見えない文書」ですねw

245 :デフォルトの名無しさん:2008/11/25(火) 00:01:04
自分が読んでないことを露呈する用語だな

246 :デフォルトの名無しさん:2008/11/25(火) 00:12:49
説明できない=仕様書読んだ事ありませんと
言っているようなもんか

247 :デフォルトの名無しさん:2008/11/25(火) 02:41:38
";" 単体は空文であって文の一種だから文法的に問題ない…でいいんじゃないのかな

248 :デフォルトの名無しさん:2008/11/25(火) 04:32:27
>>231みたいな面倒くさい人に絡まれたときには相手にしないのがいいと思うけど、
>>234で「行」ではなくてexpressionとでも書いておけば揚げ足もとられなかったのだね。

249 :デフォルトの名無しさん:2008/11/25(火) 04:36:52
expressionじゃまだつっこまれるぞ

250 :デフォルトの名無しさん:2008/11/25(火) 05:55:50
ちなみに、>>231がしてるのは";"じゃなくて";"の話だからな。
細かい違いに絡む人なんだから、勝手に";"の話とか解釈すると
これも揚げ足とられるから注意ね。

251 :デフォルトの名無しさん:2008/11/25(火) 06:54:59
>>249 ちょっと気になるなぁ・・・。
>>250 それこそ文意を汲んであげないと可哀想。
そういえば最近「鼻から悪魔」ってよく聞くんですが流行ってるんですか。


252 :デフォルトの名無しさん:2008/11/25(火) 07:24:09
>鼻から悪魔
C++を使おうという人ならこの程度は読んでなきゃ話にならない、という本で使われてたね。
もちろん、その本を読んで無くてもその程度のことが当たり前に身についてる人も居るだろうけど。

それと、最近じゃないよ。昔から。

253 :デフォルトの名無しさん:2008/11/25(火) 07:31:35
元々はなんかのフォーラムのネタじゃないんですか?
最近よく聞くようになった気がするのは仕様の話をする人と接する機会が増えたせいかな・・・。

254 :デフォルトの名無しさん:2008/11/25(火) 07:39:37
>>251
えー。困ったちゃんキャラになって文意を汲まない遊びをしてる人なんだから、
乗ってあげなきゃ逆に可哀相じゃん。

255 :デフォルトの名無しさん:2008/11/25(火) 07:45:43
>>253
1992年ごろにcomp.lang.cあたりに投稿された記事が由来だそうだが。
まあ最近っちゃ最近だわな。

256 :デフォルトの名無しさん:2008/11/25(火) 18:27:26
>鼻から悪魔
自分、この言葉にはなにこれって感じで、なんか、ぽかーんって感じ
英語ではぴったりの表現なんかな?それとも、良く使われる表現?


257 :デフォルトの名無しさん:2008/11/25(火) 18:52:50
>鼻から悪魔
自分、この言葉にはなにこれって感じで、なんか、ぽかーんって感じ
英語ではぴったりの表現なんかな?それとも、良く使われる表現?


258 :デフォルトの名無しさん:2008/11/25(火) 18:55:59
お前らこぴぺすんなよ、絶対だぞ

259 :デフォルトの名無しさん:2008/11/25(火) 21:16:09
「未定義動作はどんなに突拍子もないことも起こりうる」っていうことの
突拍子もないことの喩えなんだからその印象であってる

260 :デフォルトの名無しさん:2008/11/25(火) 21:30:25
なんかあっちの人っぽい言い回しだよな。
日本的な言い方に変えた方がいいんじゃね?
モニタから美少女とか。

261 :デフォルトの名無しさん:2008/11/25(火) 21:33:39
有りうるからダメ

262 :デフォルトの名無しさん:2008/11/25(火) 21:41:37
>>259-260
目ん玉が飛び出す の方が日本的でいい
鼻から悪魔じゃ、日本語能力低すぎて、ひどい翻訳している翻訳者と同じレベルだな

263 :デフォルトの名無しさん:2008/11/25(火) 22:01:06
鼻からではないけど、ハクション大魔王が元ネタだと思っていた。

264 :デフォルトの名無しさん:2008/11/25(火) 22:01:56
鼻から牛乳が好きなのだが

265 :デフォルトの名無しさん:2008/11/25(火) 22:06:19
>>262
そこで「既存の慣用句に使われている表現」を出すのは、ちょっと違うんじゃないかなぁ。
未定義の世界に踏み込んだ結果起こりうる、まったくの「予測不可能」を表現するには、
他で一切使われていないナニか、のほうが相応しいと思う。

たとえばの話、「物凄い金額を見せられる」という定義された行動でも「目玉は飛び出る」ものだから、
「未定義だと、こんなことさえ起きかねないんだぜ!?」っていう、未定義ならではを表現する言葉としては、
それだとインパクトが薄いのではないかと。

ここまで書いてやっと気付いたけど、すげえどうでもいい話題だなこれw

266 :デフォルトの名無しさん:2008/11/25(火) 22:31:56
変に凝らずに「パソコンが爆発しても仕様に反しない」でいいじゃない

267 :デフォルトの名無しさん:2008/11/25(火) 22:38:05
ケツからタケノコでどうでしょう。

268 :デフォルトの名無しさん:2008/11/25(火) 22:40:41
ボスに挑発的なメールを送ってもよい
競合他社にソースコードをFAXしてもよい
試験ではうまく動いて一番大事な顧客の前で突然動かなくなってもよい


269 :デフォルトの名無しさん:2008/11/25(火) 22:46:02
> 競合他社にソースコードをFAXしてもよい
どうせならFTPでファイルください

270 :デフォルトの名無しさん:2008/11/25(火) 22:47:34
チップから煙なら出たことある

271 :デフォルトの名無しさん:2008/11/25(火) 22:52:53
ただし魔法は尻から出る

272 :デフォルトの名無しさん:2008/11/25(火) 22:53:30
>>268
> 試験ではうまく動いて一番大事な顧客の前で突然動かなくなってもよい
Effective C++だっけ。サラッと流すような書き方が逆に笑えた。

273 :デフォルトの名無しさん:2008/11/25(火) 23:06:46
5次元ベクトルを格納する領域をn本 (nはわからない) を1グループとしてそれをmグループ持つデータ構造ってどんなのが
考えられるでしょうか?
nの数はグループによって違います


グループ1

double[5]
double[5]
  ・
  ・
  ・
---------

グループ2

double[5]
double[5]
  ・
  ・
  ・

アクセス時は、グループ2の1本目を見る、2本目を見るみたいにアクセスしたいです

274 :デフォルトの名無しさん:2008/11/25(火) 23:13:54
std::vector<double[5]>

275 :デフォルトの名無しさん:2008/11/25(火) 23:19:09
グループのタグ(stringかcharで)も付けたいんですが・・

276 :デフォルトの名無しさん:2008/11/25(火) 23:23:13
>>275
そうですか
さらに次の要求をどうぞ

277 :デフォルトの名無しさん:2008/11/25(火) 23:24:54
あとvectorの中に配列使った場合の値の入れ方がわかりません・・・


vect.push_back(  )

みたいには入れられませんよね
;


278 :デフォルトの名無しさん:2008/11/25(火) 23:26:49
vector<double[5]> test;

double tmp[5];

 tmpに入れたい値を一回入れる

test.push_back(tmp);

279 :デフォルトの名無しさん:2008/11/25(火) 23:44:53
STLコンテナの要素にはCopyConstructibleかつAssignableなものしか使えないよ

280 :デフォルトの名無しさん:2008/11/25(火) 23:47:12
stringとdoubleの構造体にしてその構造体のvectorをつくればいい

281 :デフォルトの名無しさん:2008/11/26(水) 00:20:21
>>280 良く分からないんですけど
struct neko {
string* nyah;
long piki;
vector<double[5]>* otte;
};
vector <neko> nekos;
こんな感じですか...うんーーん

282 :デフォルトの名無しさん:2008/11/26(水) 00:51:00
グループ内の順序とか、速度やメモリ効率を気にしないなら、
std::map<std::string, std::map<std::string, double[5]> >でいいんじゃない。
あ、タグは外側グループ、内側グループの両方につけた形だけど、そこんとこどうなの?

283 :デフォルトの名無しさん:2008/11/26(水) 01:05:36
どういう使い方を想定しているのかもうちょっと詳しく書けないものか
使い方次第で,適したデータ構造などは変わるものだが

284 :デフォルトの名無しさん:2008/11/26(水) 12:05:12
自分が何を望んでいるのかを、
質問してから先の問答で初めて真剣に考える奴って
割といる。

「俺は何かを望んでいるけど、どうやらそれが上手く行かない、誰か助けて〜」

死ねばいいと思う。

285 :デフォルトの名無しさん:2008/11/26(水) 12:58:27
C++の初心者向けの本でオススメの本があったら教えて下さい。

286 :デフォルトの名無しさん:2008/11/26(水) 13:15:24
accelerated C++
C++ coding standard 101

287 :デフォルトの名無しさん:2008/11/26(水) 13:16:17
C++ Primer

288 :デフォルトの名無しさん:2008/11/26(水) 17:55:52
>>284
あなた自身のことですね。死ねばいいと思う。

289 :デフォルトの名無しさん:2008/11/26(水) 18:12:04
Modern C++ Designマジお勧め

290 :デフォルトの名無しさん:2008/11/26(水) 18:20:22
WindowsSDKで行数取得とかってある?

291 :デフォルトの名無しさん:2008/11/26(水) 18:22:41
C++初心者向けって聞いてるのにModern C++ Designはないと思う。
Accelerated C++はマジお勧め。
学部のプログラミング演習等の副読本にも適していると思う。


292 :デフォルトの名無しさん:2008/11/26(水) 18:29:22
ロベール

293 :デフォルトの名無しさん:2008/11/26(水) 18:41:45
いやいや
C++が学ぶべき価値がある言語か判断するために最初にMC++Dを眺めとくのは重要
アレに興味を持って、理解できるようになるまで勉強しようと思えない限りC++には触らない方がいい

294 :デフォルトの名無しさん:2008/11/26(水) 18:46:10
ごめん、APIスレと間違えた

295 :デフォルトの名無しさん:2008/11/26(水) 18:49:27
>>293 は
Modern C++ Designの内容を完全理解し、書いてあることを使いこなしているいるのか

296 :デフォルトの名無しさん:2008/11/26(水) 18:59:28
自分で使いこなせなくても、既存のテンプレートライブラリを使うことはあるだろうし
トラブルが起これば中の汚物を読まなきゃならなくなることもあるはずだ
その時にMC++Dの知識は役に立つ

297 :デフォルトの名無しさん:2008/11/26(水) 19:12:18
俺もModern C++ Designは好きだけど初心者にオススメする神経が分からんな。

普通はマナちゃんのやさしいC++とか柴田望洋とか林晴比古あたりじゃないの。

298 :デフォルトの名無しさん:2008/11/26(水) 19:22:32
理解できなくてもパラパラめくるだけでいいよ
そこで吐き気を催したら引き返した方がいいというだけ

299 :デフォルトの名無しさん:2008/11/26(水) 19:29:05
>>298 
じゃ、本屋でパラパラ見るだけで良いってことか
パラパラ見て、お前は
アレに興味を持って、理解できるようになるまで勉強しようと決意してC++
を始めたのか。で、最初のステップとしてどの本を読んだ?

300 :デフォルトの名無しさん:2008/11/26(水) 20:57:10
おれは
独習C → ポインタの極意 → 独習C++ → Effective C++
で独習C++は選択を間違えたと思えた

301 :デフォルトの名無しさん:2008/11/26(水) 22:09:23
ここまで林本なし

ま、いいことだw

302 :デフォルトの名無しさん:2008/11/26(水) 22:12:14
>>300
独習C++ って俺のC++の最初の本だ
なっ、なぜそう思うんだ

303 :デフォルトの名無しさん:2008/11/26(水) 22:26:06
標準C++/STLの基礎知識3部作
柏原正三著

ちょっとあちこちに記述に癖があるけど、それをわかってて
読むなら結構易しい入門書

304 :デフォルトの名無しさん:2008/11/26(水) 22:27:33
Cのリファレンス→C++のリファレンス→やさしいC++→猫でも分かるCからネットワークまで→その辺のSDKリファレンス

305 :デフォルトの名無しさん:2008/11/27(木) 02:01:46
>>302
300じゃないけど、独習C++とかC++入門の類って基本的にどれも同じ匂いがする。
それぞれ記述に工夫はしているだろうけど、どれもC++の大味なダイジェストにしか過ぎないというか。
学ぶという点ではAccelerated C++に一票。

306 :デフォルトの名無しさん:2008/11/27(木) 09:02:51
独習C++は罠
絶対途中で飽きる…

307 :デフォルトの名無しさん:2008/11/27(木) 09:31:19
適性試験用に禿本

308 :デフォルトの名無しさん:2008/11/27(木) 14:49:10
>>302,305
独習C++の入門という意味では普通に読了できたんだけど
その後読んだEffective C++で知らないものばかりでてきて
独習C++だけじゃ全然知識足りないのかよ,って当時の自分は困ってしまってたから,こういう印象かな

そのあとは結局大学の図書館でいろんな本あさりまくってしまい効率悪かった
独習C++の後はこれ読むといいよ,っていうオススメな本とかも思い当たらないしなあ
でもそういう過程で知識がついたっていうのもあるけど

309 :302:2008/11/27(木) 18:33:54
>>308
入門書で必要十分な知識なんて得られないと思っている

独習C++ -> accelerated C++ -> 詳説C++ ってな感じだったな。
独習C++:C++さわりの勉強
accelerated C++:C++らしいコーディング、使い方
詳説C++:より詳しく
これら全ての読み終わってようやく入門過程終わりって感じかな。入門過程復習を兼ねて
禿げ教科書を詳説C++の後あたりに読むのも良いかもしれん。
次は初級過程でEffective C++、Effective STLなど自分の興味に応じて読めって感じだな

310 :デフォルトの名無しさん:2008/11/27(木) 19:46:18
Effective C++は必須だろ
興味なくても読んでくれないと困る

311 :デフォルトの名無しさん:2008/11/27(木) 19:56:03
Cは大学の講義で習い、C++は独学
C++専用ライブラリを使い倒して学んだ


その後、流行りのJAVAを興味本位だけで理解してみようと
入門書『明解JAVA』を購入

結構良かった



何が言いたいかっつーと、同じ著者で『明解C++』も出している
読んだことはないがちょっと期待

312 :デフォルトの名無しさん:2008/11/27(木) 20:35:05
Effective C++読むくらいならExceptional C++のほうがいいと思う。
Effective C++は当たり前の事ばかり書いててあんま役に立たんかった。

313 :デフォルトの名無しさん:2008/11/27(木) 20:44:47
その「当たり前の事」が大事なんだろ
平気でコンストラクタで仮想関数呼んだりデストラクタで例外投げたりするんだぞ初心者は

314 :デフォルトの名無しさん:2008/11/27(木) 21:36:08
Effective C++を初めて読んだ後
基底クラスの非virtual関数と同名のメンバ関数を派生クラスで定義していたのを
納品前にこっそり修正したのは
今となってはいい思い出だ

315 :デフォルトの名無しさん:2008/11/27(木) 22:01:01
C++ depthシリーズ読んだ後で作ったコードレビュー時の俺チェックリストが凄い事になった
自動化できそうなチェック項目も結構多いんで
こういうのを自動的に点検してくれるようなコードチェッカーってのが欲しいと思ったな
精度の高いパーザがあればそう苦労せずにできそうだとは思うけど
gccならコンパイラオプションでeffective c++に載ってるような間違いに対してある程度警告してくれるんだよね

316 :デフォルトの名無しさん:2008/11/27(木) 22:12:10
-Weffc++だな
しょうもないのしかチェックしてくれないけど

317 :デフォルトの名無しさん:2008/11/27(木) 22:12:42
>>285
初心者向きなのは
プログラミング言語 C++
Effective C++

上の2つを読んだらこれがおすすめ
More Effective C++
C++ In-Depth Series

318 :デフォルトの名無しさん:2008/11/27(木) 22:18:15
More Effective C++は原著(英語)の方がオススメ
間違いなく日本語訳より読みやすいから

319 :デフォルトの名無しさん:2008/11/27(木) 22:19:17
高橋麻奈のやさしいC++やロベールのような最近の本は
こういう時ろくに話に出てこないよな。

320 :デフォルトの名無しさん:2008/11/27(木) 22:20:53
C++を「やさしい」なんて言う本はそれだけで信用ならない

321 :デフォルトの名無しさん:2008/11/27(木) 22:23:24
基本機能一通りなんてどれでやっても大差ないだろうし

それより、言語仕様上やれるけど辞めてください項目を知ってもらうのが



322 :デフォルトの名無しさん:2008/11/27(木) 22:27:10
>>319
おっさん、じじいが多く、最近の入門書なんて読んでないから
話できないんじゃね。


323 :デフォルトの名無しさん:2008/11/27(木) 22:28:12
>>320
C++はやさしいだろ。

324 :デフォルトの名無しさん:2008/11/27(木) 22:43:51
厳しいと思うよぉ

325 :デフォルトの名無しさん:2008/11/27(木) 22:45:04
コードを書く奴に厳しいのが多いだけ。
言語自体はやさしい。

326 :デフォルトの名無しさん:2008/11/27(木) 22:48:49
C++はそこまで難しいとは思わない

だがしかし、GoTo文とかあるんだけど滅多に使うなって言われるものの説明が無い本が多いw

327 :デフォルトの名無しさん:2008/11/27(木) 22:50:49
ダメなC++本の見分け方
ひとつでも該当したらその本は捨てろ

・void main()
・定数をマクロで定義してる
・コンストラクタの初期化リストを使わない
・using namespace std;
・意味もなくキャストが旧形式
・_で始まる名前を勝手に使う
・ヌルポインタがNULL
・X x = new X(); if(x == NULL){ ... }
・ポリモーフィズムの例え話にAnimalクラス
・void operator +=(X)
・X& operator +(X,X)
・多重継承をとりあえずこきおろすが理由は書いていない
・「グローバル関数は危険です、全部メンバ関数にしましょう(キリッ」
・「コンストラクタから例外を投げてはいけません(キリッ」

あと何かな

328 :デフォルトの名無しさん:2008/11/27(木) 22:52:15
>>327
using namespace std;を一方的にダメだというのがダメだと思う

329 :デフォルトの名無しさん:2008/11/27(木) 22:55:11
古臭い本
#include <iostream.h>
auto_ptrをコンテナの要素にする。
nothrowでないnewの結果をヌルと比較している。

330 :デフォルトの名無しさん:2008/11/27(木) 22:57:20
>>328
説明を簡素にするためには必要悪だよね。

331 :デフォルトの名無しさん:2008/11/27(木) 23:38:10
>>327
入門者用Good本の見分け方,please

332 :デフォルトの名無しさん:2008/11/27(木) 23:44:25
ソースファイルの全てのincludeの後だったら別にいいんじゃね? >328

333 :デフォルトの名無しさん:2008/11/28(金) 00:40:25
実際のプログラムでは使うなよ、って書いてあれば十分

334 :デフォルトの名無しさん:2008/11/28(金) 01:35:51
using namespace ATL;

335 :デフォルトの名無しさん:2008/11/28(金) 07:16:03
というか、初めてC++に入る人間に対して名前空間がどうだあーだって説明してもわからんだろう。
はじめから順番にやっていってクラスが終わった辺りででてくりゃまだ実感沸くだろうけど。

336 :デフォルトの名無しさん:2008/11/28(金) 09:39:50
>>327
>ヌルポインタがNULL
現行でどうせいっちゅーんだ?
C++0xはまだドラフトだぞ。

337 :デフォルトの名無しさん:2008/11/28(金) 10:10:15
現行ではヌルポインタは 0 と書くのが一番いいんじゃね

338 :デフォルトの名無しさん:2008/11/28(金) 12:34:23
あるコンパイラで浮動小数がIEEE754かどうかを判別するためのマクロってありますか?

339 :デフォルトの名無しさん:2008/11/28(金) 12:41:32
>>338
標準には、ない。実装上は、なくもない。

340 :デフォルトの名無しさん:2008/11/28(金) 12:49:22
ヌルポインタはreinterpret_cast<void*>(0)だろ常考

341 :デフォルトの名無しさん:2008/11/28(金) 12:50:44
__STDC_IEC_559__ とかいうやつかな

342 :デフォルトの名無しさん:2008/11/28(金) 12:58:23
>>340
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#463
> A null pointer constant, which has integral type, is not necessarily converted to a null pointer value.

343 :デフォルトの名無しさん:2008/11/28(金) 13:02:49
>>340 m9(^Д^)プギャー

344 :デフォルトの名無しさん:2008/11/28(金) 13:08:30
bccで64bitの整数使いたいんだけど・・・long long intが通らない
どうすりゃいいの?


345 :デフォルトの名無しさん:2008/11/28(金) 13:25:24
bcc捨てればいいんじゃね

346 :デフォルトの名無しさん:2008/11/28(金) 13:32:34
__int64 で

347 :デフォルトの名無しさん:2008/11/28(金) 17:16:57
>>340
それをまたキャストするんですね分かります

348 :デフォルトの名無しさん:2008/11/28(金) 18:07:47
今まで上がってる本は、C言語を把握している事が前提?
本当にズブのド素人が読むには何がオススメ?

349 :デフォルトの名無しさん:2008/11/28(金) 18:15:20
せめてstatic_cast<void*>(0)だろ…
reinterpret_cast<void*>(0)はバイト列0x0をポインタと見做したものであってヌルポインタとは限らない

350 :デフォルトの名無しさん:2008/11/28(金) 18:19:25
>>349
試してから出直して来いカス

351 :デフォルトの名無しさん:2008/11/28(金) 18:25:47
まあ偶然うまく行く環境が多いだろうけど
それで正しいことにはならないぞ

規格読んで出直してこい

352 :デフォルトの名無しさん:2008/11/28(金) 19:04:49
なるぽ

353 :デフォルトの名無しさん:2008/11/28(金) 19:10:27
今日、コンストラクタでは
変数の初期化以外はするなと指摘されたんですが・・

わざわざCreateや、Initなんてメソッド作るメリットって何ですか?

354 :デフォルトの名無しさん:2008/11/28(金) 19:12:29
例外が嫌いな人はそう言うかもね。
コンストラクタは例外以外で直接はエラーを表現できないから。

355 :デフォルトの名無しさん:2008/11/28(金) 19:13:29
そうなんです。
コンストラクタの例外も突っかかれました・・・

356 :デフォルトの名無しさん:2008/11/28(金) 19:17:13
取り敢えず引き数なしで定義しておいて、後から初期化処理を呼ぶことができると
フレームワークのようなライブラリでは便利なのかもしれないという程度だと思う。

357 :デフォルトの名無しさん:2008/11/28(金) 19:19:06
別にコンストラクタから例外を投げても何ともないんだけどね。
RAII を使う場合はエラー時にコンストラクタから例外を投げるのは常識的な行為。
Google みたいに「例外を使ってはいけない」とかいうコーディング規約がないのであれば。

358 :デフォルトの名無しさん:2008/11/28(金) 19:20:08
>>356
初期化のタイミングをコントロールしたい場合は便利だよね。
new する手もあるけど、new は失敗するかもしれないし・・・。

359 :デフォルトの名無しさん:2008/11/28(金) 19:20:13
あとコピー代入演算子の実装が楽になる

360 :デフォルトの名無しさん:2008/11/28(金) 19:22:01
しかし、デメリットとしては、初期化が十分に行われていないうちに
色んなメンバ関数を呼ばれると困るという点があるね。

361 :353:2008/11/28(金) 19:25:19
RAIIという言葉は今はじめて知りました。
でも自分が理想としてるのは、まさにこんな感じです。
wikipediaチラ見ですけど。

362 :デフォルトの名無しさん:2008/11/28(金) 19:26:22
どっかで仮想関数呼んじゃったらアウトだからな
だから逆に「コンストラクタでメンバ関数を呼んではいけない」ルールがよいという主張もある
どっちが正しいと言うもんでもない

363 :デフォルトの名無しさん:2008/11/28(金) 19:32:14
まあ setter 使っても RAII できないわけじゃないので
(語源的にどうかと思うかもしれないけど、
 重要なのはデストラクタで自動的にリソースが開放される点なので)、
コーディング規約によっては setter 使っても悪いわけではない。

364 :353:2008/11/28(金) 19:43:09
>>358
自分は、おそらくそういう意図で指摘されたんだと思います。
new でタイミングをコントロールしちゃまずいんでしょうか。
その方は高速化がどうのこうのとも言っていました。


365 :デフォルトの名無しさん:2008/11/28(金) 19:45:30
>その方は高速化がどうのこうのとも言っていました。
寝言は兎も角w
>new でタイミングをコントロールしちゃまずいんでしょうか。
タイミングコントロールだけが目的なら感心しないが。

366 :デフォルトの名無しさん:2008/11/28(金) 19:45:38
まあ new は遅いからね。

ベストは両方可能にすることな気もするが。

367 :353:2008/11/28(金) 20:06:13
考えてたら、両方可能にしとけば
問題ないような気がしてきております。
既存のクラスって結構そういうのが多い気がしますし・・
いろいろご教授ありがとうございます。

368 :デフォルトの名無しさん:2008/11/28(金) 22:04:57
本ネタで思い出したが
来月ビャーン著の入門者向けの本が出るよ
http://www.research.att.com/~bs/programming.html

369 :デフォルトの名無しさん:2008/11/28(金) 23:48:01
イラネ

370 :デフォルトの名無しさん:2008/11/29(土) 02:47:21
ハゲはむしろC++0xの本を

371 :デフォルトの名無しさん:2008/11/29(土) 11:51:18
VC++2008を使っています。
無名名前空間にプロトタイプだけ突っ込んで、定義は他の場所で行おうと思っているのですが、どうにもうまくいきません。
func1()の方は特に問題なく動くのですが、func2はerror C2825が出てコンパイルエラーとなります。
何故でしょうか、、、

#include <windows.h>
namespace{ int func1(); BOOL func2(); };
int ::func1(){ return 1; }
BOOL ::func2(){ return TRUE; }

372 :デフォルトの名無しさん:2008/11/29(土) 13:36:48
::だとグローバルネームスペースになるんじゃなかったっけ?

373 :デフォルトの名無しさん:2008/11/29(土) 13:39:04
:: いらないよ

374 :デフォルトの名無しさん:2008/11/29(土) 15:01:34
template< typename BaseType = char >
class ChTraitsBase
{
public:
typedef char XCHAR;
typedef LPSTR PXSTR;
typedef LPCSTR PCXSTR;
typedef wchar_t YCHAR;
typedef LPWSTR PYSTR;
typedef LPCWSTR PCYSTR;
};
って言う記述があった場合、これってどういうこと?
クラスなのにメンバ変数とか、関数とか物理的なものが何もない。
これはtypedefの及ぶ範囲をChTraitsBaseクラスおよびその派生クラスで限定したいテクニックなのかな?


375 :デフォルトの名無しさん:2008/11/29(土) 15:04:52
特殊化と併用して
参照の参照を回避するのに使ったり

376 :374:2008/11/29(土) 15:09:37
レスありがとう。

でも何のことやら理解できない(TT)

377 :デフォルトの名無しさん:2008/11/29(土) 15:20:17
>>374
ChTraitsBaseはwchar_tで特殊化されているはずで、
全体としてみると、charかwchar_tでの使用しか念頭に置いていないCStringTで、
X〜は自身のテンプレート引数と同種、Y〜は違うほうの文字の型になるようにできている。

例えば、ChTraitsBase<char>::YCHARがwchar_tで、
ChTraitsBase<wchar_t>::YCHARがcharになるという具合。

具体的には、コンストラクタなどでは、X系の型ならそのまま格納、
Y系の型が来たら変換して格納なんて区別に使っている。

378 :デフォルトの名無しさん:2008/11/29(土) 15:43:32
なるほど。。考えた奴頭良すぎ

こういう使い方はC++の世界では、そういうテクニックとして認識されるものなのですか?



379 :デフォルトの名無しさん:2008/11/29(土) 16:52:47
>>378
標準ライブラリに std::char_traits や std::iterator_traits やらあるから、まぁそうだね。

最近は ..._traits みたいにひとつの型に複数の要素を入れるより、テンプレート引数から
一つの結果(型 type またはコンパイル時定数 value など)だけを取得できるようにして、
関数のような使いかたができるようにした「テンプレートメタ関数」のほうが好まれる。

380 :デフォルトの名無しさん:2008/11/29(土) 18:56:28
他の場所でnewで確保されたオブジェクトのポインタを持っているとき、
そのオブジェクトがすでにdeleteされたことを
ポインタを保持している側が判断することは可能ですか?

381 :デフォルトの名無しさん:2008/11/29(土) 18:57:45
>>380
面倒だから、削除された時に中身NULLとか書いておけば?

382 :デフォルトの名無しさん:2008/11/29(土) 19:07:10
shared_ptrならば、weak_ptrがある。

383 :デフォルトの名無しさん:2008/11/30(日) 00:09:15
「Effective C++があたりまえ」って言うけど、C++の言語仕様を読んだだけでこれらのテクニック全て
を当たり前だと理解できるのはすごいと思う。
普通に使ってても、テンプレート関連のテクニックとかを悟るのは相当厳しいんじゃないか?

あとみんなクラスのメンバ変数はどんな時でも全てprivateにしてるの実際?

384 :デフォルトの名無しさん:2008/11/30(日) 00:27:11
実は大抵のSTLの実装では
vectorやらlistやらのメンバ変数は
protectedか、実装によってはpublicだったりする。
継承すべきclassじゃないのに。

まあstackやqueueに使うためなのかな、と後で思ったが。

385 :デフォルトの名無しさん:2008/11/30(日) 00:30:32
protectedメンバ変数は悪だと言われてるけど実際は使っちゃうなぁ
派生クラスからしてみれば「自分の一部」として扱いたいこともあるし
protectedなアクセサ書くのもダルいし

publicにはしない

386 :383:2008/11/30(日) 00:42:08
実際俺も仕方なさそうな時はprotected使ってます。
OSSのコードとか見ても「メンバ変数は絶対private」を守ってるのはすごく少ないように思いますね。

387 :デフォルトの名無しさん:2008/11/30(日) 00:47:41
>>383
前半部分に付いて。
Effective C++(やその他Must Readな本)の内容は先人たちの長年の試行錯誤の成果だよ。
だから普通のC++ユーザは、自分で悟らなくてもそれらを享受すればよいだけ。
ただ、読んで盲目的に倣うんではなくて、勘所を理解した上で効果的に使って欲しいと思うけどね。

388 :デフォルトの名無しさん:2008/11/30(日) 01:19:07
protected なメンバはほとんど使わないな。
使いたくなった時はカプセル化の単位を見直せば、だいたい片付く。

this 以外を通しては同じクラスでもアクセスできないとか、
private/public には無いわかりにくいルールもあるんで、あんまり
使いたくも無い。

389 :デフォルトの名無しさん:2008/11/30(日) 03:03:24
俺なんかクラス内でさえprivateメンバはアクセサ経由してるさ

390 :デフォルトの名無しさん:2008/11/30(日) 03:30:24
ほう
アクセサもアクセサ経由で書いてるのか

391 :デフォルトの名無しさん:2008/11/30(日) 03:32:11
アクセサにアクセサ用のアクセサがあり、そのアクセサ用のアクセサにはアクセサ用のアクセサのためのアクセサがある。

392 :デフォルトの名無しさん:2008/11/30(日) 03:33:57
private変数使わずにstatic変数でがんばります

393 :デフォルトの名無しさん:2008/11/30(日) 04:05:20
まぁ俺は開き直って全部publicだけどね。
もはや構造体でも十分かも


394 :デフォルトの名無しさん:2008/11/30(日) 04:10:08
例外もprotectedも気にしなくていいC言語使えばいいじゃない

395 :デフォルトの名無しさん:2008/11/30(日) 04:24:45
cobolでも使ってろハゲ

396 :デフォルトの名無しさん:2008/11/30(日) 07:48:44
御大にcobolでも使ってろとはなんたる暴言

397 :デフォルトの名無しさん:2008/11/30(日) 08:06:22
publicにすると楽で良いぞ〜
マルチスレッドで排他でもしない限りまったく必要ないしな
ウインドウズアプリだけどさw


398 :デフォルトの名無しさん:2008/11/30(日) 08:15:25
マルチスレッドは関係ないと思う
あとウィンドウズアプリも

399 :デフォルトの名無しさん:2008/11/30(日) 08:19:40
マルチスレッドでアクセスさせるときはアクセサつくって排他制御したほうが楽ジャン
ウインドウズアプリって言ったのは規模がオモチャ程度ってことを言いたかっただけさ


400 :デフォルトの名無しさん:2008/11/30(日) 09:01:24
オモチャ程度(笑)

401 :デフォルトの名無しさん:2008/11/30(日) 10:58:48
Scott Meyers氏も、Effective C++だったか、More Effective C++だった、俺の記憶が曖昧なのだが、protectedの存在意義について、明確な
ではないということを、書いてたな、
ただ思うに、何でもかんでもprivateにして、アクセッサーを作れば良いのかといえば、そういうもんでは無いと思う
コンストラクタの動きを熟知したうえで作られた、genericのコードを見ると、思わず、なるほどと感心する事もあるからな


402 :デフォルトの名無しさん:2008/11/30(日) 12:30:24
>>368

   ∧ ∧  ∧ ∧
    (・ ∀・) (・ ∀・) ビャ〜ン
    (〜)〜 (〜)〜
    ┘|   ┘|

403 :デフォルトの名無しさん:2008/11/30(日) 12:36:57
>>401の続き
C++再考、古い本だが、良書である
この本では、「仮想関数を使うべきでない場合」という章があって、パフォーマンスの面で
仮想関数を使う場合は、そのコストも良く勘案して使うべしのような、ことが書かれているのだが
その解決手段の一つに、protectedを用いて、継承を可能にする事例が掲載されている。
デザパタでいうところのFactoryパターンで、インスタンスの生成を制限するのに、
protectedを上手に使うよね。
ようするに、適材適所、使い方次第ってことかな。
終わり。

404 :デフォルトの名無しさん:2008/11/30(日) 12:45:51
protectedメンバ関数に疑義を唱えてる人は少ないだろ
問題はprotectedメンバ変数の方
こっちは禿もD&Eで後悔してるって言ってるしHerb Sutter氏は邪悪だと言い切ってる

405 :デフォルトの名無しさん:2008/11/30(日) 13:20:54
ただ、悪魔の囁きで使いたくなるんだよねって話。

406 :デフォルトの名無しさん:2008/11/30(日) 13:27:17
ねーよ。

407 :デフォルトの名無しさん:2008/11/30(日) 18:59:47
splitみたいなのATLにないかな・・・

408 :デフォルトの名無しさん:2008/11/30(日) 19:03:24
>>401
アクセス制御のprotectedと
protected継承は明確に区別しような。

409 :デフォルトの名無しさん:2008/11/30(日) 21:35:22
newしたオブジェクトをそのコンストラクタが実行し終わるまでにdeleteするのは合法ですか?

410 :デフォルトの名無しさん:2008/11/30(日) 21:36:57
>>409
どうやるんだ、それ?
コンストラクタが実行し終わらないと「newしたオブジェクト」が存在しないと思うんだけど。

411 :デフォルトの名無しさん:2008/11/30(日) 21:37:57
コンストラクタで
delete this
とか?
どう考えてもやばいだろ

412 :デフォルトの名無しさん:2008/11/30(日) 21:42:25
>>411
そういうことです。

413 :デフォルトの名無しさん:2008/11/30(日) 21:44:02
>>412
どうしてそれが合法かもしれないと思うの?

414 :デフォルトの名無しさん:2008/11/30(日) 21:45:38
>>413
違法であるとは定められていないかもしれないからです。

415 :デフォルトの名無しさん:2008/11/30(日) 21:45:42
>>413
違法だと確信できないからです


416 :デフォルトの名無しさん:2008/11/30(日) 21:49:10
>>414-415 騙りをやろうとして失敗乙

417 :デフォルトの名無しさん:2008/11/30(日) 21:50:53
そもそもどんな動作を期待してるんだ?
new の戻り値がまったく使えないことになるだろ、どう考えても。

418 :デフォルトの名無しさん:2008/11/30(日) 22:36:51
コンストラクタで例外を投げるというのなら当然のようにするけど、
コンストラクタでdelete thisは聞いたことがない。

コンストラクタが完了してない、つまりオブジェクトの構築が終わっていないのに
デストラクタを呼ぶというのはC++のオブジェクトに対するモデルにそぐわないと思う。

419 :デフォルトの名無しさん:2008/11/30(日) 22:51:41
つまりコンストラクタでdelete thisが呼べてしまうC++の欠陥というわけだ。

420 :デフォルトの名無しさん:2008/11/30(日) 22:53:20
free(this)じゃ駄目?

421 :デフォルトの名無しさん:2008/11/30(日) 22:54:52
>>420
問題外。newしたものをfree()で解放した場合は鼻から悪魔。

422 :デフォルトの名無しさん:2008/11/30(日) 23:00:14
せめてメモリだけでも開放させてあげたい親心なのに...
水子霊が成仏できなくて夢枕に毎晩たつようになる(T_T)

423 :デフォルトの名無しさん:2008/11/30(日) 23:02:10
一体どうしてそんなことをしたいだろうか。
例外を投げるようなライブラリを初期化処理で使いたいとかだったら、
FactoryMethodパターン使えばいいだけだし。

424 :デフォルトの名無しさん:2008/12/01(月) 00:02:52
コンストラクタで例外投げたら、自動的にメモリ解放されるだろ

425 :デフォルトの名無しさん:2008/12/01(月) 00:05:27
端的すぎるだろ

426 :デフォルトの名無しさん:2008/12/01(月) 00:29:43
>>424
何のメモリ?コンストラクタ内で確保したメモリとかも?

427 :デフォルトの名無しさん:2008/12/01(月) 00:36:05
newしようとしたオブジェクト用に確保された領域

428 :デフォルトの名無しさん:2008/12/01(月) 00:55:43
>>422
コンストラクタ内で動的に確保したメモリは、コンストラクタ内で例外が発生した場合はコンストラクタ内で解放する必要があります。

Foo::Foo():
m_p1(NULL),
m_p2(NULL)
{
try {
m_p1 = new P1;
m_p2 = new P2;
}
catch(std::exception & e) {
delete m_p1;
delete m_p2;
}
}

429 :デフォルトの名無しさん:2008/12/01(月) 00:59:07
だからこれは二重deleteで落ちる

struct A{
 A(){delete this; throw 1;}
};

int main()
try{
 A *a = new A;
}catch(...){
 return 1;
}

430 :デフォルトの名無しさん:2008/12/01(月) 01:00:31
>>428
変なサンプル載せんな。バグってるし。

その問題に対する修正は RAII を徹底することだ。

431 :デフォルトの名無しさん:2008/12/01(月) 01:16:05
>>428みたいなおぞましいコードを平気で書いて人に見せびらかすような輩の存在に恐怖する

432 :デフォルトの名無しさん:2008/12/01(月) 01:26:21
たまには関数try-catchのことも……

433 :デフォルトの名無しさん:2008/12/01(月) 01:29:40
>>432
それがこの流れと関係あると思うんなら、たぶん何か勘違いしてる。

434 :432:2008/12/01(月) 01:31:17
そんな、ネタにつっこまれても困ります。

435 :デフォルトの名無しさん:2008/12/01(月) 01:34:42
>>429に出てきてんじゃん
ネタにもなってない

436 :デフォルトの名無しさん:2008/12/01(月) 01:42:29
>>428ってバグってるか?
delete 0 はOKらしいから大丈夫じゃね?
一定周期で話題になるよねコレ

437 :デフォルトの名無しさん:2008/12/01(月) 01:50:12
>>436
そこは関係ない。

>>428
まず、この場合は throw される型に関係なく delete したいんだろうから、
catch (...) じゃないと不完全。

そしてもう一点、 new P2 で例外が投げられた場合に delete 済みの m_p1 を
メンバに残したままコンストラクタが完了してしまっている。これは catch の最後に
throw を置けばいい。

ただし >430 の言うとおり、 RAII による対処が望ましい。コードが減るうえに
上記2点の対処もコンパイラに任せられる。

438 :デフォルトの名無しさん:2008/12/01(月) 01:52:12
>>436
例外が中で握り潰されるから、delete済みの無効ポインタを持ったゴミオブジェクトが生成されてしまう
多分デストラクタでm_p1とm_p2をdeleteしてるはずだから、
ゴミオブジェクトが破壊される時に二重deleteが起こる

439 :デフォルトの名無しさん:2008/12/01(月) 02:36:15
>>437
>>438
catch(...)は微妙だが、それ以外は
全部仮定の上の話じゃん。バグとまでは言えない。

440 :デフォルトの名無しさん:2008/12/01(月) 02:41:53
と、馬鹿が申しております

441 :デフォルトの名無しさん:2008/12/01(月) 02:45:21
>>439
デストラクタでdeleteしてない変な設計だったとしても、
newしてる以上どっかで必ずdeleteしてるはずだ(それをしてないならメモリリークのバグ)
中のメンバがnewに成功してるのか、失敗してゴミになってるのかは移植性のある方法で確認できないから
「ゴミならdeleteしない」という方法で逃げることも出来ない
よってnewに失敗すればメモリリークか二重deleteのどちらかがどっかで必ず起こる

これをバグでないと思うような奴がC++のプログラム書いてると思うと恐ろしい

442 :デフォルトの名無しさん:2008/12/01(月) 02:53:41
とりあえず
 delete m_p, m_p = 0;
とかしとけばいいんじゃないの

443 :デフォルトの名無しさん:2008/12/01(月) 02:54:21
>>441
だからそれも仮定の話じゃん。
バグと思うか思わないかは知らないが
>>428のコンストラクタのコードだけみて
バグであるとは言えないと言ってる。

444 :デフォルトの名無しさん:2008/12/01(月) 03:00:55
>>437
ぐぐったら出てきましたが、auto_ptrをこういう使い方をして大丈夫でしょうか?
class RAII {
  std::auto_ptr<Test> m1;
  std::auto_ptr<Test> m2;
public:
  RAII() : m1(new Test), m2(new Test) { }
};


445 :デフォルトの名無しさん:2008/12/01(月) 03:04:02
>>444
それが正解。

446 :デフォルトの名無しさん:2008/12/01(月) 03:05:01
>>443
それを強弁して何がしたいの?
バカがあのコード見て見習ったら困るじゃん。

447 :デフォルトの名無しさん:2008/12/01(月) 03:05:11
>>443
本当のバカみたいだから丁寧に説明する

>>428を含むプログラムがバグを持たないためには、次のどちらかが保証されなければならない

・Fooクラスのインスタンスがどんな実行パスでも一切生成されない
・new P1とnew P2が絶対に例外を投げない

前者ならFooクラスの定義自体が無意味だ
後者ならわざわざあんなtryブロックを書く必要はない

よって>>428のコンストラクタのコードを含むプログラムは
全く無意味なことを書いてるか、バグがあるか、どちらかと言うことになる

428がチラシの裏に脈絡のない落書きをしたつもりでない限り、あれはバグだということだ

448 :デフォルトの名無しさん:2008/12/01(月) 03:06:12
>>445
ありがと、メンバで使ってるのははじめてみた。

449 :デフォルトの名無しさん:2008/12/01(月) 03:19:50
みんな delete なんか書かずに auto_ptr なり何なり使ってくれよ。
デストラクタで delete してるクラスなんか半分ぐらいコピーコンストラクタや
代入演算子でバグってるのが実情だろ。

450 :デフォルトの名無しさん:2008/12/01(月) 06:05:15
>>421
鼻から悪魔、なつかしいw
えぴすてーめーさんだっけ?この言い回し好きだったのは.

451 :デフォルトの名無しさん:2008/12/01(月) 06:39:58
>>449
そういう場合だとauto_ptrを使ってもなんの解決にもならない

452 :デフォルトの名無しさん:2008/12/01(月) 06:43:12
それはしらん

453 :428:2008/12/01(月) 08:12:56
すげー変なサンプルですまんかった。>>437に全面的に同意するよ。
酒に酔ってたと思いたいorz

454 :デフォルトの名無しさん:2008/12/01(月) 14:21:51
C++をCに変換するツールみたいなのってありますか?

455 :デフォルトの名無しさん:2008/12/01(月) 14:26:14
つ[派遣社員]

456 :デフォルトの名無しさん:2008/12/01(月) 14:41:11
一瞬まじめに答えろやって思ったけど
ジワジワ来て結局笑ってしまった

457 :デフォルトの名無しさん:2008/12/01(月) 15:43:06
>>455
いや、その派遣社員なんですけど…

458 :デフォルトの名無しさん:2008/12/01(月) 15:59:12
>>457 
自分のツールとなる自前の派遣社員を調達する


459 :デフォルトの名無しさん:2008/12/01(月) 17:35:26
>>454
cfront
http://www.softwarepreservation.org/projects/c_plus_plus/cfront/release_3.0.3/cfront_3_0_3.tgz

460 :デフォルトの名無しさん:2008/12/01(月) 18:32:12
enumについて質問です。

enum A{b,c,d};
enum E{f,g,h};

のように書いた場合、例えばcからタグ名であるAを取得する方法はあるのでしょうか?

461 :デフォルトの名無しさん:2008/12/01(月) 18:37:17
decltype (c)って言っていい?

462 :デフォルトの名無しさん:2008/12/01(月) 18:39:27
まだ早い

463 :デフォルトの名無しさん:2008/12/01(月) 20:07:25
typeid(c).name() とか

464 :デフォルトの名無しさん:2008/12/01(月) 20:32:25
>>463
それは"int"が帰ってくる

465 :デフォルトの名無しさん:2008/12/01(月) 20:36:25
なんちゃって

466 :デフォルトの名無しさん:2008/12/02(火) 01:57:21
いつも忘れちゃうんですが、コンストラクタ内でのthisポインタを通した操作は合法ですよね?

467 :デフォルトの名無しさん:2008/12/02(火) 02:04:32
仮に違法だったとしようか
コンストラクタの中で出来ることがまともに残ってるか?

少しは考えようぜ

468 :デフォルトの名無しさん:2008/12/02(火) 02:06:47
グローバル変数にthisポインタを渡して
別スレッドに操作してもらえば
コンストラクタ外だから問題ないですよね

469 :デフォルトの名無しさん:2008/12/02(火) 02:21:48
>>468
理由と結論にまったく脈絡が見られないんだが。

470 :デフォルトの名無しさん:2008/12/02(火) 06:34:51
C++使いって屁理屈好きばかりで、いやーね。

471 :デフォルトの名無しさん:2008/12/02(火) 07:18:38
意味のわからない理屈は往々にして屁理屈に見えるものだよ。
自分を大きく越えちゃってる世界に行くと、住人すべてが屁理屈ばっか言ってる馬鹿に見える。

472 :デフォルトの名無しさん:2008/12/02(火) 07:38:06
まあでも例外安全の強い保証とか移植性・汎用性確保のためのテンプレート技法とか
大半のC++プログラマにとって意味不明っつーか知らなくても問題ない話が
粗大ゴミじゃねえ、醍醐味なんだよな

473 :デフォルトの名無しさん:2008/12/02(火) 09:02:22
C++使いは優秀な人多いと思うんだけど、それでも仕事は底辺ITドカタなのかな?
まぁ別の意味で使えない人種なのかもしれないけど。

474 :デフォルトの名無しさん:2008/12/02(火) 09:14:59
C++を本当の意味で「使えてる」ひとならそこそこ優秀だろうよ。

残念ながら勘違いしてる人が多い。

475 :デフォルトの名無しさん:2008/12/02(火) 09:16:08
本当の意味で「使えてる」ひと(笑)

476 :デフォルトの名無しさん:2008/12/02(火) 10:04:16
使えないひとがヒス起こしました。

477 :デフォルトの名無しさん:2008/12/02(火) 11:58:16
オレがC++を使うのは計算実験プログラムや各種のツール作りで
一人で作っていいものがターゲットだから
手段のC++が大好きなだけで

他人に発注するプログラムや
面倒そうなターゲット依存GUIアプリ作りにはC++を決して使いませんよ
共同開発もストレスたまりそう

478 :デフォルトの名無しさん:2008/12/02(火) 12:08:15
日本では大多数を除いて
プログラミング能力のある人間ほど、プログラミング自体を職に設定していないと思われ

それなりの能力と社会的常識があれば、他の待遇の良い職についてるだろうし
仕事で行うコーディングは決して楽しいとはいえないわけで

479 :デフォルトの名無しさん:2008/12/02(火) 12:53:48
>>472
例外安全を知らないのは C++ に限らず大問題じゃね?

480 :デフォルトの名無しさん:2008/12/02(火) 14:04:55
例外安全性の検証とか機械にやらせたいわ
あるメソッドが呼び出しグラフを追って例外を吐く可能性のあるメソッドの呼び出しを含むか否か
を手作業で確認あるいは脳内dbに問合せするなんて人間様のやる事じゃねー

481 :デフォルトの名無しさん:2008/12/02(火) 14:34:40
>>480
べつにそんなことしなくても例外安全に作る方法はわかってるでしょ。

「呼び出しグラフを追って〜」なんて、コードに不備があるときにそれが実害に
結びつくかどうかを検証するだけのこと。

コードに不備があるかどうかの検証はその場のコードと、そこから呼び出される
関数それぞれが例外を投げるかどうかを見ればわかる(はず)。これは戻り値で
エラーが報告される場合と同じ。

482 :デフォルトの名無しさん:2008/12/02(火) 15:45:48
>>481
その場のコードと、そこから呼び出される関数群とさらにそれらの関数群が呼んでる関数群
例外危険性は伝搬するから(例外安全で無い関数を呼ぶ関数は例外安全では無い)、
結局「安全性」の確認にはその場のコードを根とする木の全探索が必要になるよね
それらを馬鹿で面倒臭がりですぐ忘れたり間違えたりするという厄介な特性を持った
人間様が一つ一つチェックするわけ?


483 :デフォルトの名無しさん:2008/12/02(火) 16:56:08
例外安全性をコンパイラで保証するのは無理だよな
constのような修飾子を手で加えて例外安全でない呼び出しを追跡させるのが精一杯だろうが
正直そこまでいらないぜ

484 :デフォルトの名無しさん:2008/12/02(火) 17:00:53
そういう静的コード解析ができるツールがあったらいいのになぁっていう
関数名指定したら再帰的にチェックして例外安全性の有無を判別してくれたりとか

485 :デフォルトの名無しさん:2008/12/02(火) 18:01:55
>>484
C++プログラマなら自分で作る。
C++コーディング出来るだけじゃドカタ。そんなツールを作れてプログラマ。
俺は底辺ドカタだからクレクレだがな、orz


486 :デフォルトの名無しさん:2008/12/02(火) 18:29:23
>>480
半手動みたいな方法だけど
C++ Sourceに、関数が例外安全かどうかをタグ付けして、コンパイル時にタグを検証する方法が投稿されてたよ

487 :デフォルトの名無しさん:2008/12/02(火) 20:09:02
C++初心者です。

list<int> list[M][N];

みたいな2次元配列って出来るんですか?

488 :デフォルトの名無しさん:2008/12/02(火) 20:22:11
できますよ。

489 :デフォルトの名無しさん:2008/12/02(火) 20:33:57
「みたいな」っていうのは良い訊ね方ではないなぁ。
もうちょっとこう、譲れない要求がハッキリしていないと、
二次元配列であるという以外にコトを絞れなくて、当然のように>>488が答になる。

490 :デフォルトの名無しさん:2008/12/02(火) 21:21:01
C++のライブラリ設計のノウハウ的な良書ってない?
実装の本はいっぱいあるけど、設計的な視点なのってあんまない気がする。

491 :デフォルトの名無しさん:2008/12/02(火) 21:26:54
>>489
>>487です。
確かに尋ね方が悪かったと思います。

とりあえず二次元配列を用意したのですが、
・初期化
・for文を使った要素の挿入
・displayの仕方
がわかりません。
御教授お願いします。

492 :デフォルトの名無しさん:2008/12/02(火) 21:35:46
>491
まずそもそも欲しいものは list の二次元配列で正しいのか?二重の list (list<list<int> >)だったりしないか?*
for 文を使った要素の挿入って挿入したいのは list でいいのか、int なのか?
挿入っていうからには後の要素は後ろにずれないといけないのか?
やりたいことを正確に説明しようぜ。

493 :デフォルトの名無しさん:2008/12/02(火) 21:49:08
>>492
二重のlist(list<list<int>>)とlistの違いがわかりません。どう違うのですか?
挿入するのはint型の要素です。
挿入したら後の要素は後ろにずれるようにしたいです。

494 :デフォルトの名無しさん:2008/12/02(火) 21:52:14
二重のlistは二次元構造だけど、listの二次元配列は三次元構造だ
どっちが欲しいんだ?

495 :デフォルトの名無しさん:2008/12/02(火) 21:56:28
欲しいのは2次元構造です。

496 :デフォルトの名無しさん:2008/12/02(火) 22:07:16
じゃあどっちかだな
好きな方にしろ
list<list<int> >
list<int>[]

497 :デフォルトの名無しさん:2008/12/02(火) 22:14:05
list<list<int>> lst1;
↑このような形で宣言するのですか?
使い方がわかりません。

498 :デフォルトの名無しさん:2008/12/02(火) 22:19:03
>>497
list<list<int> > lst1;
な。
> と > の間にスペースが要る

499 :デフォルトの名無しさん:2008/12/02(火) 22:22:30
そもそもint hoge[M][N]でいいんじゃないか? ひょっとして。

500 :デフォルトの名無しさん:2008/12/02(火) 22:26:51
list<list<int> > lst1;
で定義しました。
後はint型の要素を入れていきたいのですが、pushでは、
「error C2664: 'std::list<_Ty>::push_front' : 1 番目の引数を 'int' から 'const std::list<_Ty> &' に変換できません。」
と出ます。
要素はどうやって入れればいいのですか?

501 :デフォルトの名無しさん:2008/12/02(火) 22:27:17
list<list<int> > lst1;
の lst1 の要素は list<int> だ。

502 :デフォルトの名無しさん:2008/12/02(火) 22:33:52
>>499
それじゃ、要素の削除、追加大変だからだろ
2次元に連なる要素の削除、追加を高速にしたいんじゃね

503 :デフォルトの名無しさん:2008/12/02(火) 22:38:00
>>502
それでもせめてvector<vector<int> >じゃね

504 :デフォルトの名無しさん:2008/12/02(火) 22:39:23
もっと勉強してから来いというのが一番優しい回答ではあるまいか

505 :デフォルトの名無しさん:2008/12/02(火) 22:41:12
どういう風にしたいのが図に書いてくれればまだ理解できそうな気がする。
答えるほうも聞くほうも。

506 :デフォルトの名無しさん:2008/12/02(火) 22:42:09
list<list<int> >はlist<int>のlistなんだからlist<int>を入れるに決まってるだろ
エラーメッセージでそっくりそのまま言われてるじゃないか
少しは自分で考えろや

507 :デフォルトの名無しさん:2008/12/02(火) 22:44:23
いろいろ省略しますが、

#define M 10
#define N 10
main()
{
list<list<int> > lst1;
list<int> list1;
int i, j;
for(i = 0;i < M;i++)
{
for(j = 0;j < N;j++)
{
list1.push_front( 値 );
}
}
}
こんな感じでいいのですか?

508 :デフォルトの名無しさん:2008/12/02(火) 22:47:47
もうこの人にはmap<pair<int,int>,int>が一番いいような気がしてきた

509 :デフォルトの名無しさん:2008/12/02(火) 22:49:27
boost::multiple_arrayのドキュメントとテストとサンプルをよく見ればいいよ

510 :デフォルトの名無しさん:2008/12/02(火) 22:51:57
>>503
vectorの要素削除、追加速度で問題なければ良いと思うが

511 :デフォルトの名無しさん:2008/12/02(火) 22:52:44
>>507
その「こんな感じ」は、最初の質問の「みたいな」と同じ問題を抱えてると思う。
基本的に、君が頭に抱くイメージ、及びモノの表現には、隙間がありすぎる。
事の本質は、君がなにかとすっ飛ばしたがるディテールの中にあるんだよ。

きちっとした本なりサイトなりで勉強するべきだと思う。
現状だと、説明されても、説明の為の説明が必要になるだけ。

512 :デフォルトの名無しさん:2008/12/02(火) 22:53:05
507の使い方とかどう見ても末尾にしか追加してない
vectorが一番だな

513 :デフォルトの名無しさん:2008/12/02(火) 22:53:52
追加速度気にするなら deque でいいんじゃね

514 :デフォルトの名無しさん:2008/12/02(火) 23:05:30
>>512
構築過程だからじゃね
構築したら、ビシバシ途中要素の追加削除するんだよ

515 :デフォルトの名無しさん:2008/12/02(火) 23:08:33
lst1.front().push_front(値); でもダメ?

516 :デフォルトの名無しさん:2008/12/02(火) 23:34:56
http://msdn.microsoft.com/ja-jp/library/cc440190(VS.71).aspx

↑大変だけどこれ読んでみ
例外安全性ってマジパネェ
コンストラクタを使わなきゃまるく収まるのかな?

517 :デフォルトの名無しさん:2008/12/02(火) 23:40:56
コンストラクを避けるだと…

518 :デフォルトの名無しさん:2008/12/02(火) 23:42:44
むしろC++を避けろw
いやもちろん他の言語でも例外安全の概念は意識すべきだと思うよ。

519 :デフォルトの名無しさん:2008/12/02(火) 23:50:30
メソッドの命名規則って
動詞+名詞だっけ?
名詞+動詞だっけ?

どっちだっけ

520 :デフォルトの名無しさん:2008/12/02(火) 23:51:15
知らネェよ

521 :デフォルトの名無しさん:2008/12/02(火) 23:53:20
セッ詞+クス詞

522 :デフォルトの名無しさん:2008/12/03(水) 01:32:34
>>482
> 例外危険性は伝搬するから(例外安全で無い関数を呼ぶ関数は例外安全では無い)

これが間違いじゃないの?
「バグってる関数を呼ぶ関数はバグってる」なんて言わないでしょ。

int main() { std::puts("Hello"); } という関数にバグがあるかないかの検証をするのに
puts() の実装まで確認する必要は無いよね?

同じように int main() { std::puts("Hello"); } という関数が例外安全かどうか検証するのに
puts() の実装まで確認する必要は無いよね?

523 :デフォルトの名無しさん:2008/12/03(水) 01:42:09
>>522
確かに実装まで確認する必要はないな
putsは例外安全ではあり得ないからmainも例外安全ではあり得ない

例外安全でぐぐってから出直してこい

524 :デフォルトの名無しさん:2008/12/03(水) 01:43:11
>>522
例外安全って何か知ってる?

525 :デフォルトの名無しさん:2008/12/03(水) 01:44:12
ごめん強い例外安全ではあり得ないだけだな
putsでも基本保証は出来るか

だからってバグと例外安全が一緒ではないけどな

526 :デフォルトの名無しさん:2008/12/03(水) 01:46:54
522が強い例外安全でない関数を呼ぶ強い例外安全なコードを披露してくれるそうです

そんなのがあったらHerb Sutterが泣いて喜ぶぞ
早く見せてくれよほらほら

527 :522:2008/12/03(水) 02:02:59
>>523
std::puts() には最強の例外非送出保証があるよ。そうでなければ規格違反。

528 :522:2008/12/03(水) 02:08:43
>>526
だれもそんなことは言ってないよ。

例外安全性の検証をするのにすべての関数呼び出しツリーをたどる必要があるという話に
異を唱えているだけ。

まぁ基本例外保証の処理に一時変数を加えて強い例外保証を与えることができたり
するんだけどね。そんなもの見せてもあたりまえすぎて誰も喜ばない。

529 :デフォルトの名無しさん:2008/12/03(水) 02:17:40
たしかにC標準関数は例外を外に投げちゃいけないって規格に書いてあるな(17.4.4.8)
throw()例外指定されてるだけかと思ってた

でも中で例外を握り潰してはいけないとは書いてないな
握り潰してたら安全じゃないし、そういう関数を呼んでる関数も安全じゃない

530 :522:2008/12/03(水) 02:30:19
>>529
> 握り潰してたら安全じゃないし、そういう関数を呼んでる関数も安全じゃない

そうなるとどんなコードも例外安全とは言えないことになるのには、気づいてて言ってるの?

たとえば >444 にある class RAII のコンストラクタは例外安全と言えると思ってるんだけど、
違うの?

要は、例外安全性はあるコード辺について評価されるものだと思ってるんだけど、
実行結果に対して評価されるものだと思ってる人が多いってことなのかな?

531 :デフォルトの名無しさん:2008/12/03(水) 02:31:35
握りつぶしているってことは
例外を処理したってことで
例外安全なんじゃ?

532 :デフォルトの名無しさん:2008/12/03(水) 02:36:27
>>531
握りつぶした結果、変なことが起こってるかもしれないっていいたいんだろ。きっと

533 :デフォルトの名無しさん:2008/12/03(水) 02:37:53
でもそんなの関係ねぇ

534 :デフォルトの名無しさん:2008/12/03(水) 02:39:12
>>532
そんなひどい標準関数はいやだなw

535 :デフォルトの名無しさん:2008/12/03(水) 02:39:17
でもそんなの関係ねぇ

536 :デフォルトの名無しさん:2008/12/03(水) 02:43:25
例外を握り潰してる関数はcatch節や例外に伴って破棄される可能性のあるクラスのデストラクタでは呼べない
呼んでたら二重例外で未定義動作になる

537 :デフォルトの名無しさん:2008/12/03(水) 03:13:23
>>536
断定口調で嘘を書くな。

二重例外がまずいのは、例外に伴うスタック巻き戻し中に実行されたデストラクタが
例外を「送出する」場合。中で握りつぶしてれば握りつぶしたなりの動作をする。また、
その場合でも未定義動作になるんじゃなくて terminate() に直行することになっている。
規格内の該当箇所は 15.5.1 "The terminate() function" ね。あと、 catch 内でも
同様に、握りつぶせばそのとおりに動作する。


なんなんだ昨日からの流れは。10年も前になろうかという間違い混じりの記事を
いまさら貼るやつまでいるし。 C++ の例外を誤解させようという組織でも活動してるのか?

538 :デフォルトの名無しさん:2008/12/03(水) 11:11:29
basic/strong guaranteeでいうbasic invariantsが何であるかを
構文解析だけで特定できるのだろうか?
あと「例外を投げ得るコードを含まない」に合致するのは
no throw guaranteeの一部だけなのではないか

539 :デフォルトの名無しさん:2008/12/03(水) 11:50:47
>>538
何言ってんのかわからん。
静的解析で例外安全性を検証したい、とかいう話?

540 :デフォルトの名無しさん:2008/12/03(水) 12:04:33
yes

541 :デフォルトの名無しさん:2008/12/03(水) 12:35:11
>>538
とりあえず invariants が何かというのは既存のコードを解析するだけじゃ無理なのは
明白だろう。明示的な記述の追加が必要だと思う。いくつかの言語がサポートしている
DbC に関する機能を真似ることになるだろう。ただし invariants の評価を静的に
行うことができるかどうかも大きな問題になるはず。

例外安全性と言えば、これに加えてリソースリークの有無を判別する必要もある。
これについてもリソースの確保・解放を行うコードを何か統一された書式で記述しないと
無理だろう。

さらに strong guarantee の検証には、観測しうる状態が変化しないことを確かめる
必要がある。グローバル変数や volatile 変数へのアクセスを考えると、これについても
何か追加の情報を与えてやらないと機械的に判別できない。

現状から考えるとあまりにも非現実的と言うしかない。ドキュメント化された
インターフェースの仕様から invariants やリソース確保・解放や副作用に関する
情報を集められる人間が検証する以外に考えられない。


最後の no throw guarantee についての話はあたりまえで、内部に例外を投げうる
コードを含んでいても、外部に漏らさないように補足して処理できていれば
no throw guarantee は達成できる。

542 :デフォルトの名無しさん:2008/12/03(水) 17:35:48
オープンソースのC++のコードで、最近のちゃんとしたC++で書かれているものって
ありますか?

「ちゃんとした」ってのは曖昧ですが、勉強のために読みたいという感じなので
主観でかまいません。

たとえば話題に上ってる例外安全とか。

543 :デフォルトの名無しさん:2008/12/03(水) 20:08:03
>>542
デザインパターンも含め、スタンダードで模範的なコードか?
優等生ベンダが保有するソースじゃないと、C/C++でそういうのは
少ないと思うぞw

544 :デフォルトの名無しさん:2008/12/03(水) 20:58:37
boostでは駄目?

545 :デフォルトの名無しさん:2008/12/03(水) 21:03:58
>544
勉強のためには変態的すぎるんじゃないかと思うんだ。

546 :デフォルトの名無しさん:2008/12/03(水) 23:26:49
C++が変態だから、しょうがないよ

547 :デフォルトの名無しさん:2008/12/03(水) 23:40:32
boostにはシンプルなのから変態的なものまで色々あるよ

548 :デフォルトの名無しさん:2008/12/03(水) 23:59:28
boost の中では何がお勧めでしょう?
shared_ptr とか?

549 :デフォルトの名無しさん:2008/12/04(木) 00:06:03
boostなんて見ない方がいい
あんなもの真似しちゃダメだ

550 :デフォルトの名無しさん:2008/12/04(木) 00:34:09
progress_barがオススメ

551 :デフォルトの名無しさん:2008/12/04(木) 00:41:35
boost::preprocessorおすすめ

552 :デフォルトの名無しさん:2008/12/04(木) 00:46:53
やめろぉおおおおおおおおおおお

553 :デフォルトの名無しさん:2008/12/04(木) 01:26:29
boost::date_timeおすすめ

554 :デフォルトの名無しさん:2008/12/04(木) 01:29:22
お前らそんなboostのなかでもアレげな奴紹介するなよw
boost::mplマジお勧め

555 :デフォルトの名無しさん:2008/12/04(木) 01:34:47
boost::lambdaとか

556 :デフォルトの名無しさん:2008/12/04(木) 01:35:29
boost::spiritだろ

557 :デフォルトの名無しさん:2008/12/04(木) 01:37:38
boostの乱数は普通に勉強になる。乱数の

558 :デフォルトの名無しさん:2008/12/04(木) 04:45:49
Boost Graph Libraryに決まってるだろ

559 :デフォルトの名無しさん:2008/12/04(木) 04:59:57
program_optionsの放置されようはひどすぎ。
ワイド文字がまともに使えねーし。
所詮一文字一バイトの世界で生きてる南蛮人の書いたコードなんだなと。

560 :デフォルトの名無しさん:2008/12/04(木) 07:38:52
BOOTSまじオススメ

561 :デフォルトの名無しさん:2008/12/04(木) 08:03:46
boost::optionalマジお勧め。

562 :デフォルトの名無しさん:2008/12/04(木) 20:22:33
boost は互換性を保つという事がいかに大変かという教材になるっしょ。
char で new して placement new する時に
いかにしてアラインメントを揃えるかとか。

563 :デフォルトの名無しさん:2008/12/04(木) 21:30:32
動的生成vector用のスマートポインタは何を使ってますか?

564 :デフォルトの名無しさん:2008/12/04(木) 21:47:19
とりあえずスマートポインタは置いといて
vectorを別のコンテナに突っ込むかな


565 :デフォルトの名無しさん:2008/12/04(木) 21:52:40
それって、どうするんですか?

566 :デフォルトの名無しさん:2008/12/04(木) 22:53:10
とりあえず日本語でおk

567 :デフォルトの名無しさん:2008/12/04(木) 23:00:37
vectorの要素にできるスマートポインタという意味ならshared_ptr。

vectorを指すスマートポインタという意味なら、状況に応じて適切なものを選ぶ。
vectorだからといって特別扱いする必要はない。

568 :デフォルトの名無しさん:2008/12/05(金) 00:12:25
void file_read_test(const char* filename)
{
std::vector<char> temp;
std::ifstream ifs( filename, std::ios::binary );
std::copy( std::istreambuf_iterator< char >( ifs ),
std::istreambuf_iterator< char >(),
std::back_inserter(temp) );

std::cout << "read size =" << temp.size() << std::endl;
}
ここのtempを他のところで処理したいんです。
そこで動的にこのvectorを生成し、そのdeteteをスマートポインタに任せたら良いんじゃないかと。
ただ、ポインタでアクセスが->になるのが不便なんですが

569 :デフォルトの名無しさん:2008/12/05(金) 00:54:17
ケースバイケースだが、呼び出し側から渡してもらうのも検討してみたら?

570 :デフォルトの名無しさん:2008/12/05(金) 02:39:09
>>568
そのtempがそれほど大きくないならそのまま返しちゃっても高が知れているけどね。

571 :デフォルトの名無しさん:2008/12/05(金) 07:35:20
http://d.hatena.ne.jp/tetsuarossa/20070307/p1
Windowsに限った方法ではあるが、俺はこのサイトで、例外処理の勉強をさせてもらった
このようなクラスに改造しているので、stlの例外も、捕まえることができる。

class Exception : public std::exception
{
protected:
  std::vector<char> msg_;

public:
  /// コンストラクタ
  Exception();
  Exception(const char *fmt, ...);

  /// 構造化例外処理コンストラクタ
  Exception(PEXCEPTION_POINTERS pInfo);

  /// デストラクタ
  virtual ~Exception(){}

  /// エラー内容の取得
  const char* what() const;

  /// 構造化例外をC++の例外に変換
  static void set_transrator();
};

572 :デフォルトの名無しさん:2008/12/05(金) 07:52:38
ほほう。それで?

573 :デフォルトの名無しさん:2008/12/05(金) 08:26:11
windowsに限ったってより・・・・・・

574 :デフォルトの名無しさん:2008/12/05(金) 10:27:15
C++はコンパイラとランタイムの手抜きを補うための尻拭きがマンドクセー
もうC#とCでいいよ

575 :デフォルトの名無しさん:2008/12/05(金) 10:40:15
>>572
>>573
>>571です
先に掲示した、サイトの作者が意図したところは、「C++の例外処理とWindowsの構造化例外処理が同時に使えない。」ので
全ての例外をキャッチ出来るクラスを作って使っている。更に俺は猿真似して
stlの例外もキャッチさせたくて、改造を施した。
発案した、先のHPの作者は、賢いし、ヒントを与えてくれて感謝している。
俺の作ったクラスも、思い通りの振る舞いをしてくれているので、とても役立っている。

576 :デフォルトの名無しさん:2008/12/05(金) 12:16:59
>>571,575
「stlの例外を捕まえる」の意味がわからん。
そのせいか、リンク先の記事と比べて改良されてるように見えないんだが。
改造されてるのはわかるけど。「キャッチするクラス」も合わせて意味不明だな。
クラスが例外をキャッチするわけじゃないだろうに。

「Windows 構造化例外処理を C++ 例外に変換している」とだけ言えば何も
おかしなことは無いんだが。

で、その例外トランスレータの使い方は >516 のコラムの最後、 2000 年発表の
「例外処理、第 17 部」にずっと先に載ってるものなので、発案したのが
その人なわけじゃないと思うよ。どうでもいいけどね。

577 :デフォルトの名無しさん:2008/12/05(金) 14:08:57
自分で作ったコンテナもどきでイテレータを実装したいんだけど、
これって、やっぱり STL で提供されているイテレータの流儀にのっとって
(std::iteratorを継承するとか) 作ったほうがメリットあるのかな?

それとも、適当にシグネチャを合わせておけば十分?

578 :デフォルトの名無しさん:2008/12/05(金) 14:16:22
>>577
自分しか使わないんならエラーが出るたびに不足してるメンバを調べて足していく
方向でもいいかもしれない。ごく狭い範囲で基本的なメンバしか使われないなら、
こっちのほうが早いかも。

汎用的に使いたいとかエラーが出るたびに調べるのが嫌なら、最初からイテレータの
要件をひととおり揃えておいたほうがいい。

どのみち足りないメンバを足す時には要件を見ることになるわけだから、やっぱり
後者がおすすめ。

579 :デフォルトの名無しさん:2008/12/05(金) 14:19:08
適当に作るよりなんらかの方針がある方が楽でしょう

ここのConceptっていうのに沿って作っていけば楽だよ
ttp://www.boost.org/doc/libs/1_37_0/libs/range/doc/range.html
あと
ttp://www.sgi.com/tech/stl/table_of_contents.html
も参考になると思う

580 :デフォルトの名無しさん:2008/12/05(金) 18:05:35
>>571
コピー時に多重例外でterminate

581 :デフォルトの名無しさん:2008/12/05(金) 19:41:34
>>569-570
どうもありがとうございます。
ファイルサイズが大きい時で10MBになるんで
return std::vector<char> temp; じゃなく
void file_read_test(const char* filename, std::vector<char>& vect)
にすることにしました。

582 :デフォルトの名無しさん:2008/12/08(月) 03:41:34
enum OPPAI {
 hinnyu = 0,
 hutsuu,
 kyonyu
};
static const unsigned int OPPAI_N = 3;

void gen_girl(OPPAI oppai);

void gen_all_girl(OPPAI oppai) {
 for (unsigned int i=0; i<OPPAI_N; ++i) {
  gen_girl( static_cast<OPPAI> (i) );
 }
}

こんな風にenum型使ったがためにキャストする機会があると
なんかenum使うべきじゃなかったんじゃないかと思っちゃうんだけど、
こういうときって

typedef unsigned int OPPAI;
const OPPAI hinnnyu = 0;
const OPPAI hutsuu = 1;
const OPPAI kyonyu = 2;

の方がデザイン的にベターなのかしら?
どうでもいいことなんだろうけど、気になって夜も眠れない。
誰か教えてくださいm(__)m

583 :デフォルトの名無しさん:2008/12/08(月) 03:42:31
↑あ、gen_all_girlの引数はいらないね。ごめん

584 :デフォルトの名無しさん:2008/12/08(月) 04:51:31
enumを無名にはしたくない状況?

585 :デフォルトの名無しさん:2008/12/08(月) 06:24:39
OPPAIでありつつ(i)とはこれいかに

586 :デフォルトの名無しさん:2008/12/08(月) 06:37:10
enum {
 chinko
}

gen_girl(chinko);


これは困るから型付けはしたいとです・・・。


587 :デフォルトの名無しさん:2008/12/08(月) 11:48:14
>>582
キャストが嫌なら、そういう操作はなるべく enum 提供側で用意してあげればいいんだよ。
たとえば class oppai_iterator 作るとか。

そこまでする必要があるかどうかは疑問だけどね。

588 :デフォルトの名無しさん:2008/12/08(月) 12:30:34
演算子多重定義でやってみた。
enum OPPAI {
 hinnyu = 0,
 hutsuu,
 kyonyu
};

inline OPPAI& operator ++(OPPAI& o)
{
 return o = static_cast<OPPAI>(o + 1);
}

inline OPPAI operator ++(OPPAI& o, int)
{
 OPPAI r = o;
 ++o;
 return r;
}

static const OPPAI OPPAI_N = static_cast<OPPAI>(3);

void gen_all_girl() {
 for (OPPAI i=static_cast<OPPAI>(0); i < OPPAI_N; ++i) {
  gen_girl(i);
 }
}

589 :デフォルトの名無しさん:2008/12/09(火) 14:34:15
数学の組み合わせ(combination)の実装のことなんですが、
「n個のアイテムの中からk個のアイテムを選ぶ」はどうやって実装するのが良いのでしょうか?

考えたのは、
・0からn-1までの乱数をk回取得して、同じ数字が出たら乱数を取得しなおす方法。
・コンテナにアイテムのインデックスを入れて、1回選ぶ毎に選んだアイテムをコンテナから取り除く方法。
前者は、乱数の精度に影響がでそうで良くない気がします。
後者は、コンテナの構築とコンテナからアイテムを取り除くのにコストがかかるのが嫌な感じです。
nが大きく、何度も繰り返し実行される部分なので、高速なのがいいのですが、うまい実装はないですか?

590 :デフォルトの名無しさん:2008/12/09(火) 15:30:26
nが大きいなら前者で良いじゃない。

591 :デフォルトの名無しさん:2008/12/09(火) 16:12:08
>>590
確かに同じ数字を引く確率は低く、影響は気にしなくていいのかもしれません。
問題はシンプルなのに、実装にすっきりしない感が残るのですが、仕方ないんですかねぇ・・。

592 :デフォルトの名無しさん:2008/12/09(火) 16:16:31
取り出すアイテムが完全にランダムでいいなら前者でいいんじゃないかね
ある程度コントロールしたいんなら後者のほうがやりやすそうな気はする

593 :デフォルトの名無しさん:2008/12/09(火) 16:38:57
>>592
前者にします。
ありでした。

594 :デフォルトの名無しさん:2008/12/09(火) 16:50:17
ちょっと気になったんで聞くだけだけど、
前者の「同じ数字が出たら」っていうのは、例えばコンテナに既に出た数字を詰めたりして判断するんだよね?
で、後者の「1回選ぶ」っていうのは乱数で選ぶの?

595 :デフォルトの名無しさん:2008/12/09(火) 16:55:53
インデックスを詰めたコンテナをrandom_shuffleして先頭からk個選択して出力先にコピーとか
そんな感じじゃないかな

596 :デフォルトの名無しさん:2008/12/09(火) 16:57:43
n, k の大きさによって、どうすべきかが大きく変わりそうだ。

597 :デフォルトの名無しさん:2008/12/09(火) 16:58:30
>>594
>>589の文に不備がありました。
×「n個のアイテムの中からk個のアイテムを選ぶ」
○「n個のアイテムの中からk個のアイテムをランダムに選ぶ」

前者についてはその通りです。
同じ数字は取り除いて、コンテナの要素数がkになるまで乱数を詰めます。

598 :デフォルトの名無しさん:2008/12/09(火) 17:10:21
>>595,596
kは10以下で、nは1000以上も想定しています。

599 :デフォルトの名無しさん:2008/12/09(火) 20:46:59
>kは10以下で、nは1000以上も想定しています。
なら
>・0からn-1までの乱数をk回取得して、同じ数字が出たら乱数を取得しなおす方法。
が、けっきょく一番じゃありませんか。


600 :デフォルトの名無しさん:2008/12/09(火) 21:12:56
>>599
実際には、乱数の取得しなおしは必要なくて、ちょうどk回の乱数の取得で十分。

vector<T> v;
int n = static_cast<int>(v.size());
for (int i = 0; i < k; ++i) {
  int j = random_int(i, n); // [i, n) の範囲の整数をランダムで取得する
  swap(v[i], v[j]);
}
// v[0] ... v[k-1] に選択された要素が入る

>>595 の言っている random_shuffle とほぼ同等だけど、全体をシャッフルするんじゃなくて
最初のk個のシャッフルで十分であるところがポイント。

601 :デフォルトの名無しさん:2008/12/09(火) 22:24:53
>>600
vを破壊していいならね。

602 :デフォルトの名無しさん:2008/12/09(火) 22:30:47
1000個ぐらいなら、vを0..999で埋めておいて、
v[0..k-1]がインデックス配列になるというのでもいいか。

603 :デフォルトの名無しさん:2008/12/10(水) 00:06:33
=== hello.cpp ===
#include <iostream.h>

main() {
cout << "Hello World\n";
return 0;
}
==================

$ gcc hello.cpp

参考書を見ながら入門しようと思ったのですが
コンパイルできませんでした。
OSはLinuxでgcc-4.1.2です。

604 :デフォルトの名無しさん:2008/12/10(水) 00:08:36
=== hello.cpp ===
#include <iostream.h>

using namespace std;

main() {
cout << "Hello World\n";
return 0;
}
==================


605 :デフォルトの名無しさん:2008/12/10(水) 00:08:45
$ g++ hello.cpp

606 :デフォルトの名無しさん:2008/12/10(水) 00:08:54
#include <iostream>

int main() {
std::cout << "Hello World\n";
return 0;
}

C++では古い入門書で勉強するのはやめたほうがいい
それ以前の問題も含んでるけど

607 :デフォルトの名無しさん:2008/12/10(水) 00:09:58
#include <iostream>


608 :デフォルトの名無しさん:2008/12/10(水) 00:19:53
#include <iostream>

int main() {
std::cout << "Hello World" << std::endl;
return 0;
}

$ g++ hello.cpp

出来ちゃいました

609 :デフォルトの名無しさん:2008/12/10(水) 00:22:51
endl付けてないと改行が二つほど入るね

610 :デフォルトの名無しさん:2008/12/10(水) 18:06:15
なんのこっちゃ。

611 ::2008/12/10(水) 18:09:52
名簿管理プログラム


・データの一覧表示
・キーボードからのデータ追加
・名前によるデータ検索
・学生番号によるデータの整列(昇順)
・ファイルからデータ入力
・ファイルへデータ出力

ただし単方向の直結リストを使わなければならない。

教えてください。。

612 :デフォルトの名無しさん:2008/12/10(水) 18:12:55
>>611
宿題は宿題スレに、丸投げしないということなら初心者スレに。

613 :デフォルトの名無しさん:2008/12/10(水) 18:20:38
むずい・・・

614 :デフォルトの名無しさん:2008/12/11(木) 09:49:52
C++に限ったことではないですが、
C++でスレッドセーフという場合は、
一つのインスタンスにおいてセーフにするべきか、
複数のインスタンスにおいてセーフにするべきかが、
よくわかっていません。
これってどうなんでしょう?
複数のインスタンスにおいてセーフなものを作るのって大変な気がします。

また、この辺に関していい例がありましたら、URL等を教えてもらえると助かります。

615 :デフォルトの名無しさん:2008/12/11(木) 10:49:00
例としてはXMLパーサなんかがわかりやすいかな

http://xerces.apache.org/xerces-c/faq-parse-3.html#faq-6

616 :デフォルトの名無しさん:2008/12/11(木) 11:36:18
なるほど。
パーサは複数のインスタンスでスレッドセーフなのですね。
http://naoyuki.hirayama.googlepages.com/caper_more.html
(逆に、1つのインスタンスではスレッドセーフではない? 少なくとも上のURLにはそう書いてあります。)

今はデータベースを作っているのですが、
その場合は複数のインスタンスにおけるスレッドセーフティを実現するのが
難しいと思ってますが、どうなんでしょうか?
(細かい話になってしまいますが、
クラスのメンバとして、staticなpthreadオブジェクトを持っていると、
他のデータベースに対するインスタンスに対しても同じpthreadオブジェクトが使われてしまうなど。)



617 :デフォルトの名無しさん:2008/12/11(木) 11:52:52
それはそもそもstaticなのがまずいのでは
異なるデータベースに対して異なるスレッドを使いたいのなら、
staticではなくデータベースインスタンスのメンバであるべきだろう

618 :デフォルトの名無しさん:2008/12/11(木) 11:56:37
俺がイメージするのはシングルトンとプロキシを使った解だけど
もうちょっと具体的に状況を説明して欲しい



619 :デフォルトの名無しさん:2008/12/11(木) 12:10:42
色々教えて頂きありがとうございます。

今の状況を説明します。(
以下、説明のためのコードです。)

class DataBase {
// constructor and destuctor

bool put(/* key and value */)
{
pthread_rwlock_wrlock(&rwlock_);
// update the database
pthread_rwlock_unlock(&rwlock_);
}

bool get(/* key and value */)
{
pthread_rwlock_rdlock(&rwlock_);
// some retrieval action from the database
pthread_rwlock_unlock(&rwlock_);
}

private:
pthrad_rwlock_t rwlock_;
};

このような感じで、今は1インスタンスにおけるスレッドセーフを実現しています。
これを複数インスタンスでもスレッドセーフにしたいのですが、
どうやっていいのかを悩んでいます。


620 :デフォルトの名無しさん:2008/12/11(木) 12:19:44
>>619
各インスタンスで共通に参照するpthread_rwlock_tオブジェクトをプロセス内に置いて
利用すれば、複数インスタンスによるアクセスも大丈夫ではないでしょうか。

621 :デフォルトの名無しさん:2008/12/11(木) 12:29:50
pthread_rwlock_tオブジェクトをstaticにするということでしょうか?
そうすると、1プロセス内の複数のスレッドが別々のデータベースを開くと問題になると思いますが、
いかがでしょうか?
何か勘違いしてるようでしたら、ご指摘ください。

622 :デフォルトの名無しさん:2008/12/11(木) 12:52:44
>>621
一般に、同じクラスから生成した各インスタンスが、それぞれ全く別々のデーターベースをアクセス
するような設計には至らないでしょうが、もしそのようなケースであれば、普通にデーターベースの
参照と更新において競合関係があり、排他制御をしなければならないインスタンス間だけでロックの
共通をすれば問題ないでしょう。
しかしそんなクラスは作れない(作れたとしてもトリッキーで無駄に時間を費やす)場合が多いので、
データーベースへのアクセス単位でクラスを分けて、static属性のクラス内メンバオブジェクトにします。

623 :デフォルトの名無しさん:2008/12/11(木) 13:42:48
>>619
そのコードで何が問題なの?
「複数インスタンスでスレッドセーフ」とか意味わかんないから、具体的な問題を書いて欲しい。

624 :デフォルトの名無しさん:2008/12/11(木) 13:50:11
>>622
ありがとうございます。
参考にさせていただきます。



625 :デフォルトの名無しさん:2008/12/11(木) 14:11:03
>>623
説明不足ですいません。
上のコードだと、以下のパターン1はOKですが、パターン2がNGなので、
両方ともいける良い方法はないかと考えているところです。

* パターン1
---
DataBase db;
db.open(/**/);

// thread作成
// 各threadはdbを共有 (dbへのポインタを各スレッドに渡す)
---

* パターン2
---
// thread作成 (下記のprocを処理するようにする)

// 各スレッドが処理する関数
void proc(void *p)
{
DataBase db;
db.open(/**/); // 各スレッドは同じデータベースをopen
// なんか処理
}
---

626 :デフォルトの名無しさん:2008/12/11(木) 14:33:56
>>625
オープンを失敗させればいいんじゃない。
すでに開かれていますとかなんとか言って。

627 :デフォルトの名無しさん:2008/12/11(木) 16:10:05
クラスAをクラスB、Cが継承しています。
B、Cにほぼ同じ処理があるのでAにその処理を書きたいのですが、
if(dynamic_cast<B*>(p))... と if(dynamic_cast<C*>(p)).. の違いなのです。
thisから型を得て、それでキャストできればAに書くだけで済むのにと思っているのですが、
そういったことは出来るのでしょうか?

628 :デフォルトの名無しさん:2008/12/11(木) 16:26:39
if (typeid(p) == typeid(this))
こんな感じ?

629 :デフォルトの名無しさん:2008/12/11(木) 16:45:10
Aを継承するAImplクラスを作ってそこに実装を書き、
BとCはAImplを継承するって形にするのは駄目?

630 :627:2008/12/11(木) 16:53:53
>>628
確かにそんな感じならAに書けますね。
ありがとうございます。
ただ、書いてなくて申し訳ないのですが、
p2 = (B*)p; 、 p2 = (C*)p; と言った処理もあって、
これもthisを使って p2 = (thisの型)p; のようにできますか?

>>629
B、Cもそれぞれ派生クラスを持っていて、
その処理から返ってくるポインタがBならBの派生、CならCの派生かそうじゃないかで処理を分岐させています。
だからAImplを作っても結局はAに書くのと変わらないです。
分かり難くてごめんなさい。

631 :デフォルトの名無しさん:2008/12/11(木) 17:20:11
p2の型ってどうなってるの?

632 :デフォルトの名無しさん:2008/12/11(木) 17:23:47
> p2 = (thisの型)p;

それをどう使うつもり?
BあるいはCにキャストしたいということは、
BまたはCに固有の、共通でないメンバを使いたいということだ
共通のコードで書けるはずないと思うのだけど
共通のメンバならAに持ってくればいいだけだし

633 :デフォルトの名無しさん:2008/12/11(木) 17:36:11
>>631-632
p2の型はB*、C*です。
よく考えると>>632さんの言うとおりです。
すみませんでした。
いろいろ変更すれば>>628の書き方でいけそうな気がしてきました。
皆さんありがとうございました。

634 :デフォルトの名無しさん:2008/12/12(金) 03:10:00
>>625
パターン 2 の問題を解決する自然な方法がパターン 1 ということだろ。

無関係なオブジェクト同士が非同期に動いて大丈夫なわけがない。
どうにかして情報(たとえば排他オブジェクト)を共有する必要がある。
DataBase インスタンス同士を明示的に繋ぐコードを書きたくないなら
static な何かで繋げるほか無い。

そのパターン 1 で何か不満なのか?

635 :デフォルトの名無しさん:2008/12/12(金) 03:53:31
comp.std.c++ 復活 age
http://groups.google.com/group/comp.std.c++/browse_thread/thread/4516117afeac669d

636 :デフォルトの名無しさん:2008/12/12(金) 13:15:20
http://www.open-std.org/jtc1/sc22/wg21/
> News 2008-12-12: The 2008-12 mailing is available
> News 2008-12-12: The C++ Standard Core Language Issues List (Revision 60) is available
> News 2008-12-12: The C++ Standard Library Issues List (Revision 61) is available

637 :デフォルトの名無しさん:2008/12/12(金) 14:06:16
マジで0xがコンパイラ標準になるのは老後の楽しみになるかもorz

638 :デフォルトの名無しさん:2008/12/12(金) 18:12:10
Zip32.dllを使用して、Zipファイルを作成するプログラムを作成しなければ、なりません。

とりあえず、ネットで色々調べた結果、以下の流れで関数を発行していけば可能ということはわかりました。
ZpInit→ZpSetOption→ZpArchive
しかし、それ以上の詳しい情報が全くわかりません。
なるべくなら日本語で詳しく説明されているサイトやドキュメント等はないでしょうか?

639 :デフォルトの名無しさん:2008/12/12(金) 20:49:20
スレ違いだボケ、どっか他所に逝けって旨を
非常にソフトなテイストで且つ皮肉たっぷりに伝えたいんだが、
自分にそんな文才がないことが非常に悔やまれる。

640 :デフォルトの名無しさん:2008/12/13(土) 00:28:35
>>638
zpinitをグーグルで検索してヒットしたページにサンプルが置いてあるけど、それでは何かご不満?
残念ながら、私にはそれ以上に詳しい説明なんてものが存在し得るとは思えないのですが。
まぁ、どうしてもこれ以上話を続けたいと言うのでしたら環境依存スレでどうぞ。
あー、その際はどこまで理解できたかを書いたほうがいいかもしれませんね。
案外、日本語の勉強から始めないといけないかも知れませんし。

641 :デフォルトの名無しさん:2008/12/13(土) 00:51:13
わからないならレスしないでくださいウザいです

642 :デフォルトの名無しさん:2008/12/13(土) 01:06:36
>>641
おいばかやめろ
Win32APIスレへおかえりください^^

643 :デフォルトの名無しさん:2008/12/13(土) 02:32:01
WIN32APIスレ。。 

戻ってこなければどこのスレいったっていいんだけどさ。 
どこにいったって同じ事聞いて、同じ事かえすんでしょ? ダムすれでもいいんじゃね?

644 :638:2008/12/13(土) 10:03:48
スレ違いの質問をしてしまったようで、申し訳ありませんでした。

C++で作成使用としていたため、ここに書き込んでしまっていました。

645 :638:2008/12/13(土) 10:06:11
あ、一応誤解されたままは嫌なので、>>641は私ではないです。

646 :644:2008/12/13(土) 11:24:08
>>645は私ではないです。

647 :デフォルトの名無しさん:2008/12/13(土) 11:25:48
ローカルクラスなんてのが、あったんだね・・・知らなかった
何処までC++って奥が深いんだろう
と、C++の淵に佇む

void Fun()
{
  class Lcal
  {
    ...メンバー変数...
    ...メンバー関数定義...
  };
  Localを使用するコード...
}

648 :デフォルトの名無しさん:2008/12/13(土) 11:26:44
訂正
void Fun()
{
  class Local
  {
    ...メンバー変数...
    ...メンバー関数定義...
  };
  Localを使用するコード...
}

649 :デフォルトの名無しさん:2008/12/13(土) 11:28:24
動的にメモリを確保してくれるitoa見たいな関数ってありますか?

650 :デフォルトの名無しさん:2008/12/13(土) 11:30:52
std::ostrstream

651 :デフォルトの名無しさん:2008/12/13(土) 11:38:32
ostrstreamは古いからostringstream使え。
boostならlexical_castとか。

652 :デフォルトの名無しさん:2008/12/13(土) 12:29:20
関数ローカルクラスってテンプレートパラメータに渡せない
っていう制限があった気がする

それで一気に萎えた記憶がある

653 :デフォルトの名無しさん:2008/12/13(土) 12:33:17
そんなあなたにC++0x
関数ローカルクラスだろうと無名クラスだろうと何でもテンプレートに渡せるぞ!

654 :デフォルトの名無しさん:2008/12/13(土) 12:48:18
0xはsyntaxが果てしなく汚いhaskellみたいな感じになってて吹く

655 :デフォルトの名無しさん:2008/12/13(土) 13:22:48
>>652
そんなあなたにD
関数ローカルクラスだろうと関数リテラルだろうと
メンバメソッドだろうと何でもテンプレートに渡せるぞ!

656 :デフォルトの名無しさん:2008/12/13(土) 16:28:03
ATLスレかこっちか迷ったんだがプロが多いこっちに。

ATL::CSimpleMap のキーを順に全部取得する場合ってどうやってやってる?
インデックスで対象のキーを拾えればいいんだけど、できないっぽい。

GetStartPosition/GetNext 使わなきゃむりぽ?

657 :656:2008/12/13(土) 16:54:39
ごめん、Simple の方はそんなのなかった。スマソ。

658 :デフォルトの名無しさん:2008/12/13(土) 16:58:03
スレ違いです。

659 :デフォルトの名無しさん:2008/12/13(土) 17:08:33
たすけてください><

関数Aに書かれている_tfopen_sは成功(戻り値:0)なのに、
関数Bに書かれている_tfopen_sは失敗(戻り値:EBUSY)するんです。

引数はともに全く同じで、_tfopen_sの前や処理後には必ず_fcloseallしてます。
なんで2回目は失敗するんでしょうか・・・

660 :デフォルトの名無しさん:2008/12/13(土) 17:18:45
それだけじゃ分からん
引数が実は違う
実はcloseしてなかった
どっかでスタック破壊してる
等々いくらでも原因が・・・

661 :デフォルトの名無しさん:2008/12/13(土) 17:22:53
>>660
そうですよね…すみません。
引数1は単純なFILE*で、モードは"r"、パスはフルパスで正しい。
呼ぶ前に_fcloseall()しても閉じ忘れとか考えられます?
EBUSYってどっかで開かれてますよー状態ですよね。

あとはメモリ破壊をチェックか…長旅になりそうです><

662 :デフォルトの名無しさん:2008/12/13(土) 17:33:38
ソースみせれば早いと思うよ

663 :659:2008/12/13(土) 17:51:07
>>662
けっこうでかいソースだけど、とりあえず端折って・・・

DWORD CClass1::hogeFunc(ATL::CString* szFormatfile){

  // Open file
  FILE *filebuf;
  DWORD dwRet;

  _fcloseall();
  dwRet = _tfopen_s(&filebuf, (LPCTSTR)szFormatfile , _T("r"));

  /* なにやらな処理 */

  _fcloseall();

}

こんな感じです。
dwRet に 16 が返ります。

664 :デフォルトの名無しさん:2008/12/13(土) 17:58:47
そもそも_fcloseall()を使うのってどうなのって思うんだが。

665 :デフォルトの名無しさん:2008/12/13(土) 18:16:20
CString*をLPCTSTRにキャストするって頭大丈夫か?

666 :デフォルトの名無しさん:2008/12/13(土) 18:24:44
他で複数のファイルハンドル使ってたらドツボにはまるし
普通に閉じた方がいいと思うよ

667 :デフォルトの名無しさん:2008/12/13(土) 18:26:02
"他で複数の" じゃなくて "他で" だた

668 :659:2008/12/13(土) 18:32:11
>>664,666
fclose でもだめですたorz でもこれからは fclose にします

>>665
読んだとき、「operator LPCTSTRがあるだろーが」と思ってしまったんですが、
よく見直してみたら「CString::operator LPCTSTR を使った char* を指定する動き」じゃなくて
「CString* を LPCTSTR と見做す動きに」になってしまっていたorz

dwRet = _tfopen_s(&filebuf, (LPCTSTR)szFormatfile , _T("r"));

dwRet = _tfopen_s(&filebuf, (LPCTSTR)(*szFormatfile) , _T("r"));
に直したらうまくいきました!

本当にありがとうございました。反省して精進します。


669 :デフォルトの名無しさん:2008/12/13(土) 18:37:18
そこで明示的にキャストする必要ってあるのか?

670 :デフォルトの名無しさん:2008/12/13(土) 22:09:24
キャストするなら static_cast にするべきかもな。

671 :デフォルトの名無しさん:2008/12/13(土) 23:10:35
いや、キャスト要らないだろ。

672 :デフォルトの名無しさん:2008/12/14(日) 00:04:47
#include <iostream>
using namespace std;

上のほうでusing使うなみたいなこと書かれてたけど、どうして?

673 :デフォルトの名無しさん:2008/12/14(日) 00:15:50
>>672
using 全部じゃなくて using namespace の話だよな。

まずヘッダでやるのは論外。名前空間の意味が無くなる。

それ以外には、スコープ指定の無い通常の名前が指すものが
曖昧になってしまうという問題がある。
http://d.hatena.ne.jp/mb2sync/20080317/p1
最初からエラーになってくれればまだしも、取り込んだ名前空間内部の
変更によって後からエラーが発生するようになる可能性もある。

674 :デフォルトの名無しさん:2008/12/14(日) 02:08:54
>672
つ “More Exceptional C++”
詳しい解説があったから、確認してみ。

大雑把に言うと、「名前空間を汚染する/順番依存な問題を発生するから使う場所に気を付けないとダメ」つうこと。

675 :デフォルトの名無しさん:2008/12/14(日) 02:16:50
上で書いてあるのは、とにかく何も考えずにおまじないで「using namespace std;」と書けと言ってる
クソ入門本がいっぱいあるから

676 :デフォルトの名無しさん:2008/12/14(日) 02:17:16
>>670は、
「余計なキャストしたからこそ、ケアレスミスを見逃した」
ってことを言いたいんじゃねえのかなと思った。

677 :デフォルトの名無しさん:2008/12/14(日) 02:44:58
0x03A40000 4d 5a 90 00 03 00 ....
で、
DWORD* dwOffset = 0x03A40000;
したときの、
*(dwOffset + 0x00000002) の値って、0x00030090 になるよね!?(もちろんIA32)

なぜか 0x00000004 になるorz

678 :デフォルトの名無しさん:2008/12/14(日) 02:51:53
*((char*)dwOffset + 0x00000002)

679 :デフォルトの名無しさん:2008/12/14(日) 02:53:28
そらそうよ
*(dwOffset + 2) = dwOffset[2] だもん
それやるなら
BYTE *dwOffset=0x03A40000;
*(DWORD*)(dwOffset + 2) みたいな感じでは
規格見てないけどw

680 :デフォルトの名無しさん:2008/12/14(日) 02:59:38
>>677
とりあえずこのスレ的には未定義動作と言っておこう。
実際、アライメント違反で CPU 例外が発生する環境もあるし。
あ、 "IA32" なら大丈夫なんだっけ?

681 :デフォルトの名無しさん:2008/12/14(日) 03:17:54
>>677
dwOffset + 2 だと8バイト移動するんじゃないか?

682 :デフォルトの名無しさん:2008/12/14(日) 03:26:49
正解

683 :677:2008/12/14(日) 03:43:18
ΩΩ Ω<ぱ、ぱんだってー!?

それは、例えば DWORD に 0x0 が入っているとして、
DWORD + 2 っていうのは、0x0 + 0x2 = 0x2 ではなく、
0x2 + sizeof(DWORD) * 2 = 0xA っていう事か!?

ポインタ変数に対し + 演算子を使う時は単純合計と考えてはいけないって事なのか!?



684 :デフォルトの名無しさん:2008/12/14(日) 03:51:18
>>683
いや、ポインタとその内部表現であるアドレスとを混同しなければ
その結果で十分単純だから。

685 :デフォルトの名無しさん:2008/12/14(日) 03:52:49
生のアドレスで考えるから混乱するんだよ。
DWORD a[2];
DWORD p = &a[0];
で p + 1 は &a[1] になるってだけの話だ。

686 :デフォルトの名無しさん:2008/12/14(日) 04:00:31
ポインタ演算の超基本なんで
Cから勉強し直すことをお勧めする

687 :デフォルトの名無しさん:2008/12/14(日) 04:13:29
>>683
「ポインタの極意」をオヌヌメするよ

688 :デフォルトの名無しさん:2008/12/14(日) 06:26:47
--
それは、例えば DWORD に 0x0 が入っているとして、
DWORD + 2 っていうのは、0x0 + 0x2 = 0x2 ではなく、
0x2 + sizeof(DWORD) * 2 = 0xA っていう事か!?
--
だめだこいつ、落ち着きがなさ過ぎる。

689 :672:2008/12/14(日) 08:03:49
>>673-675
ありがとう
今までバリバリ使ってたわ・・・

690 :デフォルトの名無しさん:2008/12/14(日) 08:28:06
あまり流行っていないがusing宣言で使うものだけにする方がベター
using std::vector; とか。

691 :デフォルトの名無しさん:2008/12/14(日) 09:01:08
>>677
*(dwOffset + 0x00000002)
  ↓
  ↓コンパイル時の解釈
  ↓
*((DWORD*)((BYTE*)dwOffset + sizeof(DWORD) * 0x00000002))

692 :デフォルトの名無しさん:2008/12/14(日) 11:18:44
dllファイルの中の関数を使ってtry文を書いたんですけど
構文エラーがでてしまいよくわからないので
dllファイルの関数の使い方を教えてください

693 :デフォルトの名無しさん:2008/12/14(日) 11:32:07
ヘッダをインクルードして .lib をリンクすれば
あとは普通の関数と同じように使える。

694 :デフォルトの名無しさん:2008/12/14(日) 11:33:40
>>693
すいません.libのリンクはどうやればいいのですか?

695 :デフォルトの名無しさん:2008/12/14(日) 11:38:26
さすがにスレ違いだし、少しは調べてから聞けよ

696 :デフォルトの名無しさん:2008/12/14(日) 12:07:28
すいません.lib探したんですけど見当りませんでした
dllだけの場合最初に#using <XXX.dll>
だけでいいんですか?

697 :デフォルトの名無しさん:2008/12/14(日) 12:08:16
>676
言葉が足りなかった。
キャストをつける必要はないけど、キャストをつけるんだったら static_cast にしておけば
誤りには気づいたかもね、ぐらい。
暗黙のうちに変換されるものについてはキャストつけた方が呼び出しが明確になるという
考え方もあるかと思って。

698 :デフォルトの名無しさん:2008/12/14(日) 12:13:14
>>696
その辺はもうC++の範囲外だから、適切なスレでやってくれ。

699 :デフォルトの名無しさん:2008/12/14(日) 12:13:16
>>696
どのDLLが使いたいのか隠さずに言ってみろよ。

700 :デフォルトの名無しさん:2008/12/14(日) 12:13:59
>>696
VS2008スレが妥当かな。ここは言語のスレだからすれ違いだ。
DLLはいろいろ種類があるから何のDLLかも移動先に書いとけ。

701 :デフォルトの名無しさん:2008/12/14(日) 14:45:12
DLL だけしか提供されてないなら
コンストラクタで LoadLibrary と GetProcAddress をして
デストラクタで FreeLibrary するラッパクラスを作っとけ。

702 :デフォルトの名無しさん:2008/12/14(日) 17:45:07
Baseというクラスを継承したDer1、Der2といったクラスがあり、
関数に対しDer1,Der2のポインタを、基底クラスであるBaseのポインタを用いて受け渡しています。

現在は、関数内部では、受け渡せれたクラスがDer1なのか、Der2なのかをdynamic_castで判定し、
Der1であったばあいはvector<Base*>に対し、push_back(new Der1)
Der2であったばあいはpush_back(new Der2)
といった処理を行っているのですが、この方法であると、dynamic_castを多用するのでパフォーマンスが心配なのと、
派生クラスを増やすとpush_backを行う関数の書き換えも必要となるといった点で、問題があるかなと思っています。

そこで、Baseクラスに純粋仮想関数としてgetInstance()を持たせ、各派生関数で
Base* Der1::getInstance(){return new Der1;}とし、
push_back(p->getInstance())
することも考えたのですが、getInstanceというとsingletonパターンみたいに見えるので、
可読性が落ちるのでやめたほうがいいよ といった意見もありました。

今回のように、基底クラスのポインタを用いて渡されたオブジェクトの型が「new 型」するためだけに必要な場合は
どのような手法を用いるのが最適なんでしょうか?

703 :デフォルトの名無しさん:2008/12/14(日) 18:25:12
> 基底クラスのポインタを用いて渡されたオブジェクトの型が「new 型」するためだけに必要

AbstractFactory?

704 :デフォルトの名無しさん:2008/12/14(日) 18:25:35
>>702 Clonable

705 :デフォルトの名無しさん:2008/12/14(日) 18:26:52
ちがう、Factory Methodだ

706 :デフォルトの名無しさん:2008/12/14(日) 18:26:59
>>702
受け取ったオブジェクトを vector に入れるんじゃなくて、同じ型の
デフォルトコンストラクタで生成したオブジェクトを入れるの?
なんかおかしくない?

707 :デフォルトの名無しさん:2008/12/14(日) 19:20:54
>>702
とりあえず関数名はgetInstanceからcloneあたりに変えたほうがいいかな。

708 :デフォルトの名無しさん:2008/12/14(日) 20:40:17
cloneじゃなくて「自分と同じクラスのデフォルトコンストラクタで生成されたオブジェクト」だろ
見たことないけど名前どうするのがいいんだろうな、createDefaultとか?

そのデフォルト生成のオブジェクトにセマンティックな意味があるならその名前を付けた方がいい
例えば空のレコードならcreateEmptyRecordとか

709 :デフォルトの名無しさん:2008/12/14(日) 21:32:32
ふつう newInstance() じゃん。

710 :デフォルトの名無しさん:2008/12/14(日) 22:57:03
命名スレかと思った

711 :702:2008/12/14(日) 23:15:40
回答ありがとうございます。
やはり関数名がgetInstance()では混乱をきたしそうなので少し考える必要があるみたいですね。

上であげた例のような完全にデフォルトのコンストラクタを呼ぶ場合は
newInstance()あたりが良いのかなと思います。

また、実際に利用する際は、デフォルトをそのままpush_back()するだけではなく、
例えばpushObject(Base *obj,int ID)
といったように付加情報を付ける場合も多いので、
そういった場合は
Base *nObj = obj->newInstance();
nObj->setID(ID);
push_back(nObj);
といった形をとり、より複雑にオブジェクトを構築する必要がある場合は
FactoryMethodの利用も考えたいと思います。

712 :デフォルトの名無しさん:2008/12/15(月) 21:20:33
http://pc11.2ch.net/test/read.cgi/prog/1229250800/l50
こちらのスレで、STLやらそういう技術をメモリの少ないハード(ゲーム機)で
使うかどうか中途半端に議論になっているのですが、
実際のところ、どうなんでしょうか?

713 :デフォルトの名無しさん:2008/12/15(月) 21:46:04
eastlでヤフれ

714 :デフォルトの名無しさん:2008/12/16(火) 01:45:55
質問です。
自分で確保したメモリ上のクラスをコピーするにはどういったコピーをすればいいのでしょうか。
たとえばstd::vectorをコピーするときってどうやって内部を複製しているのでしょうか。
コピーコントラクタがいいのか、イコールがいいのか。
最悪memcpyって手もありますけど、これは気持ち悪いからしたくないです。
どなたかご教授ください。

715 :デフォルトの名無しさん:2008/12/16(火) 01:59:30
定石としてはコピーコンストラクタと代入演算子を両方作る
中身は「メンバをひとつずつコピーする」だけ
(コピーコンストラクタの場合はメンバ初期化子でやるのがいい)

これ守っていればどんなクラスを作ろうと同じやり方で済むし
引数に渡しても戻り値でもらっても他クラスのメンバにしても
ローカル変数で実体作られても例外で投げられても問題ないし
何よりstd::vectorなんかに突っ込むときに余計な心配がいらない

memcpyが気持ち悪いと感じているのは感覚として正しい
でも理屈を理解したほうがいい

716 :デフォルトの名無しさん:2008/12/16(火) 02:00:32
自分で確保したメモリ上って表現が気になる、というかよく分からないから詳しく。

717 :デフォルトの名無しさん:2008/12/16(火) 02:11:31
>>715-716
レス感謝。えぇっと。書き方悪かったです。
コンテナの方を再発明してるんですが、コピーするときの方法を知りたかったのです。
ってこれ最初にかいてれば・・・。すいません。

自分で確保って言うのは、クラス配列を自分でnewしたときの事です。
newして確保時にコンストラクタが動いてそこからコピーする2重苦は避けられないのでしょうか??

お願いします。

718 :デフォルトの名無しさん:2008/12/16(火) 02:28:48
えーっと>>717です。妥協しました。
一応コピーコンストラクタで解決ってことにします。
セオリーの代入とコピーコンストラクタを同時に実装するというのはコンテナはコピー方法を選ばないと解釈しました。
そういう感じで回答ありがとうございました。抜けます〜。

719 :デフォルトの名無しさん:2008/12/16(火) 07:28:43
>>712
STLとか、わけのわからんくくりで考えてるうちは一生答えは出ないだろうよ。
せっかく部品に分かれてるんだから、問題ないものは使う、問題があれば使わない、と
個別に考えないと何も見えてこない。

720 :デフォルトの名無しさん:2008/12/16(火) 10:06:32
>>718
> 自分で確保って言うのは、クラス配列を自分でnewしたときの事です。
> newして確保時にコンストラクタが動いてそこからコピーする2重苦は避けられないのでしょうか??

vectorなんかの実装見れば分かるけど、allocatorで領域だけ確保した後placement newしてる。

721 :デフォルトの名無しさん:2008/12/16(火) 23:51:38
template< uint_t u >
struct c_t
{
uint_t m;
c_t() : m(u){}
};

const uint_t u = 0;
c_t< u > f0;
uint_t xx = 3;
*const_cast< uint_t * >(&u) = xx;
c_t< u > f1;
stream << _T("c_t< 0 > = ") << f0.m << std::endl;
stream << _T("c_t< 3 > = ") << f1.m << std::endl;

結果:
c_t< 0 > = 0
c_t< 3 > = 0

これってバグってると思う?




722 :デフォルトの名無しさん:2008/12/17(水) 00:04:30
コンパイル時と実行時がごっちゃになってないか

723 :デフォルトの名無しさん:2008/12/17(水) 00:07:49
const宣言した定数にconst_castで無理矢理代入するのは未定義動作

724 :デフォルトの名無しさん:2008/12/17(水) 00:16:41
テンプレートで無駄に複雑にしてるけど本質はこれだろ

int main(){
const int i = 0;
std::cout << i << ",";
*const_cast<int*>(&i) = 3;
std::cout << i << std::endl;
}

このプログラムは「0,3」を表示しても「0,0」を表示しても「0,924877096」を表示してもよい
何も表示せずPCを炎上させても良い
要するに未定義だ

725 :デフォルトの名無しさん:2008/12/17(水) 00:24:31
関数内のstatic const はリテラル扱いで
const は、読み出しオンリーのauto変数扱いだと
思ってたけど違うのか

const uint_t u が
templateのパラメータに使えてしまうのが、そもそもおかしいのかと思ったので


726 :デフォルトの名無しさん:2008/12/17(水) 01:49:19
初期化されているconst変数は、全てコンパイル時定数として扱われる。

727 :デフォルトの名無しさん:2008/12/17(水) 01:51:08
うそ乙


728 :デフォルトの名無しさん:2008/12/17(水) 07:17:48
>>727
釣りなの? 馬鹿なの? 死ぬの?

729 :デフォルトの名無しさん:2008/12/17(水) 09:30:05
>>728
static じゃないconst メンバ変数は?

730 :デフォルトの名無しさん:2008/12/17(水) 10:13:47
>>729
それをどうやってコンパイル時に"初期化されている"状態にするんだ?

>>726については規格の5.19に書いてあるよ

731 :デフォルトの名無しさん:2008/12/17(水) 10:20:45
>>730
726 には「コンパイル時に」とは書いて無かったから嘘だと突っ込まれてるんだろ。
規格の 5.19 に「初期化されているconst変数は、全て」なんて記述も無い。

732 :デフォルトの名無しさん:2008/12/17(水) 11:51:40
>>724
volatile constにするとどうなる? それでも非定義?

733 :デフォルトの名無しさん:2008/12/17(水) 13:13:37
どうでもいいが非定義なんていう未知の用語を
使いなさんな。

734 :デフォルトの名無しさん:2008/12/17(水) 17:36:45
>>720
placement newてそういう風につかえるんですね。新発見です。

735 :デフォルトの名無しさん:2008/12/17(水) 21:16:15
volatile const だとどうなるんだろう・・・。
大丈夫そうなイメージはあるが。

736 :デフォルトの名無しさん:2008/12/17(水) 23:35:12
const-qualified type なことには変わらないから未定義だと思う。
じゃ、volatile const にどんな意味があるのかと言えば、読み込み専用のメモリマップド I/O とかだったら
有り得るような気がする。

737 :デフォルトの名無しさん:2008/12/17(水) 23:38:35
volatile constのポインタならもちろん意味あるけど
プログラムの管理領域にvolatile constの変数取って意味あるかなぁ…

738 :デフォルトの名無しさん:2008/12/17(水) 23:49:52
リンカが特定の領域に割り当ててくれるという状況なら存在意義があると思う。

739 :デフォルトの名無しさん:2008/12/18(木) 01:58:14
MFCのシングルドキュメントでゲームを作っているのですが、効果音の挿入方法を教えてください。

740 :デフォルトの名無しさん:2008/12/18(木) 02:17:24
>>739
MFCスレなりゲ製板なりへどうぞ。

741 :デフォルトの名無しさん:2008/12/18(木) 04:06:17
シフトってエンディアンの影響受ける?

742 :デフォルトの名無しさん:2008/12/18(木) 04:14:13
いいえ

743 :デフォルトの名無しさん:2008/12/18(木) 04:16:15
unionを使わない限りは、影響無いと思うぜ

744 :デフォルトの名無しさん:2008/12/18(木) 04:55:47
ありがと。

745 :デフォルトの名無しさん:2008/12/18(木) 07:41:53
>>736
ああそうか。
そのプログラムには書き込み禁止だけど
別な所で値が変更されるような場合もあるだろうしな。

746 :デフォルトの名無しさん:2008/12/19(金) 03:07:03
解の公式を加算減算だけで表したいんだがどういうプログラムになるのかわからない・・・

747 :デフォルトの名無しさん:2008/12/19(金) 07:02:34
何の解の公式だよ

748 :デフォルトの名無しさん:2008/12/19(金) 09:07:16
>>746
まず、解の公式を加算減算だけで表した数式を書くのが先では?
コンピュータというのは、人がやったら物凄い時間がかかるのを単に高速にやってくれる
だけのものなんだから。自分が分からないものを自動的にはやってくれないよ。

749 :デフォルトの名無しさん:2008/12/19(金) 09:43:47
ニュートン法を使いなさい

750 :デフォルトの名無しさん:2008/12/19(金) 20:00:46
bad_allocがcatchされません。コンパイラはg++です。どうしてでしょうか。

#include <iostream>
#include <new>
using namespace std;

int main()
{
double *p;
unsigned long int count = 0;

cout << "double一個のサイズは" << sizeof(double) << endl << endl;
for (;;) {
try {
p = new double;
count++;
} catch(bad_alloc ba) {
cout << "error:"<< count << "回目に起こった" << endl;
return 1;
}
}
cout << "outside of loop" << endl;
return 0;
}

751 :デフォルトの名無しさん:2008/12/19(金) 20:29:44
>>750

1が返らないかチェックした?
bad_alloc がthrowされた時点でメモリが不足してるから標準出力されないと予想。

最初にメモリ確保しておいてcatchの先頭でdeleteして空きメモリを作れば
出力されると予想

752 :デフォルトの名無しさん:2008/12/19(金) 20:34:47
俺も試してみたけど、
cout なくても terminate 内で terminate が呼ばれたというメッセージが出てで死んでた。
例外機構を実行すること自体にメモリ足りなくて
また例外投げて落ちてるのかもしれない。

753 :デフォルトの名無しさん:2008/12/19(金) 20:35:43
>>750
多分、newするだけでメモリアクセスしてねーから、ページを予約だけして
実際にページインは発生してない、
ゆえにいつまでたってもエラーにならないんじゃないか?

まあ、C++言語仕様の範疇の話ではないな

754 :デフォルトの名無しさん:2008/12/19(金) 20:41:48
って、内部的にはヒープツリーをゴリゴリ書き換えてんだろうから
流石にそれはないか

755 :デフォルトの名無しさん:2008/12/19(金) 20:42:30
>>753
ちゃう。malloc に失敗自体はする。
ただ、catch される前に死ぬ。

756 :デフォルトの名無しさん:2008/12/19(金) 20:43:35
え?badallocの補足って意味ないん?

757 :デフォルトの名無しさん:2008/12/19(金) 20:46:28
B は A (8バイト)をコンストラクタで作って保持する
参照カウンタ式のスマートポインタで、
参照カウンタは A が保持しているとする(侵入型)。
んで、

int main()
{
try {
std::list<B> v;
for (;;) {
v.push_back(B());
}
} catch (const std::bad_alloc& e) {
return 1;
}
return 0;
}

とすれば catch される前にメモリが開放されるはずなので
大丈夫かと思いきや、それでも死んだ。
多分、throw の実装が例外オブジェクトをヒープに確保するようになってて、
そこでメモリ確保に失敗して死ぬんじゃないかと予想する。

758 :デフォルトの名無しさん:2008/12/19(金) 20:48:33
>>756
常に失敗するわけじゃなくて、
細かいバイト数ずつ確保していった場合のみ、こういう現象がおこるらしい。
bad_alloc 例外を受ける事は普通は全く問題ないんだが、
こういう極端な例の場合は問題が発生することもあるようだ。

759 :デフォルトの名無しさん:2008/12/19(金) 20:52:50
これは GCC か何かのバグと言ってもいいような気がするね。

760 :750:2008/12/19(金) 22:24:15
大学のmacでやったらダメだったのに、家のlinuxでコンパイル・実行したらちゃんとcatchしてcoutされました。
(error:201046784回目に起こった)
どちらのPCでもg++でコンパイルしたのですが、、、不思議です。

761 :デフォルトの名無しさん:2008/12/19(金) 22:26:42
巨大な領域の確保に失敗する場合は有益だが、
double 1つごときが確保できないような状況では、
はっきりいってなにもできないに等しい

762 :デフォルトの名無しさん:2008/12/19(金) 22:35:31
「BINARY HACKS HACK #38 g++ の例外処理を理解する(throw 編)」
によると、throw では __cxa_allocate_exception() によって例外オブジェクト用メモリが割り当てられるらしい。
で、gcc 4.2.1 の libstdc++/libsupc++/eh_alloc.cc では、32 bit 環境では、512 バイト×32 個の緊急回避用バッファを
用意しているものの、それを使い尽くしてどうにもならなかった場合には std::terminate() を呼んでいるようだ。

763 :デフォルトの名無しさん:2008/12/19(金) 22:36:55
>>760
へー…
これは個人的な興味だけど、
new_handlerで出力しようとするとどうなるの?

764 :750:2008/12/19(金) 23:13:35
>>763
new_handlerを知りません。
とりあえず細かくメモリを割り当てると今回のようなことが起るかもしれないと思って置きます。
いままで逐一例外処理を書いてたけど無駄な作業になっていたのも多かったかもw

765 :デフォルトの名無しさん:2008/12/19(金) 23:23:04
>>762
オフトピで申し訳ないのだが,そのソース中の
__cxa_allocate_exception() 内の goto の使い方は正当なのだろうか

766 :デフォルトの名無しさん:2008/12/20(土) 00:11:48
どうでもいいが例外って普通参照でキャッチするんじゃないか?

767 :デフォルトの名無しさん:2008/12/20(土) 00:16:08
何をとつぜん?

768 :デフォルトの名無しさん:2008/12/20(土) 00:17:27
>>760
coutのせいじゃねえの?
printfは意外とヒープにデカいメモリ要求することがあるから
シビアな環境でのデバッグには使えなかったりする
coutのoperator<<はよく知らないけど同じようなことしてるんじゃね

769 :デフォルトの名無しさん:2008/12/20(土) 00:24:47
>>768
おまいさんは今までの流れの何を見てたんだ・・・

770 :デフォルトの名無しさん:2008/12/20(土) 00:34:38
ごめんよく読まずに書いてた
cout外しても症状同じなのな

771 :デフォルトの名無しさん:2008/12/20(土) 03:41:23
>764
bad_alloc に対する例外処理が、ってことだよね?
Exceptional C++ Style やそれに基づく前スレでの議論
C++相談室 part63
http://pc11.2ch.net/test/read.cgi/tech/1221144557/672-695
辺りも参照するといいと思う。

>765
特に問題があるようには見受けられない。
最後の後始末部分だけまとめるという意味では goto の使用法として
それなりに良くあるパターンに見えるけどどの辺りが気になる?

772 :デフォルトの名無しさん:2008/12/20(土) 10:46:38
下のサンプルのようにmain()のなかのスコープ内でDataオブジェクトを作成して
そこにDBからデータを読み込んでいます。
スコープから出ればローカルのDataオブジェクトは完全にメモリから解放される
はずなのになぜかメモリリークっぽくなっています。
C++の書き方が問題なのかSQLiteのバグなのか検討がつきません。
ところどころでgetchar()で止めて確かめたメモリ使用量はコメントで
記しています。アドバイスお願いできないでしょうか。

// DBのデータを格納するデータ構造
class Data {
public:
 vector<string> data;
};

int main() {
 cout << "before scope" << endl; getchar(); // 2.7MB
 {
  Data d;
  func(&d);
  cout << "push data" << endl; getchar(); // 83MB
 }
 // ここでdは解放されて元の2.7MBに戻るはずなのに戻らないでリーク?
 cout << "out of scope" << endl; getchar(); // 22MB

 return 0;
}


773 :デフォルトの名無しさん:2008/12/20(土) 10:48:05
SQLiteのコールバック関数とfunc()は下のようになってます。

// SQLiteのコールバック関数、Dataオブジェクトにデータを流し込む
int callback(void *unused, int columnCount, char **values, char **columnNames) {
 Data *d = (Data*)(unused);
 for (int i = 0; i < 10; i++) {
  d->data.push_back(*(values+30));
  d->data.push_back(*(values+25));
  d->data.push_back(*(values+30));
  d->data.push_back(*(values+30));
 }
 return SQLITE_OK;
}

void func(Data *d) {
 sqlite3 *handle;

 string query = "select * from Table1";
 sqlite3_open("test.db", &handle);
 cout << "before exec" << endl; getchar(); // 2.9MB
 sqlite3_exec(handle, query.c_str(), callback, d, NULL);
 cout << "after exec" << endl; getchar(); // 83MB
}


774 :デフォルトの名無しさん:2008/12/20(土) 10:52:30
sqlite3_close() は?

775 :デフォルトの名無しさん:2008/12/20(土) 11:11:23
もしかしたらそれかもしれませんが、オリジナルでは確か書いたと思います。
手元にないのですぐに確かめられないのですが
それ以外で怪しいところがあったらご指摘お願いします。

776 :デフォルトの名無しさん:2008/12/20(土) 11:13:10
環境とコンパイラにもよるが、一般に free/delete でメモリが全部
OSに返されるわけではない。
new/delete、malloc/free のすることは、
(1) ページという単位でOSからメモリを取得し
(2) 必要なサイズにぶつ切りにしてプログラムに渡し
(3) 解放されたら再利用できるようにリストにしておく
という感じ。

だから、delete/freeでプロセスのメモリ使用量が完全に元に戻るわけではない。
その処理を1000回繰り返してメモリ消費量がどんどん増えるようなら
確かにリークしているが、1回だけの実行では何とも言えない

777 :デフォルトの名無しさん:2008/12/20(土) 11:34:13
自分ではnew/delete使ってませんが、確保してるのはDataのメンバのvectorとかstringの内部でしょうか。それともsqliteの内部かな。今度繰り返して試してみます。もし他にC++の書き方としてまずい点があったらヒントをいただけると助かります。



778 :デフォルトの名無しさん:2008/12/20(土) 11:47:00
リークっぽくなる、というのはどうやって確かめたの?

まさかタスクマネージャ・・・

779 :デフォルトの名無しさん:2008/12/20(土) 12:03:50
このプログラムでメモリリークするとしたらsql_lite部分位じゃね?
まあ、stlとか信用していないならvectorとstringも怪しいが。


780 :デフォルトの名無しさん:2008/12/20(土) 12:20:31
>>778
Windowsのタスクマネージャのメモリ使用量ですが・・・ダメですか?
あとLinuxではps alx | grep a.outでRSSを見てます。

781 :デフォルトの名無しさん:2008/12/20(土) 12:22:10
>>779
SQLiteの最新版を使ってはいるんですが、Googleで調べてみたらメモリリークのバグありとかなんとか・・・>>776さんの方法で確かにリークしていたらそこくらいしか思いつかないのです。

782 :デフォルトの名無しさん:2008/12/20(土) 12:39:17
>>781
さっさとループにして試せばいいじゃん
5秒でできるだろ

783 :デフォルトの名無しさん:2008/12/20(土) 12:49:46
せめて10秒はください

784 :デフォルトの名無しさん:2008/12/20(土) 12:50:16
>>782
ごもっともだと思うので今試してみます。
環境がMacしかないうえのsqlite3もDBも手元にないので5秒では無理ですが報告します。

785 :デフォルトの名無しさん:2008/12/20(土) 12:54:13
>>782
せめて3分ぐらいください。

786 :デフォルトの名無しさん:2008/12/20(土) 12:58:51
>>785
782から15分経ってるからとっくに出来てるよな
早く見せろ

787 :デフォルトの名無しさん:2008/12/20(土) 13:04:31
ためしてみました。

cout << "before scope" << endl; getchar();
{
Data d;
func(&d);
cout << "push data" << endl; getchar();
}
cout << "out of scope1" << endl; getchar();

{
Data d;
func(&d);
cout << "push data" << endl; getchar();
}
cout << "out of scope2" << endl; getchar();

こんな感じで5回繰り返しています。使ってるDBは同じじゃないです。メモリ使用量はps alxのRSSです。sqlite3は3.6.6です。
最初: 356
DB読み込み直後: 74884
out of scope1: 70808
out of scope2: 71784
out of scope3: 72752
out of scope4: 73720
でした。やっぱリークかな・・・

788 :デフォルトの名無しさん:2008/12/20(土) 13:16:43
5回かよ

789 :デフォルトの名無しさん:2008/12/20(土) 13:17:14
5回といわずずっと回し続けてみてよ

790 :デフォルトの名無しさん:2008/12/20(土) 13:21:14
そして1年後、、、

791 :デフォルトの名無しさん:2008/12/20(土) 13:29:42
まさかコードコピペで繰り返すとは思わなかった

792 :デフォルトの名無しさん:2008/12/20(土) 13:33:16
そういのはものすごい回数くりかえして、リークしてなきゃありえない使用量になるぐらいまでやれよ

793 :デフォルトの名無しさん:2008/12/20(土) 13:41:26
では、100回ループしてみました。

cout << "before scope" << endl; getchar();

for (int i = 0; i < 100; i++) {
{
Data d;
func(&d);
cout << "push data" << endl;
}
}
cout << "end of scope" << endl; getchar();

1回目ループ後:75860
100回目ループ後:166840

うーん。やっぱり少しずつもれてるんでしょうか。

794 :デフォルトの名無しさん:2008/12/20(土) 13:48:35
そういうのは100回、200回、300回、400回・・・と回数変えてループして
グラフにするんだよ。

795 :デフォルトの名無しさん:2008/12/20(土) 14:48:57
>>794悪乗り乙

796 :デフォルトの名無しさん:2008/12/20(土) 15:11:13
>>795 いや、普通だろ・・・。

797 :デフォルトの名無しさん:2008/12/20(土) 15:12:50
>>795
普通のことだろ

798 :デフォルトの名無しさん:2008/12/20(土) 15:21:03
sqlite3_close()は?

799 :デフォルトの名無しさん:2008/12/20(土) 15:46:45
sqlite_closeくらい当然のようにすでに書いた
上でループコードを回してるんだよな・・・
当然だよな・・・
・・・

800 :デフォルトの名無しさん:2008/12/20(土) 15:54:27
>>773

801 :デフォルトの名無しさん:2008/12/20(土) 15:54:50
sqlite3_closeって、全処理の最後にDBファイルのクローズを行うものだから、
少なくともこの現象とは関係無いよ。

802 :デフォルトの名無しさん:2008/12/20(土) 16:00:55
>>773
コールバックの中でpush_backしてるのをコメントアウトしてみたらどうなる?

803 :デフォルトの名無しさん:2008/12/20(土) 16:53:20
>>801
いやいや、開いた handle をクローズしなきゃまずいだろ
sqlite3_close のシグネチャは
int sqlite3_close(sqlite3*);
だよ?

804 :デフォルトの名無しさん:2008/12/20(土) 17:05:59
あの、そのhandleは何かというのは分かってる?
例えれば、FILE* と同じものだよ。おまえは、ファイルの読み書きをする時に、
readのループで毎回fopenしてfcloseしてるのか?

805 :デフォルトの名無しさん:2008/12/20(土) 17:14:49
というか、sqlite3_closeが無いとか言ってる奴は、
元の質問とコードを全く読んでないだろ。
それとも読解能力が無いのか?

806 :デフォルトの名無しさん:2008/12/20(土) 17:40:02
「オリジナルでは確か書いたと思います」 とは
言ってるけど、正しい位置で呼び出してるかどうからわからんし、
コピペされたコードにない以上、答える側が疑うのは当然だろ

>>805
func でsqlite3_open して、closeしてないじゃん?
ここでいうループってのは、メモリ使用量を測るための
処理全体の恣意的なループのことを言ってるんだから、毎回解放するべきに
きまってるじゃん

ていうか、おまえは 普通のプログラムで fopen 読んでおいて fclose を
呼ばないのか?お前らこそコード読んでないだろ

#fcloseは自動的に呼ばれるってのは無しな

807 :デフォルトの名無しさん:2008/12/20(土) 17:51:01
デストラクタにsqlite.close()入れておけばいいじゃん

808 :デフォルトの名無しさん:2008/12/20(土) 17:52:10
closeは例外返さないの?

809 :デフォルトの名無しさん:2008/12/20(土) 17:56:00
>>808
ヒント:C言語

810 :デフォルトの名無しさん:2008/12/20(土) 17:56:22
おまえら今気づいたけど、スレ違いじゃねコレ

811 :デフォルトの名無しさん:2008/12/20(土) 18:02:30
まぁいいじゃないか相談室なんだし

812 :デフォルトの名無しさん:2008/12/20(土) 18:23:18
質問です。

newで確保したメモリはヒープ領域から割り当てられて、
ヒープ領域は双方向リストで構成されてますよね。(wikipedia調べ)

下の図で分割されてる四角が双方向リストを表してます。
この左側には次の空き領域のアドレスが入り、0が入ってるのは次の空き領域がない状態です。
右側には空き領域のサイズが入ってます。

この空き領域と割り当て済の領域はスタック構造なのでしょうか?
メモリについてよく理解していないので変なこと言ってるかもしれないです。
ttp://kita.kitaa.net/10/s/10mai81022.jpg

813 :デフォルトの名無しさん:2008/12/20(土) 18:33:45
3行目ですでに違う

と思うが、これからWikipedia見てくる

ヒープが双方向リスト構造をしているわけではない

814 :デフォルトの名無しさん:2008/12/20(土) 19:01:40
メモリブロックがリストで管理なのは普通じゃないか?

815 :デフォルトの名無しさん:2008/12/20(土) 19:38:45
ヒープ領域をどのように管理するかは実装依存。
使う側としてはどのように管理されているのか意識しなくていいはず。
自分でカスタムアロケータを書く際の参考にするとか、アセンブラレベルでコードを
追っかけてるとか、メモリダンプを解析しているとかでなければ。
とはいえ、リスト構造によって管理するのはありがちな実装だとは思う。

「スタック構造」が何を指しているのかよくわからないけど、領域の割り当てと解放は
任意の順序で発生しうるので、先入れ後出しのスタック構造とは言えないと思う。

816 :デフォルトの名無しさん:2008/12/20(土) 19:44:09
ヒープという言葉自体C++の用語じゃないでしょ。
C++の用語としてはフリーストアが正しい。
C++の規格内にヒープという言葉は
std::make_heap などのヒープ構造の操作関数以外存在しない。

817 :デフォルトの名無しさん:2008/12/20(土) 19:57:25
http://video.google.com/videoplay?docid=2914803742593360351

818 :デフォルトの名無しさん:2008/12/20(土) 20:00:26
wikipediaの記事も微妙だな・・・
たしかに間違ってはいないんだが、いろんなレイヤーの話がぐちゃぐちゃに
書いてあるから、初心者は混乱するような気がする
OSとページングとプロセスモデルの話があって、
その上に libc の話があって、
その上にC/C++の話があるわけだけど

819 :デフォルトの名無しさん:2008/12/20(土) 20:12:19
wikipediaは、大人になりたくて背伸びをしてる若者が、うまく整理できていない
雑多な知識の風呂敷を広げるところでもあるからな。

820 :デフォルトの名無しさん:2008/12/20(土) 20:33:07
>>812
まず、「スタック」 には2つの意味があって、
「プロセスが利用するメモリ上のスタック領域」 と、
「スタックと呼ばれるデータ構造」 がある。この両者の区別はついてる?
両者は、別物。正確には、メモリ上のとある領域が、「データ構造のスタック」 と
似ているから「スタック領域」 などと呼ばれる、ということだけど。

同様に、
「メモリ領域のヒープ」 と 「データ構造のヒープ」 も完全に別物。

まずはこの区別を付けること。

ちなみに、質問にストレートに答えるなら、答えは 「NO」

821 :デフォルトの名無しさん:2008/12/20(土) 20:33:47
>>816
malloc()やfree()がC++の標準に入ってないとでもお思いですか?

>>812
メモリ割り当ての構造やアルゴリズムを知りたければ
ベストフィット/ファーストフィットなどのキーワードでぐぐれば
それなりに詳しいものに当たれるはず。

822 :デフォルトの名無しさん:2008/12/20(土) 20:36:26
フリーストアは別にヒープを使わなくても仕様上構わないお。
実際にヒープが使われる事が多いだけであって。

823 :デフォルトの名無しさん:2008/12/20(土) 20:36:59
メモリ領域をスタックとかヒープとか呼ぶのは
Perlで連想配列をハッシュと呼ぶのと同じようなもんだな。

824 :デフォルトの名無しさん:2008/12/20(土) 20:38:23
malloc や free を使う分にはヒープを使ってるということだろう。

825 :デフォルトの名無しさん:2008/12/20(土) 20:45:16
規格と実装を混同すんなよ

826 :デフォルトの名無しさん:2008/12/20(土) 20:45:56
malloc や free を「直接」使う分には、と言わないと分からんか

827 :デフォルトの名無しさん:2008/12/20(土) 20:50:32
背伸びしたい年頃の子には、そういう思い込みが多いのですよ。

828 :デフォルトの名無しさん:2008/12/20(土) 20:53:26
>>826
>>822

829 :812:2008/12/20(土) 20:57:41
スタック領域、ヒープ領域はメモリの一部分に名前をつけたもの。
スタック領域はプログラム開始時に変数作り終了時に一斉解放する場所。
ヒープ領域は動的に確保する変数をリスト構造使って割り当ててく場所。

この認識であってますか?

830 :デフォルトの名無しさん:2008/12/20(土) 21:02:00
フリーストアとヒープの違いって何?

831 :デフォルトの名無しさん:2008/12/20(土) 21:03:20
スタックについては違う
ヒープについてはおおむね正しい

832 :デフォルトの名無しさん:2008/12/20(土) 21:04:04
>>828
C++の標準関数であるmalloc()が持ってくるのはどこの領域ですか?

833 :デフォルトの名無しさん:2008/12/20(土) 21:04:22
>>829
スタックが間違ってる

834 :デフォルトの名無しさん:2008/12/20(土) 21:09:31
>>830
正直なところ、名前が紛らわしいから付け替えただけ、というのが本当な気がする。

名目上は、ヒープはプロセスの仕組みとかと比較的結びついていて
どこから割り当てられるかある程度決まっているけど
フリーストアはその出自を問わない領域、ということにはなってる。

もちろん、malloc()が割り当てるのはヒープで
operator new()が割り当てるのがフリーストアであり、
フリーストアの割り当てに失敗すると
new_handlerが呼ばれたりbad_allocが投げられたりする、という違いはあるけどね。

835 :デフォルトの名無しさん:2008/12/20(土) 21:09:48
>>832
ヒープ

836 :812 829:2008/12/20(土) 21:10:04
間違ってる点を教えてもらえないでしょうか?
俺にはどこが違うのかわからないので・・・。

837 :デフォルトの名無しさん:2008/12/20(土) 21:19:00
とりあえず「スタック」という言葉にも
データ構造としてのスタックと
CPUの動く仕組みとしてのスタックがあるから混同するなよ。

もちろん、由来は同じなんだが
「スタック領域」と「スタック構造」は違うから。

838 :デフォルトの名無しさん:2008/12/20(土) 21:28:21
あーあー勘違いしました。
>>829はスタック領域→普通のメモリですね。
スタック領域はサブルーチンなどで使われるauto変数が置かれる場所ですね。

ttp://www.geocities.co.jp/SiliconValley-Bay/8490/c/c_047.html
このURL先の
■ 4、auto変数についてについて
▼ スタック領域の原理
の説明って正しいですか?
スタック領域とスタック構造ごっちゃになってるような・・・

839 :デフォルトの名無しさん:2008/12/20(土) 21:30:01
>>836
「プログラム開始時に」 ではなく、「関数開始時に」 ならおおむね正しい
関数を呼ぶごとに、その関数のローカル変数を含んだ 「フレーム」 が
スタック領域に積まれていく。

ttp://www.kumikomi.net/article/explanation/2008/15stack/03.html


840 :デフォルトの名無しさん:2008/12/20(土) 21:30:37
>>793書いたものですが
ループ100回回したのサンプルでsqlite_close忘れてましたorzすみませんorz
sqlite_close入れたらループ100回回したあとのメモリ使用量は70812で増えてはいませんでした。
ただ完全に解放されてはいないようです。
これは>>776さんの言う通りにあとで使い回すためにキープしてあるのかもしれません。

vectorにもswap技法なんてのもあるようなので強制解放できないか調べてみます。


841 :デフォルトの名無しさん:2008/12/20(土) 22:07:01
結局closeかい

842 :デフォルトの名無しさん:2008/12/20(土) 22:07:15
>>835
>>816は正しいのですか?

843 :デフォルトの名無しさん:2008/12/20(土) 22:08:37
ヒープ違い
ヒープという言葉には2通りある

844 :デフォルトの名無しさん:2008/12/20(土) 22:09:44
すまん答えになってなかった

正しい

845 :デフォルトの名無しさん:2008/12/20(土) 22:10:50
>>838
たしかに、そのページは全体的にいろいろおかしい。
参考にするべきではないね。

「autoと宣言することによるメモリを効率的に使えます」 ってなんだ

846 :デフォルトの名無しさん:2008/12/20(土) 22:59:37
>>844
標準関数のmalloc()はヒープからメモリを割り当てるのに
>C++の規格内にヒープという言葉は
>std::make_heap などのヒープ構造の操作関数以外存在しない。
が正しいのですか?

>C++の用語としてはフリーストアが正しい。
のならば、malloc()のところにも「フリーストア」と書いてあるのですか?

847 :デフォルトの名無しさん:2008/12/20(土) 23:01:31
あ、何も書いてないんですかね。

848 :デフォルトの名無しさん:2008/12/20(土) 23:16:18
本人が「ヒープ」という言葉を使っている、
つまりmallocで確保したメモリのことを言ってる可能性もあるのに
「C++の用語としてはフリーストアが正しい」なんてわけないだろ。

849 :デフォルトの名無しさん:2008/12/20(土) 23:18:17
C++の企画において、C言語は 「参照によって」 含まれる

850 :デフォルトの名無しさん:2008/12/20(土) 23:26:15
C99の7.20.3 Memory management functionsより

The order and contiguity of storage allocated by successive calls to the calloc,
malloc, and realloc functions is unspecified. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an allocated object extends
from the allocation until the deallocation. Each such allocation shall yield a pointer to an
object disjoint from any other object. The pointer returned points to the start (lowest byte
address) of the allocated space. If the space cannot be allocated, a null pointer is
returned. If the size of the space requested is zero, the behavior is implementationdefined:
either a null pointer is returned, or the behavior is as if the size were some
nonzero value, except that the returned pointer shall not be used to access an object.

どこに確保しろとは一言も言ってないな
アライメントちゃんとしろとかallocationからdeallocationまで寿命持てとか
別に確保したのは被らないようにしろとか失敗したらNULL返せとか要件しか書いてない

851 :デフォルトの名無しさん:2008/12/20(土) 23:36:59
つまりフリーストアとは書いてない、と

852 :デフォルトの名無しさん:2008/12/20(土) 23:37:32
まあC99の規格なら当たり前か

853 :デフォルトの名無しさん:2008/12/20(土) 23:42:20
少なくとも、mallocはフリーストアからは確保しない。これは正しい。
だから、mallocで確保した領域について話す場合は、
「C++の用語としてはフリーストアが正しい」は正しくない。

854 :デフォルトの名無しさん:2008/12/21(日) 00:10:25
>>845
> 「autoと宣言することによるメモリを効率的に使えます」 ってなんだ
Cの話だな。
関数内で修飾子を付けずに宣言した int x; みたいなのは auto int x; の省略形とみなされている。
このautoの意味は領域が必要なとき(スコープが有効になったとき)に自動的に確保されて
不要になったら(スコープから抜けたら)自動的に解放されるということをstaticとの対比で明確にしたもの。

必要になったときに確保されて不要になったらすぐに解放されるんだから
プログラム実行中は確保されっぱなしの静的なものよりはメモリを効率的(容量的な意味で)に使えるってこと。

・・・何をいまさらって説明だな。


855 :デフォルトの名無しさん:2008/12/21(日) 00:18:09
先日、「あかね色に染まる坂」の長瀬湊が裸エプロンをしたパネルがとらのあなとゲーマーズに
あった事をお伝えしたが、秋葉原駅西側広場に、特大のDVD広告があるのに気が付いた。
広告には、長瀬湊や片桐優姫やこれからのストーリーみたいな事も書かれていた。

http://www.akibaos.com/img/2008/12/02/20081202k04.jpg
http://www.akibaos.com/img/2008/12/02/20081202k00s.jpg
▲「第10話で息を呑み、第11話で涙する−」
  秋葉原駅西側広場に「あかね色に染まる坂」の特大のDVD広告

現在放映中の「あかね色に染まる坂」は、2007年に発売されたエロゲ(美少女ゲーム)が原作の
TVアニメで、10月から放映されている。
ファミ通.comでは、『主人公・長瀬準一と、彼の前に現れた少女・片桐優姫は、親どうしが決めた
許嫁。しかし、ふたりの仲は最悪だった。そんなふたりをよそに、両親たちからの命令で、進級
するまでともに過ごすことを義務づけられてしまう』とストーリーを紹介している。

広告があったのは秋葉原駅電気街口の西側にある広場で、
『DVDシリーズ12月19日リリース開始!』と告知されており、長瀬湊と片桐優姫が描かれていた。
広告には『お店によって特典が変わるんだからね!』等のセリフがあったが、
『第10話で息を呑み、第11話で涙する――』とこれからのストーリーみたいなのもあった。

http://www.akibaos.com/img/2008/12/02/20081202k02.jpg
▲「お店によって特典が変わるんだからね!」片桐優姫(CV:釘宮理恵)

http://www.akibaos.com/img/2008/12/02/20081202k03.jpg
▲「どの特典も魅力的ですよね♪」長瀬湊(CV:平野綾)

アキバOS
http://www.akibaos.com/?p=4465

・関連
【アニメ】「あかね色に染まる」DVD第7巻、発売中止? ソフマップ、2009年6月26日→発売中止の表記へ変更
http://gimpo.2ch.net/test/read.cgi/moeplus/1228230000/

856 :デフォルトの名無しさん:2008/12/21(日) 00:19:12
>>854
auto修飾しない場合、コンパイルオプションでレジスタ変数への最適化を許容させていた名残かもね。

857 :デフォルトの名無しさん:2008/12/21(日) 00:43:09
auto 修飾した場合にそういう最適化をしないコンパイラがあった頃の名残、と言いたいのかの?
今でもレジスタへの最適化は普通にするし。

858 :デフォルトの名無しさん:2008/12/21(日) 01:02:12
longjmpしたとき、volatile修飾されてないauto変数の内容は復元される保障がない
というのを思い出した

859 :デフォルトの名無しさん:2008/12/21(日) 01:21:43
いずれにせよ今のautoは全く意味のない修飾子だし
C++0xでは型修飾子ですらなくなるし
型修飾子autoを使ったC++コードを今書くことは有害なだけだな
解説ページに書くことではない

860 :デフォルトの名無しさん:2008/12/21(日) 01:24:46
そろそろ register の活用も考えてやるべきだと思うんだ。

861 :デフォルトの名無しさん:2008/12/21(日) 02:24:17
スタック領域、静的領域、ヒープ領域のそれぞれの使える容量はコンパイラによって違うのでしょうか?
一般的にそれぞれどれくらいの割合が普通なのでしょう?

862 :デフォルトの名無しさん:2008/12/21(日) 02:41:37
>>861
とりあえず大小関係は スタック < 静的 < ヒープ が一般的かなぁ。
割合は、同じぐらいの環境から 1000 倍の違いのある環境まで見たことあるし、
どれぐらいが一般的とかわかんないねぇ。

863 :デフォルトの名無しさん:2008/12/21(日) 11:28:21
コンパイラによってっていうか、実行環境によっても変わるし、大抵、設定によっても変えられる。
単なる興味本位でなければ、なぜそういう質問をしているかという背景があると望みの答えが得られやすいかも。

どのデータをどの領域に割り当てるか、について考えるために聞いているなら、サイズがどうこうより
そのデータの使用方法によってどの領域に割り当てるかがほとんど決まるので意味がない。

・関数内のみ→スタック
・プログラム中維持、サイズ不変→静的
・プログラム中の任意の時点で確保、解放、サイズ変更あり→ヒープ

サイズによって変える場合があるのはでかすぎてスタックに入らないパターンくらい。

864 :デフォルトの名無しさん:2008/12/21(日) 11:38:03
スタックは普通結構小さいからな。

865 :デフォルトの名無しさん:2008/12/21(日) 13:01:38
いや、おまえら元ページを見ないで
そんな議論してると思うけど、元ページはそんなレベルじゃないと
思う。めっちゃくちゃなページだから



866 :デフォルトの名無しさん:2008/12/21(日) 13:10:58
すまん>>865はautoの話な

867 :デフォルトの名無しさん:2008/12/21(日) 14:45:17
#define PI atof("3.1415ちんころり")

動いた!?Σ(゚д゚lll)

868 :デフォルトの名無しさん:2008/12/21(日) 14:48:30
>>867
http://ja.wikipedia.org/wiki/Atof
だってさ

869 :デフォルトの名無しさん:2008/12/21(日) 15:12:24
>>867ロリちんこだと・・・!?

870 :デフォルトの名無しさん:2008/12/21(日) 15:50:23
>>865
> いや、おまえら元ページを見ないで
> そんな議論してると思うけど、元ページはそんなレベルじゃないと
> 思う。めっちゃくちゃなページだから
見てきたがそれほどひどくない、
っていうかああいった方向でだめなプログラマはめずらしくもないので正直どうでもいい。

871 :デフォルトの名無しさん:2008/12/21(日) 15:51:05
すじまんこ!?

872 :デフォルトの名無しさん:2008/12/21(日) 20:25:55
マルチスレッドの書き方がよくわからないのですが、
もっと簡単に関数にマルチスレッドフラグのようなものはないんですしょうか?

873 :デフォルトの名無しさん:2008/12/21(日) 20:26:22
ない

874 :デフォルトの名無しさん:2008/12/21(日) 20:32:12
>>872
何がしたいからマルチスレッドにするの?
スレッドを複数動かせばマルチスレッドだけど・・・
NowLoading?

875 :デフォルトの名無しさん:2008/12/21(日) 20:39:42
マルチコアCPUで一つの処理を速くしたいために
マルチスレッドにするならOpenMPでも使えば良いんじゃね。

本質的にマルチスレッドな処理がしたいなら
マルチスレッドな処理をプログラムすればいい。


876 :デフォルトの名無しさん:2008/12/21(日) 20:45:26
boost::thread func();
すいません、調べたらBoostライブラリを使えばいいと書いてありました。


877 :デフォルトの名無しさん:2008/12/21(日) 23:07:42
完全に独立できる処理ってなかなかないからマルチスレッドも定型処理じゃないとあんまり役に立たないよね
CPU2つあるからって処理に2つ使っちゃったらレスポンス最悪だしね
処理時間長めでも軽いほうが大抵いいよね
って考えると余計なお世話的場面のがどうしても多くなる

878 :デフォルトの名無しさん:2008/12/23(火) 17:22:49
C言語に特化したリファクタリングの本知らないですか?

879 :デフォルトの名無しさん:2008/12/23(火) 17:58:57
なんでここで聞くの?

880 :デフォルトの名無しさん:2008/12/23(火) 19:46:52
仮想関数で、継承クラスを書かず基本クラスの仮想関数を呼び出した場合、
基本クラスの仮想関数が実態になる、であってますか?

881 :デフォルトの名無しさん:2008/12/23(火) 19:51:53
あいまいすぎる
コードで書け

882 :デフォルトの名無しさん:2008/12/23(火) 19:57:31
class a
{
 virtual void funk();
}

class b : public a
{
 funk();
}

a::funk() でb::funkが呼び出される
b::funk() でb::funkが呼び出される

まではわかったんです。
この場合、class bが存在していない場合
aのfunkが実態になるんでしょうか?それとも起動しないんでしょうか

883 :デフォルトの名無しさん:2008/12/23(火) 20:02:56
実態とかいう意味不明な言葉は置いておいて
bが存在しなかったらa::funk()が呼び出されるに決まってるだろ

884 :デフォルトの名無しさん:2008/12/23(火) 20:07:21
質問の意味は分らんが試してみれば?

885 :デフォルトの名無しさん:2008/12/23(火) 20:50:06
a::func() が純粋仮想関数ならclass aはインスタンス出来ないからコンパイルエラー
a::func() が純粋仮想関数で無いなら a::func() が実行される

886 :デフォルトの名無しさん:2008/12/24(水) 02:14:41
a::funk()で呼び出されるのはa::funkだろ。


887 :デフォルトの名無しさん:2008/12/24(水) 07:32:02
Boostの1.36以降の追加ライブラリを日本語で調べられるのはどこかにありますか?

888 :デフォルトの名無しさん:2008/12/24(水) 18:01:21
日本語の情報は常に不足している
君が書くんだ

889 :デフォルトの名無しさん:2008/12/24(水) 18:32:58
名前の衝突と,クラスとスコープについてよく分かりません

class A {
public:
char* hoge = "A::hoge";
void func();
private:
void piyo();
}

A::piyo() {
cout << "A::piyo()";
}

A::func() {
cout << hoge;
piyo();
}

A::func() 内で int hoge; などと別に宣言した場合の曖昧性を回避するにはどうすればいいですか
あと,グローバルスコープで別に定義された piyo() を A::func() の中で呼び出すにはどうすればいいのですか

890 :デフォルトの名無しさん:2008/12/24(水) 18:34:53
>>889
同じ変数名にしない
::piyo()

891 :デフォルトの名無しさん:2008/12/24(水) 18:37:34
つか曖昧性云々の前にA::func()でint hoge;宣言したら以降のhogeはこのint hogeが使われるんじゃね
A::hogeでないとメンバ変数のhogeにはアクセスできないんじゃね

892 :デフォルトの名無しさん:2008/12/24(水) 20:15:03
this->hoge って出来ないの?

893 :デフォルトの名無しさん:2008/12/24(水) 23:13:14
>>889
実務的には命名規則とか決めて名前が重複しないようにする。
言語仕様的なことは置いといて。
m_XXXとか、_XXXとか。

894 :デフォルトの名無しさん:2008/12/24(水) 23:20:11
>>893
先頭アンダースコアは無い

895 :デフォルトの名無しさん:2008/12/24(水) 23:30:49
>>894
そうか、C/C++は予約されてたな。
他の言語では使うこともある。

896 :デフォルトの名無しさん:2008/12/25(木) 12:19:52
>>895
ここはC++のスレだ
他の言語ってなんだよw

897 :デフォルトの名無しさん:2008/12/25(木) 13:00:56
std::list::sort() は安定なソートなのでしょうか?

898 :デフォルトの名無しさん:2008/12/25(木) 13:41:40
>>897
うん。

規格に std::list のメンバ関数 sort() についてに以下の記述がある。
23.2.2.4 "list operations" p31
> Notes: Stable: the relative order of the equivalent elements is preserved. ...

899 :デフォルトの名無しさん:2008/12/25(木) 15:16:14
質問です。

C++のクラスの初期化についてです。
メンバー変数を増やしたり減らしたりしていると、ついつい増やした際にコンストラクタでの初期化を書くのを忘れてしまうことがあります。
もちろん「メンバー変数を増やしたら、コンストラクタに初期化処理を書け」を守ろうとはしているのですが、たまに忘れ、Releaseビルドだとうまく動かない!ってことが起きます。

この手のヒューマンエラーを無くす方法で、何か良いものはないでしょうか。
例えば「クラスのメンバー変数が全て0で初期化されていることを保証するコンパイルオプション」とか、そういう類のものがあれば・・・と思うのですが


900 :デフォルトの名無しさん:2008/12/25(木) 15:30:25
>>899
コンパイルオプションを例に挙げながら
コンパイラが何なのかは書かないんだな

901 :デフォルトの名無しさん:2008/12/25(木) 15:50:19
気になるならメンバ変数のクラスのデフォルトコンストラクタを
protectedにでもしておけばいいんじゃね
かなり不毛だけど

902 :デフォルトの名無しさん:2008/12/25(木) 16:17:29
boost::value_initialized

903 :デフォルトの名無しさん:2008/12/25(木) 17:03:41
>>900
gccならこんなオプションがあるよ。って答え方すりゃいいんじゃね?
まー初心者くさいからVC2008だと思うが

904 :デフォルトの名無しさん:2008/12/25(木) 17:56:20
質問です

クラスAAAのメンバ関数の引数にクラスBBBのインスタンスがあって
クラスBBBはメンバ変数としてクラスAAAのインスタンスを持っているとき

class AAA
{
  void test(BBB inst);
};

class BBB
{
  AAA mem;
};

というコードにすると、最初のクラスAAAの部分で、まだクラスBBBが定義されてないためにエラーがでて、
順番を逆にすると、今度は逆にAAAが定義されていないと、同様のエラーが出ます
こういう場合、どうすればよいでしょうか?

905 :デフォルトの名無しさん:2008/12/25(木) 17:57:54
class BBB;
って先頭におけば

906 :デフォルトの名無しさん:2008/12/25(木) 18:55:11
>>904
今回のケースでは必要ないかもしれないがインターフェイスを使った設計を知っておいた方がいい。
http://www.geocities.jp/ky_webid/cpp/language/010.html

907 :デフォルトの名無しさん:2008/12/25(木) 20:02:14
どうしてC++は、純粋仮想関数の宣言に =0 と書くルールを採用したんだろうな
気持ちは分からんでもないが、知らないと理解できないルールは実用上良くないだろ

908 :デフォルトの名無しさん:2008/12/25(木) 20:29:53
C++のルールなんて知らないと理解できないようなものばっかりだろ

909 :デフォルトの名無しさん:2008/12/25(木) 20:40:13
そもそも何で仮想関数と呼ぶんだ?
virtualというキーワードでは直感的に意味が分からないから、よろしくない

910 :デフォルトの名無しさん:2008/12/25(木) 20:45:02
何だったらよろしいんだ? 例えば?

911 :デフォルトの名無しさん:2008/12/25(木) 20:46:09
a.foo()と書いた時に、呼ばれるべきfooがどこにいるかは
aの実体(具体的にはvtbl)を見るまでわからない
だから仮想

912 :デフォルトの名無しさん:2008/12/25(木) 21:11:37
abstractとでも言いたいだけだろう。

913 :デフォルトの名無しさん:2008/12/25(木) 21:18:40
日本語にすると意味分からんよな。仮想。
virtual = (表面的には違うけど)実質上の、事実上のっていう意味だから。

てか、virtual = 仮想って誤訳だよな。まぁ定着しちゃったから別にいいけど

914 :デフォルトの名無しさん:2008/12/25(木) 21:20:35
>>913
訳語を一種類しか見ない馬鹿?

915 :デフォルトの名無しさん:2008/12/25(木) 21:25:33
>>914
は?煽るんならまずお前の解釈とか意見を書けよ

前提抜きで考えれば、仮想関数は意味的におかしいだろ。

別にvirtual=仮想と訳すのが世の中全部で間違ってるとは言ってねえよ

916 :デフォルトの名無しさん:2008/12/25(木) 21:27:45
日本語にはしっくりする訳語はないだろう
polymorphicだって多態だの多相だのとわけわからん訳しかないから
結局「ポリモーフィック」で通ってるんだし

917 :デフォルトの名無しさん:2008/12/25(木) 21:33:08
ニュアンスとしては、「virtual X」は「ほんもののXではないが、
Xのように見える/振舞うもの」じゃないの。

C++では「インタフェースの一致」に主眼を置いてvirtualといっているんだと
思うが、virtualという言葉は「偽」「〜もどき」「バッタもん」という
イメージがとても強いので、イメージ的に混乱が生じる

仮想派生とかになるともっと意味わからん

918 :デフォルトの名無しさん:2008/12/25(木) 21:52:23
overridable か derivable あたり
もしくは indirect とか

919 :デフォルトの名無しさん:2008/12/25(木) 22:11:34
抽象関数でいいよ

920 :デフォルトの名無しさん:2008/12/26(金) 00:31:00
動的メンバ関数はどうだ

921 :デフォルトの名無しさん:2008/12/26(金) 00:53:51
動的だと静的の対義語みたいじゃないか

922 :デフォルトの名無しさん:2008/12/26(金) 10:58:03
>>917
> virtualという言葉は「偽」「〜もどき」「バッタもん」という
> イメージがとても強いので、
そのへんのニュアンスは、マスコミのゲーム批判とかネット批判で
強化されてきた感が、個人的にはある。

923 :デフォルトの名無しさん:2008/12/26(金) 13:07:49
virtualは英語的には「実質」とか「実際の扱いでは区別しなくてよい」くらいの強めの意味があるからなあ。
その意味ではvirtual関数はインターフェースとしての性質をよくあらわしている。
バーチャルリアリティは目標としては「現実と区別できない」だが実装された技術はそこまででもない、みたいな。

924 :デフォルトの名無しさん:2008/12/26(金) 13:44:07
class IA{...};
class IB{...};
class A : public IA{
private:
  IB* pB_;// Bにアクセスするために使う(デストラクタでdelete pB_;とするわけではない)
};
class B : public IB{
private:
  IA* pA_;// Aにアクセスするために使う(デストラクタでdelete pA_;とするわけではない)
};

newされたAとBの寿命管理は別のクラスがするとします。
メンバ変数として保持された参照(pA_またはpB_)が生きているか死んでいるかを検知するにはどういう方法がいいのでしょう?
考えたのは
・ハンドルを使う(boost::weak_ptrなど)
・デストラクタで相手に死んだことを伝える(pB_->NoticeDeleted(this)など)
・メンバ変数で参照を保持するのをやめて、参照が必要なときに寿命管理クラスに問い合わせて参照を取得する
ケースバイケースな気はするのですが、この中で絶対にやめたほうがいいとか、これにするべきというのはありますか?
また、他にも方法があったらお願いします。

925 :デフォルトの名無しさん:2008/12/26(金) 13:54:24
それだけ密接に関連したクラスの寿命管理を別々のクラスにさせること自体がそもそもおかしい

926 :デフォルトの名無しさん:2008/12/26(金) 13:57:27
>>924
そのコードを「参照を保持する」と呼ぶのは止めて欲しい。

927 :デフォルトの名無しさん:2008/12/26(金) 14:11:46
>>925
> newされたAとBの寿命管理は別のクラスがするとします。
これはAの寿命管理はBでなくC、Bの寿命管理はAではなくCという意味です。
わかりにくくてすみません。

>>926
すみません、型名&で宣言される参照と紛らわしいですね。
そのままポインタと呼ぶべきでした。

928 :デフォルトの名無しさん:2008/12/26(金) 14:21:02
オブジェクト設計からやり直し

929 :デフォルトの名無しさん:2008/12/26(金) 14:23:17
>>928
相互参照が発生してる時点で失敗してるということですか?

930 :デフォルトの名無しさん:2008/12/26(金) 15:16:57
スマートポインタ使え

931 :デフォルトの名無しさん:2008/12/26(金) 15:55:46
AもBも、直接お互いの参照を持たないで、Cに問い合わせる形にするべきじゃないか?
AとBはお互い同じ「偉さ」(主従関係にない)なんでしょ?
実質Cが親みたいなもんじゃない。

CはAやBがいつ死んだのか知ってるわけだから、安全でしょ。
(Aから「Bのポインタが欲しい」って言われた時、Bが死んでいたらNULLを返すとか)

932 :デフォルトの名無しさん:2008/12/26(金) 16:41:12
>>928
Cがどういった形でAとBを管理してるのかわからんが
俺だったらCにshared_ptrでAとBを保持させて
AからB、BからAへのアクセスはweak_ptr使うかな

933 :デフォルトの名無しさん:2008/12/26(金) 16:49:08
A が B にアクセスして B が A にアクセスする
なんとなく構造が変だよな 依存しあってる code smell

934 :デフォルトの名無しさん:2008/12/26(金) 16:51:30
循環参照ねー・・・

STGで、敵は主人公の位置が知りたいので主人公へのポインタを持つ。
主人公も敵の位置を知りたい(オートロックオンとかそういう機能があったので)ので敵へのポインタを持つ。

って設計になったとき、これはおかしいぞって思った。
確かにお互いがお互いの情報を欲しいから、参照を持つと楽そうなのはわかる。
でもなぁ。

というわけで、主人公は「敵達を管理するクラス」から敵の位置を取得するようにしたし、
敵は「ゲーム全体を司るクラス」から主人公の位置を取得するようにした。

935 :デフォルトの名無しさん:2008/12/26(金) 16:57:15
そうして、ゲーム全体を管理するクラスを更新するたびに
敵を管理する cpp 全てを再コンパイルするはめに…と
気づいたら、何を更新しても全てを再コンパイルする羽目になった

936 :デフォルトの名無しさん:2008/12/26(金) 17:02:34
Relationをオブジェクトにしてしまえ

937 :デフォルトの名無しさん:2008/12/26(金) 17:03:56
>何を更新しても全てを再コンパイルする羽目になった
良いではないか、良いではないか。

938 :デフォルトの名無しさん:2008/12/26(金) 17:19:47
ゲームでの性能がシビアだったらしらんがインターフェース実装で依存切れるだろ。

939 :デフォルトの名無しさん:2008/12/26(金) 17:37:30
普通はインターフェース実装だわなぁ。
でもインターフェースが増えるとやっぱり再コンパイルとなるわけでw

940 :デフォルトの名無しさん:2008/12/26(金) 17:43:22
>>930-934
アドバイスありがとうございます。
>>924に書いた方法のうち1番目か3番目がいいようですね。


941 :デフォルトの名無しさん:2008/12/26(金) 19:12:19
>>934
ポインタの保持はグローバル変数と並ぶ大罪
引数で渡すのが王道

942 :デフォルトの名無しさん:2008/12/26(金) 22:33:28
その辺のコードはスクリプトで記述するもんじゃないの?

いまだにc++でゴリゴリ書いてんの?

943 :デフォルトの名無しさん:2008/12/26(金) 22:41:07
ポインタ保持できなかったらうっかりメモリも確保できねえ。

944 :デフォルトの名無しさん:2008/12/26(金) 22:42:25
すべてスタックに確保か

945 :デフォルトの名無しさん:2008/12/26(金) 23:11:16
>>935
ふいたwww

946 :デフォルトの名無しさん:2008/12/26(金) 23:40:05
>>943
複数保持だろ?
昔のC言語の本には結構書いてあったな
ゲーム作ってるとDirectXのデバイスのロストで大抵痛い目見るんだ

947 :デフォルトの名無しさん:2008/12/26(金) 23:43:09
どっかで保持してあるインスタンスがあって
そのインスタンスのポインタをどっかのクラスがもっちゃ駄目だよね

そのインスタンスを破棄した情報をどっかのクラスは知らないわけだし
どうしたってバグる
そういう構造にそもそもしちゃ駄目
引数使え引数

948 :デフォルトの名無しさん:2008/12/26(金) 23:43:57
スマートポインタ使おうぜ。

949 :デフォルトの名無しさん:2008/12/26(金) 23:45:30
引数にすると処理ごとに別のインスタンスが渡されることを考慮しないといけないから、
そう簡単に置き換えられないこともあるでしょう。

950 :デフォルトの名無しさん:2008/12/27(土) 00:04:28
インスタンスのエイリアスが複数あると最適化が阻害されるじゃん
基本的に、最適化しづらいコードってよくないと思うんだ。

951 :デフォルトの名無しさん:2008/12/27(土) 00:11:53
とか言って、最適化しやすく書くと処理系依存だのって叩かれるんだよな

952 :デフォルトの名無しさん:2008/12/27(土) 00:14:40
>>949
それって結局別の処理かかなきゃいけないわけだしいいんじゃないの?
駄目なの?
必要もないのに必要のない値が一括で流れてる構造っていいの?駄目なの?
引数できっちり渡すことこそきちんとしたプログラムじゃない?
それとも実装の手間惜しんでバグ増やすほど作業時間切迫してるの?

953 :デフォルトの名無しさん:2008/12/27(土) 00:30:39
class T
{
public:
 void foo(C& c);
 void bar(C& c);
 // foo() と bar() には必ず同じインスタンスを渡してください!!
};

こんなコメント書くぐらいなら T の中に C& c を持ったほうがいいこともあるでしょ。

954 :デフォルトの名無しさん:2008/12/27(土) 00:32:09
>>953
ないって
よしんばあったら設計がまずい

955 :デフォルトの名無しさん:2008/12/27(土) 00:33:01
どんな状況だそれは

956 :デフォルトの名無しさん:2008/12/27(土) 00:44:21
そもそも使う側からみて

if(pC)chinko.setC(pC);
chinko.foo();
unkounko();←実はこのときにpCシボンヌ
chinko.bar();←そうとは知らないchinkoがpC使おうと必死の形相で実行

なんて見た目問題おきないようなコードでやられたら一生バグがみつからん
っていうかチェックが甘すぎる
このコードはせめてこうなってなきゃ駄目だろ
素人じゃないんだから

if(pC)chinko.setC(pC);
if(pC)chinko.foo(pC);
if(pC)unkounko(pC);
if(pC)chinko.bar(pC);

なら使用してる側からもpCにアクセスしてるってわかるだろ常考(エラー処理もほしいが)

↓これじゃ意味不明じゃん

if(pC)chinko.setC(pC);
chinko.foo();
unkounko();
chinko.bar();

957 :デフォルトの名無しさん:2008/12/27(土) 01:07:14
>924
AとBは一対一対応?
何で多重継承じゃダメなの? 動的に切り替わったりするの?


>956
昔からある所有権の問題だな。
素直にスマートポインタ使うのがベター。

958 :デフォルトの名無しさん:2008/12/27(土) 01:09:08
>>957
そうかぁ?
スマートポインタって落ちないだけじゃね?
俺は引数を使ってうまく組むべきだと思うけどね

959 :デフォルトの名無しさん:2008/12/27(土) 01:09:29
>>953
自分ならせめてこうする。
class T
{
public:
  void foo_bar(C& c) {
    foo(c);
    bar(c);
  }
private:
  void foo(C& c);
  void bar(C& c);
}

960 :デフォルトの名無しさん:2008/12/27(土) 01:14:50
>>959
ポインタの保持の問題をいってるのにおかしなこという

961 :957:2008/12/27(土) 01:16:25
>958
依存関係を減らすのは重要だけど、本質的に依存するものを切り離すのは本末転倒だからね。
結局のところ、クラス同士がどういう関係で、何を処理するか次第だと思うよ。

962 :デフォルトの名無しさん:2008/12/27(土) 01:23:36
>>961
いや、そんなことねぇよ
やっぱり、こういうポインタを保持しちまうなんてのは
PGの怠慢なんだよ

怠慢するならするでさ
なにかフォローが必要なんだと思うぜ
もちろん他の人間もわからないしさ
人に対してもソースに対してもそういう配慮が必要になるのを忘れちゃいけない
資料作ったりコメント残したりね

そういうのが嫌だったら引数で渡すようにしたほうがいいぜ
引数だって構造体でまとめて変更あってもソース変わらないですよね?
なんて意地悪しないでちゃんと一つ一つチェックして渡すべき

963 :957:2008/12/27(土) 01:25:32
ついでに言うと
・引数で渡す
 オブジェクトが生きていることを保証する責任は関数を呼び出す側(のプログラマ)が持つ

・スマートポインタのメンバとして保持
 オブジェクトが生きていることを保証するのはスマートポインタ。
 ただし、循環参照など別の問題が発生するかどうかを管理する責任はスマートポインタを
 扱う部分全体(のプログラマ)が持つ

といった感じかね。

964 :デフォルトの名無しさん:2008/12/27(土) 01:27:26
> 基本的に、最適化しづらいコードってよくないと思うんだ。
最適化されますようにって気を使って技巧的に書いたソースからできたバイナリよりも
深く考えず自然な形で書いたソースからできたバイナリのほうが最適化されていることがある罠。

965 :957:2008/12/27(土) 01:30:24
>962
だから内容次第だってば。
例えばイテレータとかはポインタをメンバとして持たないと何にもできないぜ?

966 :デフォルトの名無しさん:2008/12/27(土) 01:36:02
>>965
ごめん
C++のそういう機能全般使ったことないわ
俺、C+クラスぐらいの機能でもう10年ぐれーそれで通ってきてる

これまで言語は規制をかけることで発展してきたけど
C++のテンプレート類はなんか便利な機能群な感じがして
これまでの言語の進歩とは違うっていうか勘違い系が入ってる気がするんだよね

毎回、何がいいの?その程度の機能って感じがする

967 :957:2008/12/27(土) 01:43:49
さすがにC++をC++として使うのなら、STLとか使わないのは勿体無いよ。
ベターCとして使うんだったら別に構わないけど。

もちろん、純粋関数だけを使用して宣言的にプログラムすることもある程度可能だけど、
全部それでやろうとすると大変な部分が出て来るからね。

968 :デフォルトの名無しさん:2008/12/27(土) 01:52:42
>>967
あんまり便利にならなくね?
むしろ、問題ばっかりおきる
あれだけ汚いコードかかせてやってくれること可変配列だけっていらないだろ

969 :デフォルトの名無しさん:2008/12/27(土) 01:55:27
配列 new ダイレクトに使ってんのか?
ちょっと例外起きただけでメモリリークするようなプログラム組んでんじゃねーだろうな。

970 :デフォルトの名無しさん:2008/12/27(土) 01:59:14
newはオーバーライドしてあるからいいチェック入ってるな
でもmallocラップした関数のがいい機能あるんだよね・・・orz

971 :デフォルトの名無しさん:2008/12/27(土) 02:03:05
いい機能w

972 :デフォルトの名無しさん:2008/12/27(土) 02:03:56
shared_ptrとか使わずにnewやmallocをラップしただけで対策してる気になってる?
だったら間違いなく例外脆弱なコードになってるな

「俺は例外なんか使わないから関係ないぜ!」とか言わないように
関係なくないから

973 :デフォルトの名無しさん:2008/12/27(土) 02:08:37
>>972
引数通すから必要ないよ
お前が想定してる自体のほとんどの可能性からいって潰れてるから
必要ないんだろうな

974 :デフォルトの名無しさん:2008/12/27(土) 02:08:56
ライブラリが勝手に例外投げる事もあるからな。

975 :デフォルトの名無しさん:2008/12/27(土) 02:09:43
>>973
騙るならまず日本語を勉強してからにしてくれ。

976 :デフォルトの名無しさん:2008/12/27(土) 02:15:33
ポインタの保持もしない
引数で渡してるならほとんど問題おきないな

引数で渡すって怠慢をするから他の多くのものが必要になってる感はたしかにある

977 :デフォルトの名無しさん:2008/12/27(土) 02:16:18
X引数で渡す
○引数で渡さないでポインタを保持する

978 :デフォルトの名無しさん:2008/12/27(土) 02:19:39
newしたポインタを誰も管理せずに関数の引数で持ち回ってるの?
それだから例外安全だって言ってるの?

ダメだこいつ早く何とかしないと

979 :デフォルトの名無しさん:2008/12/27(土) 02:23:28
void foo(X *px){
...
bar(px);
...
}

int main(){
foo((X*)malloc_wrapper(sizeof(X)));
delete X;
}

引数で渡すってこういうこと?

980 :デフォルトの名無しさん:2008/12/27(土) 02:28:11
>>978
どういう場合を考慮して駄目って言ってるの?

>>979
インスタンス1つに付き変数1つみたいな感じだ
なんではじめのmallocで確保したときは変数もってもいいぜ
でもそれ以外は駄目
引数で渡すってのはそれであってる

981 :デフォルトの名無しさん:2008/12/27(土) 02:49:44
fooやbarが例外投げたらとか下らないことは言うなよ
絶対投げない関数しか使わないから

982 :デフォルトの名無しさん:2008/12/27(土) 02:57:32
エラーメッセージだして終了だろ常考

983 :デフォルトの名無しさん:2008/12/27(土) 03:36:18
例外を送出しない保障の関数しか使わないのかー。
そんな最強クラスに強い例外安全性だけでコード書くとか俺には無理すぎる。


984 :デフォルトの名無しさん:2008/12/27(土) 03:52:25
>>983
例外使えないとなんか駄目なんだw
そんなにあの機能役に立つとは思えないけどなー
コードスタイルひっくり返すほど重要なんだw
あんまり応用効かない技術に頼ってんのな

985 :デフォルトの名無しさん:2008/12/27(土) 03:55:16
なんかの位置間違えたんだろうなきっと

986 :デフォルトの名無しさん:2008/12/27(土) 06:05:13
>>984
だって便利とかの以前にC++の他の人が書いたライブラリはほぼ全滅。
標準ライブラリもboostも諦めるしかない。
newもnothrowとかplacement newとかしか使えないじゃん。

ついでにoperator hoge(=,+,etc)系は、
本質的に例外使えないとエラーを表現できないから使えない
同じくコンストラクタもエラーの通知方法は例外だから使えない
operator =とコンストラクタが使えないって事は結局ただのPODと殆ど同じ。

エラーの発生しない事が保障できるなら上の構文も使えるけど、
そんなのはPODに毛が生えたようなしょぼいデータ構造だけだろうし役には立たなさそう。

POD相当のクラスしか使えないC++って何に使えるの?
本当にCよりはマシってぐらいしか使い道なさそう。

個人的にはC++では例外は空気のように存在してて、それが無い世界が割と想像できん。

987 :デフォルトの名無しさん:2008/12/27(土) 06:41:42
Google 社では例外禁止だけどな。

988 :デフォルトの名無しさん:2008/12/27(土) 07:10:12
>>987
突然、どうしたんだ?

989 :デフォルトの名無しさん:2008/12/27(土) 08:39:31
>>986
だから全部使ってねぇって
C+クラスしか使ってねぇっていってんじゃん

990 :デフォルトの名無しさん:2008/12/27(土) 08:43:22
つまり、C99で拡張された機能も使えずC++の便利な機能も一切使えず、
未だに20年近く前の技術にしがみつくということなのですね、判ります。

991 :デフォルトの名無しさん:2008/12/27(土) 08:47:02
>>990
仮に使うと何がどうよくなんの?
って機能ばっかりだけどな
クラスにしてもあんまりご利益ないんだよね

992 :デフォルトの名無しさん:2008/12/27(土) 08:54:07
老害

993 :デフォルトの名無しさん:2008/12/27(土) 09:28:12
いやだから、頭が20年前のレベルから進化してないのだろ?
大人しくCを使っておけばいいと思うよ。
COBOL専業のソフトハウスだってあるご時世だ、C専業もあるだろさ。
つーか、>992に同意。


994 :デフォルトの名無しさん:2008/12/27(土) 09:59:51
>>960
ならそもそも、954も言っているが、953のような有り得ない状況を元に話をするなよ。

995 :デフォルトの名無しさん:2008/12/27(土) 10:09:48
>>993
みんなそうだけど
全然説明できないよね
テンプレートまわりの利点ってさ
作り手のオナニー以上の効果は絶対にない

996 :デフォルトの名無しさん:2008/12/27(土) 10:19:34
こういうのをマクロではなく関数として記述できるとか、
#define swap(type, x, y) do {type t = (x); (x) = (y); (y) = t;} while (0);
CのqsortよりC++のsort関数テンプレートのほうが見た目が自然でしかも速いとか。

997 :デフォルトの名無しさん:2008/12/27(土) 10:21:06
>>996
枝葉末節だな

998 :デフォルトの名無しさん:2008/12/27(土) 10:22:40
言ってみろって言われて初っ端そんなことしかでてこないところとか
もうホントなんもねぇだろw

999 :デフォルトの名無しさん:2008/12/27(土) 10:24:52
↓最後に当を射たレス

1000 :デフォルトの名無しさん:2008/12/27(土) 10:25:32
1000ならC言語に戻す

1001 :1001:Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。

237 KB
★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)