C++相談室 part69at TECH
C++相談室 part69 - 暇つぶし2ch461:デフォルトの名無しさん
09/05/25 07:46:16
しばらくVBAばっかりいじってたから、C++のウィンドウの扱いが面倒に思えて困る

いつもVCの空のプロジェクトにダイアログリソース突っ込んで出してるんだが
ひょっとして空のプロジェクト使わなければC#とかみたいに簡単に扱えるのかな?
空じゃないプロジェクトって最初からコードいっぱい書いてて抵抗あったから今まで触ったこと無いんだ

462:デフォルトの名無しさん
09/05/25 07:48:25
スレ違いすぎるだろ…

463:デフォルトの名無しさん
09/05/25 08:31:50
>>461
vcでポトペタできるのはダイアログだけだよ
ウィンドウはムリポ
スケルトンコードは慣れかな
どうせ似たようなコード書くんだし

続きはVSスレかWinAPIスレかMFCスレで

464:デフォルトの名無しさん
09/05/25 08:46:11
461です、スレ違いすまんかった
覗いてみた感じここの奴は視野が広そうだったから、ここで聞いてしまった

数年前に比べて大して便利になってないという事だな
昔作ったスケルトン掃除して使ってみるよ、ありがとう

465:デフォルトの名無しさん
09/05/25 19:30:32
blitz::Arrayって何を意味してる? ググってもわからんかった

466:デフォルトの名無しさん
09/05/25 19:46:06
>>465
C++の言語に関する話としては
blitzというクラスの、Arrayというメンバ。もしくは、blitzという名前空間に含まれる Array というもの。

実際ぐぐってみたところ、Blitz++というライブラリがあるみたいだね。
このライブラリでblitzという名前空間を使っているようだ。

467:466
09/05/25 19:47:15
英語が苦手で無いなら以下をどうぞ。
URLリンク(www.oonumerics.org)

468:デフォルトの名無しさん
09/05/25 20:11:46
>>467
回答どうも 軽く読んでみた。
じゃあどうやら 『blitz::Array< int, 2 > A 』 って宣言だと
『中に整数値の入る2次元の行列式の定義をbiltzっていう名前空間でやってる』って感じでいいのかね
Arrayは直訳で行列じゃなくて配列なのが気になるんだけどね・・・

469:デフォルトの名無しさん
09/05/25 20:15:59
>>468
細かいとこちょっと違うけど概ねそんな感じ。

470:デフォルトの名無しさん
09/05/25 20:21:33
>>469
ごめん Cは前々からやってたんだけどC++は最近独学で始めたばっかりなんだわ…
で、違うところって? (俺の知識が浅いから、伝わらなそうだったらスルーしてくれ)

471:デフォルトの名無しさん
09/05/25 20:24:23
>>470
ごめん、ちょっと忙しくなるから、後でまた来るわ
そのときまでに他のレスがついてなかったら書くよ

472:471
09/05/25 21:07:14
まず、blitz::Array そのものは blitz名前空間の中に入ってるが、
blitz::Array< int, 2 > A;
とした場合、(これ自体をblitz名前空間の中に書かない限り)このAはblitz名前空間には入らない。

あと、「行列式」じゃなくて「行列」だな。(似てるけど意味が違う)

473:デフォルトの名無しさん
09/05/25 21:10:27
行列式でいいだろ
行列を表すexpressionなんだから

determinantのことを言いたいなら、それは揚げ足取りと言うものだ
感心しない

474:デフォルトの名無しさん
09/05/25 21:10:55
C++始めたばかりなら名前空間をよく分かってないかもしれんが
まあ、ちょっと語弊があるけど “blitz::Array<int,2>” で1つのクラス名だと思ってしまってもよい。
int a;
がint型の変数aであるのと同じように
blitz::Array<int,2> a;
は blitz::Array<int,2> 型の変数aだ。

名前空間ってのは、例えばライブラリ作成者がArrayっていう名前のものを提供している場合、
利用者のコードにもArrayってのがあると名前が衝突してしまって不都合だから、
名前がぶつからないように blitz:: という修飾をつけてるんだと思えばよい。

475:デフォルトの名無しさん
09/05/25 21:12:06
>>473
そうか? 俺はどうしても気になるし明確に誤りだと思うが、まあ揚げ足取りと取られるならこれ以上は言うまい。

476:デフォルトの名無しさん
09/05/25 21:14:04
>>473
アホだろお前。

477:デフォルトの名無しさん
09/05/25 21:55:28
行列式は駄目でしょ

478:470
09/05/25 22:04:48
なんか複数人からレスもらってるみたいで、皆さんどうもありがとう
blitz::Array<int,2> 型の変数aって感じは掴めてたんだけど、そもそもblitz::Arrayは何を表現するのかが不明で困ってたのよ

それはそうとプログラム板って初めて来たけどID表示ないんだな、不便じゃない?

479:デフォルトの名無しさん
09/05/25 22:13:22
>>476
そういう言い方はたとえ2chでもどうかと思うぞ

まぁでも
行列と行列式は…何と何くらい違うんだろ。ブドウとグレープフルーツくらい?

480:デフォルトの名無しさん
09/05/25 22:16:39
>>478
スクリプト書けばID丸わかりだから不便じゃないよ。

481:デフォルトの名無しさん
09/05/25 22:53:31
IDが分からなくても別に不便を感じたことない。

482:デフォルトの名無しさん
09/05/25 23:01:25
Win32APIスレはなりすましで大変なことに…

483:デフォルトの名無しさん
09/05/25 23:06:44
別に大変じゃないし

484:デフォルトの名無しさん
09/05/26 10:34:48
>>395

A(int i) { i = hoge; }

↑ は何をしたいの?

485:デフォルトの名無しさん
09/05/26 15:55:38
とてもサイズの大きなメンバ変数があったとき、
「そのメンバ変数のポインタを返すようなメンバ関数を作る」か、
「そのメンバ変数のコピーを返すようなメンバ関数を作る」か、
どちらがオブジェクト指向としてはよろしいのでしょうか?
前者だと、privateなメンバ変数に対して外部からタッチしてしまうことになりますが、
無駄が少ないように思えます。
後者だとprivateなメンバ変数を保護(?)できるというか、そういう考え方に則しているような気がしますが、
無駄にメモリを食ってしまう気がします。
完全に独学のため、ちょっと意味不明な単語が混じっているかもしれませんが、
教えてください。よろしくお願いします。

486:デフォルトの名無しさん
09/05/26 16:03:49
>>485
どちらも問題外
クラスの設計をし直せ

487:デフォルトの名無しさん
09/05/26 16:11:05
int gethoge();のような関数を作るのはよろしくないということなんでしょうか?
↑だとintのコピーを返す関数に当たると思うのですが、問題外となると、ちょっと目の前が真っ暗になってきました…。

488:デフォルトの名無しさん
09/05/26 16:49:15
privateな構造がしゃしゃり出てくるクラス設計が間違い
最初からpublicに分類すべき
それで問題が出るなら普通の人なら根本から作り直すね

489:デフォルトの名無しさん
09/05/26 16:54:31
すみません、現段階ではちょっと理解できないのですが、文献を漁ってなんとかしてみます。
貴重なアドバイスありがとうございます。

490:デフォルトの名無しさん
09/05/26 16:55:12
>>485
const なポインタ or 参照を返せば、他から変更はできないけど、
他の部分がそのオブジェクトの構造に依存することになるね

491:デフォルトの名無しさん
09/05/26 19:08:44
アクセス制御がなんのためにあるのかという根本が分かってないように見える

492:デフォルトの名無しさん
09/05/26 19:49:43
>>485
まあ要するに、

クラスのクライアント(使う人)が
privateなメンバ変数(およびprivateメンバ関数)
については何も知らなくても
publicなメンバ関数を見るだけで
使えるように設計すべき

ということだよ。
これはすなわち、public/protectedなメンバ関数以外が変わっても
クライアントが書いたコードには影響がないということ。

ちなみにpublicなメンバ変数なんて大抵はクソ設計の証。


493:デフォルトの名無しさん
09/05/26 20:06:47
485じゃないけど
>>492
それは基本的にはカプセル化に重点を置いてコードを書いた方が良い、ということで良いんでしょうか?

494:492
09/05/26 20:41:33
>>493
そう。基本的にはね。
オブジェクト指向プログラミング (OOP; object-oriented programming)
においてカプセル化はとーーっても大事。

たまにいっそ全部publicにということで構造体structを使うことがあるけど
基本的にはそういうこと。


495:デフォルトの名無しさん
09/05/26 21:29:31
なんとなく分かってきました、ありがとうございます

496:デフォルトの名無しさん
09/05/26 21:44:30
まあ現実的にはpublic変数だの参照返しも使うことはあるけどね

497:デフォルトの名無しさん
09/05/26 21:47:56
ねえよ

498:デフォルトの名無しさん
09/05/26 21:52:34
無意味な隠ぺい無意味な複スレッドは考える力が足りない人が一度はハマる道程だからね

499:492
09/05/26 21:54:08
現実にはそういう場合もあるかもしれないけど、
「良いクラス設計」の話に限った場合、フツーはない。

「全部publicにということで構造体struct」
は返り値に複数の情報を持たせたい時とかにありえる。
ただ複数の型を束ねただけ。


500:デフォルトの名無しさん
09/05/26 21:57:34
GetとSetがズラリと並んだクラスは結構見るな

501:デフォルトの名無しさん
09/05/26 22:00:53
ねえよ

502:デフォルトの名無しさん
09/05/26 22:04:41
>>500
学生の頃作ったプログラム見直してみるとGetとSet多用しててえらいことになってた
今でもうまい設計はできないけど、他で使うならpublicでいいよねって話だよな

503:デフォルトの名無しさん
09/05/26 23:46:22
Effective C++には最悪でもget()とset()用意しろって書いてあるよ^^

structでメンバ変数をpublicにするのは
>>499の言うとおり、値を束ねただけのものとして、
構造体を値として扱う場合にだけ許される。

Effective C++やC++ Coding Standards、Google Coding Standardsなんかを
ひとつも読んでいない人間はC++触らないでください

504:デフォルトの名無しさん
09/05/27 00:14:57
>>503センセー俺1つも読んだことないんですけどー

505:デフォルトの名無しさん
09/05/27 00:21:02
読むだけなら馬鹿でもできるから気にする必要無い

506:デフォルトの名無しさん
09/05/27 00:43:52
class A{
int a;
public:
int get(){return a;}
void set(int i){a = i;}
};

こういうのはさすがにpublic派のほうが多い気がする

507:デフォルトの名無しさん
09/05/27 00:53:05
宗教になぞらえられたりする理由なんだろうけど本人が気付くまで周りが何を言っても無駄なんだよね
距離を置いて厄災に巻き込まれないようにするだけ

508:デフォルトの名無しさん
09/05/27 01:15:12
>>506 が「何を」 public にするのかは知らないけど、
もし int a を public にする気なら、豆腐の角に頭をぶつけて死ねといいたい

509:デフォルトの名無しさん
09/05/27 01:27:16
メンバ変数をpublicに置くような人間は抽象化には興味ないんだろうな。
C++使う理由がないよ。多分。

510:デフォルトの名無しさん
09/05/27 01:33:51
aがクラスや配列やポインタなら全くもってその通りだがintだぜ?
こんなプリミティブなメンバまで変更しなきゃならない時にはどうせインターフェースも変更入るよ
そこまでいちいちgetset噛ませと言い出すとちょっと原理主義すぎて現実的でない

511:デフォルトの名無しさん
09/05/27 01:49:08
こういうとき、プロパティのある言語がうらやましいと思う。

512:デフォルトの名無しさん
09/05/27 01:50:40
もしgetterやsetterで参照する対象が巨大な配列やクラスだったら
重いコピーが発生する事を覚悟しなければならない

つまり巨大な配列やクラスはgetterやsetterの対象にはならない

513:デフォルトの名無しさん
09/05/27 01:55:01
>>510
返すのがintだからどうだって話じゃないだろ。たとえば
class A{
int a,b,c,d,e,f,g,h,i,j,k,l,m,n;
以下略
};
こんなのの実装をimplイディオムに変えたいと思ったときどうすんだよって話。


514:デフォルトの名無しさん
09/05/27 01:55:07
どこの世界も原理主義には付き合ってられない

515:デフォルトの名無しさん
09/05/27 02:00:14
getとsetをpublicで公開するということは、
「いつでも誰でも見ていいし好き勝手に変えてもいい『何か』を持ってますよ」ということを
外部に向けて大っぴらに公開しているということです
したがって、そのセマンティクスを変更するのはインターフェースの変更なんだから
getとsetを使っている全ての箇所に影響が出てしまいます

これってよく見ると『何か』を変数としてpublicで公開した時と状況はまったく変わりませんね
publicなgetとsetを両方用意するというのは、同じ事を回りくどく書かせるだけであって
可読性も保守性も一切上がりません

intだろうと何だろうと何でもかんでもgetsetというのは罠であり、有害な迷信です
public変数のセマンティクスを持つものはpublic変数でいいんです

516:デフォルトの名無しさん
09/05/27 02:10:14
わずかなタイプ数の増加が"現実的"でない理由って何よ?

517:デフォルトの名無しさん
09/05/27 02:13:29
privateに固執するおまえはマダマダ無能と言われてるんだよ。

518:デフォルトの名無しさん
09/05/27 02:14:45
無意味なget setで行が肥大化するのはプログラムを見づらくするだけ。
原理主義的には、カプセル化した気分に浸れていい

519:デフォルトの名無しさん
09/05/27 02:14:47
現実には、そのセッタでだた代入するだけなんてことはなくて、
たいてい、ついでにどこかに値の変更を通知したり、
入力値が範囲外なら例外投げるようにしたりしていて、
単純にメンバ変数をpublicにできる場合なんて全然ないと思うんだけど。

そんな場合の話はしていないって?

520:デフォルトの名無しさん
09/05/27 02:18:11
今回の基準は>>506だろ。ただ代入するだけ。

521:デフォルトの名無しさん
09/05/27 02:18:39
今話題に上がっているのは、ただのset get。
意味があるのは問題なし。

522:デフォルトの名無しさん
09/05/27 02:27:02
マルチスレッドから操作されるようになったので、
aを防御したくなったらどうするの?
aが頻繁に変更されるようになったので、
毎回最新の値をサーバから取得したくなったらどうするの?
aに連動してbも変更したくなったらどうするの?
正当な値だけ受け付けるようにしたくなったらどうするの?
aが更新されたことをBに通知してあげたくなったらどうするの?
将来行われる変更を全部見通すことができるの?

523:デフォルトの名無しさん
09/05/27 02:31:06
>>519
そういう色んなことをする関数は単純なsetではなく、もっと意味のある名前を付けられるはず
なんかの大きさならresizeとか、通知するんだったらnoticeとか
その相方はgetとしか言い様がないこともあるだろうけどさ

両方とも本当にget,setとしか名付けようもないようなものは、その意味合いは内部的にも外部的にも
ただのpublicメンバ変数だと思うんだけどなぁ

>>522
排他制御はともかく、他はgetXXだのsetXXだのという名前を付けるべき操作ではない

524:デフォルトの名無しさん
09/05/27 02:36:49
>>523
何を根拠に。
ちょっとした処理付きのgetXX/setXXなんて普通に使うぞ?

525:デフォルトの名無しさん
09/05/27 02:41:39
お行儀の悪いプログラムってやつだな

526:デフォルトの名無しさん
09/05/27 02:46:21
>>525
アホは黙ってろ

527:デフォルトの名無しさん
09/05/27 02:54:33
もういいからsetしようとしたら強制的に例外投げろよ

528:デフォルトの名無しさん
09/05/27 02:59:26
>>527
それもpublicメンバ変数じゃできないな。
アクセス違反がせいぜい。

529:デフォルトの名無しさん
09/05/27 03:00:35
>>524
例えば「正当な値だけ受け付ける」ようにsetXXを変更したとしようか
そうなると不当な値が入ってきたらエラーなり例外なりを返すんだろうが、
旧バージョンのsetXXを使ったコードは当然そのエラーに対応する処理をしていないので問題が起こる

つまり、この変更はインターフェースの変更であって、全てのsetXXを使用するコードに修正を迫るものであるわけだ
素直にsetXXの呼び出しを全部修正してもいいし、旧setXXとは機能が違う新setXXを(機能に見合った名前で)
新しく別に作って適宜置き換えるのでもいいが、結局はsetXXの呼び出しは全てチェックする必要がある

でも、どうせset箇所を全部見直す必要がある変更なんだから
最初からpublic変数で書いて、必要になってからset関数を書いてもまったく同じだろ?

530:デフォルトの名無しさん
09/05/27 03:05:45
>>529
確かに、エラーの追加はインターフェースの変更だ。
そこは全面同意。

でも1つしか答えてないぞ。

531:デフォルトの名無しさん
09/05/27 03:56:00
> getとsetをpublicで公開するということは、
> 「いつでも誰でも見ていいし好き勝手に変えてもいい『何か』を持ってますよ」ということを
> 外部に向けて大っぴらに公開しているということです
この認識は間違い。
getとsetをpublicで公開するということは誰でも自由に行ってもいいのはただセッタゲッタの呼び出しだけで
その結果は呼び出し側の都合ではなくクラスの都合で決定されます。
クラスの都合を無視してクラスの状態の参照や変更を行うことはできませんということをいっている。

> 例えば「正当な値だけ受け付ける」ようにsetXXを変更したとしようか
> そうなると不当な値が入ってきたらエラーなり例外なりを返すんだろうが、
> 旧バージョンのsetXXを使ったコードは当然そのエラーに対応する処理をしていないので問題が起こる
こうした場合は実装の変更ではなく仕様の変更なのでセッタゲッタによるカプセル化(=実装の隠蔽)のメリットとは無関係。


532:デフォルトの名無しさん
09/05/27 04:06:47
個人的には自由変数を1個インターフェースとして公開するごとに
そのクラスの内部設計の自由度が減るのがいやだな

あとは>>519と同じ意見でただ代入するってのはあまりない
たいていマルチスレッド用の排他処理がくっついたりする

533:デフォルトの名無しさん
09/05/27 08:09:58
メソッドとメンバしかないC++が全て悪い。

object.set_value2( object.get_value0()->get_value1() );
こう書くより、

object.value2 = object.value0->value1;
こう書いた方が、見やすいものなぁ。

534:デフォルトの名無しさん
09/05/27 08:13:32
>>533
operator =で見やすいほうの書き方にできるのでは?

535:デフォルトの名無しさん
09/05/27 08:34:48
>>533
10年前に作られた言語だからな…

>>534
できなくもないけど結構面倒だよ

536:デフォルトの名無しさん
09/05/27 08:51:13
C++知らない俺が言うのもなんだけど、set/getなんていう
低レベルのインタフェース作るのが間違ってるんだよ。
もっと抽象化された機能のメソッドを作るべき

537:デフォルトの名無しさん
09/05/27 09:24:08
>>535
>10年前に作られた言語
wikipediaによると標準化からは10年だが、C++2.0から20年、前身のC with Classesから30年のようだ
D&Eなんかで示された考え方も今では古くなりつつあるのかと思うと少し寂しくなる


538:デフォルトの名無しさん
09/05/27 09:28:03
何でさっき知ったばかりなのに寂しがってんだよw

539:デフォルトの名無しさん
09/05/27 10:04:33
>>536
get/set全てが低レベルなインターフェースとも限らないけどね
2,3行目は俺も同じ意見だ

540:デフォルトの名無しさん
09/05/27 12:02:18
結局、変数をpublicに置くような連中に何を言っても無駄ということが証明された様子。
>>515に対する反論はEffective C++にずばり書かれてる。
ちなみに、Effective C++の著者であるメイヤーは別の書物、
Effective STLの中でそういう連中とは距離を取れと書いている。
まさに>>507の予言どおりだ。

541:デフォルトの名無しさん
09/05/27 12:26:20
ところで、メンバ変数をpublicにおく場合ももちろんある。
議論の冒頭、>>499はちゃんとそういう例外事項があることを認めている。
C++ Coding Standardsの第41項でも例外事項を設けているし、
setとgetの功罪(設計の過ち)についても言及している。

だから、「原理主義」でくくるのは議論の前提を無視している。

542:デフォルトの名無しさん
09/05/27 12:36:27
C++ Coding StandardsはC++関係の本の中でも厚さが特に薄い本だが
内容は濃いな

543:デフォルトの名無しさん
09/05/27 12:54:51
wikipediaのメソッドの記事にアクセサ論争って項目があるんだな
やっぱ昔から争ってる内容なのか

544:デフォルトの名無しさん
09/05/27 13:34:11
boost::arrayはpublicにメンバ変数を置いてるけどなぁ・・・。
これもだめなのか?

545:デフォルトの名無しさん
09/05/27 15:18:29
安全性を重視するか、高速性を重視するかは、設計者に委ねられてる
どっちが正解とかいうものではない

546:デフォルトの名無しさん
09/05/27 15:31:38
ときどき「高速化するため」といって安全性をスポイルすることを正当化する人間が出てくるが
そういう人間もCoding Standardsを読むべきだな。
高速化が正当化されるには「時期」があることが説明されている。
アジャイルプラクティスとかもあわせて読んでおきたい。

547:デフォルトの名無しさん
09/05/27 15:59:17
性的な意味で

548:デフォルトの名無しさん
09/05/27 18:00:17
>>544
PODにするためだから仕方ない

549:デフォルトの名無しさん
09/05/27 22:36:05
>>545
だから詳しく知らないなら断言するなよ。

getter/setterの速度がどうとか言ってる奴は
議論に参加する資格すらないから。

550:デフォルトの名無しさん
09/05/28 00:07:33
なんじゃこりゃ。
>>485の質問からなんでこんな流れになるのかさっぱりわからん。
ここは聞かれてもいない知識をひけらかす似非回答者たちのオナニー相談室ですか?


551:デフォルトの名無しさん
09/05/28 00:07:56
はいそうです

552:デフォルトの名無しさん
09/05/28 00:25:57
>>550
申し訳ありません。
ここは質問に淡々と答えるだけの
ボランティアたちによる慈善スレでした。
以後気をつけます。


でいいですか?

553:デフォルトの名無しさん
09/05/28 00:31:45
結局 >>485 に対する解答が1つも見当たらないんだが…
そもそも質問には、public なんて単語すら全く出てきてないよ?

>とてもサイズの大きなメンバ変数があったとき、
>「そのメンバ変数のポインタを返すようなメンバ関数を作る」か、
>「そのメンバ変数のコピーを返すようなメンバ関数を作る」か、
>どちらがオブジェクト指向としてはよろしいのでしょうか?

結局どうすればいいのよこれ?俺も知りたいよ

554:デフォルトの名無しさん
09/05/28 00:40:02
たぶん、オブジェクト指向の観点からは「どうでもいい」。
実際には実行速度とかconstnessとかあるだろうが、オブジェクト指向の問題ではないかと。

555:デフォルトの名無しさん
09/05/28 00:50:44
え、まじでいいの?
質問者の書き方だと、その巨大なメンバ変数は外部からは readonly にしたいんだと思うけど、
ポインタを返すと write できちゃうってのはオブジェクト指向からすると問題なんじゃないの?
俺の理解不足なのか…すまない

556:デフォルトの名無しさん
09/05/28 01:08:45
問題な事もあれば問題でない事もある。全てのパターンに付いて書いていたらきりがない。
その場その場で最も適当(若しくは、それなりに妥当)な方法を選ぶのがC++。

557:デフォルトの名無しさん
09/05/28 01:12:23
なるほどね

オブジェクト指向的には値を返すべきだが、
実行速度が必要な場合などは、オブジェクト指向に捕らわれるよりも処理速度を優先させてもいい

的な答えだと思ってた。そうでもないのか。さんきゅー。

558:デフォルトの名無しさん
09/05/28 01:19:01
以後、大きなサイズのメンバ変数を持っているクラスをA、メンバ変数をaとする。
1. 本当にaを外部に晒す必要があるのかよく考える。
2. Aに処理を任せられないかよく考える。
3. Aの名前を変えてみて、やっぱりAに任せられないかよく考える。
4. aの要素をすべて晒す必要があるのかよく考える。

それでもだめなら、

返却するメンバ変数も安全に作られているなら、
constのポインタか参照を返すようにすればそれで十分。
呼ばれるたびに新たなオブジェクトの生成が必要なら躊躇せずコピーする。

悪意あるプログラムから保護する必要がある場合も躊躇せずコピーするが、
たいていはそれだけでは不十分だと思われ。


90点回答だ。おまいらひれ伏せ。
異論はオカマ言葉で行うこと。

559:デフォルトの名無しさん
09/05/28 01:23:50
>>558
あたしの身体はひれ伏してるのに、あたしの息子が……どうしてくれんのよ! もう!

560:デフォルトの名無しさん
09/05/28 07:46:40
>>553
>>486が答えだろ
それ以降は雑談

561:デフォルトの名無しさん
09/05/28 09:38:38
参照するだけで値はいじらせない参照ができればいいんですよね
イテレータ的なものを使うという案は出ていないようですが
この方法はそれほどスマートな解決策ではないということでしょうか

562:デフォルトの名無しさん
09/05/28 09:40:03
えっと、参照するだけで値をいじらせないなら、const参照を使えばいいわけだが。

563:デフォルトの名無しさん
09/05/28 09:41:42
>>485って、例えば
class Person{
std::string name_;
public:
std::string *name() const { return &name_;} //A
std::string name() const { return name_;} //B
const std::string &name() const { return name_;} //C
const std::string *name() const { return &name_;} //D
};
みたいなのでAにするかBにするかってことだよね。
「とてもサイズの大きな」ってのが曖昧だけど、つまりコピーにコストがかか
るものってことだろう。
つまり回答は>>490だな(C,D)。
もちろんクラスやメンバの意味が変われば>>486もあるだろうけど、頭ごなしに
「問題外」というのは何か勘違いや思い込みがあるのだろう。


564:563
09/05/28 09:43:56
ああ、constを打つクセが……
- std::string *name() const { return &name_;} //A
+ std::string *name() { return &name_;} //A


565:デフォルトの名無しさん
09/05/28 11:37:19
>>563
そうかな
俺も
「データメンバAがあったとき、それを扱うメンバ関数Bはどう作ればオブジェクト指向っぽいでしょうか」
という質問はおかしいと思う

nameの例はあくまでnameがあってこそのname_でしょ?

566:デフォルトの名無しさん
09/05/28 11:42:58
nameっていっぱい書くとなめなめみたいでいやだよね

567:デフォルトの名無しさん
09/05/28 12:22:56
なるほどね
「とてもサイズの大きな」ってのが、そもそもおかしいよな。
大きかろうが小さかろうが、オブジェクト指向な振る舞いは同じはず。

568:デフォルトの名無しさん
09/05/28 15:32:14
実用上の振る舞いに問題が出るだろう。

569:デフォルトの名無しさん
09/05/28 15:46:30
タイ米はたいて買ったのに
古米に違いが出たら
悲しいやね

570:デフォルトの名無しさん
09/05/28 16:51:43
うん

571:デフォルトの名無しさん
09/05/28 18:31:51
ふ、古米・・・

572:デフォルトの名無しさん
09/05/28 21:12:43
(環境はcygwin) Blitz++のインストールエラーについて質問。
URLリンク(island.geocities.jp) のページに従ってBlitz++をインストールしようとしたんだけど、

cygwinの場合
"blitz-0.9"フォルダで以下を実行
$ ./configure
$ make install

の最後の行のmake install をコマンドしたら、
延々インストール文流したあとにエラー吐いて止まるのよ。
で、最後のエラー文をググったら、Blitz++のメールサポートページ
URLリンク(www.oonumerics.org)
にたどり着いてどうやら俺と同じエラーみたいなんだけど、
回答者は「gccのバージョン古いんじゃねーのー?」みたいなことしか答えてない。

誰か分かるひといたら助けてくれ


573:デフォルトの名無しさん
09/05/28 22:24:39
cygwinのgccは3.45だっけ?
後何カ所止まるか想像もできないのに
全部この板で聞いて解決するつもり?

無駄な努力はやめてgccバージョンあげとけ。
あと質問の仕方の問題点について20字以内で述べなさい。

574:デフォルトの名無しさん
09/05/29 01:51:39
環境依存で標準C++に何の関係もない。スレ違い

575:デフォルトの名無しさん
09/05/29 05:03:48
Effective C++を買おうと思うんだが、原著三版ってやつで大丈夫?

576:デフォルトの名無しさん
09/05/29 05:50:52
>>575
俺はそれ買ってみた。
とても良かった。

577:デフォルトの名無しさん
09/05/29 07:09:15
vsいれたほうがいいんちゃうんかと

578:デフォルトの名無しさん
09/05/29 13:43:45
じゃあ原著vs三版買うよ
改訂2版とか言うのがあるから、どっちにしたらいいのか迷ったんだけど
発売日で比べりゃ一目瞭然だったわ
サンクス

579:デフォルトの名無しさん
09/05/29 14:37:17
俺は両方買った

というか最初改訂2版しかなくて買ったら次本屋に行ったら
第3版があって俺涙目orz

580:デフォルトの名無しさん
09/05/29 21:23:58
Visual C++ 入れたいんだけど、Express Editionてやつだと
インスコ先にDドラ指定してもCドラを800MBぐらい食うのよ(今Cドラは1.5GBぐらいしか空きない)
スリム版みたいなのってないんですかね

581:デフォルトの名無しさん
09/05/29 21:59:08
ないよ

582:デフォルトの名無しさん
09/05/29 22:00:41
ぽいね

583:デフォルトの名無しさん
09/05/29 22:01:49
Cドライブを空けろ

584:デフォルトの名無しさん
09/05/29 22:14:07
新しくプロジェクトを作った後ソースやヘッダファイルを丸々コピーしてフォルダに移した後、既成項目の追加をして同じものを作ったつもりなのですが

アプリケーション更生が正しくないためアプリケーションの開始に失敗しました
マニフェストファイルを参照してエラーの原因を調べてください

と出ます、何がおかしいのでしょうか?DXUTを使っています

585:デフォルトの名無しさん
09/05/29 22:14:46
了解、といっても残り1GBからCCleanerかけてやっと1.5GBなんだよね・・
正直もう消すものないんだけどね 使ってない付属ソフトでも消そうかな・・・

答えてくれた人ありがとう!

586:デフォルトの名無しさん
09/05/29 22:25:14
>>585
Dドライブには空きがあるのなら、
ジャンクションやシンボリックリンク使ってDドライブにファイルを移せばいい。

587:デフォルトの名無しさん
09/05/29 23:20:46
>>586
ジャンクションやシンボリックリンクって
もしかしてXPだと無理? ググったらなんかVistaで使用可能とかでてきたんだけど

588:デフォルトの名無しさん
09/05/29 23:37:05
マウントのことなら別にWindows 2000でも出来てたが。

589:デフォルトの名無しさん
09/05/29 23:57:22
URLリンク(d.hatena.ne.jp)

590:デフォルトの名無しさん
09/05/29 23:59:50
00?

591:デフォルトの名無しさん
09/05/30 00:11:10
>>587
たしかできるはずー
EeePC901で容量稼ぐためにがんばったことがあった

592:デフォルトの名無しさん
09/05/30 00:57:10
今、フリーのBCCでWindowsのコンソールのプログラム書いてたんだが、
アラインメント関係がわからない。
とりあえず、現状を書くとある大きい処理がmain関数中に埋まってたんだが、
やたら遅いから(まぁ、処理量もあるんだが)なんとなく関数化してソースの先頭に
移動させたら早くなって、アラインメントが原因だと思うんだ。

で、ものとしては
for(i = 0; i<32*32*32; i++)for(i2 = 0; i2<32*32*32; i2++);
だけなんだが、原因は何だろう?
(関数の位置なのか、変数の位置なのか。
アラインメントがどのように影響するか分からないので、
どの辺に注意したらいいかおしえてほしい)

へたくそな文章でごめんなさい。。。分かる人お願いします。

593:デフォルトの名無しさん
09/05/30 01:26:05
本当にアラインメントなのか?
map出力して確かめてみたらどうよ(bcc32なら-M)

594:デフォルトの名無しさん
09/05/30 01:49:07
>関数化してソースの先頭に
>移動させたら

レジスタ割付されただけじゃねーの

595:デフォルトの名無しさん
09/05/30 03:11:59
このスレに書くべき話題かどうか分からないのだが、static_castってかなり誤解を受けてない?
俺もいくつかの入門向けサイトを見て「暗黙の変換を明示的に書くというだけの意味しかないのかな?」
と勘違いしていたが、実際には暗黙の変換が認められないいくつかのケースでもstatic_castができる。
このことってどれくらい知られてるんだろ。

596:デフォルトの名無しさん
09/05/30 03:20:57
そうかな?俺はdynamic⇔staticで対称になってて
static_castはコンパイル時にキャストに問題がないか判断するもの、って覚えてたが

むしろ「暗黙の変換を明示的に書く」って解説してるサイトがあるのか?
それは問題がある解説に見えるなぁ

597:デフォルトの名無しさん
09/05/30 03:24:33
自分は、static_castで可能なのは暗黙の変換とその逆向き、そしてユーザ定義変換と覚えていた。

598:595
09/05/30 03:25:48
うーん、改めて見てみると、俺が初心者時代に変な思い込みしただけかもしれん。まあいいや。

599:デフォルトの名無しさん
09/05/30 08:16:34
(なんかVC++から派生してC++の話と離れてきてる感じですいません・・・)
URLリンク(www.forest.impress.co.jp) ここによると、
>また、本ソフトは“ジャンクション”や“ハードリンク”なども作成可能。
>Windows Vistaでは多くの場合、シンボリックリンク以外を利用する必要はないが、
>Windows XP以下のバージョンのWindowsではシンボリックリンクが利用できないので、
>これらで代用しよう。
ってあるからシンボリックリンクはだめだけどジャンクションはいいみたいです

で、つまりCドラのファイルをDドラに移して、CドラにはDドラの移転先へのリンクだけ残しておけばいい
みたいな感じでいいんでしょうかね?



600:デフォルトの名無しさん
09/05/30 09:47:49
std::vector<double> a;
std::vector<double> b = a;

この場合って、
コピーコンストラクタが呼ばれるのか、代入演算子が呼ばれるのか
コンパイラによって違うんだっけ?

どこかに書いてあった気がするんだが忘れてしまった。

601:デフォルトの名無しさん
09/05/30 10:01:08
>>600
必ずコピーコンストラクタ。

602:デフォルトの名無しさん
09/05/30 10:01:48
const_cast…cv修飾子を除去するのに使う。
reinterpret_cast…ポインタと整数型の変換に使う。
dynamic_cast…略。滅多に使わず事足りる。
static_cast…以上3つ以外

っていう認識でいるわ。

603:デフォルトの名無しさん
09/05/30 10:04:10
>>600
カンチガイしているな

std::vector<double> a;//デフォルトコンストラクタ
std::vector<double> b = a;//コピーコンストラクタ
これらは「新しいオブジェクトを作る(construct)」なのだから
呼ばれるのは両方ともconstructor。
そして呼ばれるのは当然
前者はデフォルトコンストラクタ、後者はコピーコンストラクタ。

一方、
std::vector<double> x;//デフォルトコンストラクタ
このとき
x=b;
としたら、これは新しいオブジェクトを作るわけではないのだから
代入演算子operator =
が呼ばれる。

604:デフォルトの名無しさん
09/05/30 10:15:58
>>601,603
ありがと!

605:デフォルトの名無しさん
09/05/30 15:07:01
>>602
君はキャストしない方がいい。いつか死ぬ。

606:デフォルトの名無しさん
09/05/30 15:15:03
>>605
どこが間違い?


607:デフォルトの名無しさん
09/05/30 15:27:56
>>606
>>605ではないが、禿本のキャストに関する部分を読んでこい。

608:デフォルトの名無しさん
09/05/30 15:40:16
>>607
禿本持ってないが、今度勉強してみるわ。

んで
>>605さん、>>602のどこが間違い?

609:デフォルトの名無しさん
09/05/30 15:49:27
dynamic_castを多用するようになってきたら設計ミスを疑った方がいい。

610:デフォルトの名無しさん
09/05/30 15:53:01
俺はクロスキャストの時だけdynamic_castを使っているけどな

611:デフォルトの名無しさん
09/05/30 15:54:56
やむを得ない場合もあるけど、クロスキャストを多用するのも以下略

612:デフォルトの名無しさん
09/05/30 15:58:07
クロスキャストは仮想関数では解決できないだろ

613:デフォルトの名無しさん
09/05/30 15:59:31
そういう状況が多数生まれる時点で糞設計ってことを言いたかったんだけど。

614:デフォルトの名無しさん
09/05/30 16:04:06
誰も「多数」とは言ってないわけだが

615:デフォルトの名無しさん
09/05/30 16:07:31
>>614
>そういう状況が多数生まれる
の多数ってのは
>クロスキャストを多用する
の意味なんじゃないの?
なんで分からないの?w

616:デフォルトの名無しさん
09/05/30 16:22:24
全くの初心者でお聞きしたいんですが、C++の講義ではTurboCというソフトを使って講義が進められるのですが
自宅のPCで同じことをするにはどういったソフトを使えば良いのでしょうか?
講義も全くわからずコンパイルという意味も全くわからずソフトを探すこともままなりません。どうかご教授ください。

617:デフォルトの名無しさん
09/05/30 16:22:51
誰もクロスキャストを「多用する」とは言ってないわけだが

618:デフォルトの名無しさん
09/05/30 16:26:17
>>617
>>612と同一人物?
そうだとしたら、>>612は誰に対するレス?

619:デフォルトの名無しさん
09/05/30 16:27:30
何一人でエキサイトしてんの?

620:デフォルトの名無しさん
09/05/30 16:30:20
>>619
お前は誰に対するレス?
安価つけてくれ、分からないから。

621:デフォルトの名無しさん
09/05/30 16:32:15
>>620
断る
それ位自分で見抜け

622:デフォルトの名無しさん
09/05/30 16:34:06
>>621
いや、それを明らかにしておかないと、
俺が論破してもはぐらかされるだろ。

そういうヤツが多すぎるから、はっきりさせないと不毛な書き込みになる。

623:デフォルトの名無しさん
09/05/30 16:34:32
初めから不毛だと気づいてないのかこの馬鹿は

624:デフォルトの名無しさん
09/05/30 16:36:34
2chで議論すること自体不毛だよな。

625:デフォルトの名無しさん
09/05/30 16:41:11
まあせめてID付きの板でやるとか、コテハン付けるとかね。

626:デフォルトの名無しさん
09/05/30 16:44:20
>>622
顔真っ赤

627:デフォルトの名無しさん
09/05/30 16:47:07
>>626
鏡見て言ってるんだよね?

628:デフォルトの名無しさん
09/05/30 17:02:09
鏡?ディスプレイで十分なのに鏡?なぜに?

629:デフォルトの名無しさん
09/05/30 17:02:51
dynamic_castよりconst_castやreinterpret_castの方が多用したらまずいと思うんだけどどうだろうか
const_castなんかいまだに使いどこがわからん

630:デフォルトの名無しさん
09/05/30 17:08:12
const_castはsetの要素を変更するのに使う

631:デフォルトの名無しさん
09/05/30 17:09:15
>>630
そりゃまずいんじゃね?
木構造が壊れそうだが

632:デフォルトの名無しさん
09/05/30 17:18:40
>>629
const_castを使う主なケースは、糞なCのライブラリ関数の引数に
constな変数を渡すときだな。例を挙げるとこんな感じ。

void stupid_func(char *filename); // prototype

void Foo::some_method(const std::string& filename)
{
stupid_func(const_cast<char*>(filename.c_str()));
}

633:デフォルトの名無しさん
09/05/30 17:22:24
>>631
もちろん比較に影響及ぼすような変更はダメだぞ
構造体とかを入れたsetで、メンバの一つをキーに使ってるような場合があるだろう
そういう時にキー以外のメンバを変更するために使う

634:デフォルトの名無しさん
09/05/30 17:30:54
>>632
なるほど、ライブラリに渡すときなんかに使うのか
いくら糞でもライブラリ側を修正するわけにいかないもんな

635:デフォルトの名無しさん
09/05/30 17:55:27
volatile、組み込みでは見かけるがそれ以外では見かけたことがないんだが
おまいらはvolatileってどんな時(除く組み込み用途)使っている?
あと、const_castでvolatileを取るとる時ってどんな時?

636:デフォルトの名無しさん
09/05/30 17:55:44
>>633
俺はそういうのはmutableでやるなぁ。
const_castでやると、keyも含めて全て変更可能な「状態」になってしまうし。

637:デフォルトの名無しさん
09/05/30 18:09:49
>>583
aliceとかいう名前の開発ツールがたくさん入ってるから㍉

638:デフォルトの名無しさん
09/05/30 18:27:09
>>635
デバイスドライバを書く時には当然使う必要あるよね。

あとは、インラインアセンブリでローカル変数を上書きする時とか。
こんなことめったにやらないが。

639:デフォルトの名無しさん
09/05/30 18:48:24
>>636
mutableにすると、本当にキー以外もconstにしたいときに困るだろう
あくまでsetに入れたときの制約であって、そのためにmutableにするのは乱暴すぎる

640:デフォルトの名無しさん
09/05/30 19:11:35
キーがあるようなのはmapを使うなぁ
setの要素を変更とかやったことないな
今度やってみるか

641:デフォルトの名無しさん
09/05/30 21:11:30
>>635
VC++ではマルチスレッド対策の効果を独自に付加している。
URLリンク(msdn.microsoft.com)
Unixだとマルチスレッドでvolatileなんて使うなボケらしいが。

const_castで外したくなる状況は分からない。

642:デフォルトの名無しさん
09/05/30 22:40:15
誰も答えてやらない>>616のために
Visual C++ Express Editionでぐぐれ

643:デフォルトの名無しさん
09/05/30 22:44:10
Visual C++ Express Editionを知った後にTurbo Cを使うなんて、、、地獄だ。。

644:デフォルトの名無しさん
09/05/30 22:45:14
>>638, >>641
どうも、ほとんどアプリ系じゃ使わんということですな

>>641 の例じゃ普通はmutexやクリティカルセクション使うんじゃないの
それでvolatileを使うメリットがよく分らん,orz. コードが簡単になるがメリット?

645:デフォルトの名無しさん
09/05/30 23:24:24
Effective C++でconst_castはoperator[]の定義で使うことがあるみたいに書いてあったよね?
URLリンク(ritaz.blog64.fc2.com)
より引用。

class sample
{
public:
...;
const char& operator[](unsigned int position) const
{
...;
return dat[position];
}
char& operator[](unsigned int position)
{
return const_cast<char&>(static_cast<const sample&>(*this)[position]);
}
...;
};


646:デフォルトの名無しさん
09/05/30 23:32:43
>>645
blogにも書いてあるが、やりすぎな工夫の一例だな

647:デフォルトの名無しさん
09/05/30 23:44:12
>>644
どちらかというと、そういう排他制御の仕組みを自分で作るときに使う。

例えば下のコードをコンパイラが最適化した結果、
ロック確保する前や解放した後にhogeへ読み書きするコードが生成されたらシャレにならない。
MS仕様では、volatileなデータに読み書きするとそこを境界として、それより前後に読み書き処理が
ずらされないように最適化を抑えると言っている。

void f(hoge_t* hoge) //hogeを使うには排他制御でロックが必要とする
{
// ...
ロック確保

hogeを使う

ロック解放
// ...
}

648:デフォルトの名無しさん
09/05/30 23:48:16
>ロック確保する前や解放した後にhogeへ読み書きするコードが生成されたらシャレにならない。

意味が分からん。

最適化によって、「hogeを使う」に相当するコードが、「ロック確保」の前や「ロック解放」の後に配置されたらシャレにならないってこと?


649:デフォルトの名無しさん
09/05/30 23:50:52
>>648
ああ、ごめん。そういうこと。
携帯から打つのが面倒でいろいろ略した。

650:デフォルトの名無しさん
09/05/31 00:34:14
>>642
ありがとうございます。探してみます。

651:デフォルトの名無しさん
09/05/31 00:44:58
>>645
それ第何版の何節に書いてあるの?

652:デフォルトの名無しさん
09/05/31 01:30:20
>>644
そういう用途にも使えるってだけでWindowsでもマルチスレッドでvolatileなんて使わない
mutexなりクリティカルセクションなりInterlocked-系関数なり使えばそこでフェンス張られるし
(Interlocked-系関数でvolatile使われてるけどね。間接的には使うことになるのかな)

やっぱり組み込みとかドライバ以外で使うことはないと思うな

653:デフォルトの名無しさん
09/05/31 17:24:40
>>647, >>652
どうも、どうも

>>647
>そういう排他制御の仕組みを自分で作るときに使う
ずばり、自分でそういう仕組みは作ることないです

654:645
09/05/31 20:04:50
>>651
忘れた。
原著第3版に書いてあった。
確か、最初の方の章に。

655:デフォルトの名無しさん
09/05/31 21:20:51
改訂2版にはどこにも書いていないんだが、
第3版には本当に書いてあるのか?


第4版まであと2年はかかりそうな気がするし、
第3版買ってくるか・・・

656:645
09/05/31 21:28:28
>>655
第3版には本当に書いてある。
厳密に同じコードかどうが覚えてないが、
const版をnon-const版にて呼び出してconst_castでconst属性を外す
という方式であることは本当。
俺もそんなことして良いの!?と思ったから信じられなくても無理はない。


657:645
09/05/31 21:31:01
わざわざ引っ張ってきて確かめみた。
原著第3版(日本語翻訳されているもの)で
15ページから始まる項目にある。

658:デフォルトの名無しさん
09/05/31 21:48:18
2版の21項「使えるときは、必ずconstを使おう」に
対応するんじゃないかなと思うけど、
そこではmutableをサポートしてないコンパイラのための苦肉の策として
「みっともないけど」と前置きした上でconst外しをしている。

これのことじゃないよな?

659:デフォルトの名無しさん
09/05/31 22:06:17
>>658
じゃないってば。
少しは俺を信じろ(笑)

他の人も誰か証言してくれ。

660:デフォルトの名無しさん
09/05/31 22:08:18
ようやっと見つけたが、
さっぱり読めなくて意図が分からん。
URLリンク(books.google.co.jp)

俺の英語力も落ちたな・・・

661:デフォルトの名無しさん
09/05/31 22:10:32
ああ、これって王家の血を引く者にしか読めないよ

662:デフォルトの名無しさん
09/05/31 22:10:40
>>659
すまんwww
明日買ってくる。

663:645
09/05/31 22:12:21
>>660
メンバ関数foo()のconst版とnon-const版の定義が
同じようなものになることは多々あるじゃない。
同じような定義を繰り返し書きたくない、そんなあなたにconst_cast

って言うような主旨。
const版をうまく定義することで、non-const版の定義は
それを呼び出してconst性を除去するだけ
で良くなる。


664:デフォルトの名無しさん
09/05/31 22:13:17
>>661
俺読めたw
・・・そろそろ天の啓示が来る頃だろうか。

665:デフォルトの名無しさん
09/05/31 22:14:26
>>664
もしかして、お兄様なの!
こんなところで巡り合えるなんて。。

666:デフォルトの名無しさん
09/05/31 22:16:24
おまえか
しょせん、暇をもてあました神々の遊び

667:デフォルトの名無しさん
09/05/31 22:20:04
理解した。解説thx

感覚的にconst側で非constのコードを
再利用したくなりそうなものだけど
それも理由があるのかな。

とりあえず第3版買ってくるよ。
生き別れた妹はいなかった気がするし。

668:645
09/05/31 22:23:19
>>667
俺もそう思ったが、
理由としては
const側で非constメンバ関数を呼び出すというのはダメ
ってことらしい。
たとえ実際にはオブジェクトが変更されないとしても。

まあ買ってくる価値はあるかと。
何てったって名著だし、無駄な出費ではないと思う。

669:デフォルトの名無しさん
09/05/31 22:41:23
#define UNICODE
#define _UNICODE
で定義されたソースコードがあるとします。

それを
#define UNICODE
#define _UNICODE
と定義してはエラーになってしまう、つまりANSI版のソースに混ぜて使いたい場合どの
ようにすればいいのでしょうか?

たとえば


int WINAPI WinMain(…){
    …(ANSIソースコード)
   sub();
}

int sub(){
#define UNICODE
#define _UNICODE
   …(UNICODEソースコード)
}


みたいなことはできるでしょうか?


670:デフォルトの名無しさん
09/05/31 22:49:30
できます。

671:デフォルトの名無しさん
09/05/31 22:52:12
いまいち質問内容がよく分からんが、

#define UNICODE
#define _UNICODE
したあと
#undef UNICODE
#undef _UNICODE
すればdefineは消える。

でもWIN32なら、
UNICODE版、ANSI版両方そろってるはずだが。

672:デフォルトの名無しさん
09/05/31 23:25:45
CreateWindow("aaa",....
とかやってるんだろ

673:デフォルトの名無しさん
09/05/31 23:59:32
>>670 >>671
いやできなかった
結論からいうと
原理からいうとその方法でできるのは確かなんだが
UNICODEと_UNICODEは最初の最初で定義しておかなければならならないみたいだ
先にwindows.hとか読み込まれてるからその関係で動作がおかしくなる

>>672
アホすぎ



てか解決法をいうと単純にソースファイルをわければ解決できる
最初からやればよかったけど

674:デフォルトの名無しさん
09/06/01 00:14:01
本筋とは全く関係ないが、>>669を見ると_tWinMainにしろと言いたくなる。

675:デフォルトの名無しさん
09/06/01 01:15:41
もうこれから書くコードは全部_UNICODEでいいかもと思ってしまうがな。

676:デフォルトの名無しさん
09/06/01 04:06:41
なに、いいってことよ┏( ^ω^)┛

677:デフォルトの名無しさん
09/06/01 14:32:49
下の様な感じで合成関数を作ろうと思ったのですが、
error C2678: 二項演算子 '*' : 型 'composite_impl<result_type_,arg_type_>' の左オペランドを扱う演算子が見つかりません
とエラーが出ます。どうやって回避すればいいのでしょうか?

678:デフォルトの名無しさん
09/06/01 14:33:55
struct composite_type{};
template<typename result_type_, typename arg_type_>
struct composite_impl{
typedef result_type_ result_type; typedef arg_type_ arg_type; typedef result_type (*fn_type)(arg_type);
static fn_type &fn_holder(){ static fn_type fn; return fn; }
result_type operator ()(arg_type a) const{ return (fn_holder())(a); }
};
template<typename result_type_a_, typename result_type_b_, typename arg_type_b_>
struct composite_impl<result_type_a_, composite_impl<result_type_b_, arg_type_b_> >{
typedef result_type_a_ result_type; typedef arg_type_b_ arg_type; typedef result_type (*fn_type)(arg_type);
static fn_type &fn_holder(){ static fn_type fn; return fn; }
result_type operator ()(arg_type a) const{ return (fn_holder())(composite_impl<result_type_b, arg_type_b_>()(a)); }
};
template<typename result_type, typename arg_type>
inline composite_impl<result_type, arg_type> operator *(composite_type, result_type (*fn)(arg_type)){
composite_impl<result_type, arg_type> a; a.fn_holder() = fn; return a;
}
template<typename result_type_a, typename result_type_b, typename arg_type_b>
inline composite_impl<result_type_a, composite_impl<result_type_b, arg_type_b> > operator *(composite_impl<result_type_a, result_type_b> a, result_type_b (*fn)(arg_type_b)){
composite_impl<result_type_a, composite_impl<result_type_b, arg_type_b> > a; a.fn_holder() = fn; return a;
}
composite_type composite;
#include <iostream>
#include <cstring>
int fn_a(int a){ return a * a; }
char *fn_b(int a){ static char str[0xFF]; std::sprintf(str, "%d", a + 1); return str; }
int main(){ std::cout << (composite * fn_a * fn_b)(2) << std::endl; return 0; }

679:デフォルトの名無しさん
09/06/01 14:42:39
>>668
> const側で非constメンバ関数を呼び出すというのはダメ
> ってことらしい。
これって、単純にconstメンバ関数内で非constメンバ関数を呼び出すと
コンパイルが通らないって話。

680:デフォルトの名無しさん
09/06/01 15:00:03
>>679
const_castで*thisからconstを外すって話だよ。

681:デフォルトの名無しさん
09/06/01 15:12:45
>>680
あーそういうことね。
でも*thisのconst外しが駄目なのも当たり前の話だな。

682:デフォルトの名無しさん
09/06/01 20:59:19
*thisのconstは外してないぜ
むしろconstメンバ関数を呼ぶために*thisにconstを付けてる
外してるのは戻り値のconst

683:デフォルトの名無しさん
09/06/01 21:04:09
>>682


>>667-668
>>679-681
を読みかえしくれ。



684:デフォルトの名無しさん
09/06/01 21:13:26
???
>>645のことだろ?
static_cast<const sample&>(*this)は明らかに*thisにconstを付けてる
何か間違ってるのか

685:デフォルトの名無しさん
09/06/01 21:15:12
>>684
> >>645のことだろ?
否。
>>667-668の事。
それに対し>>679-681というやりとりが行われている。
皆は>>645は理解している。


686:デフォルトの名無しさん
09/06/01 21:18:48
なるほど理解した

687:デフォルトの名無しさん
09/06/01 22:34:32
いろいろあるよ。
URLリンク(www.sengoku.co.jp)

個人的には極細より線と鈴メッキ銅線が好きだけど (どうせ趣味だし)、
信頼性からジュンフロン線使う人のほうが多い。
このシリーズのより線はストリッパー必須。

ジュンフロンは苦手です。ええ。

688:デフォルトの名無しさん
09/06/01 22:36:18
ご、誤爆・・・

689:デフォルトの名無しさん
09/06/01 22:43:04
どんまい、
というかハードとソフト両方いけるとかうらやましい

690:デフォルトの名無しさん
09/06/01 22:45:09
>>687
全然 なんだかわからないwww
すごいな。

691:デフォルトの名無しさん
09/06/02 01:02:51
とりあえずイミフだからストリッパーってあたりに反応しとこうぜ

692:デフォルトの名無しさん
09/06/02 01:44:25
ストリッパーくらい分かるだろ
線の被覆を剥ぐための工具だろ

693:デフォルトの名無しさん
09/06/02 02:19:34
struct A{A();virtual void fun() = 0;};
struct B:A{B();fun();};
struct C{C(A&b); C problem(A&b);};

C c(B());
c.problem(B()); // no-match function になるのは何故?

C::problem(一時オブジェクト参照)を弾くならコンストラクタでも弾くべきだと思うんだけど

694:デフォルトの名無しさん
09/06/02 02:57:23
>>692
しらんがな(´・ω・`)

695:デフォルトの名無しさん
09/06/02 03:51:45
ドラクエなどで登場する戦士や魔法使いを意味するFighterクラスと Mageクラスがあったとして、
そのクラスのインスタンスが持つHPやMP,攻撃力などのステータス一覧を表示する関数を作るとき、
クラス自信にその関数を持たせるのか、あるいはクラスとは関係のない部分で作るのか、どちらがいいんでしょう?
クラス設計の考え方がまったくわかりません・・。


696:デフォルトの名無しさん
09/06/02 06:17:21
>>695
その場合はカプセル化を優先する。

まず、HPやMP,攻撃力などのステータスを格納する変数(intだったりstd::size_tだったりするだろう)のアクセス指定子がどう宣言されているかによって考えを分ける。
1.
もしprivateで宣言されていて、そのステータスをpublicなメンバ関数h_point()で取得するような仕組みにしている場合(むろんそれが望ましい)は、「クラスとは関係のない部分で作る」が正解。
つまり別の関数show_status(~)を作り、~の部分にキャラクタのインスタンスを渡すようにする。
2.
もしpublicで宣言されているならば、「クラス自身にその関数を持たせる」ないし「friend指定して外部関数を作る」が正解。しかしステータスを格納する変数がpublic指定されていること自体、そもそも望ましくないことだが。


697:デフォルトの名無しさん
09/06/02 06:23:39
>>693
private継承しているからだろ

698:デフォルトの名無しさん
09/06/02 08:07:42
>>693
そのコンストラクタで本当に動くか試した?

699:デフォルトの名無しさん
09/06/02 17:56:43
C c(B());

C c(B (*)());
という関数宣言に解釈される。
B b0;
C c(b0);
c.problem(b0);
とするとできましたが。
関数の引数のリファレンスの型にconstをつけて
"const B&b"、"const A&b"のようにすると
C c = C(B());
c.problem(B());
でもいけました。
なぜかは僕には分かりませんのでどなたか解説お願いします。
コンパイラはgcc4.2.1で確かめました。

700:デフォルトの名無しさん
09/06/02 19:02:59
const参照型のインスタンスは、呼び出す側が値渡しと同じ感覚で扱えるように、
一次オブジェクトで初期化できることになっている。

701:693
09/06/02 20:13:27
実コードはstruct Bにtemplate特殊化やらvirtualメンバやらなんやら絡んで魔窟状態で実は
C c(static_cacst<A&>(B())); に成ってますた。

>>699
C c((B())); でも逝けますね。

702:デフォルトの名無しさん
09/06/02 21:44:52
>>701
Effective STL の第1章第6項「C++の最も奇妙な解析に注意しよう」に書かれてるね。
(この本自体はSTLの解説本だけど…)
でも、すべてのコンパイラで成功するとも書かれていない・・・おそろしや。

703:デフォルトの名無しさん
09/06/03 17:16:04
#include <stdio.h>

void main(void)
{
char data[3465300]
int idata[3465300];
int KOTAE[3465300/2];
int data1[12032/2][300];
int idata1[300][300];
int i,j,id,a,b,No,day,LDAY,d;
char fnamein,fnameout;
FILE *fin,*fout;
#define LDAY 30 //月ごとに変える
//No=1→ステータス;No=2→交通量;No3=速度;No4=オキュパンシー
#define No 2
for(day=0;day<LDAY;day++){
d=day+1;
printf("%d/%d\n",d,LDAY);
sprintf(fnamein,"D:\\/torakan-Y/R_barashi/Ku0409/Ku0409%02d.dat",d);
sprintf(fnameout,"D:\\/torakan-Y/R_barashi/Ku04/Q_Ku0409%02d.txt",d);
fin = fopen(fnamein,"rb");
fread(&data,1,3465216,fin);
fclose(fin);
if((fout=fopen(fnameout,"w"))==NULL) printf("Cannot open output file\n");


704:デフォルトの名無しさん
09/06/03 17:17:18
>>703
なんだこの凶悪なのはっ!!

705:703
09/06/03 17:19:00
703のプログラムですが、コンパイルは通る一方で
出力される結果が同じ数字の繰り返しになってしまいます。

エラーの原因としては、以下の4行が怪しいと思っています。
詳しい方、よろしくお願いします。
sprintf(fnameout,"D:\\/torakan-Y/R_barashi/Ku04/Q_Ku0409%02d.txt",d);
fin = fopen(fnamein,"rb");
fread(&data,1,3465216,fin);
fclose(fin);

706:デフォルトの名無しさん
09/06/03 17:23:44
>>705
あんたが勝手に”エラー”って呼んでいるものを,具体的に書き表してごらんよ
少なくとも”出力される結果が同じ数字の繰り返し”になることは具体的に書け

707:デフォルトの名無しさん
09/06/03 17:29:33
変数宣言で嫌になるものは久しぶり…

708:デフォルトの名無しさん
09/06/03 17:32:39
スレの住人の中におエスパー様はおられませんか?

709:デフォルトの名無しさん
09/06/03 17:34:40
>>703
とりあえず変数を#defineで上書きしているのが分かった

710:703
09/06/03 17:42:02
≫>705様
レスありがとうございます。
出力されたファイルを開くと
526855268552685といった感じで同じ数列がただ繰り返されたファイルが
出力されます。

このプログラムはもともと、膨大なデータの中から
一部分を抽出するプログラムとなっています。
また、その莫大なデータにはそのような数列は見られないので
勝手にエラーと判定してしまいました。

>709様
ありがとうございます。
さっそく そこを修正したいと思います。

711:デフォルトの名無しさん
09/06/03 17:52:30
>>710
かんじんのファイルに出力している部分が・・・ねぇwwwwwwさすがにESPじゃない俺にはむり

712:703
09/06/03 17:57:36
for(i=0;i<3465216;i++){
idata[i]=int(data[i]);
if(idata[i]<0){
idata[i]=256+idata[i];
}
}
id=0;
for(i=0;i<3465216;i=i+2){
a=idata[i]/16;
b=idata[i]%16;
KOTAE[id]=a*16*16*16+b*16*16+idata[i+1];
id=id+1;
}

id=0;
for(j=0;j<288;j++){
for(i=0;i<12032/2;i++){
data1[i][j]=KOTAE[id];
id=id+1;
}
}

713:703
09/06/03 18:00:29

/*区間データの抜き出し*/
id=0;
//////6号三郷JCT‐江戸橋JCT間////////////
for(j=0;j<288;j++){
for(i=0;i<17;i++){
idata1[id][j]=data1[4*i+(8+4*501+No-1)][j];
id=id+1;
}
id=0;
}

for(j=0;j<288;j++){
for(i=0;i<2;i++){
idata1[id+17][j]=data1[4*i+(8+4*772+No-1)][j];
id=id+1;
}
id=0;
}



714:703
09/06/03 18:02:01
for(j=0;j<288;j++){
for(i=0;i<15;i++){
idata1[id+19][j]=data1[4*i+(8+4*542+No-1)][j];
id=id+1;
}
id=0;
}

for(j=0;j<288;j++){
for(i=0;i<34;i++){
fprintf(fout,"%d",idata1[i][j]);
}
fprintf(fout,"\n");
}
}
}


715:デフォルトの名無しさん
09/06/03 18:02:27
>>712
> for(j=0;j<288;j++){ 
> for(i=0;i<12032/2;i++){ 
この辺で悪意を感じた

あと,もし仮に名前を付け替えるのが許可されているなら,ぜひデータ構造と名前を変えるべきだとおもふ


716:デフォルトの名無しさん
09/06/03 18:10:48
まずマジックナンバーが多過ぎるから定数で宣言して分かりやすい名前を付けるべき

それと、
>char fnamein,fnameout;
ここはファイル名格納するバッファじゃなかろうか

717:703
09/06/03 18:11:01
>712

すいません。まったく悪意はないです。
もうしわけないです。

名前は変更できます。



718:デフォルトの名無しさん
09/06/03 18:16:08
なげぇwww
codepad
URLリンク(codepad.org)
せめてここに貼るとかさあ。。

719:デフォルトの名無しさん
09/06/03 18:19:07
そもそも何の目的で作られた何をするためのプログラムで
どうなれば成功なんだよ
そこが分からないのに何も答えられるわけがないだろ

どうせ宿題なんだろうけど

720:703
09/06/03 18:26:59
>719様

説明不足ですいません。
トラカンデータといわれる交通量や平均速度といった
情報が網羅されているデータから
一部分を抽出して、自分たちが調べたい路線の
交通量を抜き取るプログラムです。

数列が同じ数字の繰り返しにならなければ、ほぼ成功だと思います。

宿題ではないです。申し訳ないです。

>718様
さっそく、張ってみようと思います。

721:703
09/06/03 18:30:03
URLリンク(codepad.org)

さっそく貼ってみました。

722:デフォルトの名無しさん
09/06/03 18:32:15
ふむふむ
ひどすぎて目眩がしてきた

一つ言えるのは、これはCであってC++ではないということだ
だからスレ違い

723:デフォルトの名無しさん
09/06/03 18:32:56
と思ったらnew使ってるからC++かよ
なんだこれは

724:デフォルトの名無しさん
09/06/03 18:52:09
読むのに時間かかりそうだ…

725:デフォルトの名無しさん
09/06/03 19:03:32
管理番号とかファイルのパスとか
危険な香りのする文字列がたくさんあるけど大丈夫なのか

726:デフォルトの名無しさん
09/06/03 19:09:39
>>703
とりあえず
fread(&data,1,3465216,fin);

fread(data,1,3465216,fin);

727:デフォルトの名無しさん
09/06/03 19:12:43
プログラムに間違いらしきものはなし。
データ解析部分でデータの構造が合致していないような感じだが?

728:703
09/06/03 19:18:54
>726様

あなたは神様です。
あなたのおかげで無事解決しました。

なんてお礼をいえばいいのかわかりません。

729:デフォルトの名無しさん
09/06/03 20:18:52
すげえうれしくない感謝の言葉だなぁ

730:デフォルトの名無しさん
09/06/03 20:22:20
You are God.
I solved the problem, thank you.
What it only has to say the reward is not understood.

731:703
09/06/03 20:27:36
と思ったら、まだ解決していませんでした。
申し訳ないです。

732:デフォルトの名無しさん
09/06/03 20:39:13
<stdexcept> と <exception> って、
どっちをインクルードするほうが望ましいの?

733:デフォルトの名無しさん
09/06/03 20:41:32
<stdexcept>で定義されている例外を使いたければ<stdexcept>

734:デフォルトの名無しさん
09/06/03 20:42:12
>>731
書き直してもいい?

要するにファイルの内容は unsigned short 型のデータが
ビッグエンディアンで 6016x288 個格納されているのを
data1 に代入すれば data も idata も KOTAE も必要ないよね

735:デフォルトの名無しさん
09/06/03 20:53:56
>>703
社内で使ってる(であろう)コードをこんなところに晒して、
ただで済むと思ってるのか?
オープンソースじゃないだろうし、上司に知られたらやばいんじゃねーの。

736:デフォルトの名無しさん
09/06/03 21:21:08
スタックオーバーフローエラーを直してくれた先輩には
もう見限られたのか?

737:デフォルトの名無しさん
09/06/03 21:58:15
>>731
なにが解決してないの?

738:デフォルトの名無しさん
09/06/03 22:40:43
ほんとプロが作るソースって
ゴミクズだよな。
どこもかわらねえなぁ。

739:デフォルトの名無しさん
09/06/03 22:48:19
え?>>703の話なら、プロのコードじゃないっしょ。

社内でコンピュータにちょっと詳しい人(事務職とかバイトのお兄ちゃんとか)に
アホ課長が「エクセルで計算するのめんどいからお前プログラム書けよ」って
仕方なくしこったんじゃない?

どうみてもCで書いたコードを、その人がやめちゃって保守要員がいなくなったので
これまたその辺のちょっとコンピュータ詳しい奴にむりくりやらせてるってところでは。

すごいエスパー。昔、エスパドリューはエスパーが身につける特別な装備だと思っていたのを思い出した。

740:デフォルトの名無しさん
09/06/03 23:49:15
ふと思ったんだが↓↓

C++では関数が返せる変数の型は1つだけである。
(その型と継承関係によってはその子クラスの型でも返せることもあるが。)
ところが、例外処理におけるthrowは関数から外へ任意の型の例外を投げることが可能である。
これをその関数の返り値(戻り値)とみなして
プログラミングをするという面白い技法が
この世に存在していてもおかしくないのではないか

と思ったのだが、誰か知っている人いない?
例外を使ったプログラミングの話をしている訳じゃ無くて
あくまでthrowによる例外を戻り値として利用するスタイルってことで。

741:デフォルトの名無しさん
09/06/03 23:55:54
テンプレートクラスを使えば戻り値の型なんて自由自在ですよ。
無茶しないでください。


742:デフォルトの名無しさん
09/06/03 23:57:22
そのアイデアに「catchされなければ呼出元へ伝播する」という例外の特徴も考慮した?
していないならboost::any返せばいいでしょという話だと思う。

743:デフォルトの名無しさん
09/06/03 23:57:35
>>740
実用してる奴がいたら絶対に近づきたくないが
ネタとしてはおもしろそうだな。

はたして意味のあるプログラムを作ることができるのか・・・

744:デフォルトの名無しさん
09/06/04 00:04:54
もしうまいことやったとしても、Schemeなんかの継続のきわめて限定的なまねごとになるのではと思う。
どういう形か想像もつかないが。

745:デフォルトの名無しさん
09/06/04 00:10:33
継続ねえ。
じゃあお題は例外でC#で言うところのyield()を作る
でどうよ。

746:デフォルトの名無しさん
09/06/04 00:17:20



さっそく自分で否定しちまった・・・

747:デフォルトの名無しさん
09/06/04 00:39:24
>>740のは面白いな
何か可能性を感じる

748:デフォルトの名無しさん
09/06/04 01:27:32
variantでいいじゃん
戻り値の型として使いたいものの集合がコンパイル時に決まっていないと
例外使う方法も結局何もできないわけだし

749:デフォルトの名無しさん
09/06/04 02:00:23
変態プログラミングの可能性と聞いて

750:703
09/06/04 02:02:54
>734様

先程、プログラミングを回してみた結果
無事解決しました。
727様のおっしゃるとおり
データ解析部分でデータの構造が合致してないことが
原因でした。
もし、お時間があるなら、書き直してくださったプログラムを
見せていただきたいです。

751:デフォルトの名無しさん
09/06/04 02:36:54
>>740
そういうのはイベント駆動型とかいうやつじゃないか

752:740
09/06/04 06:28:37
>>741
え?
どういうことだい?
よく分からないんだが。。。

みんなありがとう。
俺も絶対やらないと思うけど、
>そのアイデアに「catchされなければ呼出元へ伝播する」という例外の特徴も考慮した?
一応考えてる。
boost::anyやvariantは頭をよぎったが忘れることにした。

うーん、むずかしいよねぇ。
少なくとも俺はやらないけど、きっと誰かが何かすごいことを
やってくれるんじゃないかと思った。


753:デフォルトの名無しさん
09/06/04 11:11:57
やらないのかよ

754:デフォルトの名無しさん
09/06/04 11:52:00
>>752
c#でもやっていてください
とくにLINQ

755:デフォルトの名無しさん
09/06/04 14:00:53
>>752
例外のキャッチってコストかかるんでパフォーマンス劣化が激しいと思うぞ

756:デフォルトの名無しさん
09/06/04 14:02:25
アゲ

757:732
09/06/04 17:05:22
>>733
ありがとう!

758:デフォルトの名無しさん
09/06/04 17:20:46
>>740
むやみやたらにthrow使うのはgotoと大して変わらないので、
普通やらん。
やめとけ。

759:デフォルトの名無しさん
09/06/04 17:51:57
普通に関数オブジェクトでも引数として渡せばいいだけやん。

760:740
09/06/04 17:57:29
もちろん俺だって普通はやらんさ。

でもまあどこかの変態級のプログラマがうまくこれを生かして…(ry

761:デフォルトの名無しさん
09/06/04 20:32:06
試しに
#define return assert(0)
して、throw以外で関数から出るのを禁止してプログラム書いてみたらいい
何かが見えてくるかもしれんぞ

762:デフォルトの名無しさん
09/06/04 20:42:01
C++の関数を全部こう書き換える

retType func(/* ... */){
  /* ... */
  return foo;
}



function func(/* ... */) throw(retType){
  /* ... */
  throw foo;
}

そして
class function{private:function();~function();};
と定義すれば、めでたく例外指向プログラミング言語の出来上がり

使うのは遠慮します

763:740
09/06/04 21:00:49
>>761-762
ありがとう。
うーん、なんとも気持ち悪い物が出来上がりそうだw

764:デフォルトの名無しさん
09/06/04 23:10:07
三値論理の関数型言語?で似たような事が出来たような?
よくわからんが

765:デフォルトの名無しさん
09/06/04 23:20:59
boost::any を使えば受け取る側は関数側から何が返ってくるか知らなくてもいいけど
例外の場合は、帰ってくる型が何であるかは知っておく必要があるよね?

間違ってるかしら・・・

766:デフォルトの名無しさん
09/06/04 23:47:52
>>765
一応catch(...)で、何でも受けれる。
受けられるだけだが。

戻り値返しにない例外の機能として、
安全な中間すっとばしがある。

funcA() -> funcB() -> funcC() -> 例外発生
↑-----------------------------」

これを使えば、非常に柔軟な逆フロー制御が実現できる。
つまり、メインルーチンを例外のcatch()ブロックに書くのだ。
これを使って何が出来るかというと、それは次の人どうぞ。

767:デフォルトの名無しさん
09/06/05 00:11:17
一方ロシアはgotoを使った。

768:デフォルトの名無しさん
09/06/05 00:16:15
anyだろうと何だろうと型を知らないと何も出来ないから、
結局そのままどっかに転送するしかないよな
throw;で同じ事が出来そうな気はする

769:デフォルトの名無しさん
09/06/05 00:19:15
VC9だと落ちるんだけどw
#include <iostream>
void fib(int n) {
  if (n < 2) { throw 1; }
  else {
    try { fib(n-1); } catch (int r1) {
      try { fib(n-2); } catch (int r2) {
        throw r1 + r2;
      }
    }
  }
}
int main() {
  try { fib(20); } catch (int ret) {
    std::cout << ret << std::endl;
  }
  return 0;
}

770:デフォルトの名無しさん
09/06/05 00:21:40
あーそうだ、多重例外は未定義だったな

標準C++の範囲で例外指向プログラミングはできないようです

771:デフォルトの名無しさん
09/06/05 00:29:57
うーん、
変態Chain Respinsibility?

void discover() {
 switch (random) {
 case 0:
  throw Chair;
 case 1:
  throw Human;
 case 2:
  throw Orange;
 case 3:
  throw Truth;
 }
}

void loop() {
 while (1) {
  Sitter(Killer(Eater(Philosopher(discover))));
 }
}

どうすんだこれ・・・

772:デフォルトの名無しさん
09/06/05 00:31:46
綴りひでぇorz

773:デフォルトの名無しさん
09/06/05 00:45:36
いいかんじに変態的だな

774:デフォルトの名無しさん
09/06/05 02:23:18
>768
visitorで何とかする手はあるよ。
URLリンク(www.boostpro.com)


775:デフォルトの名無しさん
09/06/05 05:26:42
多重例外って何ですか?
アクティブな例外が2つ以上同時に発生することですか?
それともtry・catchブロックの中にtry・catchブロックがあることですか?

776:デフォルトの名無しさん
09/06/05 09:32:40
例外ハンドラで例外が出ること

777:デフォルトの名無しさん
09/06/05 11:12:55
テンプレートクラスで自身を返す場合、書き方としてどっちが正しいのでしょうか。
1も正しいなら今後1で書こうと思ってます。

template<class T> class X
{
public:
X &Func() // 1
X<T> &Func() // 2
{
return *this;
}
}


778:デフォルトの名無しさん
09/06/05 11:33:33
C++を1から学習しようかと思うのですが、参考書は何がおすすめでしょうか?
visual C++を使おうかと思っているのですが。
分厚くてもよいので、一冊で応用まで深く学習出来るのはありませんかね?

779:デフォルトの名無しさん
09/06/05 11:52:54
>>777
2、テンプレート引数を省略しないといけないのはコンストラクタだけ

780:デフォルトの名無しさん
09/06/05 12:03:14
>>778
禿本を買っておけば間違いは無い

781:デフォルトの名無しさん
09/06/05 13:44:02
>>780
禿本とは何ですか?

782:デフォルトの名無しさん
09/06/05 13:53:12
softbank

783:デフォルトの名無しさん
09/06/05 13:54:12
そういう時に真っ先に「C++ 禿本」で検索しない精神がよくわからん。

784:デフォルトの名無しさん
09/06/05 14:47:44
検索したのですが、出てきませんでした。
ていうより、59件ヒットしてその全てがただ禿本とC++を含んでるやつのみで
何の略かも書いてありませんでした。
その本の正式名称がわかりません。
すいませんが、本の正式名称で書いていただけませんか?


785:デフォルトの名無しさん
09/06/05 15:01:04
C++ 禿

でぐぐったら一番上におっさんの名前出てきたわw

786:780
09/06/05 15:04:39
確かにC++ってググるときに引用符を付けないと駄目なんだよな。

正式名称はThe C Programming Language(邦訳はプログラミング言語C++)
著者はC++の設計者である禿ことBjarne Stroustrupだ。
URLリンク(www.research.att.com) に写真があるからよく拝んでおくように。

日本語訳については色々言われているみたいだが、俺は原著しか使ったことが
ないので分からん。英語に問題ないなら原著をすすめておく。

787:デフォルトの名無しさん
09/06/05 15:07:13
一番、二番目に出てくるならまだしもそれ以外でググレとか言う奴の精神が分からん。
素直に教えて感謝されればいいのに

788:デフォルトの名無しさん
09/06/05 15:12:09
>>786
禿本とはそういう意味だったのですか。
教えてくださってどうもありがとうございました。参考にします。


789:デフォルトの名無しさん
09/06/05 15:37:25
確かに"禿本"だけであとググれってのはちょっとひどいなw

英語に問題ないならTC++PL(禿本)よりも先にProgrammingを読んだほうがいいかも
同じようなこと書いてあるけどProgrammingのほうが分かりやすい
TC++PLにしか書いてないこともあるからどのみちTC++PLは読むんだけどね

790:デフォルトの名無しさん
09/06/05 15:39:18
途中で送信しちまった…
TC++PL(禿本): URLリンク(www.research.att.com)
Programming:  URLリンク(www.research.att.com)

791:780
09/06/05 15:42:31
>>876
自己レススマソ。原著名間違えた。K&Rじゃないっての。

>>787
まあ2chだから仕方ないね。
禿本ってこのスレでは良く知られてると思ってたけど、意外とそうでもないのかな。

792:777
09/06/05 15:44:42
>>779
ありがとう。コンパイル通るからいいのかと思ったけど
やっぱり基本的には全部書かないとだめなのね。


793:デフォルトの名無しさん
09/06/05 15:45:04
禿本と書いてても意味がわからんからスルーしてた
スルーで正解だった

794:デフォルトの名無しさん
09/06/05 16:20:14
>>787
> 一番、二番目に出てくるならまだしも
Googleを使わせるか否かを考えるのに「一番、二番目に出て来るかどうか」を基準にする、
怠惰な人間をつけあがらせる使命でもあるかのような考え方は理解不能だし、
悪いけど二番目の結果(環境依存OKスレの2スレ目)にこういう文章が出て来るぞ。
> 「プログラミング言語C++」は禿本と呼ぶ。

あ、"C++"と"禿本"をダブルクォーテーションで括る発想に至らないバカは考慮してないけど。

795:デフォルトの名無しさん
09/06/05 16:27:12
質問です。どうしてこのスレには捻くれた奴が湧くんですか?

796:デフォルトの名無しさん
09/06/05 16:30:53
たとえばどのレスのことなのか例を挙げてくれないと、
本当にそういう傾向があるのか、自分のバカさを指摘されたバカが
必死にそう見ようとしてるだけなのか判断つかず、回答できないです。

797:デフォルトの名無しさん
09/06/05 19:26:31
>>792
2でもいいんだけどね。テンプレートパラメータは
宣言された範囲(テンプレートのスコープ)内では省略していいことになっている。
クラス定義の冒頭で template が宣言されていて、その範囲内に入っているので、
この場合のメンバ関数宣言のテンプレートパラメータは省略できる。
(Accelerated C++ p.197などを参照)

template < class T > class foo {
 template < class T > foo &bar( foo<T> &t );
};

のような紛らわしい宣言も可能な様子。

798:デフォルトの名無しさん
09/06/05 19:26:34
>>795
捻くれものは大抵、過去に何らかの形で虐げられた経験がある
あとはわかるな?

799:デフォルトの名無しさん
09/06/05 19:29:36
>795
C++自体が捻れた言語だからです。

800:デフォルトの名無しさん
09/06/06 15:12:48
>>797
全然別人なんだけど割り込んで聞いて良い?

template < class T > class foo {
 template < class T > foo &bar( foo<T> &t );
};
ってのは要するに
template < class T > class foo {
 template < class U > foo<T> &bar( foo<U> &t );
};
ってことだよね?

801:デフォルトの名無しさん
09/06/06 20:23:43
>>798
わかります。
現実の現在で叩きのめされたので、架空の過去を夢想して脳内逆襲ですね?

802:デフォルトの名無しさん
09/06/06 20:26:59
>>800
最初の方はgcc 4.2.1ではエラーになった。

803:デフォルトの名無しさん
09/06/06 21:46:37
(・3・) エェー。ぼじゅあるくっぷぷ(Visual C++)では問題なしだYO

>>800
Yes。

804:デフォルトの名無しさん
09/06/06 22:04:24
以下の変態プログラムでテンプレートパラメータの挙動についてご確認ください
#include <iostream>
using namespace std;

template < class T > class foo {
public:
foo() : x( 0 ) {};
foo( foo *p ) : x( p ) {};
template < class T > foo &bar( foo<T> &t ){
cout << t.member << endl;
return *x;
}
T member;
foo *x;
};

int main() {
foo< int > base;
base.member = 1000;

foo< int > i(&base);
foo< char > c;
i.member = 1;
c.member = 'a';

foo< int > r = i.bar( c );
cout << r.member << endl;
}

805:デフォルトの名無しさん
09/06/07 05:02:33
危うく騙されそうになったが
return *xだから挙動自体は普通だな

806:デフォルトの名無しさん
09/06/07 05:28:11
r.memberが初期化されない…と思ったがコピーコンストラクタじゃないのか。

807:デフォルトの名無しさん
09/06/07 12:07:05
>>804
読むだけで疲労した。
barメンバ関数が何をやりたいのか意図が分からない
(練習プログラムだから仕方ないことだが。)
のに理解をじゃまされた。

分かって良かった。

808:デフォルトの名無しさん
09/06/07 12:38:25
>>807
>>797の再現じゃないの?

809:807
09/06/07 12:56:34
>>808
ああそうなのか、ここのところこのスレ見てなかったから
全然流れを読んでなかったわ。


810:デフォルトの名無しさん
09/06/07 13:58:30
下のように、クラスAAのインスタンスを、メモリーに割り当てたときに。
コンストラクタとデストラクタをどうやって起動したらいいのでしょ?

class AA { int i1,i2; AA(); ~AA(); }
void func()
{
 char dat[100];
 AA *dat;
 dat = (AA *)dat;
}

811:デフォルトの名無しさん
09/06/07 14:02:17
コンストラクタ
new(dat) AA();
デストラクタ
dat->~AA();

812:デフォルトの名無しさん
09/06/07 14:11:53
AA * dat = new AA[100];
delete[] dat;

813:デフォルトの名無しさん
09/06/07 14:38:59
上の例、バッファーとポインターが同じでした、ミスすみません
>>881 下記のようにうにエラーになります  >>812 100個のインスタンスを作るわけではないです
class AA
{
 int a1,a2;
public:
 AA() { printf("AA コンストラクタ\n"); }
 ~AA() { printf("AA デストラクタ\n"); }
};
int _tmain(int argc, _TCHAR* argv[])
{
 char buf[100];
 AA *datp;
 datp = (AA *)buf;
 new(datp) AA(); // ここがエラーになる…
 datp->~AA();
 return 0;
}
エラー 1 error C2660: 'operator new' : 関数に 2 個の引数を指定できません。


814:デフォルトの名無しさん
09/06/07 14:39:55
#include <new> が抜けてるだろ

815:デフォルトの名無しさん
09/06/07 14:41:49
URLリンク(atnd.org)

URLリンク(124.45.27.25:12086)
IRCNET #CRYBUTSU

816:デフォルトの名無しさん
09/06/07 14:55:53
>>814 できました、ありがとうございます。

817:デフォルトの名無しさん
09/06/07 15:12:11
ローカル変数に対するplacement newって、アラインメントを気にする必要がなかったっけ?

818:デフォルトの名無しさん
09/06/07 15:16:19
気にする必要があると思います。
実際のプログラムは、sizeof で確認をしています

819:デフォルトの名無しさん
09/06/07 16:27:09
std::vector のようなコンテナを作ろうと思うんだが、
要件について詳しくまとまってるページない?

820:デフォルトの名無しさん
09/06/07 16:49:49
規格を読め

821:デフォルトの名無しさん
09/06/07 16:55:54
別にinterfaceクラスを継承してるわけでもないし、
要件なんて無いぞ。

822:デフォルトの名無しさん
09/06/07 17:05:30
要するに value_type なんかの必須 typedef や
領域確保時の用件とかを知りたいんじゃろ?

領域確保に new を使っちゃらめとか、
知らないとはまる部分もあるしー。

823:デフォルトの名無しさん
09/06/07 17:09:05
>>819
URLリンク(www.open-std.org)
の23.2.6をしっかり読むこと。

SGIのドキュメントはまとまっていて良かったんだが、最新の仕様と乖離してるのかな。
URLリンク(www.sgi.com)

>>821
馬鹿か?

824:デフォルトの名無しさん
09/06/07 17:17:18
>>820-823
トンクス

825:デフォルトの名無しさん
09/06/07 17:21:58
>>821
ちょwww

826:デフォルトの名無しさん
09/06/07 19:02:35
>>769-770
>>775-776
このレスで出てきている多重例外「例外ハンドラで例外が出ること」についてですが、
try
{foo();}//適当な例外を投げる関数
catch(const std::exception& ex)
{throw 42;}//ここが多重例外
ってことですよね?
では
try
{foo();}//適当な例外を投げる関数
catch(const std::exception& ex)
{throw ex;}//ここは?
この様に例外を再送する場合も多重例外となり未定義の動作ですか?
また、再送する場合{throw;}と書いても未定義になりますか?


827:デフォルトの名無しさん
09/06/07 19:33:06
>>826
>770や>776は何か勘違いしているような・・・。
例外ハンドラ(catch節)で例外を投げるのは正当。

多重例外というのはもっと異常な事態で、
例外によるスタックの巻戻し中にデストラクタがさらに例外を投げたとか、
値渡しのcatchへ例外をコピー中にコピーコンストラクタが例外を投げたとかのことを言い、
そういう時でも未定義ではなく、terminate()が呼ばれるんじゃなかったっけ?

828:==775==826
09/06/07 20:20:29
とりあえず例外の再送出は問題ないと分かれば当面は解決です。ありがとうございます。

>>827
>例外によるスタックの巻戻し中にデストラクタがさらに例外を投げた
は、
私(>>775)の言う
>アクティブな例外が2つ以上同時に発生すること
ってヤツですよね。
この場合は未定義だとEffective C++で紹介されています。
しかし
デストラクタからの例外送出::実装技術
URLリンク(cppemb.blog17.fc2.com)
ここによると
>デストラクタから例外を送出するクラスAのオブジェクトを自動記憶域で宣言し、
>その生存期間内で他の例外が発生した場合、A::~A()が呼び出されて、
>その中でまた例外が送出されます。これは二重例外と呼ばれ、
>問答無用でstd::teminateが呼び出されます。
>次に、デストラクタから例外を送出するかもしれないオブジェクトを
>静的記憶域期間で宣言した場合を考えてみてください。
>静的記憶域のオブジェクトを監視ブロック(try~catchの制御文)で囲む構文を
>記述することはできません。すなわち、こちらはデストラクタから例外が発生した
>時点で(std::terminateの呼び出しではなく)未定義の動作になります。
と書いてありますが、果たして何がどうなんでしょうね。


829:デフォルトの名無しさん
09/06/07 21:16:02
catch節で例外を受けた場合、受け取った例外を再送するか、
受け取った例外を破棄して別の例外を送出するしかなくて、
結局、伝播する例外は1つだけになるので問題ない。
それ以外で例外伝播中に他の例外が発生すると、
2つの例外を伝播させなければならなくなるけど、
それはできないことになってて、かわりにstd::terminate()が呼ばれる。

830:828
09/06/07 22:14:01
>>829
・・・としますと
Effective C++の未定義だという記述の方が誤りで、
デストラクタからの例外送出::実装技術
URLリンク(cppemb.blog17.fc2.com)
の方が正しいと言うことでしょうか?


831:デフォルトの名無しさん
09/06/08 03:03:48
多重例外が未定義動作だなんてどこに書いてあった?

832:デフォルトの名無しさん
09/06/08 05:20:46
デストラクタで例外を投げてもちゃんと動作は定義されている
意味のある(まともな)動作をさせるのが困難というだけ

833:828
09/06/08 06:59:07
>>831
Effective C++ 原著第3版
p39末行
~p40頭の数行
にかけて、はっきりと未定義と書かれています。

>>832
それもEffective C++で上と同じ節に書いてあります。


834:デフォルトの名無しさん
09/06/08 08:03:12
>>830
静的記憶域期間を持つオブジェクトがデストラクタで例外送出したらterminateじゃなかったっけ

と思ったら「staticでnon-local」はterminateらしい
「staticでlocal」は記述が見当たらねぇ…

835:828
09/06/08 16:14:44
そしてまあ困ったことに、たしかVC2008とかの有名どころですら
複雑な例外処理の仕様は、正確には実装されていないと聞いたことがあります。

結局は多重例外になるという状況を作らないように気をつけていくしかないのでしょうかね。


836:デフォルトの名無しさん
09/06/08 21:14:03
>>833
そこは仕様書を持ち出すべきだろ。

837:828
09/06/08 21:15:40
>>836
私は仕様書を持ってないんですよ。
趣味グラマなもんでして。

838:デフォルトの名無しさん
09/06/08 21:22:44
例外処理の実装を詳しく説明している書籍は何がありますか?


839:デフォルトの名無しさん
09/06/08 21:26:27
more exceptional C++

840:デフォルトの名無しさん
09/06/08 21:55:50
>>837
興味があるならタダで見られる、日本語で。
URLリンク(www.jisc.go.jp)から規格番号X3014。

841:837
09/06/08 21:58:59
>>840
ありがとうございます。
なんとかDLしたいものですが、ガードされているようですね。

必要に応じてWEBで見るようにします。

842:デフォルトの名無しさん
09/06/08 23:40:41
FDISでよければこことか
URLリンク(www.kuzbass.ru)

15.5.1に
>when the exception handling mechanism,
>after completing evaluation of the expression to be thrown but before the exception is caught,
>calls a user function that exits via an uncaught exception,
>...
>In such cases, void terminate(); is called.
とあるから、terminate()が呼ばれるのは間違いないと思うのだが、
Effective C++には確かに未定義っぽいことが書いてあるし…
英語版でもそうなのかなあ

843:デフォルトの名無しさん
09/06/09 00:25:07
しかし、デストラクタで例外なげるようなプログラムなんて書く訳無いし、あんまり気にしすぎても仕方ないよ。
いえ、ごめんなさい。

844:デフォルトの名無しさん
09/06/09 20:20:17
関数テンプレートがインスタンスを指定することによって実体化できるのに対し、
クラステンプレートは型名を指定しないと実体化できないところに不便さを感じます(boost::rangeとか特に)。
何かいい方法はないですかね?

845:デフォルトの名無しさん
09/06/09 20:26:59
そのためのtypedefだろ?

846:デフォルトの名無しさん
09/06/09 20:27:22
クラステンプレートは、型を引数に取って型を返す関数

847:デフォルトの名無しさん
09/06/09 21:35:16
>>846
TMPか。

848:デフォルトの名無しさん
09/06/09 21:40:37
>>844
std::make_pairやboost::make_iterator_rangeのように関数テンプレートでラップすればいい。

849:デフォルトの名無しさん
09/06/09 21:41:43
>844
関数テンプレートもインスタンスで指定しているわけじゃないぜ。単に引数の型を推論しているだけ。
#動的な型は対応できない

どうしてもというなら関数テンプレートでラッパー作ればよろし。


850:デフォルトの名無しさん
09/06/09 22:05:43
>>845
型指定するのが手間に思えます。型推論してくれないかなと。
>>846
関数の引数をテンプレートに変更してもそのまま使えるのに、クラスのメンバ変数をテンプレートにすると使う側に手間が増えるのが不便に感じます。
>>848
makeXXXの戻り値を受け取るところで結局型指定が必要になってしまいます。
>>849
書き方が悪かったです。

template<class T>
void F(T t);
template<class T>
class C {
  T t_;
public:
  C(T t):t_(t){}
};
F(hoge);// hogeを簡単に渡せる
C<Hoge> c(hoge);// 型を指定しないと渡せない
この違いを埋めることってできないですか?
rangeを渡す時、後者はめんどくさく感じて仕方ないです。

851:デフォルトの名無しさん
09/06/09 22:13:14
>>850
> F(hoge);// hogeを簡単に渡せる 
> C<Hoge> c(hoge);// 型を指定しないと渡せない 
どう書ければうれしいの?

852:デフォルトの名無しさん
09/06/09 22:31:30
>>851
Hogeを書かなくてよくなればうれしいです。
言語の仕様上、Cを非テンプレートクラスにするしかないですかね。
boost::any使っても値を取り出すことができないし、うーん・・・。

853:デフォルトの名無しさん
09/06/09 22:49:02
class B{public:virtual B&fn()=0;};
template<T>class A:B{public:T t_;A(T t);B&fn();};
class C{A&a;public:template<T>C(T t):a(C<T>(t)){};B&fn(){return a.fn();}};

実現しようと思えば物凄く面倒。

854:デフォルトの名無しさん
09/06/09 22:53:56
>>852
つまりこういうこと?
 C<> c(hoge);

855:デフォルトの名無しさん
09/06/09 23:04:50
>850
F(hoge)のhogeはどのみち静的な型になってるだろ。
C<Hoge>とするのに比べてそんなに汎用性が高くなっているわけじゃないよ。

型を推論してくれるから面倒なことは少ないけど。まあ、素直にC++0xのauto待ちでいいんじゃね?


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch