1 :
(*^ー゚)b グッジョブ!! :
2005/11/26(土) 21:20:04
#include <iostream> using std::cout; using std::endl; int main() { cout << "乙" << endl; return 0; }
テンプレは以上
乙
STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。
>>18 毎スレ恒例のテンプレみたいなもんだ。気にするな。
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後氏ね。
↑ 確かこれもテンプレ
乙
>>1 しかし、std::iteratorを継承して、独自のイテレータを作るの、面倒いね。
オーバーライドをきちんとしないと、予期しないコンパイルエラーの原因になる。
どっかにうまくまとめたサイトないですかね。
>>22 boost::iterator_adaptorやboost::iterator_facadeはどうか?
実行ファイルとは違うディレクトリにあるファイルのオープンを絶対パス指定以外で 行うにはどうしたらいいのでしょうか?
相対パス
ワロタ
自演乙
webサーバー立てて、URLでファイルを取得する。
for(int i=5, m; i < 10; i++) { } のような文の時 int i=5,m; の意味はint型の変数iとmを作ってiに5を代入するという意味でいいのしょうか?
いいえ、代入ではなくiを5で初期化するという意味です。
ありがとうございました
本当にありがとうございました
代入と初期化の違いは何ですか?
constメンバに値をカキコできるのは初期化のときだけ
>>35 実行されるのが代入演算子かコンストラクタか
PODだと違いを感じない(=C言語のつもりだと区別が実感できない)けどな C++だとコンストラクタと代入演算子で処理が変えられるから区別が必要だよな。
staticでprivateなメンバを初期化子(もしくはそれのようなもの) を使って初期化したいのですが、 どうにも苦戦しています。(PODではないため?) class a_c { private: static int x[2]; }; int a_c::x[2] = {0,1}; どうすれば よろしいのでしょう…コンスタラクタで初期化や継承など考えましたが、 旨くいきません。 初期化は、staticで、初期化子のように羅列する方式おこないたい と思うのですが不可能でしょうか。
>>39 そのコードは全然間違っていません。正しいですよ。
>>39 つまり何が上手く言ってないのか書けと。エラーメッセージとかな。
テンプレートクラスを作成し、 そのメンバ関数でそのテンプレート型を返す関数を作成したのですが 関数の失敗時の戻り値に何を返せばいいのか分からず悩んでおります 失敗判定の値を返したいのですが 型によって返す値を分岐するしかないのでしょうか
43 :
42 :2005/11/29(火) 20:17:17
>型によって返す値を分岐するしかないのでしょうか すみません、これは意味が分かりませんでした…
45 :
42 :2005/11/29(火) 20:37:15
>>44 おお、ありがとうございます
例外処理でやってみます
>42 Nullオブジェクト……とか思ったけど、C++だと使い物にならんな……
47 :
デフォルトの名無しさん :2005/11/29(火) 22:28:13
struct Point { Point() {} Point(int xx, int yy) : x(xx), y(yy) {} Point(const Point& p) : x(p.x), y(p.y) {} int x, y; }; この Point(int xx, int yy) : x(xx), y(yy) {} Point(const Point& p) : x(p.x), y(p.y) {} この部分はどういう処理をしているのでしょうか?
48 :
デフォルトの名無しさん :2005/11/29(火) 22:36:23
その前に、structでなくてclassじゃないの?
49 :
デフォルトの名無しさん :2005/11/29(火) 22:43:23
>>47 とりあえず
x = xx;
と同じだと考える。
メンバイニシャライズでは
ごめん、イニシャライザでした
この場合コピーコンストラクタは確かに不要(デフォルトので十分)だが、 Point(int xx, int yy)のコンストラクタはあったら便利。 void f(Point);のような関数に対してf(Point(10, 10));のように呼べ、 Pointの変数を作らなくてすむ。
>>48 別にstructでもいいじゃん。
つーか、全メンバがpublicなら敢えてprivate宣言を省略するために
structにするというポリシーかも知れず。
>>47 前者は整数値を二つ引き数に取るコンストラクタ、
後者はその構造体へのコンスト参照を引き数に取るコンストラクタ。
#所謂コピーコンストラクタやね。
で、どちらもメンバ変数であるxとyを引き数を使って初期化している。
って、リロードしたら被ってた罠。
#でも書き込んじゃう♪
57 :
デフォルトの名無しさん :2005/11/29(火) 23:02:13
class Point { Point() {x=0; y=0}; Point(int xx, int yy) : {x=xx; y=yy}; Point(const Point& p) : {x=p.x; y=p.y}; int x, y; }; でいいんじゃない?
>>57 初期化でできることは初期化でやるべき。
どうでもいいけど、初期化ならPoint(int x, int y) : x(x), y(y) {}と書ける。
>>57 たしかにxとyは組み込み型だからいいけど、
クラスでは初期化と代入は別物。
たとえばfstreamなんかはそういう風にできない。
60 :
デフォルトの名無しさん :2005/11/29(火) 23:12:59
>>60 fstream fs("hoge");というのがあったとして下のコードはコンパイルできない。
fstream fs2;
fs2 = fs;
コンストラクタの中でも同じ。
62 :
47 :2005/11/30(水) 02:29:42
なるほど : x(x), y(y) この使い方ははじめてみたので何なのかわかりませんでした。 メンバイニシャライザというのですね。普通に代入してもよさそうですが 覚えておきます。どうもでした
: x(1), y(x) と書いたとき y に 1 が入る保障はないな
>>63 class foo {
foo() {//1
x = 1;
y = x;
}
foo() : x(1), y(x) {}//2
int x;
int y;
};
の場合、どちらもyに1が入ることは保証されている。
a[4][2]に格納する値を条件によって変化させたいんですけど int a[4][2]={{1,2},{3,4},{5,6},{7,8}}; と初期化するみたいにいい方法はないですか? いちいち a[0][0]=1; a[0][1]=2; a[1][0]=3; ・・・ はめんどうなんですけど
: x(x), y(y) そもそもこれ意味あるのか?
>>66 個人的にはちょっとした構造体のときにメンバ変数と引き数を揃えることでシンプルになるのが気に入ってるが。
>>65 ・構造体にして一次変数を初期化→代入
・構造体にしてカンマ演算子をオーバーロードして一気に代入
・いちいち代入する部分を関数にして、引き数をずらずら並べる
ってところじゃないかな。
69 :
デフォルトの名無しさん :2005/11/30(水) 03:51:41
2つの配列を一度に入力するにはどのように書いたらいいんでしょうか? 例えばa[ ]とb[ ]に一度に1 2 3 4 5 6みたいに入れたいのですが。 ポインタはまだわからないです。 cout<<"ベクトルを2つ入力 -->"; for(j=0;j<c;j++) { cin>>a[j]>>b[j]; } 自力だとこうなのですがエラーが出て…
>>69 a[]とb[]を同じにするなら、cin >>a[j]; b[j] = a[j];
cout<<"ベクトルを2つ入力 -->"; for(j=0;j<c;j++) { cin>>a[j]; } b=a;
>64 class foo { foo() : y(x),x(1) {} int x; int y; }; こう書いても保証されるんだっけ。
74 :
73 :2005/11/30(水) 04:42:21
アンカーミスった ×71 ○72
>>72 初期化リストで保証されているのは、リストに書いた順に初期化が行われること。
76 :
72 :2005/11/30(水) 04:47:19
>73,75 いつからそんな仕様になったの?
>>76 知ってる限り、最初から。
いつならこんな仕様じゃなかったの?
いや72は保証されてるだろ。 メンバ初期化子の順序は無視され、クラスの宣言に現れた順に初期化が行われるはず。 紛らわしいから同じ順番で書けってのがセオリー
class foo { int x; int y; foo() : x(y),y(1) {} }; ということは、これは不定?
ちなみに12.6.2.5ね。 > Then, nonstatic data members shall be initialized in the order they were described in the class definition > (again regardless of the order the mem-initializers).
だーかーらー class foo { int x; int y; foo() : x(x),y(y) {} }; これも不定だってば。
>77 多分最初から。 プログラミング言語C++は持ってないけど、Effective C++にも一項使って書いてある。 クラスの宣言なのはメンバのデストラクタ呼び出しの順番を固定するためだって。 >81 それはこれのことだろ。 Point(int x, int y) : x(x), y(y) {} 不定じゃない。
>>72 ,76
ああぁ、宣言順は x, y だったのな。ごめん間違い。
どうでもいいことだが、さっきからclassで書いてるヤシは、publicつけといたほうがいいんジャマイカ
なんか、自分の勉強不足を力一杯宣言している阿呆がいるな。
fooがpoint型ならともかく何か分からないんだからどっちでもいい罠。 x,yって名前も適当に付けてんだし
constオブジェクトのためには初期化子も必要ですよね?
>>88 そんな消極的な理由で必要なわけじゃない。
基底クラスやメンバを初期化するために必要。
初期化子に付随する、function-try-block があれば、 コンストラクタで失敗したときにログを吐く場合も有効。 struct foo { auto_ptr< bar > x; auto_ptr< bar > y; // function-try-block が利用できる場合(非常に便利) foo( int v ) try : x( new bar( v ) ), y( new bar( v ) ) {} catch( exception const & e ) { cout << "初期化失敗:" << e.what() << endl; } // ここで例外が自動的に再スローされる。 // function-try-block が利用できない場合(非常に不便) foo( int v, bad_tag ) { try { x = auto_ptr< bar >( new bar( v ) ); y = auto_ptr< bar >( new bar( v ) ); } catch( exception const & e ) { cout << "初期化失敗:" << e.what() << endl; throw e; // 自分で再度投げる } } };
>>40 >>41 レスありがとうございます。
実際のコードは大きいので問題抽出してる時に間違ってしまったようです。
typedef struct {
int a[2];
} b_s;
typedef struct {
b_s bs;
} c_s;
static const c_s cs = {
{0, 1}
};
こんな感じのデータがあって、
それにクラスをかぶせたいのですが、
どうすればいいのかわかりません。
class c_c {
public:
c_c() {}
c_c(const cs& cs) {}
const b_c getC()
private:
};
static const c_c cc(cs);
この辺までで詰まってます…
>>88 実はコンストラクタ・デストラクタの中では全てのメンバはconstでないという扱い。
だからといって初期化子を使わなくて良いということではないが。
94 :
デフォルトの名無しさん :2005/11/30(水) 20:44:00
struct A { virtual void g() {} void f() { // お世話になります。 // g がオーバーライドされていればgを呼び出す。 // って事をしたいのですが、オーバーライドされた事を調べるにはどうしたら // 良いのでしょうか? // if(g != A::g) 見たいなシンプルな判定方法があれば教えてください。 } }; struct B : A { void g() { /* いろいろ */ } };
>94 デフォルトのA::g()の中身が空なら、何も考えずにg()を呼べばいいのでは?
96 :
94 :2005/11/30(水) 21:11:19
>>95 肝心な事を忘れていました。
gにパラメータを渡すのですが、そのパラメータの計算が結構長いのです。
gが空ならその計算ごと省略したいので、どうにかならないかと考えた訳です。
>>96 これって結局は「fの振る舞いが型によって異なる」ということなのだから、
fを仮想関数にして、Aを継承した型が自分のf()の中でg()関連を
担当するべきなんじゃないでしょうか。
hoge0 = hoge1 * hoge2 * 0.5; みたいな、良くある演算子オーバーロード使用のループを hoge0.x = hoge1.x * hoge2.x * 0.5; hoge0.y = hoge1.y * hoge2.y * 0.5; みたいな感じで展開してみたら、泣けるくらい実行速度が速くなりました。 計算式がまちまちな上、計算自体数百行に及ぶので、 可読性を考えると圧倒的に前者の方が助かるのですが、さりとて速度も欲しいところでして。 なにか両者を共にいただけるような方法ないッスかねぇ。
99 :
デフォルトの名無しさん :2005/11/30(水) 22:13:00
>>98 プログラム設計には2段階あって、論理設計と物理設計の二つ。
論理設計では上の方法が好ましいんだけど、性能面(物理設計)でダメと
いうことか。
演算子オーバーロードの処理が重いんだろ。
>なにか両者を共にいただけるような方法ないッスかねぇ。
ない!(笑)
焼け石に水だろうが、その演算子オーバーロード関数が もしインライン関数でなければインライン関数にしておく。
101 :
99 :2005/11/30(水) 22:24:43
>>100 なるほど、その手があったか。
演算子オーバーロードに対してinline使えたっけ?
103 :
98 :2005/11/30(水) 22:41:04
>>99-102 お二人?とも、ありがとやんす〜。なるほど2段階っすか、まさに。
とりあえずinline指定してみました。が、私のやり方がまずのかなぁ…。
なんか余計なコピーでも発生してそうなので、EffectiveC++片手にもう少し詰めてみます。
>98 遅延評価を使えばできそうな気がする。
>>103 今使ってる処理系の complex ヘッダを読むのが解への最短距離かも。
>>140 行列ライブラリではよく使われるけど98みたいな単純な例だと逆効果にならない?
106 :
105 :2005/11/30(水) 23:10:21
s/140/104/ です。104さん並びに未来の140さん失礼しました。
108 :
105 :2005/11/30(水) 23:41:59
>>105 参考になりました。URLの根っこのところをお気に入りに入れました。
>N = 4 なら全部計算してしまうようで
というところが気になったんだけど、調べてみたら
#pragma inline_depth(255)
で解決しそう。
109 :
108 :2005/11/30(水) 23:48:29
>>105 じゃなくて
>>107 です・・・・・・
アルコールに脳みその数字認識野を破壊されたようなので逝ってきます
110 :
デフォルトの名無しさん :2005/12/01(木) 01:37:48
class hoge { void f1();{f2();} void f2(){/*長い関数*/}; }; このクラスのf1を呼ぶとf2を呼んだあとf2の1行目で落ちます。 デバッグするとアセンブルコードのところで落ちていました。 しかし長い関数の部分を削除してf2の先頭3,4行のコードを残して実行すると落ちません。 おかしいですよね。削除する前は1行目で落ちていたのに、削除したら落ちないんですから。 こんなことは5年の経験で初めてです。 いったい何が原因ですか?
そういわれてもネェ…
112 :
デフォルトの名無しさん :2005/12/01(木) 01:49:18
>>110 長い関数f2()を単独に実行するとどうなんでしょうか?
f1()がくさいような気がします。
どこかプログラムでぶっ壊してる?特に内部変数あたり。
スタック壊してるね
114 :
デフォルトの名無しさん :2005/12/01(木) 02:00:27
>>110 f1()で変なところを壊してないか確認すること。
配列のMAXを超えてデータを格納していないかとか、文字列の扱いとか。
あと、ポインタ変数の処理がきちんとされているかとか。
class A { public: A(); virtual ~A(); private: init(); }; というようなクラスを定義して、 そのコンストラクタで、プライベートメソッドを呼び、その中で一括して初期化したりmallocしたり しても良いでしょうか? (例えばメンバー変数に可変長文字列のポインタを用意し、そこに mallocした領域に初期化文字列を入れる等の処理) A::A() { init(); }
116 :
:2005/12/01(木) 03:34:05
クラステンプレートのメンバの実装はソースファイルではなくヘッダファイルに書くべきなのでしょうか? このクラスを使用するとリンカエラーが出て困っております
>>115 実は質問内容はよく分からないが
複数のコンストラクタで共通する部分をinit()などに分けて
各コンストラクタ内部でそれを呼び出すのは、よくある手法。
>>116 exportが事実上存在しない現在、
複数ファイルで使うテンプレートは全てヘッダに書くのが鉄則。
118 :
116 :2005/12/01(木) 03:54:32
>>117 ありがとうございます!すっきりしました!
>116 最近マイブームで、 定義をfoo.h、実装を別のヘッダ(foo.hpp)に分けて書いて、 ・hppをincludeして使う時は普通にインライン実装。 ・hのみをincludeして使う時は、 どこか適当なソールファイルでhppを使って明示的インスタンス化。 とかやってる。
120 :
デフォルトの名無しさん :2005/12/01(木) 04:48:13
>>112 単独で実行すると同じように落ちました。
>>113 スタックですか。
>>114 はいf1はf2を呼び出すだけです。
極力直前に処理をさせないようにしたんですが(↓)落ちてしまいます
static hoge* h = new hoge;
int WINMAIN()
{
MSG msg;
HACCEL hAccelTable;
h->f1();h->f2();を直接呼び出しても同じ結果
return 0;
}
こうなるとf1以前にはhogeのコンストラクタしか呼び出されないので、コンストラクタを見ましたがコンストラクタでは何も処理をしていません。
かつて無いほど頭をひねりましたがわかりません。いつもならうっかりミスですぐ見つかるのですが・・・
121 :
デフォルトの名無しさん :2005/12/01(木) 04:56:54
hoge* h = new hoge; をWINMAINの中に入れても同じですか? int WINMAIN() { hoge* h = new hoge; MSG msg; HACCEL hAccelTable; h->f1();h->f2();を直接呼び出しても同じ結果 return 0; }
122 :
デフォルトの名無しさん :2005/12/01(木) 04:59:24
123 :
デフォルトの名無しさん :2005/12/01(木) 05:05:03
これでも、同じ?同じなんだろうな。 int WINMAIN() { hoge h; h.f2(); return 0; }
124 :
123 :2005/12/01(木) 05:05:55
f2って引数ないの?
>>123 試しましたが同じでした。
引数はありません。
126 :
123 :2005/12/01(木) 05:11:23
申し訳ないですが、ギブアップです
^д^; とんでもない。こんな時間までお付き合いいただきありがとうございます。 あとは自分でなにか見落としがないか探してみます。解決できたら報告させてください。
ソースやばければ、f2()を呼び出してる部分のasm上げてみ?
129 :
123 :2005/12/01(木) 05:28:54
関数名のWINMAINってあのWINMAINですか?
ord ptr [esp+14h]
>>128 このぐらいでよろしいですか?
02A88026 add ebx,eax
02A88028 mov eax,dword ptr [esp+8]
02A8802C mul eax,ecx
02A8802E add edx,ebx
02A88030 pop ebx
02A88031 ret 10h
02A88034 push ecx
02A88035 cmp eax,1000h
02A8803A lea ecx,[esp+8]
02A8803E jb 02A88054
02A88040 sub ecx,1000h
02A88046 sub eax,1000h
02A8804B test dword ptr [ecx],eax
02A8804D cmp eax,1000h
02A88052 jae 02A88040
02A88054 sub ecx,eax
02A88056 mov eax,esp
→02A88058 test dword ptr [ecx],eax
02A8805A mov esp,ecx
02A8805C mov ecx,dword ptr [eax]
デバッグでは→のところで止まっています。
>>129 レスするときに間違えて書いていました。正確にはWinMainです。
131 :
123 :2005/12/01(木) 05:35:36
WinMainならば、↓のように記述しないとまずいのではないですか? int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
>>131 紛らわしい書き方で申し訳ありません。レスに書くときは引数を略していました。
>>130 そのアドレスっておまいさんのモジュールか?
>>133 02a88058()
WinMain(HINSTANCE__ * 0x03bdba7a, HINSTANCE__ * 0x00000000, unsigned short * 0x1a04fcc0, int 5) line 52
WinMainCRTStartup(HINSTANCE__ * 0x03bdba7a, HINSTANCE__ * 0x00000000, unsigned short * 0x1a04fcc0, int 5) line 21 + 17 bytes
02a71506()
よくわかりませんが呼び出し履歴はこのようになっています
こういうときは本人が問題ないと思ってる部分が問題になってるケースが多い かってに省略なんかせずにソース晒せ
>>93 コンストラクタ・デストラクタの中でも const メンバは const だよ。
質問デス。 あるクラスのメンバ関数を、プロジェクトのグローバル領域から、 クラスのポインタを通さずに呼び出す事は可能でしょうか。
>>137 そのメンバ関数が静的なら問題なくできます。
139 :
137 :2005/12/01(木) 11:50:38
>>138 すばやい回答ありがとうございます。
ですが、質問の大事なところを端折っていました…orz
申し訳ありませんが、もう一度質問を…。
現在C++でActiveXDLLを作製しています。
DLLの呼出元はVBプログラムなのですが、
この時に、クラスを介せずに直接、クラスのメンバ関数を
呼出できないか、というのを調べています。
よろしくお願いします。
>>139 そのメンバ関数が静的ならその関数を然るべき手段で呼び出せばいいと思います。
#具体的な方法は環境依存につき割愛。然るべきスレでどうぞ。
普通にインタフェース用の関数を用意して,そっからメンバ関数を呼び出すんじゃダメか? Sub Hoge foo End Sub int stdcall foo() { return Bar::bar(); } class Bar { public: static int bar(); }; ・・・みたいな
142 :
137 :2005/12/01(木) 16:26:40
>>140 .141
回答ありがとうございます。
141さんの例を参考に現在構築していますが、
ActiveXDLLとして参照できるものを作るには、色々必要なようです。
色々と試行錯誤してみます。
ありがとうございました。
141の方式ではVB側でfooはおそらくDeclareで宣言することになるよ。
144 :
137 :2005/12/01(木) 17:48:13
>>143 回答ありがとうございます。
実は、VB側はすでに完成しています。
VBですでに作製してあるActiveXDLLを、
C++に移植するという事をやっているため、
呼出側は基本的にそのままという方針なんです。
そういう訳で、クラスを介さない呼出とか、考えなければいけないんですが。
>>144 他回答している香具師ら
頼むからいい加減スレ違いだと言う認識を持ってくれ。
つーか、C++に移植する段階でクラスを使わなければいいだけだろうが。
#で、ついでにextern "C"と。
144 がここはスレ違いだと気付くのキーワードを用意した ATL-COM IUnknown IDispatch GUID Single-Thread-Apartment
■質問があります std::string に格納されている「先頭の」空白文字を除去するにはどうすればいいのでしょうか? 空白文字は複数あることも、全くないこともあります。
boost::trim_left
149 :
147 :2005/12/01(木) 21:54:37
boostが使えない環境なのです(;_;)
>>147 string s = " hoge";
string n;
n = s.substr(s.find_first_not_of(" \t"));
とか?
find_first_not_ofとか、何でメンバ関数になってんだろ…? 激しくムダな気が
ふと思ったんだが。
>>147 のって、生のchar*を使うとすれば
char *s = ...;
while (isspace(*s))
s++;
で、sをずらすだけで済むケースがあるじゃん?
で、同様にstring::c_str()を使ってみると
std::string str = ...;
const char *s = str.c_str();
while (isspace(*s))
s++;
で、ここで、strに戻す(代入しなおす)わけだが、
sはstrの(実体の)内部を指している。
つまり、気楽に str = s; とすると、
実装の仕方によっては不具合が出る可能性がある気がするんだが、
仕様的にはこの辺どうなのか、知ってる人居る?
要は「stringの代入演算子の内部で元の文字列をdeleteするタイミング」
に規定があるのかどうか、って事だけど。
もちろん、char*ではなくiteratorを使っても同じだと思うけど、
・部分文字列を作って
・新規にstringのインスタンスを作り
・それを元のstrに代入する
の3段階の手順を踏むような、例えば
str = string(it, str.end());
みたいな形なら、間違いなく問題は無いはず。
>>152 仕様では、charT*を引数とするoperator=は
*this = basic_string<charT, traits, Allocator>(pointer_to_string);
を行うことになっている。
つまり、一時オブジェクトが作られ、それがthisに代入されることが保証されている。
おー、ありがとう。 安心して良いって事だね。
効率も悪いってことだな
std::string は可読性も上がり、シンプルにコードをかけるが 効率最悪
>>155 文字列が丸ごとコピーされるとは限らないよ
リファレンスカウントによる実装もある
>>157 部分文字列まで考慮したRefCountの実装って相当面倒な気がするんだけど、
実際のSTLの実装で使われてたりするんかな?
王者が1枠に来るのを待っとったで。明日は鉄板やな。 8Rはいくらなんでも王者をバカにしすぎやわ 7R 6-2 30000 12R 1-3 10000 1-5 20000
160 :
159 :2005/12/02(金) 00:20:14
スマン 誤爆や
少し上のexpression templateの話題 efficient c++に書いてあるけれど、すべてをinline展開するとコードサイズが増えすぎるので注意 コードサイズが増えると、キャッシュミスが多発して効率が下がることも。 使用コンパイラが、組込型変数の場合だけRVOする場合 =のついてない算術演算子(operator+()とか)はexpression templateが必要かも ただし、expression templateは、「演算子の種類とlhs, rhsへのポインタ」などをメンバに持つ 一時オブジェクトを生成するコストがかかる。 線形代数ライブラリみたいに巨大なオブジェクトの一時オブジェクト生成を阻止したいときならいざしらず class hoge_t { int x, y; }; みたいに小さなクラスのときは、逆効果だと思う。 どうしてもスピードがほしい部分なら、 hoge0 = hoge1; hoge0 *= hoge2; hoge0 *= 0.5;と展開するのがいいんじゃないかな。 コンパイラによっては: int i = 10; return i; はRVOせず return int(10); はRVOするようなパターンもあるらしい。operator*()の定義を、最適化されやすいよう変えてみては。
162 :
105 :2005/12/02(金) 20:38:47
>>161 コンパイル時に右辺の変数の値が確定している場合 expression template
を使えば、よく出来たコンパイラならコンパイル時に左辺値を計算するため
最高の実行速度と最小のコードサイズを得ることが出来る。
というのが
>>107 の紹介したページの主張(の一部)だと。
しかしそれほどクリティカルなケースがあふれてるものかね? C++ でストレートに書いて問題になったことなどないのだが
165 :
110 :2005/12/03(土) 07:46:15
解決しました。 長い関数の最初で、ある型の自動変数に同じ型の参照を代入していたせいでした。 コンパイルエラーにならないけど壊れるんですね。
>>164 いいサイト紹介してくれてありがとう。
ただその引用の箇所は例えば boost::lambda あたりを揶揄してるっぽいので
可読性と一時オブジェクト生成コストのトレードオフについての論評じゃないと思う。
167 :
デフォルトの名無しさん :2005/12/03(土) 11:11:08
Alt と Enterキー が同時に押されたのを検出したいのですが、 WinProc 内(WM_KEYDOWN / WM_SYSKEYDOWN)にて 検出しようというのは間違っているのでしょうか。
間違ってる このスレで聞くのも間違ってる
>166 前後ちゃんと呼んでなかったスマソ
C++勉強中です。 class A { private: A(); public: static A* Create() { return new A; } }; これはどういうことでしょうか? static関数って通常は非staticメンバ関数を呼び出せないですよね
>>170 どこで非staticなメンバ関数を呼び出してるの?
コンストラクタとか?そんなわけないよな
コンストラクタって非staticなメンバ関数じゃないんすか。そうですか。
誰が呼び出したかに注意するといいよ
たぶん private: にコンストラクタがあるので staic メンバ関数内で インスタンス化したときになんでコンパイルエラー出ないのか? ってことを言いたいんだと思うのだが、それの答えは。 staticメンバ関数は friend みたく非公開メンバにアクセスできるから。
一方「非staticメンバ関数を呼び出せない」に引っかかっているんだとしたら その文面を「暗黙の this-> を省略できない」と読みかえればいいだにょん。
177 :
170 :2005/12/03(土) 15:03:40
「暗黙の this-> を省略できない」 なるほど。 理解できました。ありがとうございました。
178 :
デフォルトの名無しさん :2005/12/03(土) 16:34:52
>>178 推薦図書スレ行ったら・・・と言おうとしたけど荒れてるね。
演習的なのをやりたいのならExceptional C++かな?
ただWisdomSoftのを読んだだけだと厳しいかもしれない。
#マ板の割にはいいレス付いてるなw
#俺がひどいスレしか見てないだけかもしれんが。
>>179 K&Rは感動の良書で、そんな演習の入ったC++本を探していますが、
気に入ったもの見つからないのです。
K&Rは1章の問題(1日で踏破できた)をやるだけで、ひととおり
C言語プログラムが書けるように工夫して書かれてました。
コンストラクタ、ディストラクタの概念などは、C言語にはなかったじゃない
ですか。なのでC++仕様の大きさには感心しています。
ただ正直のところは、クラスの定義について、どのような考え方で
システム構成を構築するか、あるいはシステムをどのように分割して
クラスに分解する?・・・みたいな考え方も知りたいところです。
あとは、どんなの応用を想定して、クラスの継承をできるようにC++ではしているのか、
その根本的思想を知りたい、と思います。
なお、
マ板は、読むと精神的に良くないのですが、酷い会社環境で
苦労している人(自分もそう)の話から、自分の知らない
世の中の現実から、学べ取れるものがあります。
クラス、オーバーロード、オーバーライド、ポリモフィズム、例外、テンプレート、STL 大雑把に言えば、C++の基礎文法はこんなとこ。後ろに行くほど分野によって不要だったりもする。 上記でまだ分からないものがあれば、ウェブなり、入門書なりでまずは補完すること。 このレベルなら独習シリーズでいいんじゃね? で、C++の機能の多くはオブジェクト志向の実装のためにあるわけだからオブジェクト指向もかじっ ておかないと、意味わからないことも多いと思われる。 ただし、組み込みみたいに特殊な分野だと、また文化が違ったりするから、目的がはっきりしている なら、その点ハッキリさせて質問したほうがいいと思われ。
>>181 >システム構成を構築するか、あるいはシステムをどのように分割して
>クラスに分解する?・・・みたいな考え方も知りたいところです。
>あとは、どんなの応用を想定して、クラスの継承をできるようにC++ではしているのか、
>その根本的思想を知りたい、と思います。
それはもう言語の話じゃないな。
_beginthreadexで作ったスレッドをメインスレッドから強制的に終了させる方法ってないすか?
ワーカスレッドでない場合は、クラスで隠蔽して、起動前にフラグ立てて、 デストラクタ処理で終了待ちのループさせるとかしか思いつかんけど。
>>178 言語仕様や文法がどうこうというのを気にするんじゃなくて
オブジェクト指向とはどういうものか、というのを一度
言語という枠を超えて(SmalltalkとかRubyとか)勉強して、
理解してからC++に戻ってきても遅くないと思うよ。
class A { public: int i; A( int _i ):i( _i ){}; A(){ A(1); } }; A a; printf("%d\n", a.i ); で分けわからない数値が出力されます。 コンストラクタ内で別のコンストラクタを呼び出すのはダメなんでしょうか?
ダメです
>188 呼び出しても一時オブジェクトが生成されるだけだよ。 デフォルト引数使って逃げるか、init() みたいな関数に共通処理をくくり出すか(初期化じゃなくなっちゃうけど)かな。
class A { public: int i; A( int _i = 1 ):i( _i ){}; }; class A { public: int i; A( int _i ) { init(_i); }; A(){ init(1); } void init( int _i ) { i = _i; }; };
A(int i=1): i(i){}
A(int i=1): { i = i; }
194 :
188 :2005/12/04(日) 11:45:37
一時オブジェクトが生成されるだけなんですか。 解りました。ありがとうございました。
>>194 どこだか忘れたけど、C++入門なんて偉そうに書いてるWebSiteでその手の間違いを堂々と書いてたな。
ご丁寧に勘違いに基づいた結果に合うようなサンプルまで用意して。
もしあんたがそのサイトで勉強しているならとっととそのページをブックマーク、キャッシュごと捨ててしまえ。
なんで何も知らないのに入門なんか書こうとするんだろうなあ・・・
自分が無知なことを知らないから (というより、自分は結構詳しいと勘違いしているから)
コンストラクタについての質問です。 独習C++で勉強した後、VC++(MFC)の勉強をしていたら、 次のような文を何気なく使われているのを発見しました。 class TestView: public CView { /*各種オブジェクトの宣言*/ private:Crect m_rectEllipse; } CMyView :: CMyView : m_rectEllipse(0,0,200,200) //←ココ { /* CMyViewのコンストラクタ . . . */ } "ココ"の文っていろいろ調べたんですが、載ってなくて。 こういう初期化の書き方ってありなんでしょうか。 それとも何か別の意味があるんでしょうか。
>>199 初期化リストでぐぐってみ。
基底クラスのコンストラクタを呼び出す意味と、メンバを初期化する意味がある。
201 :
199 :2005/12/04(日) 16:01:30
解決しました。ありがとうございました。 デフォルトコンストラクタを持たないクラスのオブジェクト、 const 宣言されたメンバ、リファレンスメンバ はメンバ初期設定リストによって初期化されなければならない。
>>201 そんな限定的に使うんじゃなくて、なるべく全部
初期化リストで初期化するようにしような。
CMyView::と{の間に : m_Hogehogeとかが大量に入るのが当たり前だったのか
引数なしのデフォルトコンストラクタが用意されてないとそうなる罠
メンバ変数の初期化リストなんてあんま見ないなと思ったら そもそもPODじゃないデータを初期化でコピーした記憶が無かった
hogeというクラスがあって int KANSUU(hoge *a){} という関数があった場合hogeを継承したhogehogeクラスを引数にとることはできるんでしょうか?
>>206 継承を理解していればそんな質問を投げないぞ。
BruceEckelのThinking in C++ってどうなの? Thinking in Javaが名著なだけに、是非読んでみたいと思ってるんだけど 邦訳が出てないようだし・・・ 原著買うしかないかなぁ
基底クラスに派生クラスのアドレスを代入したときの動きのメカニズムや クラス情報がどのようにメモリに配置されるかなどを図で説明した本はないでしょうか?
>>211 EffectiveC++にもvptr周りは図付きで説明されてた気がするが
もうちょっと詳しく知りたいならARMかD&Eじゃね?
>>212 ARMはともかくD&Eなら近くの本屋さんにあると思うので調べてみます。
ありがとうございました
ARMやD&Eが何の略かわかりません(><)
ARM : The Annotated C++ Reference Manual : プログラミング言語C++ D&E : The Design And Evolution of C++ : C++の設計と進化
>>216 >ARM : The Annotated C++ Reference Manual : プログラミング言語C++
邦訳タイトルが違う
>>215 が正しい
>>211 "vtable c++"でぐぐってみるとか。手っ取り早く知るにはまずこれ。
それにしても今晩はよく雷が落ちるなあ。さっきからUPSが3回も作動した。
220 :
デフォルトの名無しさん :2005/12/05(月) 07:13:51
C言語で関数ポインタを使って typedef { int (*func)(int param); }funcList[]={ func1,func2,func3・・・ }; int callFunc(int funcNum,int param) { return funcList[funcNum].func(param); } のような実装をC++のクラスでできますか? 関数ポインタによるリスト化したいのは protected なメソッドです。 そのクラスは継承されるのが前提でひとつのプログラム内部で複数のインスタンスが生成されるのでクラスの外に定義するのはしたくありません。 switch文で分岐もメソッド数が200以上になりそうなので実用的でないし。
223 :
デフォルトの名無しさん :2005/12/05(月) 11:47:41
どなたか、教えてください。以下で func3() の値がおかしくなってしまいます。 class base_1 { public: base_1() : data_( 123 ) {} int get() { return data_; } int data_; }; class base : public base_1 { public: typedef base_1 base_1_type; public: int GET() { return base::base_1_type::get(); } }; class other { public: int dummy_; }; class derived : public other, public base { public: int func1() { return base::base_1::get(); } int func2() { return base::GET(); } int func3() { return base::base_1_type::get(); } }; int main( int argc, char * argv[] ) { derived D; printf( "%d\n", D.func1() ); printf( "%d\n", D.func2() ); printf( "%d\n", D.func3() );// おかしい! }
>>223 cygwin g++ 3.4.4 で動かしたら 123 が3個表示された。
ただし、先頭に #include <cstdio> を足した。
なんかマイナーなコンパイラ使ってる?
225 :
223 :2005/12/05(月) 11:58:05
Microsoft VC++.NETです。 どうもbase_1のthisポインタがsizeof(other)だけずれるんです。
2003で試したけど、thisが&D+4byteを指してないといけないのに+8byteのところ指してた。
class derived : public base, public other { public:
228 :
223 :2005/12/05(月) 14:12:51
みなさん、どうも。 自分の環境だけでなかったので、コンパイラの癖みたいなものでしょうか? いろいろおかしいところはあって、 ・func3()で base::get() とか base_1_type::get() だと問題は発生しない。 ・たとえばotherとかにメンバ関数get()を持たせると問題は発生しない。 ・base内でのtypedefをprivateにしてもコンパイルビルドはできてしまう。 ・派生させるクラスの順序によって症状が変わる もともと、base_1はtemplateだったんですが、単純化するとこうなりました。 template名が長かったのでtypedefしたんですが…
230 :
223 :2005/12/05(月) 16:13:36
>>229 ありがとう。いろいろあるみたいですね。折をみて聞いてきます。
とりあえず、不便ですが回避したコードでやってます。
231 :
181 :2005/12/05(月) 20:53:07
みなさん、色々な本の紹介やアドバイスありがとうございます。 情報はすべてメモしました。 今日はとりあえず、先日見つけたWEBの演習を始めました。 今日はコンストラクタ関数と、そのオーバーロードによる 初期化の具体的やり方がわかりますた。 実際に演習で組むと、頭が良くなったような錯覚に陥りますw 紹介いただいた本は、本屋さんで眺めてから、自分に合うか 見極めようと思います。
181 はどのサイトで勉強しているのだろう。ちょっと気になる。
すいません、C++の勉強をしているんですが。 fstreamでファイルから読み込みをする際に 区切り文字を設定する事はできないのでしょうか? csvのファイルを読み込むときはどうしたら良いのかわからなくて…。 スペース区切りがデフォルトですよね?
>>233 たとえばboost::tokenizer
トークン文字が複数の場合は面倒だがgetlineじゃダメなのか?
STLとかイテレータとかまだ全然理解できてないです。。。 getlineでできそうでした。 ありがとうございました。
237 :
181 :2005/12/06(火) 23:44:29
そんなんでいいのか。 OOなんて出番なさそうな演習だな。
239 :
232 :2005/12/07(水) 01:11:33
・・・・そうか? それのCの方を見たことあるが、 一部用語が統一されてなかったりして、 書いてる本人もわかってるのかいなってところがあったが・・・。
ケチらんで本買えと >実際C++で良質の演習問題を提供するって難しい。 禿本の演習問題があるじゃん
禿禿うっさいぞ( ゚Д゚)ゴルァ!!
244 :
239 :2005/12/07(水) 01:30:28
>>240 ごまかしはあるけどあからさまな嘘は書いていないので好印象。
レイアウトに気を配って重要なところに自然に目がいくように
配慮されているとこがすごく良いと思った(印刷物だとお金が掛かるのでやりたくても出来ない)。
Kittyってサイトが上がるたびに叩かれてる記憶が
246 :
239 :2005/12/07(水) 01:42:02
>>241 Rogue Wave が tools++ を提供しているところで
エピステーメーが推奨しているってとこまでは知ってるけど・・・
Rogue Wave が日本語の演習問題を出しているのか?
Rogue Wave 有名すぎて調べにくいぞ。
247 :
239 :2005/12/07(水) 01:47:29
>>242 プップー!
237 は 買ってみた上で翻訳が糞なんでもっと効率の良いソースを求めているのだ。
俺が演習問題出してやる。 問1 自動販売機を分析して、C++で制御プログラムを作成せよ。 問2 エレベータシステムを分析して、C++で制御プログラムを実装せよ。 各 6時間
うっわー出たよ 自販機問題とエレベータ問題wwっwwwwww w
あとは巡回セールスマン問題ができたら完璧だな
>239の上のサイト、入門にありがちな応用が身に着かない教え方だな。
あーダメだ、 >ただし、綺麗で保守的なプログラムを書きたいのであれば >適当な位置で変数を宣言するのではなく、ブロックの先頭でまとめて宣言するべきです こんなこと書いてるよ。
>>252 保守的っていうがC89からの習慣や伝統を守るっていう意味だと正しいだろ。
>>253 そもそも変数の宣言箇所についてはC言語の伝統を守ること自体が間違いだと思われ。
すっかり未初期化の変数は気持ち悪いと感じる体になってしまったなぁ。
>未初期化の変数は気持ち悪い 健全だと思われ
申し訳ありません。C++言語の言語使用自体はおおまかに学び終えたものの 実際のコーディングに関してわからない点があるため質問をさせてください。 変更が不可能な既存のクラスClassAとClassBがすでに存在し コード中で ClassA a; ClassB b; a=b; あるいは b=a; などのように代入演算子を使えるようにしたいとします。 その場合にはClassAとClassBを継承するクラスをそれぞれ作成し 代入演算子をオーバーロードするしか方法はないのでしょうか?
それにもし継承したとしても、privateメンバはusingでアクセス権を復活させるなど、 かなりおかしな事をしなくてはいけない。
260 :
257 :2005/12/07(水) 13:44:36
friendも検討はしてみたのですが、class定義のほうに変更を加えなくては ならないため使えませんでした。 ClassAとClassBはヘッダファイルも含めてまったく変更不可という場合には やはり継承クラスを作って対処するしかありませんか・・・?
261 :
257 :2005/12/07(水) 13:52:07
すみません。補足です。 それぞれのクラス内のデータは適当な関数などを使って取り出せるので アクセス権限などは問題になりません
>>257 なぜ代入演算でなければならないのですか?
どう考えても設計ミスなので他の手段を考えましょう。
代入演算子でなくともClassA A2B(const ClassB&);のような関数を作れば良いと思うのですが。
>>263 privateメンバはどうやってアクセスするの?friendしかないでそ。
266 :
263 :2005/12/07(水) 15:11:11
そういえばAとBが逆でしたな。すまん。
267 :
257 :2005/12/07(水) 16:02:12
>>262 >>263 たしかにおっしゃるとおりだと思います。
代入演算子を使おうと思った理由は、ClassAとClassBが本質的には
同じ内容のデータを管理するからです。具体的には顧客情報です。
>>264 それぞれのクラスには取り出しようの関数と格納用の関数が備わっているので
privateメンバでも問題はありません。
このクラス設計がおかしいのは私も承知しておりますが
引き継いできたソース(変更不可)を流用せよという指示があるので
こうせざるを得ません。
C++流のエレガントな記述方法があるのではないかという思いから
書き込ませてもらいました。
こういう場合は263の方法をとるのが一番最適なのでしょうか?
>>267 >こういう場合は263の方法をとるのが一番最適なのでしょうか?
設計者とプロジェクトリーダーをぶん殴る
ClassAやClassBを継承しなくてもラッピングしたらどうか?
270 :
デフォルトの名無しさん :2005/12/07(水) 17:48:33
BCBのヘッダーファイルに class TestClass; っていう文法を見たんですが、 これってC++標準ですか? みたところ、TestClassがクラスだよとコンパイラに教えて、 ヘッダーインクルードは実装部(.cpp)にのみしてるっぽいんですが、 そういう使い方ですか?
ええ
設計ミスだよな。
AとBを保持するclassCでも作ったら?
>>270 普通に使う。
273 :
270 :2005/12/07(水) 18:29:29
サンクス
>>271-272 標準構文ですか。
「class」がキーワードなのでググルでも調べれなくて困ってますた。
でもヘッダーファイルに実体宣言するとエラーで、
使えるのはポインタ宣言だけなんですね。
C++言語文法自体がポインタ嫌いなので、
ちょっと不整合な感じもしなくも無いですね。
でも、どうせBCB/VCL使ってるとクラスのポインタ使いまくりですが。
>257 単にグローバル(名前空間)な二項演算子をオーバーロードするだけでいけるんじゃないの?
ってできないのか。初めて知った。
ログファイルから送信元IPアレスだけを別のファイルに抜き出して書き込みたいのですがどうすればいいでしょうか? ファイルの内容は 日付 to 送信先IP from 送信元IP:port です。 送信元IPだけを特定する手順を教えてくださる方いませんでしょうか?
>>273 どっちかがポインタじゃないと、コンストラクタの呼び出しが終わらないでしょw
A -> A::B -> A::B::A -> A::B::A::B -> ...
>>276 「from 」を検索して、その次の文字から「:」までの間を切り出すだけじゃないのか?
>>277 コンストラクタの呼び出しが終わらない、というか、そもそも
A の中に B のインスタンスが入り、 B の中に A のインスタンスが入る
という状況なのでクラスメンバの配置が確定しないんだな
>>273 それは前方参照と言われる。
ちなみにポインタだけでなく参照も平気。
前方宣言 (forward declaration) じゃね? 前方参照っていう言葉は聞いたことがないな
_| ̄|○ やってしもた。
284 :
277 :2005/12/07(水) 22:00:39
>>281 説明サンクス。
参照でも良いのね。
でも、クラスで参照使うとコンパイルエラー出まくりで苦手。
自分vectorの1行取得位にしか使えない。
> クラスで参照使うとコンパイルエラー出まくり んなこたぁない。
>>285 そりゃ、おまいさんの頭がエラーだらけなんでそ。
288 :
285 :2005/12/08(木) 10:41:07
初期値無しで参照型宣言するとコンパイルエラー出るお。
>>288 当たり前です。参照するものがあって始めて参照型を宣言できるわけですから。
そういうこともあるので、>252のようなことが書かれた入門講座はダメなのです。
boost::addressofですが、最初にconst volatile char &にキャスト しているようですが、何故volatileが必要なんでしょうか?
291 :
276 :2005/12/08(木) 14:56:37
>278,279さん、アドバイスありがとうございます。 検索してfromをみつけることは分かったのですが、fromから次の文字を切り取るにはどうすればいいのでしょうか?
std::stringについて質問です たまに string str; に対し str = ""; という方法で文字列をクリアしてるのを見かけるのですが、 これは string::clear() を使うより効率がいいとかなんでしょうか? また、string::reserve() で設定したサイズは string::clear()で解除されたりするんでしょうか? 以上、よろしくお願いします
>>292 前者は特に規格では規定されていないが、効率は多分clear()の
方が速いだろう。単に見やすさのために空文字列を代入していると
思われる。
後者は、非強制的な要求であり、必ずしも解除されるとは保証
されていない。reserve()で確保した領域を解除するには、
str.clear();
str.swap(str);
と二段階のステップを踏むとよい。
Effective STL 第17項より std::string().swap(str); と書けば、1ステップで、string::reserve で確保された領域を 解放できる。 また、特に string::clear せずに string::swap を適用した場合は、 ”きっちり詰められる”事は規格では保証されていない。2の累乗の 大きさとか、要するに処理系依存の領域になる。
class Base { public: virtual Foo() = 0; }; class Concrete : public Base { public: Foo() { Bar(); } }; という具合になってて Base* base = new Concrete; base->Foo(); とか Concrete c; Base& b = c; b.Foo(); とかがいけるのはわかるのだけど Base& base = Concrete; base.Foo(); みたいにまとめて書くことはできないのでしょうか? g++だとコンパイルは通らないけど、 VC++だとコンパイルが通って動いてしまうのが謎
>>296 VC++って6か?7.1か?
6なら糞だぞ。そんなコードを通すなら、安心してプログラムができない。
>>296 Base& base = Concrete;
これ通るのはまずいような....
非const参照に一時オブジェクトが束縛されている
7.1です・・・
cygwin環境とVC++と、両方でコンパイルできるように書いてますが、
他にもこりゃー間違いだろ、というコードをプログラマの意図を汲んで(?)
通してくれたことがありました
あれは何だったっけなあ・・・
>>298 そうそう
g++だと、そういうエラーメッセージが出ます
VCは8.0に期待するしかないな。最近バグ報告が多いな。 boostがよく通るので、出た当時は喜んでいたものだが。
vc7.1+boost1.32or33でboost::formatのぬるぽって出ます? こっちで出たけどよそでも出てないかなと気になる。
class Test { private: boost::function<void ()> fn; public: void Foo() { // fn = boost::bind(Foo, this); fn = boost::bind(&Test::Foo, this); } }; VC++7.1だと上のコメントアウトでもコンパイルが通るんだけど 文法的には可?不可?
>>302 補足しておくとISO/IECの5.3.1.3のNote参照。
gccでは、MFCでその形式が使われているのに対処するために
-fms-extensionsオプションをつけることでコンパイルを通せる。
どちらにしろ独自拡張(拡大解釈?)。
Lokiのシングルトンテンプレートのソースを読んでいて思ったのですが class SingletonHolder { static PtrInstanceType pInstance_; ... }; PtrInstanceType SingletonHolder::pInstance_; という感じの宣言をしておいて、 pInstance が NULL かどうかでインスタンスを作るか選択しています。 このようにグローバルスコープ?で宣言した変数は、 明示的に初期化しなくても0が入っている、とみなして良いでしょうか? gccやVCでテストした限りでは、グローバルスコープで宣言した変数は 初期化しなくても0が入っているようです また、それを前提として、グローバルスコープに下記の記述をしても良いのでしょうか b.cppでは、ptrがNULLで初期化されていることを前提にしています 明示的な代入で値を入れる場合、異なる翻訳単位では初期化順が不定になるようですが、 この場合、代入で初期化しておらず、その規則が当てはまるのかわかりません。 -- a.cpp -- void *ptr -- b.cpp -- int TestValue() { if (ptr == NULL) ptr = new TestClass(); return ptr->GetValue(); } int n = TestValue();
Cだとグローバル酢k-ぷ、staticスコープのポインタ変数は自動的にNULLに初期化される。 C++だとそれに加えて、クラスのメンバ変数がデフォルトコンストラクタで初期化されるとNULLになる。
まちがえた。 NULL と言ってはいけない理由でも?
>>308 レスサンクス
その自動で0に初期化されるタイミングは、
他のグローバルスコープの(明示的な)初期化が実行されるより前、
と考えて良いのでしょうか
NULLじゃいけないってのは相当古いコンパイラにしか通用しない罠
>>314 頼むからEffectiveC++に書かれている内容くらい理解してからレスしてください。
>>315 Effective C++ のどこ? もし25項って言うつもりなら「いけない」と「べきじゃない」を混同してない?
気持ち悪いなあNULL粘着厨は。
突っ込まれて開き直ってるようにしか見えない件 まぁどっちゃでもいいんだけど
おれはただ0をNULLと書いたら本質的にまずいケースがあったら教えてほしかっただけなんだけどなあ・・・
>>319 C++の設計と進化P291〜
コンパイラの定義によっては、まずい事がある。
大抵のC++コンパイラは、__cplusplus__マクロが定義されていると、 NULL を 0 と define してしまうようになっているから問題ない。
「大抵のコンパイラでは大丈夫」というのは、このスレでは通用しないな
こう言う時こそ規格書だな!
>>320 スマソ、その本持ってないんだ。概要だけでいいので説明頼む。
ISO/IEC 14882:2003 §18.1.4 The macro NULL is an implementation-defined C++ null pointer constant in this International Standard.180) 180) Possible definitions include 0 and 0L, but not (void*)0.
規格に準拠していないコンパイラにまで気を使いたくないものだな。
328 :
324 :2005/12/09(金) 15:30:44
>>327 サンクス。でもそれは知ってるわ。
このレベルで規格に準拠してないような処理系について考えてたらキリが無さそうなので、
もうちょっと本質的な例がほしかった。それなりに仕様に準拠してやつでもヤバイような。
>>326 そうそう。漢ならexportとかもガンガン使ってコーディングするよな。
うん
規格に準拠してても(void *) 0 が 0 とは限らないわけで。
必死に
気持ち悪いなあNULL粘着厨は。
もういいじゃん、動けば。
たのしいなあ、びっくりまうすわ
気持ち悪いなあNULL粘着厨は。
>>324 printf(fmt, 0, (char)0, (void*)0, (int*)0, (int(*)())0);
NULL粘着厨きんもーっ☆
#ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif
ヌルヌルヌメヌメ
ヌルヌルヌルポッポ
#if NULL!=0 #undef NULL #define NULL 0 #endif
>>342 include順によってはとんでもないことになりそうだな
たとえば
( ・∀・) | | ガッ
と ) | | ミノガストオモッタカ
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>341
nullptrが早く標準化すればいいのにな。
class F{ void f0(void); void f1(int); }f; boost::functionでメンバ関数のクラスポインタを束縛した関数オブジェクトが ほしいのですが、 boost::function0<void> ff0(メンバ関数ポインタ,クラスポインタ); と書けないのはなぜなのでしょうか? bind(&F::f0,&f) bind(&F::f1,&f,_1) とすればできるのですが、引数の数に応じて_1,_2,_3....としていかないと いけません。 何か手はあるのでしょうか?
>>347 >引数の数に応じて_1,_2,_3....としていかないと いけません。
それ以前に、引数の数が変わると function の型も変わります。
function0<void> f0(bind(&F::f1, &f));
function1<void, int> f1(bind(&F::f1, &f, _1));
だから、面倒くささは function のコンストラクタを
メンバ関数ポインタ等を受け取るように拡張しても結局変わらないと思います。
> boost::function0<void> ff0(メンバ関数ポインタ,クラスポインタ);
> と書けないのはなぜなのでしょうか?
この変換は boost::bind の仕事であって boost::function の仕事ではないと
boost の人たちが考えているからではないでしょうか。
349 :
347 :2005/12/10(土) 02:16:34
>>348 なるほど。
Function<void(int)>という記法にこだわる限り
コンストラクタで受け取るまで型(クラス)がわからないから
メンバ変数にできないのからああいう仕組みになってるのかも。
Class<F>::Function<void(int)>という感じでクラス情報があれば
メンバ関数ポインタとクラスポインタをFunctionに持てるんだろうけど...。
日本語では「は・げ」と発音するのが正解
ビヨーンって、ほっぺたを左右に引っ張ったら、よく伸びそうだなw
356 :
313 :2005/12/10(土) 11:18:19
NULLと0の議論で流されてしまった感があるので・・・ どうかご教授お願いします。 グローバルスコープに宣言した値型の変数は0に初期化されると教わりましたが、 この初期化タイミングはどうなるのでしょう。 -- a.cpp -- int a = 3; -- b.cpp -- int b; -- c.cpp -- int c = a; int d = b; という場合、 1. プログラムの起動時に a, b, c, d が 0 で初期化 2. a, c, d の代入による初期化が行われる (順序は不定) 3. c は 0 が入るか 3 が入るかわからない 4. d は必ず 0 が入る 5. プログラムのエントリポイントに入る という認識で合っていますでしょうか?
コンパイルエラー:c.pp 初期化値は定数でなければならない。
グローバル変数の初期化順は不定じゃなかったっけ
てか、a は 0で初期化はされないだろ。 3で初期化しているジャン。
NULL粘着厨きんもーっ☆
>356 (3.6.2) を厳密に解釈すると 1. a, b, c, d が 0 で初期化 (zero-initialization) される. 2. a が 3 で初期化される. ("static initialization" のうちの "constant expression" による初期化) 3. c, d がこの順で各々 a, b で初期化される. ("dynamic initialization".ただし実装は,この初期化をエントリポイント以降で 真に初期化が必要とされる瞬間まで遅延することが許される) になるかと思います.従って,c == 3 も保証されるかと思います.
362 :
356 :2005/12/10(土) 13:29:57
レスありがとうございます
>>361 なるほど・・・
c が a に依存すると初期化が遅延される、といった仕組みがあるのですね
-- a.cpp --
std::list<int> istack;
int push() { istack.push(1); return istack.size(); }
-- b.cpp --
int b = push();
こんな感じ (b.cpp と同様のものが複数ある) のコードがあったのですが、
MSVC だと istack のサイズは 1 => 2 => 3 => 1 => 2
gcc だと istack のサイズは -127 => -126 => -125 => 1 => 2
といった具合で、内部的な依存があるとやはりまずいようですね
真っ先に 0 での初期化が入ることが規定されているのであれば、
istack をポインタにして対処できると思います。
勉強になりました。ありがとうございました。
ああ、読み違えてました 依存を見ているのではなく、 dynamic initialization の前に static initialization があるから c == 3 は確定するのですね・・・
ある関数で、引数に与えられた文字列に応じて switch-case文で、処理の割り振りをしようと思っているのですが 無論switchには、数値か文字定数しか使えないわけでして。。。 どなたか、if文での代用無しにこれを実現する方法がありましたら教えて下さい
>>364 方法その1:std::map を使って文字列から関数ポインタまたはファンクタへ写像する。
完全ハッシュ関数でswitch-case(またはテーブル)で分岐、それぞれのcaseで一回だけif文
>>365 ,366 レスありがとうございます。
殆どが数行程度の処理の為、関数を作って飛ばさず
case文の中で処理しようと思っているので
>>366 さんのやり方で、実装に取り掛かったのですが
case hash("aaa"): でもコンパイラに怒られます。。
「error C2051: case 式は、整数型定数でなければなりません。」
予め計算したテーブルを作るという手もありますが、、、どうにかならない物でしょうか
>>367 自分で計算するのがいやならtemplateでやってしまえ
>364 標準じゃないけどLoki::Factoryを使う
>367 数行程度でも(処理に名前を付けるつもりで)関数にしてしまうのが吉。 最適化なんざコンパイラに任せるのがよろしいかと。
>>368 ,369
ええ、イヤなのでtemplateについて調べてみています。
実行時に再帰的に定数部分を計算させる?というもので
ハッシュを計算させれば達成できそうですね。
>>370 ,371
仰るとおり関数にしてしまえば、文字列と関数ポインタをまとめた
構造体を作るだけで解決できるんですけどね。
どうしてもやってみたかったという事で・・・
レス頂いてからずっと試行錯誤してましたが中々至りません。。。 とりあえずハッシュ関数は簡単なもので、 Wikipediaのハッシュ関数というページにあるC言語で書かれた8行を templateを用いてコンパイル時に計算させる関数に書き換えようとしています。 ぐぐると一番に出てきた、templateとenumを使い、コンパイル時に再帰的に 階乗を求めるやり方を参考に弄ってみていますが、 テンプレート引数には整数しか使えないとか、どうにも上手くいきません… 長々とすみませんが、案がありましたらもう一声頂ければと思います。
ソースを晒した方が速くないか?
いや、間違いなく、caseのラベルに変数(または関数)を使いたいという話だろ。 そして、それが出来ないから、 完全ハッシュ関数を作って、その値をラベルに使えということだと思うが それを何とかマジックナンバーではなくしたいんだろう。 俺はそんな無茶しないで 素直にmapなりを使うべきだと思うが。
うーん、、1からわからずに書いた動かないソースではどうしようも無いと思うので、
どのようなものを求めてるかをまとめます。
文字列(型は問いません)を受け取り、そのハッシュを作成し整数定数型で返す関数です。
"コンパイル時"に定数として埋め込まれる事を想定していることがポイントです。
できた関数は、enum { aaa = hash("aaa"), bbb = hash("bbb") } のような感じで使えることが理想なのですが…
ここまで書いたのですが、言いたい事は
>>376 さんのが全てです
無茶なのは承知の上ですが、ここまで来ると諦めが付かなくて。。
>>376 そうしたくないケースもあるんだよね.速度気にする場合とか.
まあ,そういう時は string で渡すなとも思うけど・・・.
非標準だがhash_mapみたいなものはだめか?
>>379 混同するなって。
ハッシュ云々はコンパイル時にcaseの条件を定数にする話だよ。
まあまあ。 mapなりhashなりを使って文字列->定数への表を作っておいて その定数部分をcaseのラベルにするという意味だろ。
switchでも文字列使えるよ #include <stdio.h> main() { char x[] = "bbbb"; switch(*((unsigned int*)x)) { case 'aaaa': printf("a*4"); break; case 'bbbb': printf("b*4"); break; case 'cccc': printf("c*4"); break; }
>>382 それはたまたまxがunsigned intのサイズと同じだったからでしょ?
「文字列リテラルの置かれている先頭アドレス」と一致しているか判定しても・・・
バカはD言語でも使っとけ
>>384 は初心者未満
#include <stdio.h>
#include <string.h>
main()
{
char x[256] = "";
strcat(x, "aa");
strcat(x, "a");
strcat(x, "a");
switch(*((unsigned int*)x))
{
case 'aaaa':
printf("a*4");
break;
case 'bbbb':
printf("b*4");
break;
case 'cccc':
printf("c*4");
break;
}
}
'abcd'がどういう扱いになるか、あるいはどういう数値になるかは 処理系依存なわけだが。
違った。 'abcd'だけじゃなくて、'ab'がそもそも処理系依存だ。 もちろん'あ'とL'あ'も含めて。
それ以前の問題
あ、つまり、sizeof(int)が4だとしても *(int *)"abcd" == 'abcd' が成り立つとは限らないと言うこと。 もちろん、'abcd'が使われている時点で警告が出る処理系もある。
つまる所、処理系依存な実装方法はやめろと
>>389 えええ
L'あ'は平気だと信じてきたのに。
'abcd' って gcc 拡張じゃなかったっけ?文字コードごにょごにょやった結果になった気がするんだけど。
>374 そもそも文字列を定数式としてコンパイル時に評価すること自体できないんだから、 どうあがいても無理じゃね。
違うよ
>>395 それをやるトリックを教えれって話でしょ
>>395 文字列自体を定数式にできないのなら、それをハッシュ数値にすればどうかという試みです。
templateでも何でもいいんですが、
コンパイル時にそのハッシュ値を計算させる事ができないものかと…
なあ、なんでswitch文で文字列つかえないの? マジでC++って糞だな
なんかそういう事するプリプロ自作すれば?
「文字列リテラルの置かれている先頭アドレス」 とカギカッコつきでディレクションしたにもかかわらず バカ、低脳、初心者未満と罵られて超カワイソ・・・
>>399 じゃあswitch文で文字列つかえる言語でコード吐いてみな。
if-elseif・・・のチェインに展開されてるから。
>398 定数式でないものから定数式を作ることが無理だって解らない?
>>402 そういう問題じゃないんだけど。
バカ?
>402 switch文なんか使うなよ。
>>402 とりあえずD言語が文字列のswitchが出来るから試してみた(gdc -S test.d)。
吐き出したアセンブリを見ると2分探索で目的の位置を探していて、
if elseのチェインなんて非効率な実装じゃなかったです。
template< char c0 > struct static_hash1 { static const unsigned int value = (0*137+c0)%1987; }; template< char c0, char c1 > struct static_hash2 { static const unsigned int value = ((0*137+c0)*137+c1)%1987; }; template< char c0, char c1, char c2 > struct static_hash3 { static const unsigned int value = (((0*134+c0)*137+c1)*137+c2)%1987; }; template< char c0, char c1 = 0, char c2 = 0 > struct static_hash : static_hash3<c0,c1,c2> { }; template< char c0 > struct static_hash<c0> : static_hash1<c0> { }; template< char c0, char c1 > struct static_hash<c0,c1> : static_hash2<c0,c1> { }; int main() { char const *s = "ef"; unsigned int v = dynamic_hash(s); switch (v) { case static_hash<'a','b','c'>::value: std::cout << "abc" << std::endl; break; case static_hash<'e','f'>::value: std::cout << "ef" << std::endl; break; default: std::cout << "default" << std::endl; } } めんどいと思ったらBOOST MPL辺りを検索
個別の文字列定数を適当なハッシュ関数処理するテンプレートを それぞれのcase文に埋め込めたとしても 完全ハッシュにするんだったら全文字列リテラルを受け取って その何番目って感じでテンプレート引数つけて 毎回全部再実行するようなものになるんだろうな。 面倒すぎ
>>402 C#(Microsoft(R) Visual C# .NET Compiler version 7.10.6001.4)でのテスト結果
選択肢が1〜7の場合:if〜else〜に展開
選択肢が8〜の場合:Hashtableを作成
>>407 だから何だって言いたいんだろう・・・・スレ違いなんだが。
>>411 まぁ、C++で同様の仕事を実現するのにどうすべきか考える参考には
なるんじゃない?
話の流れ嫁
>>413 いいえ。
>>377 >ここまで来ると諦めが付かなくて。。
こやつが諦めれば済む話です。
つか、
static const char* tbl[] = {
"aaa", // =0
"bbb", // =1
"ccc", // =2
};
int idx
for (idx=0; idx<sizeof tbl / sizeof *tbl; idx++)
if (strcmp(hoge, tbl[i]) == 0)
break;
switch (idx) {
case 0:
case 1:
case 2:
else
}
もうこれでいいよ。
つーか効率を犠牲にしてそこまでswitch文にこだわる理由が理解できん むかし川で溺れてるところをswitch文に助けられたとかそんなのか?
テクニカルな興味でしょ
>>416 まともに動く static hash なら効率は犠牲どころか向上すると思うけど
>>417 そういうこだわりが昔俺もあった。
で、結局、非効率極まりない処理をあれこれシコシコ弄り倒して
悩んでたって事に気づいた時は愕然としたものだよ
すぐ解答を求める姿勢より過程だよ
「下手の考え休むに似たり」、との見極めが難しい(´・ω・) ってか、「下手な考え〜」だと思ってたよ( ゚∀゚)'`,、'`,、
>>419 そういうことに気付くのって結構重要な経験だと思うんだよね。
あれこれ試行錯誤することは、たとえ結果が失敗だとしても何もしないよりはずっといいよ。
>>416 表記上の問題じゃない? 効率が少々犠牲になっても、表記がキレイになって
可読性・メンテナンス性が上がるなら選択肢としてありだと思うし。
あと、やっぱり抽象的なレベルで考えた時に switch な分岐を
コードに落とすときに if 列にせにゃならんってのはどうもすっきりせん。
初歩的な質問すみません。 ハードディスクから読み込んだファイルに書いてある文字列を 配列に格納する方法がわかりません。 どなたかhelp me...
ファイルポインタでいいやん。
ファイルポインタやったときの授業でてなかった… ファイルポインタの使い方がんばって勉強してみます!!
伸びないなこいつは
MCIを制御するのに(それとクラスの勉強) class MCIControl { private: char mciStrBuffer[1024]; public: char filename[256]; MCIERROR errorcode; int open() { wsprintf(mciStrBuffer,"open \"%s\" alias test",filename); errorcode = mciSendString(mciStrBuffer,NULL,0,NULL); return 0; } int play() { errorcode = mciSendString("play test",NULL,0,NULL); return 0; } int close() { errorcode = mciSendString("close test",NULL,0,NULL); return 0; } }; のようなクラスを作って、main関数より位置的に上に書いたときはいい(うまく動作した)んだが、 別ファイルにすると当然ながらクラスの存在を認識できない。 変数をexternするように、別ファイルのクラスを認識させるにはどうしたらいいの?
普通にヘッダーに書いてインクルードじゃ駄目なの
429がどういう勉強してるのか気になる
つ[必殺コピペ] 誰を殺すかは言わずもがな
なんで、関数の戻り値をintにしているのに 必ず0を返すんだ・・・ エラーコードを返さないでどうするw
>>432 おいおい、マジでその提案はやめてくれよ。
三年ほど前に、とりあえずコピペし、include順などで名前が衝突したら
関数名の末尾に1や2や_newをつけて解決すればいいと豪語した奴がいる。
もちろん、効率(インライン展開の促進など)とは関係なく、な。
この考えを、Cどころかプログラムを知らないボスが承認してしまい
今みんなそのツケを払わされてる
IHTMLDocument IHTMLDocument2 IHTMLDocument3 ‥‥‥ なんて名前付けてるOSがある件について⊂(。Д。⊂⌒`つ
とりあえず拡張したら末尾にEx付けるのは基本だな。
クラスのヘッダの作り方がわからん…
>>429 のソースをmcictrl.cppに移動して、
mcictrl.hにclass MCIControl;とだけ書いてmain.cppからインクルードしても変化なかった。
もしかして
private:
char mciStrBuffer[1024];
public:
char filename[256];
MCIERROR errorcode;
int open();
int play();
int close();
の部分だけmcictrl.hに移動して、mcictrl.cppの中に、
int MCIControl::open()
{
wsprintf(mciStrBuffer,"open \"%s\" alias test",filename);
errorcode = mciSendString(mciStrBuffer,NULL,0,NULL);
return 0;
}
というようにすればいいのだろうか?
COMインターフェースの場合むしろそれ普通じゃね?
439 :
429 :2005/12/13(火) 20:41:10
さっき
>>437 に書いた方法をやってみたらうまくいったのでそれだけ報告しておく。
CreateFileExTurboDashPlus2
ストUじゃないんだから
静かだ
E・∇・ヨノシ <444ゲット♫
素朴な疑問ですが、 C++で書かれた一番有名なソフトウェアってなんですか? Linux?
Windows
へー。 有名なゲーム部門?も知りたいお。
だいたいC++
>>449 こんなページあるんすか。すげー。
ちなみにLinuxは書いてないけど、どうなの?
unixのシステムプログラムはだいたいCじゃないかな。 手元のLinux-2.4.27のソースコードは、ぱっと見た感じC(≠C++)。
ぱっと見じゃなくてCとアセンブラ
OSのカーネルからC++を使おうってのはMonaOSがやってたな
組み込みもC++が多いと聞いたことがある。
シリアライズの実装についてわかりやすく説明したサイトありませんか? socketでデータ通信したいのですが、構造体をパックして送る方法は柔軟性が無いので シリアライズ化したいと思っています。
シリアライズするよりも、テキスト化したほうが安全な希ガス。 つーか、シリアライズって汎用性あったっけ?
データのフォーマットがもう決まってしまってるので テキスト化できないのです。 私も、テキスト化して、できればXMLか何かで送りたかったのですが、 所詮、プログラマなのでSEに逆らえません。
>>457 MIMEエンコードで。つーか、SEは転送内容まで設計していないの?
#だとしたら無能だ。
あ、余り続くとスレ違いなので適当に。
そもそもバイナリ転送で設計されているならバッファに構造体からmemcpy()、
何も設計されてないならMIMEなりヘキサダンプなりでテキスト化が無難かと。
#ネットワークプログラミングスレ向きかな? 私は見てないのだけど。
>>458 回答ありがとうございます
ちょっとそこら辺のキーワードで調べてみます。
>>458 シリアライズとネットワークは直接関係は無いでしょ。
ファイルに書いて読んで同じ意味のオブジェクトが出来ればいいんだし、
後はそれを送受信すればいいだけ。
memcpy()ってポインタはどうすんのさ?
>>460 >ファイルに書いて読んで同じ意味のオブジェクトが出来ればいいんだし
シリアライズに汎用性があるならそれでもいいかと。
>memcpy()ってポインタはどうすんのさ?
んなもん、適切にポイント先をコピーすればいいべさ。
要は、オブジェクトの型情報までは送る必要がないでしょ、と。
ちょっと調べてみましたが、MIMEエンコードって関係無いような気がするんですが。 MIMEってバイナリのテキスト化ですよね? データの構造が決まっていて、構造体をパックして送っていたのを、 シリアライズ化し、送りたいのですが。 データの種類が増えるといちいち構造体を何百個も作るわけには いかないのでシリアライズ化したいのです。
>>463 ありがとうございます!大変わかりやすいです。
>>455 boost::serializationはいいかも
466 :
デフォルトの名無しさん :2005/12/21(水) 00:03:31
iostream で、一度セットしたらずっと有効なフィールド幅設定マニピュレータはありませんか。 下のようにしても、最初の出力だけが5幅で、2つ目からは元に戻ってしまうのですが。 #include <iostream> #include <iomanip> using namespace std; int main(){ cout << hex << setfill('0') << setw(5); //cout.width(5); // これでもだめ。 cout << 10 << endl; cout << 20 << endl; cout << 30 << endl; }
>>466 widthだけは元に戻るのよん。諦めましょう。
↓そこでboost云々
469 :
デフォルトの名無しさん :2005/12/21(水) 06:05:51
http://www.open-std.org/jtc1/sc22/wg21/ News 2005-12-19: The 2005-12 mailing is available (1600 kb tar.gz, .zip 1600 kb) individual papers
News 2005-12-17: The C++ Standard Library Issues List (Revision 40) is available (.tar.gz)
News 2005-12-17: C++ Standard Core Language Issues List (Revision 39) is available, also committee version
うげっ、std::string<>もメモリ上の連続性を仮定するようになるのかよ。
std::string<>
std::string<int> hoge = "ひゃっほい";
std::basic_string<>だった…
string x(50); strcpy(&x[0], "あいうえお"); strcat(&x[0], "かきくけこ");
残念ながらそれは駄目だ std::vector<char> ならOKなんだけどな
流れからするとそうだけど 一発で変換できるから一応 std::string s(vect.begin(), vect.end())
478 :
デフォルトの名無しさん :2005/12/22(木) 18:13:57
class hg{ public: void foo(void); }; void main(void){ hg laser[10]; }; とかやると、メンバ関数foo()は10個、メモリに展開されるの?
されない。 非仮想メンバ関数は、普通、this引数を余計に持つだけの通常の関数としてコンパイルされる。
480 :
478 :2005/12/22(木) 18:17:30
教えてください。 私はVB6とVB.net2003の経験しかありません。 C言語関連を学ぶには、Cから初めてC++に移行すべきでしょうか? いきなりC++は無理ですか? また、もうひとつ教えてほしいのですが、 Cと比べてC++は、どのような恩恵があるのですか? 私の知人からはCを薦められています。 たしかにCは基礎知識として必要だと思います。 C++の利点とか開発のしやすさとか、ありますか?
>>481 プログラムとしての本質を学びたいならC++やると良いよ。面白い。
VBはGUIアプリに関しては楽といえば楽だし、それが仕事なら無理して覚える事も無いと思います。
開発で覚える必要があるなら、早いうちに覚えた方が楽ですね。
ちなみに、C・・・サブルーチンを関数としてまとめる事ができる、ポインタで変数の値を直接書き換えられる
C++・・・Cをオブジェクト指向にしたようなもの
大雑把杉ですが自分はこういう認識です。
483 :
481 :2005/12/22(木) 19:32:27
>>492 ご回答感謝します。
C++とはオブジェクト指向の面がプラス点なのですね。
ありがとうございます。
484 :
481 :2005/12/22(木) 19:39:59
>>483 C++のCに対するメリット。
・型の拘束が強い。
・クラスを作れる。
・テンプレートを使える。
・演算子オーバーロードができる。
って書いてもよく判らんだろうから具体的に言うと、
間違いを指摘してくれるチャンスが増えてオブジェクト指向プログラミングができて
同じようなことを何度も書く(或いはコピペを繰り返す)ことを避けたプログラミングができる。
まぁ、やってみろ。いいものだ。
>>481 むしろいきなりC++から初めてあとからCの制限の中でやってみることを
お勧め。色々工夫するからCの範囲の中でもかなり工夫する能力が上がる。
487 :
486 :2005/12/22(木) 21:00:29
訂正:初めて→始めて
488 :
デフォルトの名無しさん :2005/12/22(木) 23:48:12
入門書を読んでいて、const をメンバ関数に付けると const でクラス変数を宣言しても呼ぶことが出来るようになる事を知りました。 もしかして、ゲッターメソッドにconstを付けるのは常識だったりします? また、データリードしか行わないメンバ関数には constをなるべく付けた方が良いのでしょうか?
そうです
struct A { /* 〜 */ }; struct B { /* 〜 */ }; struct C { A func() { B b; return a_; } A a_; }; C::funcで、bのデストラクタはa_の戻り値コピーの後に行われました。 この順番は保証されているのでしょうか?
491 :
488 :2005/12/22(木) 23:58:25
>>489 そうですか ありがとうございます
作ったクラス書き換えなきゃ orz
492 :
デフォルトの名無しさん :2005/12/23(金) 00:46:32
enum HOGE { A, B, C, D, E }; とした時に、HOGEに含まれる列挙子の数(=5)を HOGEを後で変更しても支障が無いように求める事はできますか?
enum HOGE { A, B, C, D, E, END_OF_NUM };
END_OF_HOGE だった。 まぁ、なんでもいいんだけど。
あああ、なるほど。 ありがとうございました。
[hoge.csv] A, B, C, D=100, E=200, enum HOGE { #include "hoge.csv" }; const int HOGE_ARRAY[] = { #include "hoge.csv" }; const int HOGE_NUM = sizeof(HOGE_ARRAY)/sizeof(HOGE_ARRAY[0]); ...自分で書いてても、ちょっとどうかと思った。
>>490 イエス。スコープ抜けたあとに解体処理が走る。
あと、structをclassの代わりに使うのはお勧めしない
(struct使うと、明示的にprivate指定しないと変数も関数も
フルオープンなので)。
>>497 ありがとう。冷静に考えたらそうですよね。
>structをclassの代わりに使うのはお勧めしない
カキコするときpublic:を書くのが面倒くさくてstructにしました。
その辺は心得ています。
ModernC++を読みこなすために読んでおいたほうがいい テンプレートメタプログラミングを扱った本はないでしょうか?
C++ Templates
訳本出すべきだよなーあれ
そういえば、暇つぶしに1/3訳したところでほったらかしてあるなあ……
C++ Template Metaprogramming Concepts、Tools、and Techniques from Boost and Beyond とか。これも英文だけど。中身はBoost MPLの解説だし。
504 :
499 :2005/12/24(土) 11:45:37
英文orz 中学生程度の英語力しかない自分が読んで理解できるかな・・・
リファレンスやマニュアルなら余裕だが教本だとキツイ っていう俺は低学歴DQNなんだろうか
おいらはリファレンスやマニュアルより簡単なサンプルの方が嬉しかったりする
それは言えている。 英会話でのボディーランゲージに当たるものとしてソースコードがあるという感じ。
スマン質問 const CExtControlBar * CExtMiniDockFrameWnd::GetControlBarExt() const 関数の両方にconstがついてるけども、 左側は返り値に対してCONST。 だけども、右側のconstはどういう意味なの?
509 :
デフォルトの名無しさん :2005/12/25(日) 01:15:55
あげ
const CExtMiniDockFrameWnd hoge; hoge.GetControlBarExt(); が呼び出せるようになる。 右のconstがないとconstなオブジェクトに対して呼び出せない。
511 :
508 :2005/12/25(日) 01:32:40
>>510 ありがとうございます。
constなオブジェクトに対しては、通常のメンバ関数は呼び出せないんですね。
呼び出したい場合は、右にconstをつけると。
結果的にはそうだけど、厳密には自分自身の状態を 書き換えないという意味では? そのためconstオブジェクトが呼び出せる
512の通り 右にconstをつけたメンバ関数内でメンバ変数を変更してたりすると コンパイルエラーが出る
そこでmutableですよ
>>514 エラーがでるたび mutable か。カオスだな。
mutable は const HOGE& operatorXXX constな関数内で使いまくってます。 HOGE(BUF) << A << B << C << D << E; といった感じの、阿呆げな作りにできるのでニッチな人には便利なコです。
goto見たいな物だな。厄介者だけど便利。
>>516 const_cast 一発で済ませたほうがよくないか?
const_castを元からconstのオブジェクトに適用したら結果は未定義だったような。
その通り。 だからmutableが使えない環境で仕方なく使う。fake thisとか
まぁあんまり使うくらいなら設計見直せって誰かがそのうち言うと思うんで俺が言う
惚れた
質問です。 ある機能を薄くラップしたAクラスがあり、その機能の一部を制限し、かつ独自の機能を 追加したBクラスを作成したいとします。このときの実装方法として適切なものはどういうものでしょうか? 特に、制限するところで困ってます(´・ω・`) プラン1. class B : public A; 問題点:Aの機能をフルに使えてしまう(制限できない)。 Aに仮想関数xがあったとして、それを制限するために継承したとしてもb.A::x()とすれば呼び出し可能。 まぁコーディング規約としてそういう呼び出し方さえ禁止すれば問題ないんだけど。 なによりも、使用する側に回ったときに、Bのすべての機能についてAからどこが改変されたかを Aの機能とは別に調べないといけない。 プラン2. class B{A a;}として、使いたい機能はB::x(){a.x();}としてひとつずつ追加していく。 問題点?:has-a関係って何か間違ってるような気が・・・。 プラン3. class B : private A;で、使いたい機能だけusing A::xする。プラン2よりは自然な気がする。 問題点:特に無いような気がするけど、ホントに今後困らないかよく分からない。 いいところ:usingしたメソッドはAのものであることが保障されてるのでBの使用者はAのメソッドに 関する知識がそのまま安心して使える。 今のところプラン3で実装しているんですが、なんか根本的に違うような気もしてます。 こういうときに定石としてよく使う方法とかパターンってありますか?よろしくお願いします。
大事なのは、ライブラリとして一貫したスタイルで統一されたI/Fだと思う。 それさえ守られていれば、あたは少しのドキュメントでライブラリの使い方に直感を働かせることができる。
class B : public A pulic if_hoge { ・・・ } として、if_hoge 経由でアクセスさせるとか。
>>523 Bクラスを、「Aクラスによって実装されるクラス」と捉えるならば、
Exceptional C++ 項目22のガイドラインに従って
継承を使う必要がある場合(BがAのprotectedメンバにアクセスする場合や、
仮想関数をオーバーライドする必要がある場合)を除いて
プラン2の包括を使うべき
527 :
523 :2005/12/25(日) 20:06:36
>>524-526 回答どうもありがとうございます。
526さんのレスを参考にしつつ、EffectiveC++の6章あたりを読んでたのですが、
ラッパクラスを使用して似ているけど別のクラスを作ろうとしていると解釈すれば、
"has-a"か"実装の手段とする"のどちらかの手法をとるようにすべきだと結論付けました。
で、よく考えたら一部機能を実装するためには継承する必要があるのでプラン2は駄目でした。
そんなわけで問題が見つかるまではこのまま3で行くことにしました。
どうもありがとうございました。
>一部機能を実装するためには継承する必要がある これに何か引っかかりを感じるのって俺だけ? まー詳細分からないからなんとも言えないけれど
まぁ、俺も3だと思うよ。
>>528 同意。一部機能を実装するだけでは
継承はふさわしくないな。has-aで十分。
template< typename A> class B{ const &A a; B(const &A x) : a(x){} void x(){a.x();} }; 困ったらとりあえずこんな感じにしてるけどな、 使わない実装はコンパイル時に弾いてくれるかもしれないし。
532 :
デフォルトの名無しさん :2005/12/26(月) 22:26:47
cppllの削除依頼者って誰? ま、tietewの過去ログ公開はいつかトラブると思ってたけど。 FreeMLで伏せ字にしているメールアドレスまで公開してるんだもんな。
533 :
デフォルトの名無しさん :2005/12/26(月) 22:33:31
>>532 誰なんだろうなぁ。
しかしメーリングリストに投稿したのに、ログを削除してくれとは・・・
過去ログから削除してくれないかなあ。 そしたら誰だかわかるのに(w
537 :
デフォルトの名無しさん :2005/12/27(火) 00:11:04
>>532 すげー気になる。
どの投稿NOが削除されたか分かるやついない?
過去ログは全部あるから、教えてくれたら晒してもいいぜ
538 :
道化師 :2005/12/27(火) 00:33:28
>>537 今回の削除依頼人の行動はとても褒められたもんじゃありませんが、
晒すのは勘弁してあげてくれませんでしょうか?m(_ _)m
539 :
デフォルトの名無しさん :2005/12/27(火) 00:34:41
>>537 なんせこれだろ? もうバカかと!アホかと!
-----------------------------------------------
通知書
1. 貴殿管理下のメーリングリスト掲示板”C++:language&libraries”(あて先
[email protected] )への私の参加においては、「FreeMLユーザー規約
(
http://www.freeml.com/help/sinkiyaku.html )」(以下ユーザー規約)が、
メーリングリストの運営会社(GMOメディア株式会社、以下運営会社)との
唯一の合意文書です。
2. 貴殿ご指摘の"一般に公開"については、これが"ML情報"欄
http://www.freeml.com/ctrl/html/MLInfoForm/[email protected] の"保存メッセージ: 一般に公開"を示すとの意味であれば、上記表示は
運営会社の表示であり、著作権に関する許諾を意味するものではござい
ません。
3. 著作物の複製権を貴殿に許諾した事実はございません。著作物の複製
権に関しては、ユーザー規約第9条(著作権等) 第2項に定める通りです。
4. 従って、貴殿から第三者への複製権許諾が事実ならば、著作権法に基
づく財産権の侵害にあたる旨を本日警告するものです。
5. 本件に関する違法状態の回復が速やかにはかられない場合、ユーザー
規約第14条(準拠法および管轄裁判所)にもとづく法的措置をとる旨、
予めご承知おき下さい。
6. 本状の受領について確認する旨をご連絡ください。確認連絡がない
場合には別途内容証明郵便にて本内容を貴殿に伝達致します。
平成17年12月26日
541 :
デフォルトの名無しさん :2005/12/27(火) 00:36:54
>>540 うん、わかってる。でも出所はひとつでも少ないに越したことはないと思うんで。
ここから他に拡散させなければ良いだけの話だと。 流石にcppllとかしたらばとかに転載したらアレだとは思うが。
でもさぁ・・他のMLならまだしも、 IT系昔から関わってる(と思われる)人たちのMLでこんなこと起きるんだね〜 信じられんよ 漏れは
質問です。 複素数の配列を動的に作りたいのですが、 complexクラスを用いて作る方法って無いのでしょうか…? std::complex<double> *cstr; for(i=0;i<10;i++){ cstr[i] = new std::complex<double>; } 上のようにするとstd::complex*に二項演算は定義さていない との旨のエラーが出てしまい上手くいきません。 詳しい方、何卒宜しくお願いします。
>>545 多分君がしたいのはこう
std::complex<double> *cstr = new std::complex<double>[10];
cstr[i]; は complexのインスタンスで new が返すのはポインタだよな。 二項演算子以前にやってることがおかしい。
>>545 そのコードはcstr[i]ってどこにアクセスにいってるんだ…
vectorつかえば?
std::vector<std::complex<double> > cstr;
>>549 過去に二次元配列ばかり作ってしばらくプログラムつくってなかったので
エラーが出て悩んでしまったのです。失礼しました。
std::vector<std::complex<double> > cstr(10); 先頭要素のポインタは&cstr[0] std:vectorの要素はメモリ上で連続してることが保障されています。 関数で一時的に使うバッファとか確保するときにはvector使うと便利 newだと、制御が帰る場所ごとにdelete呼ばないといけないけれど、 vectorでauto変数にしてしまえば関数抜けるときに開放してくれるので。
>>551 二次元配列だろうが何だろうが
>>545 みたいに
確保してないアドレスにアクセスするのはおかしいですよ?
>>537 削除された投稿って1個なの?
486-496がなくなってるみたいだけど・・
555 :
252 :2005/12/27(火) 01:08:38
>>538 手遅れだと思う。
こうゆうことがあると必ず複数の人が削除してくれと頼んでこられると困るんだよね。
556 :
επιστημη :2005/12/27(火) 01:10:37
επιστημη@cppll管理人です。 僕の不行き届きで無様をお見せすることになりました。 無用なトラブルは極力避けたいと考えます。 これ以上の詮索をなさらぬよう、伏してお願い申し上げます。
>>554 ちょっ・・おま・・
消されてもgoogleキャッシュとかで見えちゃうんだよ!
誰だかわかっちゃったじゃねぇか!
そうだね。もうやめようか。
559 :
επιστημη :2005/12/27(火) 01:18:07
# 火に油を注ぐのは避けたいのですが追記 今回の削除要求は投稿者のmail-adr.が、というわけではなく、 投稿された本文中に個人情報がふくまれているから、という理由でした。 tietewさんとこのログ表示にmail-adr.が含まれていることが直接の 問題ではなかった旨、添えさせてください。 事を荒立てるのは極力避けたいと思っています。 ご理解を賜りたく。
>>554 そうなの
FreeMLと過去ログ両方ないのが252だったので252だと思ってたよ。
削除したのも1つのようだったし。
>>560 252は元々無いよ。
webarchive とか google cache とかどうするつもりなんだろね>投稿者
επιστημηさん、次のカキコからは他のみんなと同じようにメール欄に sage って入れて。 そうしないと書き込みの度に、このスレッドがスレッド一覧でトップに来るから。
>>562 あ、余計に目立たせてしまいましたか。
2chは初めてなもので。失礼しました。
っていうかそんな昔の投稿に今更何いってやがんだって感じだよな? 今までずっと公開されて来てるってのに。 ご丁寧にシグネチャに住所とかまで書いてさぁ〜
>>565 会社の宣伝をしたかったんじゃないか。
その後世の中が物騒になったので消してくれと。
こうして悪名を振りまくわけですね
ぶっそうになったのは、世の中ではなく高圧的な態度で法律持ち出してくる ヤツの方だ、と思ったり思わなかったり。
こいつの名前でぐぐると、vectorとかからこいつの作ったFreewareが 引っかかるけど、ちゃんと作者と連絡先が書いてあるんだよなぁ・・ なんでcppllに対してこんな態度とってんのこいつ? しかも会社には自分の写真まで載せてるしさぁ〜。わけわかんね。 何が気に入らなかったんだ?
>559 もう多分手遅れでしょう。 あなたの削除の行動は浅慮だったとは思いますけれど、 過去ログの資産としての価値を認識し、削除の伺いを公に問う行動は きちんと筋が通っているし、削除も迅速に(笑)対応しただけの話。 後はそれが晒されようがどうしようがあなたの管理責任の範疇外でしょう。 正直、後は野となれ山となれ。俺は知〜らないっと。
今回の件とは関係なく重複投稿や投稿先を間違えた投稿なんかも削除されてるから勘違いせんようにね。
>>570 > あなたの削除の行動は浅慮だったとは思いますけれど、
はい、いささか性急に過ぎたかと反省しています。
「いついつまでに削除せんと出るとこ出るぞ」と
先方からの通告を受けてからでも遅くはなかったのかも知れません。
「依頼に応じ、速やかに削除しました」と言い訳も立ちますけれど。
>>573 まぁ、削除依頼主の期待に応えてあげただけなんだから、あんま気ぃを落とすなよw
たとえ個人情報でも、Publicに公開した情報は個人情報保護の対象にはならないんだけど・・ こいつの場合他(会社のWebSiteやvectorなど)のPublicな場所に<自分から>公開しているので、 たとえcppllでその情報が公開されても、警告を受ける筋合いはないんだが・・
>>575 それってここに晒されても無問題ってことでFA?
>>577 C++相談室の内容じゃないぞ、それは
ところで、聞いてるとその方は会社を持ってたり、
フリーソフト作ったり結構C++の技術力がありそうですね?
技術的な参考にしたいので、その方の作ったフリーソフトを
紹介してもらえませんか?
>>579 すんません、せめて"内々"にお願いします。
いやホント、勘弁してください。 _o/L
>>579 うむ。その質問は That's make sense.
無問題ですな。誰か教えたったり。
おまえら勢ぞろいで板違いだな
おまえら勢ぞろいで意地悪だなw
>>580 なんにしても cppll のログはお蔵入り、次に ML を建てるときには
入会申請時に「投稿したメールは公開されます」と明記して、承諾
してもらう方向ですわな。
早めに引っ越し先が見つかることを期待しとります。
おまえら勢ぞろいで脳タリンだなww
>580 で、規約見直しはしたの? CCの帰属 - 非営利 - 同一条件許諾 2.0 日本に同意させてから 投稿させるようにしたら?
>>539 こんなん送られてきたらそりゃ、ビビッて相手の言う通りに削除するわなw
彼らを一掃する標準関数を教えてください。
>>588 残念ながら非標準だが
int deleteKorean(Person *target);
persons.erase(std::remove_if(persons.begin(), persons.end(), _1 == any_of("厨房"));
#include <kimuchi.h>
>>591 そのヘッダを入れたプロジェクトは、必ず失敗します。法則の発動。
漏れのいない間に祭りがw
痛い人って、 「横浜市緑区」 の人かい?
VCMLな方々はcppllにいらっしゃったのですか? 今からでも入会させてくださいませ
逮捕してどうする
2chの「削除依頼は公開」ってのはいいよねぇ
で、ここは何のスレだっけ
Hoge* create_hoge() { listHoge.push_back( Hoge() ); //listHogeはHoge型リスト Hoge* created_hoge = &(listHoge.back()); sort(); //内部ではswap等を使ってコムソートしてます return created_hoge; } 今がチャンス。リストにHogeを追加し、追加したHogeへのポインタを返す関数を作りたいのですが、 上のだとsortした時に、created_hogeの内容が変わっちまって悩んでます。 なにか上手い手はないでしょうか。
>>604 × std::sort
○ list::sort
自分も過去ログのメアドは非公開にしてほしいな。 こんなご時世(spam他)なのにいつまでも公開したままなのは 申し訳ないが過去ログサイト管理人の怠慢としか思えないですよ。
607 :
デフォルトの名無しさん :2005/12/27(火) 23:22:48
>今がチャンス ここの意味がわからないんだがw
>>563 >
>>562 >
> あ、余計に目立たせてしまいましたか。
> 2chは初めてなもので。失礼しました。
>
ありぁ、このスレで答えてんのは全部επιστημηさんだとずっと思ってたよw
クラス内のメンバ関数で、_beginthreadを使いスレッドを作ろうとしています。 同じクラス内のメンバ関数を呼ぶにはどう書けば良いのか、教えて欲しいです。 普通に呼び出そうとしても、ポインタを取ってきてもだめ・・・
>>609 class Hoge {
static void fugo(void* hoge) {
Hoge* self = hoge;
self
Hoge hoge;
_beginthread(Hoge::fugo, hoge)
途中で送ってしまった。。。orz class Hoge { static void fugo(void* hoge) { Hoge* self = hoge; self->func() } Hoge hoge; _beginthread(Hoge::fugo, &hoge); やりようはいくらでもある。
>>612 ありがとうございます。
見せて頂いたのはクラス外から呼び出した、スレッドのメンバ関数"の中"から
別のメンバ関数を呼ぶというコードだと思いますが、
class Hoge {
void fugo(void* p) {}
void hoge() { _beginthread(Hoge::fugo, 0, 0); }
};
このようにクラスのメンバ関数から、
別のメンバ関数を_beginthreadに使う方法がありましたらお願いしたいです。
上記だと、void (void *)からvoid(__cdecl *)(void*)に変換できません、と。。
>>608 奴は逆にこのスレでは質問する立場になるだろうな。
正直なところ、このスレのほうが cppll よりも話題のレベル、
反応速度、最近では S/N 比までが優れていると思う。
えっと、まとめフラッシュまだ?
てーか最近cppllの過疎化が著しい気がする。 なんか策ない? >えぴの人とか道化の人とか
>>617 いい加減他所でやれって。
知育発達不全なのか?
知育発達?
テンプレートクラスの定義のほとんどは同じで 一つのメンバ関数の定義だけを特殊化したいんですが、どうしたらいいんでしょうか?
>>621 template<typename T>
struct a
{...}//ここに共通の機能
template<typename T>
struct b : a
{...};//bに差分の機能
みたいに書いてbを特殊化させるとか
623 :
622 :2005/12/28(水) 19:50:55
×struct b : a ○struct b : a<T>
>>622 やっぱそういう風にするしかないんですかね。ありがとうございます。
普通に一つづつの関数について特殊化できてもいい気がするんですけどね。
やっぱり、共通の機能のところで差分の機能を使いたいので aとbを逆にした方がいいかもしれないです。
>>621 定義を特殊化するのではなくて、
実装を特殊化するという方法なのでやりたいこととは違うかもしれんが。
#include<stdio.h>
template<typename T>struct A{void foo();};
template<typename T>
void A<T>::foo(){printf("foo\n");}
void A<int>::foo(){printf("int foo\n");}
int main(){
A<int*> c;
A<int> d;
c.foo();
d.foo();
}
>>626 正にそういうことがやりたいです。
#include<cstdio>
template<typename T, class M>struct A{void foo();};
template<typename T, class M>
void A<T, M>::foo(){std::printf("foo\n");}
template<class M>
void A<int, M>::foo(){std::printf("int foo\n");}
//template<>
//void A<int, int>::foo(){std::printf("int foo\n");}
int main(){
A<int*, int> c;
A<int, int> d;
c.foo();
d.foo();
}
こうするとエラーなんですよね。コメントアウトしてるところは大丈夫なんですが。
>>627 それがコンパイルエラーになるのはクラステンプレートの部分特殊化が抜けているからでは。
template<class M>struct A<int, M> {void foo();};
これを追加したらコンパイルできた(VisualC++2005Express)。
コメントアウトしてるのが大丈夫なのは関数テンプレートの特殊化と解釈されるからだと思う。
関数テンプレートの部分特殊化は出来ないというのが今の言語仕様だったはず。
>>628 それはクラスごと特殊化してるんですよね。
一つのメンバ関数だけ特殊化したいので
>>622 みたくやるしかないですかね。
630 :
628 :2005/12/28(水) 22:59:25
>>629 関数テンプレートの全パラメータを特殊化するのであればメンバ関数でもできるけど、
部分特殊化を使いたいならクラス定義が必要ということです(これはC++文法の話)。
629さんの要求を推察するに、622さんのレスどおり継承ベースの手法があってるように思えます。
>>629 メンバーテンプレート関数にすればいいだけでは。
ここら辺のテンプレートの文法について詳しく説明した本ってないですか? 入門書の解説は適当だし他の本はそこら辺の知識を前提として書かれてて・・・ Cのポインタ本みたいにテンプレートについてもりもり書かれて比較的やさしい ちょうどいい感じのないのかな
>>632 C++Primer第3版(日本語)
英文でもよかったら、絶対お勧めなのが、
C++ Templates
Modern C++ Designでも軽く触れていたな
Modern C++ Design 読み始めたときは テンプレートの文法、型を置き換える程度のことしか知らない状態だったけど、 一通り読んだ後はテンプレートのコード見るのも苦にならなくなったな まえがきでCTAssert見たときは、サッパリ意味不明でどうなることかと思ったものだが template<cool>とか書いてあるし
Modern C++ Design読んでみたらしょっぱなから
クラステンプレートの継承とか引数にテンプレートとかやっちゃってて
理解不能・・・
やっぱり
>>633 の挙げてる本読んでおかないとダメなのかな
637 :
デフォルトの名無しさん :2005/12/29(木) 15:16:12
あの、調べ方が悪いと思う出のですが C++のクラスの継承についてお願いします。。 例えば class A{ ... }と宣言され class B:public A{ ... }としますと、 Aのコンストラクタ及びデストラクタ(もちろんprivateメンバもです)はコピーされませんよね?
639 :
デフォルトの名無しさん :2005/12/29(木) 15:22:36
>>637 コンストラクタがコピーされるって何のこと?
言葉が悪かったです "継承"ですね
仮想デストラクタの機能について、具体的に何がうれしいのか教えてほしいです。
642 :
デフォルトの名無しさん :2005/12/29(木) 15:28:36
>>640 調べ方
・コンストラクタの中で cout してみる
・B に A と同様の初期値を与えてみる
>>642 一応動作検証して
BにはAのコンストラクタは継承されてない事は確認したのですが、仕様としてはどうなのかなーと
644 :
デフォルトの名無しさん :2005/12/29(木) 15:39:44
>>641 Base* b = new Derived;
...
delete b;
としたときに、~Derived()を呼び出してくれること。
>>643 Bの構築時にAのコンストラクタは呼ばれるよ
あなたの言っている「継承されてない」が何を意味しているかによるけど
こういう事じゃないの struct A { A(int){} }; struct B : public A { }; B(1);//エラー
エスパー杉(゚д゚)
で、コンストラクタとデストラクタ(と代入演算子もだっけ?)は明示的に宣言しなければ、 継承とか関係なく、デフォルトの実装が暗黙的に実装される。 じゃなかったっけ?
650 :
デフォルトの名無しさん :2005/12/29(木) 18:57:36
>>648 この時点でまだそんなこと言ってる奴は鈍すぎ
>>649 確か、そんな感じ。
無ければ自動で生成される類は、継承されない。
652 :
デフォルトの名無しさん :2005/12/29(木) 19:41:00
646の2行目
参照渡しの int hoge(int *hogehoge) と int hoge(int &hogehoge) はどう使い分けるんですか?
>>653 ポインタが必要なら前者、そうでないなら後者。
nullを許容するなら前者、違うなら後者 #まぁ、後者にも無理やりnullを渡せますけどね
今月号のCマガに、明示的に管理責任を移動させる場合には 参照でなくポインタを使うってのがあったな。
値渡しと見た目が一緒だから、出力用引数に参照を使うな。 って案もあるな。
658 :
デフォルトの名無しさん :2005/12/29(木) 20:55:47
>>656 すんげー曖昧な指針だな
参照カウントとか使うケースほどでもなく
値で渡すのも何だからみたいな
ある特定の事情ってことか?
もっと単純にガッする場合のあるなしじゃね?
>>658 NULLを扱う場合の有無ももちろんだけど、それに加えてってことだろ。
660 :
デフォルトの名無しさん :2005/12/29(木) 22:12:17
質問です。 クラス内のプライベートな配列メンバを作るのはよくないでしょうか? そのドライバルーチンからそのメンバを読み(書きはしない)たいのです。 こういう設計自体が間違ってるのかな? 超初心者の質問ですが、よろしくお願いします。
661 :
デフォルトの名無しさん :2005/12/29(木) 22:21:32
ドライバルーチンとは、サブルーチン群を呼び出すmain()ルーチンのことです。 この場合はドライバとは言わないですよね・・・すみません。
>>660 まともな日本語で書け。main()ルーチンって何だ?routineは
“関数”じゃないぞ?
663 :
660 :2005/12/29(木) 22:31:19
サブルーチンに対するメインルーチンのことです。 main()とは限らないですよね・・・
>>660 >クラス内のプライベートな配列メンバを作るのはよくないでしょうか?
何でそう思ったの?
665 :
660 :2005/12/29(木) 22:39:08
一般に、プライベートなデータメンバは外部からアクセスする時、 パブリックメンバ関数のreturnしかないからです。メンバへのポインタを外部に持たせて云々 とかは言わないで下さい。 配列の場合、CやC++では、インスタンスをそのままreturn できないので、 ポインタを返すしかありません。 そのポインタを介して読み書きするのは、エレガントとはいえないです。 (っていうか、できない?) こういう場合は、どんな方法を取ったらいいのでしょうか?
イテレータでも作れば?
667 :
666 :2005/12/29(木) 22:42:52
ポインタと大差ないか・・・
668 :
デフォルトの名無しさん :2005/12/29(木) 22:48:25
>>665 1. boost::array
2. 配列への参照を返す。
3. std::vector
4. 素直にポインタを返す。
5. ポインタを返さなくて済むように設計を見直す
6. その他
どれでもどうぞ
670 :
660 :2005/12/29(木) 22:51:11
ありがとうございます。 5:設計を見直します。 お騒がせしました
まぁ、やりたいことはイテレータなんだろうけど、自前で配列云々するのはおろかだな。 STLのコンテナクラスをそのクラスのメンバにしておいて、アクセスしたい場面ではそ のイテレータをそのまま返すなりすればいいだろ。
std::vectorなら、インスタンスをコピー渡しでreturnできるよ。
汎用コンテナ作っているならともかく、普通のホルダ作っているんだったら 設計やり直したほうがいいわな。 メンバ変数を晒すなんて、責任分担がおかしくなっている兆候だろうし。
ここってネタスレじゃなかったの?
>>657 その指針からoperatorは除かねばならんな。
operatorを例外とした
>>657 の指針って結構一般的じゃないの?
>>677 そう言う人は確かに結構多いけど…では実際変更するものをポインタで、
というのも、関数書く側としては一々*を付けるのは面倒くさいわけで。
>>678 *付ける程度の労力を惜しむなら関数設計しなくていいよ
680 :
デフォルトの名無しさん :2005/12/30(金) 01:34:21
値渡しがデフォってのはまだ C を引きずってるんだろうな 参照渡しがデフォならコピコンを明示的に使うって立場もあろうが
>>680 値渡しがデフォってスタイルでなんかいいことひとつでもあんの?
そんなスタイルは、どこで変数が変更されるのか追いかけるのが大変に上に、
そーゆー用途で(必ずしも必要ではないかもしれない場面で)コピコンを呼ぶのは
パフォーマンス的に全くの無駄だし、テラ嫌ス。
C++の参照はちょっと中途半端で使いづらい。 無ければ無いでよかったのに。
>>681 >値渡しがデフォってスタイル
>どこで変数が変更されるのか追いかけるのが大変
矛盾。それとも参照渡しがデフォならどこでも変更される
可能性があるから追いかける意味がないとでも言いたいのか?
685 :
デフォルトの名無しさん :2005/12/30(金) 10:19:26
>>683 MyClass x,y,z;
...
z=x+y;
などと書けるようにするためでは?
>>683 参照がないと値渡し以外で使うときにoperatorが使いにくい罠ってこったな。
Hoge hage(Hoge *p)
{
Hoge kami(0);
Hoge fusa;
fusa = p->operator *(kami) ; //これ以外呼びようがない!
return fusa;
}
これはつらいっしょ。
>>665 bcc32.exeなら__propertyで読み出し専用配列つくれるよ!
ハ_ハ
('(゚∀゚∩ つくれるよ!
ヽ 〈
ヽヽ_)
688 :
デフォルトの名無しさん :2005/12/30(金) 11:07:07
fusa = *p * kami ; //これ以外呼びようがないか?
>>687 VCにも__declspec(property())があるよ!
ハ_ハ
('(゚∀゚∩ あるよ!
ヽ 〈
ヽヽ_)
移植性が必要なときが問題だな
環 立 イ_i_ ┼─ 土見 | イ ヒ イ 子 /\___/ヽ (.`ヽ(`> 、 /'''''' '''''':::::\ `'<`ゝr'フ\ + |(●), 、(●)、:| + ⊂コ二Lフ^´ ノ, /⌒) | ,,,ノ(、_, )ヽ、,, .:::| ⊂l二L7_ / -ゝ-')´ + | `-=ニ=- ' .::::::| + \_ 、__,.イ\ + \ `ニニ´ .:::/ + (T__ノ Tヽ , -r'⌒! ̄ `":::7ヽ.`- 、 ./| ヽ¬. / ノ`ー-、ヘ<ー1´| ヽ | :::::::::::::ト、 \ ( ./ヽ \l__,./ i l.ヽ! | .| ::::::::::::::l ヽ `7ー.、‐'´ |\-、 class Cool { public: __declspec(property(get=GetX, put=PutX)) int x[]; : : };
あ、変数宣言かぶってしまった。 その部分は脳内修正お願いします。 アク禁うざいOTL
千タ 千十 | 牛 木タ 木旧 小 ⊥  ̄ /\___/ヽ (.`ヽ(`> 、 /'''''' '''''':::::\ `'<`ゝr'フ\ + |(●), 、(●)、:| + ⊂コ二Lフ^´ ノ, /⌒) | ,,,ノ(、_, )ヽ、,, .:::| ⊂l二L7_ / -ゝ-')´ + | `-=ニ=- ' .::::::| + \_ 、__,.イ\ + \ `ニニ´ .:::/ + (T__ノ Tヽ , -r'⌒! ̄ `":::7ヽ.`- 、 ./| ヽ¬. / ノ`ー-、ヘ<ー1´| ヽ | :::::::::::::ト、 \ ( ./ヽ \l__,./ i l.ヽ! | .| ::::::::::::::l ヽ `7ー.、‐'´ |\-、 class Cool { public: #ifdef __MICROSOFT_C__ __declspec(property(get=GetX, put=PutX)) int x[]; #endif #ifdef __BORLAND_C__ __property int x[int] = { read=GetX, write=PutX }; #endif : : };
695 :
デフォルトの名無しさん :2005/12/30(金) 13:46:31
論理的な定数性について、説明して欲しいです。 ぐぐってもヒットしません。
696 :
681 :2005/12/30(金) 14:44:17
あ、ゴメン。 「参照渡しがデフォってスタイルでなんかいいことひとつでもあんの?」 の間違い。orz
もう、コンスト参照がディフォルトってことでいいよ。
>>695 「ビットの定数性」に対する語としての論理的定数性のこと?
>>696 蒸し返して悪いけど、そうじゃないかと思ったのだが、それだと
後半の値渡しを批判しているっぽいくだり『コピコンを呼ぶのは
パフォーマンス的に全くの無駄だし』と矛盾しない?
700 :
デフォルトの名無しさん :2005/12/30(金) 15:26:57
標準で定められている例外は次の通りです。 exception から直接派生しているもの bad_alloc, bad_cast, bad_exception, bad_typeid, ios_base::failure, logic_error, runtime_error logic_error から派生しているもの domain_error, invalid_argument, length_error, out_of_range runtime_error から派生しているもの overflow_error, underflow_error, range_error 例えばメモリアロケーションに失敗したり、 その他浮動小数点演算で数値として表すことができない結果が出たり、 といろいろと例外処理したいシチュエーションがありますが、 そういう例外クラスの事実上の標準なクラスライブラリってあります?
処理系依存です 処理系依存です 処理系依存です 処理系依存です 処理系依存です
702 :
700 :2005/12/30(金) 17:03:49
そうですか、その辺は処理系依存ですか。
ISO規格に含まれている
>>700 の例外だけは
ポータブルってことですね。
>>700 メモリアロケーションの失敗は bad_alloc でいいんじゃないの?
704 :
700 :2005/12/30(金) 17:31:12
>>684 Generic なアルゴリズム書くのが激しく面倒になるが。
706 :
デフォルトの名無しさん :2005/12/30(金) 19:48:53
>>699 それは
>>680 の言うコピコンの使い方(値を変えられると困る場面で、const の代わりに引数を変更
されてもいいようにコピーを渡す)を受けての話。
ClassA a; if( ClassA b = a ) b.func(); 今気付いたんだけど、ifの条件式でこんなことできるんだね。 知らなかった。
bool に変換できる型である必要があるけど
条件式と見間違えやすいからけっこう危険だよ。 dynamic_cast用にしといた方が無難だと思う。
条件式の中で代入を使うのは、間違いって教わった人は 気づかないかもしれないね
712 :
デフォルトの名無しさん :2005/12/30(金) 22:00:33
ぼけらんどの功罪
for でもできるっしょ 条件式を持っているなら、どれでもできるような気が・・・
if( int i=0, j=1) { } は合法?
>>714 do whileじゃ無理っす
まぁ、正直出来ても活用性0ですけどw
switchも可能だったはず。
昔のCの本に1["string"]とか書けるっていう記述があったな。 さすがにC++じゃ無理だろうが
>>718 a[b] は*(a+b)と同じ意味なので
1["STR"] = *(1 + "STR") = *("STR" + 1) = "STR"[1]
という事やね。
C++でも出来た気がする。
なんでfor(int i, int j; 1; ++i, --j); のように、変数導入宣言が二回以上使うことができないのだろうか? C#ではできるのかな?
for( int i=0, j=1;;)
局所的に制御変数を二つ導入したいことは結構あるのに...
沢山条件がある場合は 構造体にパックしたりすればいいんでない? またはcharとか1byte変数配列を必要な数だけ宣言して、型キャストするとか
っていうか、for(;1;)なら制御もクソもないかw
725 :
デフォルトの名無しさん :2005/12/30(金) 22:35:16
二項演算子 [] は可換
std::vector<int> v; FOREACH( v, int i){ printf("%d",i); } みたいなことのできるマクロ書いてた頃(素直にboost使う気になれなかった頃) for(int i=0, v::iterator it=v.begin; と実装できなくて困った覚えがあるなぁ
operator[]()
template <class Type> class A{ public: Type &func1(){return data1;} Type data1; }; template <class Type> class B : public A<Type>{ public: void func2(){ data2 = A<Type>::func1(); //data2 = func1(); } Type data2; }; gccで上記はコンパイルできますが、//でコメントアウトしている書き方では エラーがでてしまいます。 この例ではなぜベースクラスまで指定しないといけないんでしょうか?
>>728 テンプレートは、引数が与えられていない定義そのものと、引数を与えられた時点の
2回構文がチェックされる。
クラス・テンプレートのメンバは、あとで明示的特殊化によって御破算にされる可能性が
あるから、最初のチェックのときには名前検索の対象にならない。だから修飾されていない
"func1"はその定義が見つからず、エラーとなる。
ただし、その名前がテンプレート・パラメータに従属している基底クラスのメンバである
可能性が示されたら、2回目のときまでチェックを遅延することが許されている。
それで A<Type>::func1() はコンパイルを通る。
ちなみに
data2 = this->func1();
と書くことも可能。
ここいらへんは、テンプレートの機能の中でもややこしいところだから、詳しく解説した
本を読んだほうがいい。
C++ Templates とか
730 :
デフォルトの名無しさん :2005/12/31(土) 14:32:52
・・・・・・・ >>詳しく解説した >>本を読んだほうがいい。 >>C++ Templates とか どの本をさしますか。 ルキーの解説書ですか。 ブーストの取説ですか。 教祖の本では不十分ですか。
732 :
デフォルトの名無しさん :2005/12/31(土) 15:17:39
ちょっと質問させてください。 C++で中国と戦えるでしょうか?
>>732 おまいあきらかにC#スレからきただろ!!!
734 :
デフォルトの名無しさん :2005/12/31(土) 15:33:00
731 名前:デフォルトの名無しさん :2005/12/31(土) 14:36:57
>>730 >>9 ずばり言ってよ。
今の時間読めん
735 :
デフォルトの名無しさん :2005/12/31(土) 15:37:43
736 :
デフォルトの名無しさん :2005/12/31(土) 15:43:05
それで戦えるんですか?答えてください。
あと、全裸でお台場を走り回ることが必要不可欠
738 :
デフォルトの名無しさん :2005/12/31(土) 16:08:51
>>C++ Templates: The Complete Guid
規約無視して、変体書式で書いてある事を貴方は
どの様にお考えですか。初めてテンプレ学ぶ人には
変換することが難題だと思いますが。ソースは↓
http://www.josuttis.com/tmplbook/ The only gripe I have against this book is a very very minor one:
the authors for some inexplicable reason decided to write
"T const* p" instead of "const T* p" in function prototypes.
Both are correct and both mean the same thing but nobody uses
the first convention whose major fault is
that it's too close to "T *const p" - a different thing entirely.
Plus the second convention is such an ingrained idiom that fighting
it is pure nonsense which makes the book initially hard to read.
Example: what does "char const* const& a" mean?
(p. 17) On top of that the reader cannot simply substitute one convention for the other,
as the 25,000 C++ books already in print are
still going to *be* there plus the x billion lines of legacy C++ code is
not leaving any decade soon! So one has to keep *both* conventions
in mind in order to read the text. It's really not much of a big deal
but I wonder: what were they thinking?
739 :
デフォルトの名無しさん :2005/12/31(土) 16:15:44
人は、テキストを読むために両方の コンベンションを覚えておかなければなりません。 本当に、大したことの多くではないのか。 私が不思議に思うのは、 彼らは何を考えてたのか ボケ?
741 :
デフォルトの名無しさん :2005/12/31(土) 16:57:05
>>738 そんな qualifier の置き方がそんなに重要かよ。
main の argv の型だって、
const char * const char * const argv と書くやつもいれば
const を変なところに(意味が変わらない範囲で)くっつける奴もいる
>>738 const char* と書く人に文字列リテラルの配列を定義させると、半分以上は
const char* table[] と書く。
char const* を使う人は
char const* const table[] と書く。
Windows や Linux など、すべて RAM 上で動かすプログラミングをしていると、
前者と後者の違いが重要だとは思わないだろう。
しかし ROM 環境で、さらに RAM の少ない環境でプログラミングしていると
これらの違いに神経を使う必要が出てくる。
故に、普段から ROM 環境でプログラムしてる人
または偏執的な const マニアは後者に落ち着く可能性が高い。
743 :
デフォルトの名無しさん :2005/12/31(土) 17:33:46
>>742 偏執的な const マニア(笑
マニアかどうかわかんないが、俺も
const できるところは全部 const にしないと気持ち悪いな。
結構潜在的なバグを発見できたりするし。
const つけまくったからと行ってどの程度最適化に
反映してくれるかはわかんないけど。
>>744 俺もどっちがどっちだか分からなくなった。
まぁ宰相ググレカスだな
746 :
728 :2005/12/31(土) 17:54:14
747 :
742 :2005/12/31(土) 17:57:36
>>744 ,745
わかりやすい話だと table[0] = "modified" が、前者だと通り、後者だとエラーになる。
前者では table を書き換え可能な RAM に置く必要があり、後者ではその必要が無い。
起動時に全部 RAM にロードされる環境だと、それらの違いはほとんど無視できる。
( OS による最適化で const な table をプロセス間で共有してくれる可能性はある。)
ROM 環境では必要な分だけ RAM を使うことになるので、
table[] のサイズがそのまま RAM の消費量の差になる。
748 :
デフォルトの名無しさん :2005/12/31(土) 18:02:33
Q1:すべて RAM 上で動かすプログラミングをしていると、 前者と後者の違いが重要だとは思わないだろう 誰のことですか。発言者の出典箇所は? Q2:普段から ROM 環境でプログラムしてる人 PICとか組み込み系の人のことですか。 Q3:世界中の人の前に広く出回る本であっても貴方は後者の 書き方で問題ないと寛容にお考えですか。 この本は、英語、中国語、アラビア語で翻訳されてます。 関東圏内で会話していると 標準語と関西弁の違いが重要だと思わないだろう。 しかし大阪でさらになんばで会話をしていると これらの違いに神経を使う必要が出てくる。 私は、東京のど真ん中で偏執的な関西弁マニアが巻くし立てらたら 必ず違和感を持つ。そして、日本の公用語は関西弁に は絶対にならないと考える。
>>742 俺はconst char *派だけど、typedefする。
typedef const char *PCSTR; //大抵<windows.h>で済ます
const PCSTR *table[];
でも、const char * と char const * に違いなんてないよね? てか、const char * って形の宣言ができることがそもそも間違いの始まりなんだよなぁ。 てな、話は↓こっちでやれ・・・ って、「const だけでメシが3杯喰えちゃうスレ」がいつのまにかなくなってる。(´;ω;`)
752 :
デフォルトの名無しさん :2005/12/31(土) 18:48:32
bool MakeList(Node*&) というように、ノードのポインタのアドレスを引数にし、mainから参照したいのですが うまくいきません。 Node* node; if(MakeList(&node)){} このように、条件判断に使いたいのですが・・・・ どうすればいいのですか?
>>748 変な奴がいるみたいだが、もうしばらく相手してやる。
> Q1: (引用略)
> 誰のことですか。発言者の出典箇所は?
Windows や Linux をメインの環境としてプログラミングしてる人。
発言者とは誰のことですか。
> Q2:普段から ROM 環境でプログラムしてる人
> PICとか組み込み系の人のことですか。
そこらへんに多いと思う。あと携帯ゲーム機とか。
> Q3:世界中の人の前に広く出回る本であっても貴方は後者の
> 書き方で問題ないと寛容にお考えですか。
普段から後者に統一しているので、問題ないと考える。
C++ の書き方についての話なので、何語に翻訳されてようと変わらない。
> 関東圏内で会話していると(以下略)
大阪で暮らすために日本語を学ぶなら、標準語を学ぶだけでは不十分だろう。
逆に、東京だけで暮らすなら、関西弁を学ぶ必要は無い。
ROM 環境でプログラミングするために C++ を使うなら、以下略。
逆に、潤沢な RAM のある環境だけでプログラミングするなら、以下略。
>>752 operator void* () を定義すればどうか。
755 :
デフォルトの名無しさん :2005/12/31(土) 18:56:01
>>755 streamと同じ要領。変換演算子。"ストリーム c++ 変換演算子"でぐぐれば
いろいろ出てくる。
"ストリーム 状態 c++"の方がいいか。
>>754 MakeList() の戻り値が bool なのに、なんで変換演算子が要るの?
760 :
デフォルトの名無しさん :2005/12/31(土) 20:11:56
あれ? なんでみんなフツーに回答してんの?
>>752 がわけわかなのって俺だけ?
>>761 自分自身に似たような経験があれば、質問者の意図は理解できる。
763 :
デフォルトの名無しさん :2005/12/31(土) 21:23:04
>>752 なんかポインタのど初歩で間違えて内科医?
実引数おかしいよね
>>761 こうすれば理解できると思う。
typedef Node *NodePtr;
bool MakeList(NodePtr&);
765 :
761 :2005/12/31(土) 23:14:04
>bool MakeList(Node*&) >というように、ノードのポインタのアドレスを引数にし、 ここまではわかる。 >mainから参照したいのですが なにを? 引数? 関数? 戻り値? それ以外のなにか? >うまくいきません。 なにが? 引数を渡すこと? 関数呼び出し? 戻り値の取得? それ以外のなにか? >Node* node; >if(MakeList(&node)){} >このように、条件判断に使いたいのですが・・・・ 勝手に使えばいいじゃん。 >どうすればいいのですか? 俺も、どうすればいいのですか?
うむ。さっぱりわからんな。
ぱっと見た感じ>>759-
>>760 で解決では?
if(MakeList(&node)) { ではなくて
if(MakeList(node)) { にしろってこった。
上のじゃコンパイル通らないだろう
>>767 確かに、解決もしたんだろうし、そこでコンパイルエラーになって、
& を取っ払えばコンパイルが通るって話はわかる。
が、質問の意味がさっぱりわからん。
C++ Primerってこのスレ的にはどうなんですか。 amazonの評価は結構微妙なんですけど禿本に書いてない細かい所とか書いてあるんですよね。
量が多いから、1からC++Primerを読んで勉強するには相当辛いものがあるし、 索引がいい加減で、容も離散的に書いてあるから、マニュアル的に使うにも少々難ありって感じ。 俺の感想だけどね。 分からないトピックを絞って、その部分を集中して勉強するようなスタイルなら、それなりに使えるとは思う。 結局本棚の肥やしになってるけど。
漏れには>761が判らん。 #「がわけわかなの」?
772 :
デフォルトの名無しさん :2006/01/01(日) 09:27:06
シーケンシャルに読むならやっぱ禿本 ランダム読みに向いているのが C++ Effective マニュアルは本当に処理系の取説と ISO/JIS の規格票
773 :
デフォルトの名無しさん :2006/01/01(日) 09:31:19
>シーケンシャルに読むならやっぱ禿本 何の本のことか解りません。 タイトルを正確に教えて
774 :
デフォルトの名無しさん :2006/01/01(日) 09:39:27
おまえら、最初にどの本読んでOOPの世界に入ったのよ。ちなみに俺は 「A級B型C++ (技術評論社かソフトバンク、忘れた、すでに絶版)」
775 :
デフォルトの名無しさん :2006/01/01(日) 09:44:16
古禿 ↑ISBN4-8101-8002-6 ISBN4-8101-8047-6 ISBN4-7561-1895-X ↓ISBN4-7973-2854-1 新禿
禿禿言うなっていう忠告を理解できなかったようだな…
777 :
デフォルトの名無しさん :2006/01/01(日) 11:09:04
ハゲでもいいじゃん。 ハゲこそC++だよ。
敬意を込めて禿と呼ぶ
779 :
デフォルトの名無しさん :2006/01/01(日) 11:49:58
>ハゲでもいいじゃん。 >ハゲこそC++だよ。 この本は髪質がツルツルと光って、そのうえ薄すぎて さらにイタリックで読みにくくない。? 光沢が反射して目がクラクラするのは、俺だけか。 だいだい、あすきー社って、異常に紙質が厚いか 裏面が透過するほど薄いか、ざらざらしているか 値段が他社に比べてトビ抜けて高い。 つぶれてよし、逝ってよし。 練習問題の回答本も別途購入しないといけない。 買う人はいますか。
禿げてる奴って脳みそのしわも薄そうだよな。 頭悪そ
781 :
デフォルトの名無しさん :2006/01/01(日) 11:58:15
禿の練習問題は同じ問題をやってみた人同士で論議するように意図されているもので 誰かが出してきた答案を見てそれをやめてしまう他力本願は「ユーザが育てた言語」にそぐわない 値段にしても自己投資として買う人には問題にならない金額だね
782 :
デフォルトの名無しさん :2006/01/01(日) 14:42:27
みなさんにとってのデータアクセスの考え方についてお聞きしたいです。 class CMember { private: int m_Age; }; というクラスがあった場合、そのメンバーアクセスには bool SetAge(int Age); int GetAge() {return m_Age;} というメンバー関数を用意しておこなうようにしていますが。 もし、他に CStrVector m_NickName;// 文字列クラスの配列を管理している管理クラス というデータがあった場合、取得に関してはどのような概念をお持ちでしょうか? @メンバー関数は外から干渉絶対にさせないので、コピーにかかる時間は深く考慮せず CStrVector& GetNickName() {return m_NickName;} とおこなう。 Aprivateメンバー宣言されている時点で、さわられたくないと言う意思表示をしているので ポインタを取得させてしまう。 CStrVector* GetNickName() {return &m_NickName;} とおこなう。 ちなみにm_NickNameで配列化される文字列は300個ぐらいです、 各文字列はせいぜい20バイトほどです。 MFCで言えばCStrVectorはCStringArrayのようなものだとお考えください。 作製しているアプリは事務的な物です、決してゲームのような一刻の早さを求める物ではありません。 みなさんならどちらでしょうか?
>>782 そのクラスの設計目的を抜きにしてそんなことを議論できるとでも思ってるのが間違い。
>>782 実装からインターフェースを考えてるのが間違い。
先にインターフェースを考えろ。
785 :
デフォルトの名無しさん :2006/01/01(日) 15:05:54
Aはアフォ
>>782 (1)にコピー云々と書いてあるけど
CStrVector& GetNickName() {return m_NickName;}
CStrVector GetNickName() {return m_NickName;}
の違いは分ってる?
787 :
デフォルトの名無しさん :2006/01/01(日) 15:24:03
>Aprivateメンバー宣言されている時点で、さわられたくないと言う意思表示をしているので constを忘れているよ(w
privateは、派生クラスからも触れないので、まず使わない。protected
にするな。それと、MFCだとCMemberは、CObjectの派生クラスとして定義
する。
んでもって...
const CStrVector &GetNickName() const { ASSERT_KINDOF(CMember,this); return(m_NickName);}
CStrVector &NickName() { ASSERT_KINDOF(CMember,this); return(m_NickName);}
の2つを用意する。前者用意していないと、後者は、constなメンバ関数
から参照できないため。クラス定義の目的と場合によっては、virtual関数に
する。
なぜわざわざメンバ変数を隠蔽してアクセス関数を用意するのか理解して
いない
>>785 は、アフォ
789 :
デフォルトの名無しさん :2006/01/01(日) 15:29:16
禿げって、髪質がツルツルと光って、そのうえ薄すぎて さらにイタリックで読みにくくない。? 光沢が反射して目がクラクラするのは、俺だけか。
>>788 protectedは、派生クラスからも触れるので、まず使わない。
派生クラスから触るためにprotectedにするって......
なぜわざわざメンバ変数を隠蔽してアクセス関数を用意するのか理解して
いない
>>788 は、アフォ
792 :
782質問者 :2006/01/01(日) 16:06:16
元日早々いろいろと勉強になったような気がします。 みなさんありがとうございました。 class test { public: test() {m_a = 10;} const int& get_a() const{return m_a;} private: int m_a; }; int main() { test t; const int &a = t.get_a(); a = 20;// エラー return 0; }
>>788 みたいな奴が穴ありまくりの腐りきった関数作るんだな
>>791 や、
>>793 みたいな奴が、パフォーマンスが出なくて、再利用でき
ない糞なクラスの再発明を繰り返してして、ばかでかくて無駄なコードを
量産しているんだろうな。間違いない。
自己紹介乙
796 :
デフォルトの名無しさん :2006/01/01(日) 16:57:03
(;´Д`) おまえら、なに新年早々揉めてんだよ。
>privateは、派生クラスからも触れないので、まず使わない。 そんな論法がまかり通るならアクセス関数とか使わずに全部public。 実際それが一番良い場面も多いしな
新春早々馬鹿が現れてるようだな。
「釣れた」と言ってる馬鹿がいる。
>>803 違う、「釣れた」としか言えない馬鹿がいる、だろ。
~~~~~~~~~~~~~~
>>792 intなら参照を返す必然性は無いと思う。
あと、コンストラクタで代入するよか、
test() : m_a(10) {}
と書くようにした方が良いかも。
猫のページを参考にオペレータオーバーロードの定義方法はわかったのですが。 例えば class Age内にて Age operator + (Age& temp){ return 何か; } とされていればAge+Ageの演算は return 何か; の部分が返されるのですが、 3+Ageとか、前方がAgeでは無い場合のオペレーターロードはどうすればよいでしょうか・・
>>810 グローバルでオペレータオーバーロード+コンストラクタで数字からの変換定義
いろいろ試行錯誤してみたんですけど int operator + (int n,Age& temp) { ... } のように引数を二つ取ればよかったのですねorz すみませんでした
814 :
デフォルトの名無しさん :2006/01/01(日) 22:18:16
微分方程式を解くプログラムをオブジェクト指向で作成したいと思っています。 微分方程式、積分ルーチンのクラスを作ったところで微分方程式の解を保持する 変数はどこに置いたらいいか分からなくなりました。 当初は微分方程式のクラスにおいていましたが、複数の積分ルーチンを作る際に 不都合が生じてきました。例えば、解を補間しない場合は、積分ルーチンから得た 解を微分方程式のクラスに置いていても問題はないのですが、補間する場合は 積分ルーチンの方に置いたほうが都合がいい為です。 何か良いアイデアがあればお聞かせください。
>>814 普通に考えれば微分方程式クラスに置くべきだと思うが
それで不都合が生じるなら生じない方かもしくは
別途、解クラスとして独立させてみたらどうか?
816 :
デフォルトの名無しさん :2006/01/01(日) 22:49:18
>>815 ども。別途解クラスを作って微分方程式クラスと積分ルーチンクラス
で集約するのですね。色々考えてはいますが、クラスを使ってデータを加工していく
作業は手続き型に思えてオブジェクト指向的な設計に感じないんですよ。
集約と言うか解クラスが微分方程式クラスと積分ルーチンに依存(を利用)すると
思えばいいのかなぁ・・・。
>>816 それじゃ逆転の発想で、解とその他の計算にかかる純粋仮想関数を持ったクラスと
それから派生した2つの微分方程式クラスと積分クラスってのは?
>>816 漠然とした話なので「お好みで」としか答えようがないなあ。
前俺がその手の計算プログラムを組んだときには、
XYデータ列クラスと多項式クラスが大活躍したぞ。
何としても、シンプソンの方法(method)クラスみたいのを
作りたくなかったのだが、意味があったのだろうか。
数学計算は手続き型の方が相性がいいなと思ったしだい。
819 :
デフォルトの名無しさん :2006/01/01(日) 23:10:03
>>817 それだと結合が強すぎないですか?
うーん、やはり
>>815 さんのおっしゃる様に3つのクラスが互いに参照しあって
処理を進めるべきかな?
820 :
デフォルトの名無しさん :2006/01/01(日) 23:12:48
>>818 手続き型っすか・・・orz
XYデータ列クラスと多項式クラスってどのように使うものですか?
>>818 >>何としても、シンプソンの方法(method)クラスみたいのを
>>作りたくなかったのだが
何故なんとしても作りたくなかったのか、その心を是非聞きたいです。
822 :
デフォルトの名無しさん :2006/01/01(日) 23:18:49
>791の言うアクセス関数、所謂アクセサがパフォーマンスを落とすと思い込んでいる>794はカス。 そもそも、日本語もまともに書けない>788はゴミ。
積分ルーチン・インスタンスに微分方程式インスタンスを与えると、解インスタンスが出てくるのではいかんのか。 3つのインスタンスの関係は、上位構造で管理すればいいように思うけど。
>>822 聞かれている事が良く分からないのですが、
データ(解)の型ですか?配列にΔ時間だけ微分方程式を発展させた際の解を
入れるつもりです。
>>824 時刻t1から時刻t2になった時に、時刻t2の解だけ欲しいならば
それでも良いのですが、t1からt2の間を補間する場合はt2の解とt2を計算した
途中の情報が必要になります(それは積分ルーチンのprivateメンバになっているはず)。
t2の解を積分ルーチンのメソッドの引数として与えれば良いのかな?
時刻tの解を得るために
3種類のインスタンス:微分方程式、データクラス、積分ルーチンの
誰にメッセージを送るべきでしょうか?
つか
>>791 関連の話してる奴ら全員論法がおかしい
828 :
814 :2006/01/02(月) 00:02:59
データクラスを作ると微分方程式が多次元の場合、データ配列のどこにどの
次元の解が入っているか誰が把握するべきかという問題もありますね。
>>822 さんはこういった事を質問されたのでしょうか?
自問自答が多いので一旦出直した方がいいかもしれませんね。お騒がせ致しました。
あのーC++のstring型ってなんでしょうか それとどの様な仕掛けで変数のサイズを可変させてるのでしょうか。。
831 :
デフォルトの名無しさん :2006/01/02(月) 21:33:08
>>829 ふつうに考えて、クラスのなかに文字列へのポインタとサイズが
入っているのではないでしょうか(予想)
ですから、サイズ変更(別の文字列を代入)するときは、クラスのサイズ
を書き換えているんだと思います。(もちろんポインタも)
このような文字列も持ち方は他の言語では普通。\0で終わる文字列という
Cの仕様のほうがどちらかというと特殊。
832 :
デフォルトの名無しさん :2006/01/02(月) 21:40:35
アセンブラでは普通 \0 が MSB だったりはするが
つ malloc, new []
以下のようなことがしたいのですが、なるべく余計なコピーを行うことなしに標準的な手段で実現することは可能でしょうか。 buf = 可変長バッファ、is = istreamとして、 1) 任意のバイト数分のデータをisから取ってきてbufに追加。 2) bufの頭から「ある処理」を行い、処理を完了したバイト数分bufから捨てる。なお、「ある処理」は使用するライブラリの都合上(const)char*が必須。 いまのところbufにstringを使用していて、(2)は以下: const char* p = buf.data(); ... buf.erase(0, processed_size); のように実現できそうなのですが、(1)がうまくいきません。 今はこう(↓)なっていますが、激しく気持ち悪いです。 char *add = alloca(n + 1); // char add[n + 1]; だとg++ -ansi -pedanticで怒られた memset(add, '\0', n + 1); is.read(add, n); // 実際に読み取ったバイト数もわからない。処理前後の位置を調べるしかない? buf += add; 最初はnバイト分bufを広げてdata()の後ろに追記しようとしたのですが、返す型がconstなのでボツ。(書き換えると何が起きるかわからんで、と書いてあるし) 次にostringstreamを使おうとしたのですが、str()が返すのはコピーのようなので意味なし。 今のところ考えているのは、(1)を a) 素直に1バイトずつループで追記。 b) 可変長バッファクラスを独自実装。 のどちらかで実現、と思っているのですが、C++は初心者なので、アプローチからして何か間違えているような気がしてならないです……。
>is.read(add, n); // 実際に読み取ったバイト数もわからない。処理前後の位置を調べるしかない? >buf += add; is.read(add, n); buf.append(add, is.gcount()); でよかったと思う。あと、n は const で定義してれば char add[n +1]; でも怒られんよ。
>今のところ考えているのは、(1)を >a) 素直に1バイトずつループで追記。 >b) 可変長バッファクラスを独自実装。 >のどちらかで実現、と思っているのですが、C++は初心者なので、アプローチからして何か間違えているような気がしてならないです……。 いまのままじゃダメなん? 処理の内容にもよるけど、あんまり速度的な効率求めるよりも、 簡素な記述で目的が果たせているんならそれに越したことはないよ。
>>834 >最初はnバイト分bufを広げてdata()の後ろに追記しようとしたのですが、返す型がconstなのでボツ。(書き換えると何が起きるかわからんで、と書いてあるし)
std::vector<char>にしてよければ:
std::vector<char> buf;
std::size_t s = buf.size();
buf.resize(s + n);
is.read(&buf[s], n);
buf.resize(s + is.gcount());
とか?
>>837 ちょwwwwおまっwwwwwww
そりゃ、意図通りには動くかもしれんけど、規格的には反則だろw
# そーゆーことをしてもいいことにしようって動きはあったとは思うが。
横から失礼しますが
>>838 >規格的には反則
どこがまずい?
>>839 >is.read(&buf[s], n);
vector の要素が連続していることは保証されてたと思うけど、
こーゆー形でデータを受け取ることはまだinvalidなハズ。
いやvectorなら大丈夫だぞ?
>>840 vectorを837のように配列の代わりに渡すのは
Effective STLで紹介されていたと思う
>こーゆー形でデータを受け取ることはまだinvalidなハズ。
ソースは?
>>840 予めresizeで配列は十分要素数を持っているので問題ない。
要素数が足りないければ(reserveだけ行っていることも含む)たしかにまずいが。
845 :
834 :2006/01/03(火) 10:21:00
各位情報感謝。
>>835 なるほど、gcount()を使うんですね。
こういうインターフェースは予想してなかったので目に入ってませんでした。
> n は const で定義してれば char add[n +1]; でも怒られんよ。
ところがですね、
> error: ISO C++ forbids variable-size array `add'
そもそも可変長配列自体規格違反らしいんですわ。
// んなアホな。だったらどうしろと言うのだ。alloca()じゃ退化してるやん。>ISO C++
// まぁ-pedantic付けなきゃ通るんですが。
>>836 んー、でもそれだとC++を使う旨みが半減。効率あまり考えないなら、
他の言語の方が扱い易いような。
>>837-844 をを、vector使えるんですね。
stringのdata()のような内臓さらすメソッドがないので無理かと思ってました。
// しかし、&buf[n]ってぱっと見るとぎょっとするな……。
>>845 >そもそも可変長配列自体規格違反らしいんですわ。
ん? n が const なら可変長配列にはならんでしょ?
>んー、でもそれだとC++を使う旨みが半減。効率あまり考えないなら、
>他の言語の方が扱い易いような。
実際、そーなんじゃない?
特別に効率が求められる場面でもなけりゃ、あえて C++ にこだわる必要はないよ。
それでも、俺は C++ が好きだから C++ を使うことにこだわるけどね。
あと、C++ の旨みは効率だけじゃないし。
>>846 可変長配列にならないためには const なことに加えて
定数式("constant expression")で初期化されている必要がある。
>>847 char add[n +1]; だぞ。
849 :
848 :2006/01/03(火) 11:17:18
あ、ごめん、寝ぼけてた。忘れてくれ。
850 :
834 :2006/01/03(火) 12:10:40
>>846 残念ながら今回のシチュエーションでは、代替手段としてalloca()を使って
いることからわかるように、可変長配列でなければならないんですよう。
void fill(int n) { char add[n+1]; ... } こんな感じ。
int nをconst int nにしても、定数式じゃないのでNG。
あと、今回は効率を求めてCに行き、CでOOやるのがメンドくなってC++に
走ったので、あまり効率は落としたくない、という理由もあったり。
ま、コンテナクラスを使いまくると裏でメモリアロケータががんがん
走ってるだろうからあまり気にしても意味がないような気はしますが……。
>>850 残念だけど、効率求めんなら stream 系は使わずに C と女滋養なやり方したほうがいいよ。
852 :
デフォルトの名無しさん :2006/01/03(火) 13:25:54
Cを何年かうってきてC++を勉強中なんですがクラスを作ってそのクラスで宣言 されてる関数をつかうときに宣言したクラス名.関数名みたいな形で書くのが めんどくさく感じるんですがこれが普通なんでしょうか?こっちの方がどのクラス を使ってるのかわかりやすいと言われればそんな感じもしますが他になにかやり 方があって私がめんどくさいことをしてるだけなのでしょうか?どなたがわかる 方いらっしゃいましたら教えてください。
>>852 まさかクラスのメンバ関数を全てstaticにするとか馬鹿なことやってないよね?
854 :
デフォルトの名無しさん :2006/01/03(火) 13:28:12
>宣言したクラス名.関数名みたいな形で書くのが あんたクラスって名前空間だと勘違いしていないか?
855 :
デフォルトの名無しさん :2006/01/03(火) 13:48:24
852です。 例えばclass AAA{ int aaaa; void AAAA(){} } みたいなクラスを作ってどっかでAAA a;って宣言して 中の関数を呼び出すときにa.AAAA()って呼び出すのではないでしょうか?
a.AAAA() の a はクラス名じゃなくてインスタンス名 めんどくさく感じるのは、多分オブジェクト指向に対する理解が足りないから
>>855 そのAAAA()の中では、 a.aaaa じゃなくて aaaa で済むのが利点のひとつ。
this->aaaaが省略できてaaaaと書けるだけだけどね。 thisが省略できない場合も多々ある。
Cで構造体使ったことないんかい。
てか、いくらサンプルのコードだからってその命名は酷い。
>>855 のセンスの無さを垣間見た気がするのは俺だけですか? そーですか。
861 :
デフォルトの名無しさん :2006/01/03(火) 14:12:28
>>852 Cを長年やってきたなら、関数名(というか、外部名空間)の管理に手を焼いたことくらいあるだろう?
長ったらしいプリフィックスを毎回打たされるのとどっちが面倒だろうね
>>855 a.AAAA()はC言語ならAAA_AAAA(&a)とでも書くところなのだけど、
それでもめんどうくさく感じる?
そう考えるとusing使うなって言う意見は酷だよなやっぱり
864 :
デフォルトの名無しさん :2006/01/03(火) 16:44:57
オブジェクト指向って人によって意見がまちまちのような気がします. 本当に一つの概念として確立されているのかよく分かんなくなります. 分かる人には分かる,といったものでない雰囲気がするんですが,やはり,僕の認識が誤りなんでしょうか?
865 :
デフォルトの名無しさん :2006/01/03(火) 16:48:32
IDEのインテリセンス使ったらマンドクサイの軽減するんじゃまいか?
866 :
デフォルトの名無しさん :2006/01/03(火) 16:55:31
867 :
デフォルトの名無しさん :2006/01/03(火) 17:06:15
>>866 レスありがとうございます.
アマゾンとかで検索するとオブジェクト指向のデザインパターンを説明する本って星のようにありますよねぇ...
この本読んで勉強してみようと思います.
868 :
デフォルトの名無しさん :2006/01/03(火) 17:32:52
>>863 誰がそんなこと言うんだ?
俺だってグローバルスコープで using namespace を使っているのを見かけたら
口に出すかどうかは別としてやった奴を警戒するけど、using そのものを否定するわけじゃない
>>867 オブジェクト指向って学ばなくても組んでたらその方向へ
いくと思う。学ぶと近道になるのは確かだけどね。
しかしboost::lambdaなんか使うと グローバルでusing namespaceしないと面倒でやってらんない
グローバルって言ってもファイルスコープだろうしな
ソースのグローバルスコープなら問題なくね?
873 :
デフォルトの名無しさん :2006/01/03(火) 17:52:19
グローバルスコープ≠無名の名前空間
874 :
デフォルトの名無しさん :2006/01/03(火) 17:56:32
この問題に関しては同じことだけど
using については、C++ Coding StandardsとC++ 標準的コーディング技法 で言及されとりますな。 さすがに関数内だけでのみusing namespaceを使うつうのは厳しすぎるので、 ソースファイルの最後のincludeの後でusing namespaceを使うというのが 妥当な所かと思う。
876 :
デフォルトの名無しさん :2006/01/03(火) 19:04:08
using が効かないメンバを作れるならまだマシだけどね 自分が言及した覚えのない識別名との衝突にびくびくするのはやっぱりやだ
>>877 そうなんだよな。いくら例のための無意味な名だとしてもだ。みーんなして判でおしたように foo や hoge ばかり使うってのが没個性で気にいらねえ。
わからんちん相手には、 _____(_,__,___);
まともなプログラムじゃ使えないからせめてこういうときだけ、 o(oo,oo);
いつぞや誤用を指摘されてくやしかったから、 null(NULU, NULl_, NUl_l_ );
こんなん使ってもちっとも読みやすくならないばかりか打ちまちがえるってえのなあ…… flase(ture,tuer,fals);
嫌な奴の名前 void Kusakabe(henjin);
そういや、hogebar てのも見ないな
879 :
デフォルトの名無しさん :2006/01/03(火) 20:28:09
using namespace std; は別にグローバル空間で明記したって重大な問題にはならないような。 他は名前のルックアップとnamespace ○○=boost::lambdaと#includeの位置を調整で対処。
882 :
デフォルトの名無しさん :2006/01/03(火) 21:47:00
ヘッダにusing書かなきゃ何したって構わんけどな。それだけはやめてくれ
>>881 問題が起こらないようにわざわざ std namespace を利用してんのにそれを無駄にするようなことをするな。
まぁ、個人的にはそれで問題が起きるようならその衝突相手が悪い気がせんでもないが。
>>884 衝突が起きたらそのときにstd::で修飾すれば良い。
一般に、「グローバルでusing namespaceをすると名前空間の利点が失われる」というのは
言い過ぎだと思う。
886 :
デフォルトの名無しさん :2006/01/03(火) 22:10:48
事故ってから修復ってスタンスやだ クリーンを保ちながら育てていきたい
887 :
デフォルトの名無しさん :2006/01/03(火) 22:13:01
聞いてない空間名が出てきただけで激しく気持ち悪い
#include <iostream> #include <list> struct A{ int a, b, c; long x; }; struct B{ int a, b, c; }; struct Hoge{ A* pa; B* pb; }; void func0( std::list<Hoge>& list_hoge ){ for( std::list<Hoge>::iterator it = list_hoge.begin(); it != list_hoge.end(); ++it ){ std::cout << it->pa->a << it->pa->b << it->pa->c << std::endl; } } void func1( std::list<Hoge>& list_hoge ){ for( std::list<Hoge>::iterator it = list_hoge.begin(); it != list_hoge.end(); ++it ){ std::cout << it->pb->a << it->pb->b << it->pb->c << std::endl; } } ストライドが微妙に違うA、Bがありまして、それをアクセス用のポインタとして持つHoge型があります。 Hoge自体はいじれるのですが、厄介なことにHogeにアクセス用ポインタを持たせるという点だけは変えられません。 func0とfunc1はそのストライドの差以外は全く同じ処理なので、どうにか一つにしたいと思っています。 しかし、template、union・・・・それなりに考えて見たのですが、上手く行きません。 何か良い手をご存じの方、いらっしゃいましたら是非にも。
>>888 A を B から public継承すればいいじゃん。
>>889 ヒントありがとうございます、なんとなく出来そうな気がしてきました。
もう少し悩んできます。
>>890 あと、その func0/func1 は B のメンバ関数にするときっと幸せになれる。
>>888 メンバへのポインタを使ってみた。
typedef std::list<Hoge> HogeList;
template<typename T>
void func(const HogeList& list_hoge, T* Hoge::*member) {
for (HogeList::const_iterator it = list_hoge.begin(); it != list_hoge.end(); ++it) {
const T& foo = *(*it.*member);
std::cout << foo.a << foo.b << foo.c << std::endl;
}
}
int main(){
const std::size_t N = 3;
B a[N] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
};
Hoge hoge[N];
for (int i = 0; i < N; ++i)
hoge[i].pb = &a[i];
HogeList ls(hoge, hoge + N);
func(ls, &Hoge::pb);
}
893 :
892 :2006/01/03(火) 22:51:51
それで気付いたんだけど、イテレータに対して->*が使えないのはどうかと思った。演算子オーバーロードしろよ。 .*はなぜか*よりも優先順位が低いから、そのせいで括弧の数は増えなかったけどさ。
>>891 さらにヒント感謝です。なるほど・・・。
>>892 ぐぁ、凄い。すぐに理解できないですが、じっくり読んでみます。
お二人ともありがとうございます
895 :
デフォルトの名無しさん :2006/01/03(火) 23:24:26
横からすみません >> T* Hoge::*member はなんでT* Hoge::member じゃだめなんですか?
Loki::Int2Typeやboost::enable_if使用すべきタイミング。
898 :
デフォルトの名無しさん :2006/01/04(水) 02:15:04
メンバ関数にしない理由がわからん。
int hoge(100); なんていう初期化、ありなんですか?
int hoge(int(100));
902 :
デフォルトの名無しさん :2006/01/04(水) 12:58:58
int hoge((int)int(100));
>>899 それができなかったら、templateで使えねー。
あの、英語読めないのでC++の解説書でも読もうと思うのですが 例えばifstreamクラス内のメンバ関数や定数を一つ一つ丁寧に説明しているお勧めの本ってありますか?
後々嫌でも英語読むことになるから、イマノウチに読めるようになっとケ
907 :
デフォルトの名無しさん :2006/01/04(水) 18:02:41
Java のアプレットに対して、外部ツール(VC++で作成)からコンボボックスの操作および ボタンの押下を制御したいと思っていますが、うまくいきません。 ボタンが押されたときにアプレットのウィンドウに送られるメッセージをSPYで監視して それらしいメッセージを送ってみたのですが、期待する動作をしません。 コンボボックスの操作は出来たのですが。。。 何か考え方が間違っているのでしょうか?
909 :
デフォルトの名無しさん :2006/01/04(水) 18:30:40
goto Win32スレ;
910 :
908 :2006/01/04(水) 18:41:08
>>909 誘導ありがとうございます。
お手数をお掛けしました。
質問です。以下のようなエラーが出るのですが仕様でしょうか。 仕様なら、綺麗な回避方法はあるでしょうか。 (typeを一緒にテンプレートパラメータとして渡すとか位?) コンパイラはcygwinのgcc3.4.4です。 コード----------------------------------------- template <class T> struct foo { typedef typename T::type type; }; template <class T> struct goo : foo<goo<T> > { typedef T type; }; main() { goo<int>::type t; } コンパイル結果--------------------------------------------- test.cpp: In instantiation of `foo<goo<int> >': test.cpp:8: instantiated from `goo<int>' test.cpp:13: instantiated from here test.cpp:4: error: no type named `type' in `struct goo<int>'
template <class T> struct foo { typedef T type; }; template <class T> struct goo : foo<T> { using foo<T>::type; }; int main() { goo<int>::type t; }
913 :
デフォルトの名無しさん :2006/01/04(水) 20:43:49
>>911 goo の無限再帰でコンパイラがラリった?
コンパイラのせいというより、単純に goo<int>のインスタンス化にはgoo<int>が必要っていう 自己言及による矛盾が起きてるだけかと。
>>911 struct goo : foo<goo<T> >
これ展開しようとしたらどうなるんだっけ?
916 :
デフォルトの名無しさん :2006/01/04(水) 20:53:07
テンプレートの再帰は特殊化で止めるんだけど このケースでは無理そうだな
どうしたらこんな状況になるのか分からない
>>911 VC6,VC2005なら通るね
CRTPって言うんだっけ。
ATL/WTLなんかこんなコードだらけのような
919 :
918 :2006/01/04(水) 21:21:23
ATL gaかなりこんな感じのコードだらけなのは確かだよね。 うまく避けてるんだろう・・・
>>911 こんなとこか
template <class T>
struct foo {
struct apply{typedef typename T::type type;};
};
922 :
918 :2006/01/05(木) 00:33:53
>>911 >(typeを一緒にテンプレートパラメータとして渡すとか位?)
↓こういうことなのかな?とりあえずVCでは通る。
template <class T, class TY>
struct foo {
typedef typename TY type;
};
template <class T>
struct goo : foo<goo<T>, T> {
typedef T type;
};
でも、911の意図通りの展開がされてるのやらどうやら?
頭こんがらがってよく分らない
>>911 こんなのも
template <class T>
struct foo;
template<template<class>class F, class T>
struct foo< F<T> >{
typedef T type;
};
回避方法なんていくらでもあるってことだな。
>912-924 ありがとうございます。 >917 本当はgooはテンプレート引数がもっと多い巨大なクラス。 その中から幾つかをfooに渡してfooを特殊化すれば、 gooを全部特殊化しなくてもいい (さらに本当はfooにあたるクラスは複数あって、 各々の特殊化をgooが多重継承して一つのクラスに仕上げる、 という構造になっている。) ↓ しかしその中でgooで定義されるtypedefが必要になった ↓ gooをパラメータで渡したらこうなった といった経緯なんです。 922さんのがまさに意図していた回避法なんですが、 かなり凄い量のパラメータを与えなければならないので微妙な感じです。
>>925 一旦白紙に戻してクラス設計やり直した方がいいんじゃまいか?
流石に巨大なテンプレートクラスを複雑に多重継承していかないと
駄目なようなのは、設計として破綻してる希ガス
ていうかこれ情報小出し臭い質問の仕方でしたね。 エラーになる部分だけ抜き出したつもりだったんですが…… 結局回答を参考にしつつ、力技でなんとかすることになりそうです。
>>927 今頃気づいたか。最も第三者から見て理解不能の質問の仕方だ。
929 :
デフォルトの名無しさん :2006/01/05(木) 11:30:24
それなりに話のねたにはなったんで迷惑じゃなかったけどね
930 :
デフォルトの名無しさん :2006/01/05(木) 12:16:52
template<class T> int func(T arg); というテンプレート関数があるのですが、 Tがクラス型などの場合に備えると、引数は参照にすべきなんでしょうか? その場合参照の引数のと参照なしの引数のと2つ関数を用意すべきでしょうか?
>>930 1. boost::call_traits<T>::param_type
2. const T&
3. T
>>932 優先順位。上のほうが望ましいと俺は思っているだけ。
>>933 じゃあboostない場合はconst T&で一括でもよろし言うことですね
ありがとございますっ
template <class T> struct call_traits { typedef const T& param_type; }; template<> struct call_traits<int> { typedef int param_type; }; //以下値渡しするものすべてについて繰り返し
Boostをダウンロードすればいいじゃないか。
>>937 あっ、boostと同じようなものを作れっちゅーことでしたか
てことは組み込み型は参照で受け取ったらまずい場合があるちゅうことですかね?
>>940 いろいろ調べましたがわかりません、何故効率が悪いのか教えてくださいな?
本来間接参照しなくてもいいものを間接参照してしまうからだろ
なるほど、実引数でコピーした実体を直で扱うのではなく、 アドレスを参照して扱うので効率が悪いというわけですか
組み込み型でもdoubleだと微妙かもね。
64bitならポインタの大きさがdoubleと一緒だ
その程度だともう処理系とか周りのコードに依存するんじゃないのか
>>946 するする、doubleの引き数はスタックを介さずに受け渡すコンパイラもあることだし。
#つーか、そもそも最適化で消える可能性もあるわけで。
インライン展開できないような関数をオーバーヘッドが気になるくらい 何回も呼び出すっていう設計が想像できない俺は素人? それともでっっっかいクラスから組み込み型にまで使う超汎用ライブラリなんだろうか
まあ、素人だね。 画像処理やってみなっせ。
>>943 値渡しのとき、オブジェクトが複製されるかどうかはコンパイラも含めて状況による。
レジスタ使いまわして、まったくオブジェクトのコピーが発生しないケースもありうる。
>>948 どんなのがインライン展開されるべきかは規定されてないから、よほど自明でないかぎり
常に関数呼び出しのオーバヘッドはあると思ってたほうが安全。嫌なら手で最適化するしか。
951 :
VC++スレから飛んできました :2006/01/07(土) 10:07:19
よく単位を間違えて代入してしまうので、 別の型にしておけばいいじゃん、と思って typedef double millisecond; typedef double microsecond; typedef double second; ってやったけど、 millisecond x = 0.1; microsecond y = 0.2; second z = 0.3; としても x=y; y=z; z=x; とかなんの警告も出ないのね。 やっぱそれぞれクラスを作らなきゃだめ?
boostかどっかにstrong_typedefってなかったっけ?
D言語にするか、クラスにするかのどちらか
D言語なんか問題外。ここはC++スレです。
955 :
デフォルトの名無しさん :2006/01/07(土) 10:50:57
BOOST にあるね。 boost/strong_typedef.hpp 見てみた。 結局主要な演算子を定義した構造体を作ってるだけだった。 #include <boost/strong_typedef.hpp> BOOST_STRONG_TYPEDEF(double,strong_millisecond); BOOST_STRONG_TYPEDEF(double,strong_microsecond); BOOST_STRONG_TYPEDEF(double,strong_second); とすると、 strong_millisecond x = strong_millisecond(0.1); double d = (double)x; と明示的に変換しないといけなくなる。 うはwww、これでポカミスしないですみそうだ。 正規表現ライブラリくらいしか boost つかってなかったけど、 また一つ boost の恩恵に浴することができた。
こういう単位付きの量を表すためのライブラリってなんかBoostで作りかけのものがあったような気がする。
boost.mpl のチュートリアルに速度と質量とを掛け算したもの同士でしか比較できないとか 速度/時間 * 時間 == 速度 とか、数値と物理単位を同時にあつかうような例があったと思う。
958 :
デフォルトの名無しさん :2006/01/07(土) 11:17:07
くぁwせdrftgyふじこlp;「」’
とっつぁ(ry
お前ら面白すぎ
元々ハンガリアン記法は、型名を付けるんじゃなくて、 型の意味を付けるはずだった、と言う話を思い出した。 inchAvgDistance += mmDist[0]; で間違いが直ぐ判るとかなんとか。
全然わからん
965 :
343 :2006/01/07(土) 22:21:08
#defineを使って としてCLASSES(Hoge)を class Hoge; class HogeFactory; と展開させられないでしょうか お願いします
966 :
965 :2006/01/07(土) 22:25:31
誤爆、965≠343です
class Hoge; class Hoge ## Factory;
968 :
デフォルトの名無しさん :2006/01/07(土) 22:41:15
>>967 の ## の前後のスペースはいらないね。
って、2ch だと勝手に入っちゃうんだったっけ?
それはそうと、開区間、閉区間、片開区間を表現する
標準的なクラスって用意されていましたっけ??
969 :
965 :2006/01/07(土) 23:19:47
>967 お早いレスありがとうございます。 おかげさまで、いろいろやりたかったことができそうです。
>>965 俺もそんなことをやったことがあったが、
結局後でテンプレート使えば言いやということに気付いて#defineには引っ込んでもらった。
972 :
デフォルトの名無しさん :2006/01/08(日) 00:08:02
Boost にはあるのか。使おうかな。 Boost って本当に何でもあるよな。 えらい人たちが標準化も視野に入れてやってるんだから 大丈夫だとは思うけど、なんでもいれちゃえ、って 感じじゃないんだろうか・・・
>>972 Boostに収録されるまでにも過程があって、
認められないとBoostには収録されない仕組みになっている。
一部分だけ異なる似たような処理を、簡潔かつ実行速度が速くなるように 記述する方法ってありませんか? 2次元配列に対して処理を行う関数を複数作りたいと思っています。 例えば以下の関数sumは配列の合計を出す関数です。(変数宣言などは省略) int sum(){ (前処理) for(r = 0; r < nRow; r++){ for(c = 0; c < nCol; c++){ s += cell[r,c]; … (1) } } (後処理) return s; } 似た形として、平均値を出す関数や配列の中身をインクリメントする関数など、 (1)の部分だけが異なる関数をたくさん作りたいと思っています。 ただ、(1)の部分だけ違う関数を作るにはこのままではループ部分や前処理・後処理も 記述しないといけません。 新しく関数を付け加えたいとき、できれば(1)の部分だけ書けばいいような形に したいのですが何かいい方法がありませんか? なお、ループの回数が多いため(1)の部分は関数呼び出しの形にはしたくないです。 (コンパイルしてインライン展開されるならok)
cell[r,c]はcell[r][c]の間違いです。
>951 typedefは別の名前をつけるだけで、全部同じ型だよ。 でも、例に挙げているのは全部同じ単位だから、別の型に定義するのは 止めといた方が……double使うのなら素直に基本単位にして使うのが 吉だと思う。
>974 MetaProgram
今猫のページでC++を勉強してるのですが、 vectorクラス、mapクラス ...と勉強していっていきなり basic_stringコンテナとか不明な表現が出てきて困っています 察するに今までのvectorやmapも各々 vectorコンテナ mapコンテナ 的な感覚でいいのでしょうか
980 :
デフォルトの名無しさん :2006/01/08(日) 02:22:41
>>979 Yes
ひっくるめて、コンテナクラスライブラリといったりするね。
C++ だとそれを実現するためにテンプレートを使うから、
テンプレートライブラリと言うことも多いけど。
>>979 container = 入れ物
和訳してみれば分かりやすいものも結構ある。
頑張れ。先は長いぞ。
982 :
デフォルトの名無しさん :2006/01/08(日) 02:35:31
>>951 次元解析は Barton and Nackman trick と呼ばれる有名な解決法あり。
>>980 >>981 はい、ありがとうございます
せめてヘッダーの中が読めればいいのですが・・・
精進します
クラス内でプロトタイプ宣言した enum型の型をclass A{…}の外で実装しようとしたのですが class A{ public: enum Event; }; enum A::Event{ onClick, onMove }; //この行で未定義のシンボル A::Eventとエラーがでてしまいました どう書けば良いのですか…ご教示お願いします
985 :
984 :2006/01/08(日) 03:48:19
すいません、↑は enum A::Event={ onClick, onMove };と書き間違えました
986 :
984 :2006/01/08(日) 04:04:14
985は間違いです…ごめんなさい、もう寝ます
>>974 こんなんで。それなりの最適化するコンパイラならインライン化は十分期待できるんじゃないかな。
もちろん関数ポインタじゃなくて関数オブジェクトで書いてもいいけど好みで。
#include <iostream>
const int nRow = 3, nCol = 2;
int cell[nRow][nCol];
template<class T, void func(T&, int&)>
T apply() {
T tmp = 0;
for (int r = 0; r < nRow; ++r)
for (int c = 0; c < nCol; ++c)
func(tmp, cell[r][c]);
return tmp;
}
void inc(int &tmp, int &x) { ++x; }
void add(int &tmp, int &x) { tmp += x; }
typedef int apply_func(void);
apply_func *all_inc = apply<int, inc>;
apply_func *sum = apply<int, add>;
int main() {
all_inc();
std::cout << sum() << std::endl;
}
989 :
974 :2006/01/08(日) 11:20:58
>988 あーなるほど、関数ポインタ自体をテンプレートにしてしまえばいいのか。 自分で考えたときには関数ポインタを引数で渡す形しか思い浮かばなかったので、 これじゃインライン展開されないよなぁ…ということでドツボにはまってました。 MetaProgramってのははじめて聞きました。 でもやることに対してちょっと大掛かりすぎるので今回は見送りたいと思います。 これで見難いマクロで無理やり実現する必要がなくなりそうです。 どうもありがとうございました。
梅
新スレは?俺が立てるの?
テンプレートスレはなくなったから、 「テンプレートは別スレ」という表現はどうかと思う。
埋まるまで息止める
苦しい早く埋めてくれ
afsd
うめ
埋めはらがー
うめ
コンクラーベ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。