■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part40
251 名前:デフォルトの名無しさん :2005/05/03(火) 04:27:29
>>250 Float<1,2> と Float<2,4> が別々のインスタンスになってしまう件。

252 名前:デフォルトの名無しさん :2005/05/03(火) 10:15:53
固定小数点でやるしかないな

253 名前:デフォルトの名無しさん :2005/05/03(火) 10:49:46
>>251 約分してやれば無問題。ついでに言っとくがインスタンスの意味を取り違えてる。

問題は無理数をどうするかだ。

254 名前:デフォルトの名無しさん :2005/05/03(火) 10:57:17
>>253
正しいインスタンスの意味を教えてください。

255 名前:デフォルトの名無しさん :2005/05/03(火) 11:31:19
>>253
整数をベースに加減乗除とlogとexpを許した集合なら
がんばって比較できるんじゃないだろうか。

256 名前:デフォルトの名無しさん :2005/05/03(火) 11:32:11
インスタンスは実体。
int a=1, b=1; と宣言した場合aとbの内容は同じでも実体(インスタンス)は別ってことになる。


257 名前:デフォルトの名無しさん :2005/05/03(火) 11:37:23
>>256
型(クラス)のインスタンス(オブジェクト)と
テンプレートのインスタンス(型か関数)を混同してないか?

258 名前:デフォルトの名無しさん :2005/05/03(火) 11:44:52
>>253,256
「インスタンス」=「C++における型のインスタンス」と思い込んでいるようだが、そうではない。
「インスタンス」はモデルに対する実体を表す一般的な名詞。

259 名前:256 :2005/05/03(火) 12:04:46
クラスのインスタンスとテンプレートのインスタンスを混同してた。orz

でも、この例だと素直にclass Float{ Float(double bunshi, doouble bunbo);} で欲ねーか?

260 名前:デフォルトの名無しさん :2005/05/03(火) 12:21:34
>>259
それなら typedef double Float; でいいんじゃね?

もう何がしたいのかわかんなくなってるな。発端は>231だと思うが。

261 名前:デフォルトの名無しさん :2005/05/03(火) 13:37:47
いままでの流れ。
・浮動小数点数をテンプレートに渡したい(>>231
・そのためには等値比較が必要(>>239)
・等値比較可能な数値表現として、有理数の提案(>>250)
・等値比較可能性もコンパイル時決定性もどうでも良くなった有理数(>>259
・当然の合理化(>>260)

262 名前:デフォルトの名無しさん :2005/05/03(火) 13:50:24
これでいけ

template< class IntegralSequence, int Scale >
struct big_decimal {
typedef IntegralSequence unscaled_value;
typedef mpl::int_<Scale> scale;
};

typedef big_decimal<mpl::vector_c<int,4,5,6>,2> big4p56;

263 名前:デフォルトの名無しさん :2005/05/05(木) 20:02:02
gccでmakefileの依存関係を自動で出力するのありますよね[gcc -MM file.c]
bccやvcでは依存関係の自動出力などはありませんか?

264 名前:デフォルトの名無しさん :2005/05/06(金) 23:12:27
ふと思ったんですけどこんなことしても平気ですか?

int& ref = *new int;
delete &ref;

265 名前:デフォルトの名無しさん :2005/05/06(金) 23:14:38
http://n219078172160.netvigator.com/

っうぇっうぇwwwwwwうはっwwwおkwwwっ
っうぇwwwwwwっwwwwww
うぇwww


wwwwwwwwwwwwwwwwwwうはっwww


266 名前:デフォルトの名無しさん :2005/05/06(金) 23:36:54
>>264
ソースを書いてビルドして自分で試すよりも、2chに書き込んで返答を待つことを選んだわけだな?

267 名前:デフォルトの名無しさん :2005/05/06(金) 23:49:15
>>266
やってみてできた、ということと保証されているということは違うよ。

268 名前:デフォルトの名無しさん :2005/05/07(土) 00:19:03
>>264
それだけみると、大丈夫だろう。
何を心配している?

269 名前:デフォルトの名無しさん :2005/05/07(土) 20:34:12
質問です。
std::ostringstream s;
...sを使用
s.seekp(0,std::ios_base::beg);//再利用を試みたつもり。
...再び使用。

これで一応動作しているようなのですが、問題ありませんか?
検索したら、stringstreamでstr(string(""))すると書いてあったの
ですが、いまいち違いが分かりません。
(ついでに:ostringstreamとstringstreamの違いも分かりません)
よろしくお願いします。

270 名前:デフォルトの名無しさん :2005/05/07(土) 20:59:25
>>269
std::ios::failbitとかstd::ios::eofbitを立ててしまったら、s.clear();しとけよ。

それからstd::ostringstreamとstd::istringstreamを多重継承したのが
std::stringstreamってだけの話。当然std::ostringstreamは出力しか
できない。

271 名前:デフォルトの名無しさん :2005/05/07(土) 21:01:37
それからs.str("")はバッファをクリアするおまじない。
seekp()だけだと前に出力したゴミがくっついて出てこない?

272 名前:デフォルトの名無しさん :2005/05/07(土) 21:09:34
#include <iostream>
#include <sstream>

int main()
{
 std::ostringstream s;

 s << "abcdefgh";
 std::cout << s.str() << std::endl;

 s.seekp(0); //再利用を試みたつもり。だけどゴミが残ってる
 s << "def";
 std::cout << s.str() << std::endl;

 s.str("");
 s << "def";
 std::cout << s.str() << std::endl; // 今度はOK
}


273 名前:デフォルトの名無しさん :2005/05/07(土) 23:39:38
>>270さん
s.clear();も無条件につけとくことにします。

stringstreamも多重継承だっんたんですね。
iとかoで始まるものを見かけたら多重継承もあるかも
と考えた方が良さげですね。

>>271さん >>272さん
試したらゴミ出ました。同じ長さ以上の文字列で書き換
えていたので気づきませんでした、、

納得できました。有難うございました。

274 名前:デフォルトの名無しさん :2005/05/08(日) 10:39:20
ビッグエンディアンをリトルエンディアンにまたその逆の変換をする方法を教えてください

275 名前:デフォルトの名無しさん :2005/05/08(日) 11:04:04 ?#
_asm { bswap eax; }

276 名前:デフォルトの名無しさん :2005/05/08(日) 17:41:32
>>274
片方ができればもう片方を作る必要はない。
変換対象が単一オブジェクトなら、
template<typename _Type> static inline void endian(_Type & val) {std::reverse(reinterpret_cast<char *>(& val), reinterpret_cast<char *>(& val + 1));}

277 名前:デフォルトの名無しさん :2005/05/08(日) 18:11:05
再帰を反復子に変換するアダプタってある?



278 名前:デフォルトの名無しさん :2005/05/08(日) 18:14:20
>>277
定型的に変換できるとは思えないので、無いだろうな。
あんたの言ってる「再帰」がもっと具体的な何かであれば、可能性は有る。

279 名前:不明なデバイスさん :2005/05/08(日) 20:29:21
>>276
そうだよ。
PCIバスに挿すカードやらIDE接続するドライブなんかはプラグ&プレイであってホットプラグではないだろ?

280 名前:デフォルトの名無しさん :2005/05/08(日) 21:37:48
>>277
効率悪くなるけど再帰からの出力を別スレッドからキュー経由で受け取ったものを順次読むならboost使って可能かもしれない

281 名前:デフォルトの名無しさん :2005/05/09(月) 23:00:38
初歩的質問ですが、オーバーロードできない演算子の中に「.*」が
あるようですが、これってどういう使い方のやつですか?
普通にa.*bみたいな感じ?こんなのありましたっけ?

282 名前:デフォルトの名無しさん :2005/05/09(月) 23:08:50
>>281
「メンバへのポインタ演算子」でぐぐってみ。

283 名前:デフォルトの名無しさん :2005/05/09(月) 23:10:35
>>281
メンバへのポインタの参照。
本当は *a.b と書きたいのだが、意味が変わってしまうので、新しく作られた。
純粋なCの*演算子とは意味が違い、アドレスではなくてオフセットのような
物が入っている。

284 名前:デフォルトの名無しさん :2005/05/09(月) 23:30:47
>282 のおかげですごく理解できた。
>283 のせいで混乱した。

285 名前:281 :2005/05/09(月) 23:48:02
レスどうもです。
ぐぐってみたところ、メンバ関数のポインタから関数呼び出しする際に
使うようですね。これ以外は使い道ないですかね。

286 名前:デフォルトの名無しさん :2005/05/09(月) 23:59:38
別に関数じゃなくてもいいんだが。

287 名前:281 :2005/05/10(火) 00:10:53
あ、そうですね。メンバを指すポインタからメンバを参照するときですね。

288 名前:デフォルトの名無しさん :2005/05/10(火) 00:32:10
http://www.open-std.org/jtc1/sc22/wg21/
News 2005-05-09: The 2005-05 mailing is available (7400 kb tar.gz, .zip 7400 kb) individual papers
News 2005-05-09: The C++ Standard Library Issues List (Revision 36) is available (.tar.bz2)
News 2005-05-09: C++ Standard Core Language Issues List (Revision 35) is available, also committee version

289 名前:デフォルトの名無しさん :2005/05/10(火) 00:52:28
http://p5091-ipad02miyazaki.miyazaki.ocn.ne.jp/
wwwwwwwwwwwwっうぇおkwwwwwww

wうはっwwwwwwwwwっうはっwwwwwwwww
wwwwwwwwwwwwwwwwww
wwww

290 名前:デフォルトの名無しさん :2005/05/10(火) 06:42:26
いきなりC++から入る場合、何かよい参考書はありませんか?

291 名前:デフォルトの名無しさん :2005/05/10(火) 10:47:07
>>290
K&R

292 名前:デフォルトの名無しさん :2005/05/10(火) 11:38:23
>>291
ありがとう
とりあえず、アマゾンで注文してみました


293 名前:デフォルトの名無しさん :2005/05/10(火) 11:43:03
                |
                |
                |
                |
     /V\        ,J
    /◎;;;,;,,,,ヽ
 _ ム::::(;;゚Д゚)::| ジー
ヽツ.(ノ::::::::::.:::::.:..|)
  ヾソ:::::::::::::::::.:ノ
   ` ー U'"U'

294 名前:デフォルトの名無しさん :2005/05/10(火) 14:19:43
C++のテンプレートと演算子のオーバーロードについて質問です。

template <class T> class Parent{
public:
T operator = (T x){
・・・処理・・・
return x;
}
}

こんな感じのクラスがあり、これを他のクラスから継承して使っています。
継承クラスは「class Child : public Parent<int> {};」という感じです。
しかし、実際に「Child a ; a = 1;」などすると
「二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。」
というコンパイルエラーが出ます。
あとこの現象はイコール演算子特有なのか「+=」を使うとエラーは出ませんでした。
Childクラスにこのoperator =()を書くと正常にコンパイルできますが、継承クラスは複数あるし、
見た目的にも何だかなぁという感じなのでそれ以外の方法で解決法があれば教えて欲しいです。

環境は WindowsXP SP2 + VS.NET2003 Academicです。
よろしくお願いします。

295 名前:デフォルトの名無しさん :2005/05/10(火) 14:23:05
>>294
operator=だけは継承されない、と決められてた希ガス。

296 名前:デフォルトの名無しさん :2005/05/10(火) 14:23:34
>「二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。」
そりゃそうだ

297 名前:デフォルトの名無しさん :2005/05/10(火) 14:24:19
えぇ!?そうなんですか;;;
ごっつい初歩的な質問すみませんでした・・・。

298 名前:デフォルトの名無しさん :2005/05/10(火) 14:28:33
>>294
using Parent<int>::opereator=;
でなんとかなる。

>>295
へー。

299 名前:294 :2005/05/10(火) 14:37:56
>> 298
なるほど・・・試してみましたが、ちゃんとできました。
これなら変更とかでも対応しやすそうなので充分です。
ありがとうございました!

300 名前:デフォルトの名無しさん :2005/05/10(火) 14:56:50
operator=が自身の参照を返さないのは
ちょっとキムチ悪いかも・・・

301 名前:デフォルトの名無しさん :2005/05/10(火) 15:02:25
>>294
デフォルトの(自動生成される)
Child::operator= があるので、
Parent<int>::operator= は隠される。

302 名前:デフォルトの名無しさん :2005/05/10(火) 16:07:42
コンストラクタもコピーコンストラクタもfriendも継承されないぞ。

303 名前:デフォルトの名無しさん :2005/05/10(火) 17:41:43
>>302
>コンストラクタ
派生クラスから基底クラスのコンストラクタにはアクセスできるわけだし
継承されないっていうのは違うのでは?外から呼ぶ方法がないだけで。
そもそも関数が継承されるってどういう意味なんでしょう?

この辺は可視性やアクセス権限の問題な気がします。

304 名前:デフォルトの名無しさん :2005/05/10(火) 21:17:02
>>303
それを言うならoperator=も呼べる。

305 名前:303 :2005/05/10(火) 21:45:34
>>304
はい、呼べますよ。それが何か?
>>301が言っているように、オーバーロード解決のときに
Parent::operator= が考慮されないだけで。

306 名前:デフォルトの名無しさん :2005/05/10(火) 21:46:53
>>305
そういうのを「継承されない」って言うんだろうが( ゚Д゚)ゴルァ!!

307 名前:303 :2005/05/10(火) 21:57:15
>>306
うーん、そうなんですかね。
関数を継承するってピンと来ないんですけど。
ヒマなんで規格書でも読んでみます。

308 名前:デフォルトの名無しさん :2005/05/10(火) 22:07:21
>>306
どうでもいいが、それだとprivate継承はどうなるんだ?

309 名前:デフォルトの名無しさん :2005/05/10(火) 23:55:18
継承のルールは他の関数と同じ。
>>301 が正解。
>>295,306 は間違い。

310 名前:デフォルトの名無しさん :2005/05/11(水) 02:26:02
つまり隠蔽されるわけか。

311 名前:デフォルトの名無しさん :2005/05/11(水) 03:34:14
つまり、private継承はオブジェクトの継承ではなくて実装手段の継承だね。

312 名前:デフォルトの名無しさん :2005/05/11(水) 09:37:04
>>311 なにが「つまり」だ?だれもそんな話してないぞ。

313 名前:デフォルトの名無しさん :2005/05/11(水) 10:16:10
つまり、ぬるぽか。

314 名前:デフォルトの名無しさん :2005/05/11(水) 11:04:01
>>313
いわゆるひとつのガッ

315 名前:デフォルトの名無しさん :2005/05/11(水) 14:54:47
コンストラクタ、コピーコンストラクタ、代入演算子、friend属性は
「継承されない」と書いているC++本多いね。糞、今まで騙されて
いたのか。

316 名前:デフォルトの名無しさん :2005/05/11(水) 14:56:47
まあね、クラスの外から見えないからって継承されてないわけじゃない

317 名前:デフォルトの名無しさん :2005/05/12(木) 00:35:58
>>315
friend属性は「継承されない」で正しい。

318 名前:デフォルトの名無しさん :2005/05/12(木) 04:20:15
printf とかのC標準関数が cstdio をインクルードしても
std 名前空間とグローバルの両方にあるんだけど、
これって規格的にはOKなの?
(VC .NET 2003)

319 名前:デフォルトの名無しさん :2005/05/12(木) 10:44:00
>>318 >>167

320 名前:デフォルトの名無しさん :2005/05/13(金) 01:14:19
つまり、sex friend属性は継承されないということですね

321 名前:デフォルトの名無しさん :2005/05/13(金) 01:45:05
実際、継承とかガンガン使ってるんですか?
渡しなんかは、明に継承なんてほとんど使ったこと無いです。
単純に、外に見えるようにpublic、外に出さないようにprivate、
ぐらいの感覚でしか使ってません。protectedの使う場面は無し。
まあ何と言いますか、変数管理のしやすさ程度に使ってるって感じです。
それでもCよりC++のほうが、classを使えたり、機能的にCより上なので、
C++のほうがいいかな、とは思ってます。
(というか、C++使うのは必然的なんですけどね。)。

322 名前:デフォルトの名無しさん :2005/05/13(金) 01:57:14
>>321
継承もそれなりに使っている。
話がややこしくなるからMFCは置いておくとして、ログファイルや設定ファイルなんかは仕様が似通うので
基本クラスを作っておいてそれを派生して使うことがしばしば。
この場合、コンストラクタをprotectedにして派生クラスでしか使えないようにしている。
後は、例えば読み込み関数は仮想化してフォーマットの違いに対応するくらいかな。

323 名前:322 :2005/05/13(金) 01:59:06
>>322
いかん、冒頭に「私は」が抜けた。
まぁ、EffectiveC++でも読んでみるといいかも。

324 名前:デフォルトの名無しさん :2005/05/13(金) 07:01:50
例外を返すべきか、エラーコードを返すべきか悩んでいます。
画像を読み込む関数なんですが、例外を返すようにすると
try {
loadTexture("a.jpg");
loadTexture("b.jpg");
loadTexture("c.jpg");
loadTexture("d.jpg");
catch (hoge) {}
と複数の画像を一気に読むときに便利なのですが、
try {
loadTexture("a.jpg");
}
catch (hoge) {
try {
loadTextuer("hoge/a.jpg");
}
}
なように、最初に指定したファイルが読み込めなかった場合に違うところから
探すようにするときに不便になってしまいます。

何かいい方法はありませんでしょうか?

325 名前:デフォルトの名無しさん :2005/05/13(金) 07:21:42
>>824
ちょっと考えてこんなん出ました。

loadTexture_fuzzy(name)
{
 paths_t paths = {"hoge/"}
 paths_t::iterator i = paths.begin();
 path = "";
 for(;;)
 {
  try
  {
   loadTexture(path+name);
   return;
  }
  catch(hoge)
  {
   if(i==paths.end()) { throw; }
   else { path = *i; ++i; continue; }
  }
 }
}

try {
loadTexture_fuzzy("a.jpg");
loadTexture_fuzzy("b.jpg");
loadTexture_fuzzy("c.jpg");
loadTexture_fuzzy("d.jpg");
catch (hoge) {

326 名前:デフォルトの名無しさん :2005/05/13(金) 11:57:36
>>322
それ、いいすね。良い事聞きました。
そういう使い方っていいなーって思いました。
私もやってみようっと。ありがとございました。

327 名前:デフォルトの名無しさん :2005/05/13(金) 13:59:10
virtual継承されたくないクラスがあるのですが、
基底クラスからそれを禁止する方法ってないものでしょうか。

C言語スレに書き込んでしまった…。


328 名前:デフォルトの名無しさん :2005/05/13(金) 14:22:09
>>327
sealedがC++にあればなあ・・・・・
デストラクタをprotectedにするとかは?

329 名前:デフォルトの名無しさん :2005/05/13(金) 14:35:24
だめだ、C++で継承を禁止するスマートな方法はないや。
コンストラクタをprivateにするとか(そうするってーと基底クラスの生成方法が
限定されてしまうし)、デストラクタをvirtualにしない事で、相手が気づいて
くれるのを期待するとか、その程度しか思いつかない。

330 名前:デフォルトの名無しさん :2005/05/13(金) 14:41:46
enemyのいないfriendワールド万歳



331 名前:デフォルトの名無しさん :2005/05/13(金) 14:46:34
>>328
protected なデストラクタは継承を禁止するテクニックではなく
継承した際に、基底クラスからの delete を防ぐテクニック。
あと、>>327 は virtual 継承の話をしていると思うのだが。

332 名前:デフォルトの名無しさん :2005/05/13(金) 14:59:34
C++では、通常の継承も、virtual継承でも、強制的に禁止する手段は
ないのではないかと思う。

333 名前:327 :2005/05/13(金) 15:31:24
virtual継承するな、のコメントを目立つように工夫しました… orz。

既にやられちゃってる部分は、担当を蹴り飛ばしてきます。
いや、自分が悪いのか。

334 名前:デフォルトの名無しさん :2005/05/13(金) 15:47:07
virtual継承って事は、ダイヤモンド継承でも行いそうになってるのか?
それに実行速度が落ちるしなあ・・・・

335 名前:デフォルトの名無しさん :2005/05/13(金) 19:58:10
Boost に継承不可能なクラスを作成するためのテンプレートがあったぞ。
http://article.gmane.org/gmane.comp.lib.boost.devel/101260


336 名前:デフォルトの名無しさん :2005/05/13(金) 22:42:31
>>335
nonderivable_baseを非仮想基本クラスにすると通っちゃうのはなぜだろう。
つか仮想基本クラスだとBをエラーにできる理由がわからんorz

337 名前:デフォルトの名無しさん :2005/05/13(金) 22:43:19
http://www.kmonos.net/alang/boost/classes/noncopyable.html
これか。

338 名前:デフォルトの名無しさん :2005/05/13(金) 22:51:31
>>337
コピー不可じゃなくて継承不可の話してるんだよ?

339 名前:デフォルトの名無しさん :2005/05/13(金) 23:00:30
だめだ。昨晩飲み過ぎてから、馬鹿になった。
しばらく書き込み控えよう・・・・脳細胞が破壊された模様。

340 名前:ヽ(´ー`)ノ ◆.ogCuANUcE :2005/05/13(金) 23:31:59
>>335
> friend typename identity<T>::type;
ん、これ良いのか?

341 名前:デフォルトの名無しさん :2005/05/14(土) 01:41:25
初歩的な質問で申し訳ないですが、聞いてください。

class A;
class B;

を協調させて使うクラスCを作りました。

class C {
private:
A &a;
B &b;
C( A &a_, B &b_ ) : a( a_ ), b( b_ ) {}
...
};

質問1
クラスのメンバに参照持たせて不都合があるでしょうか?ポインタ置いたほうがいいですか?

質問2
上記のようにしたのは、aやbの動作をいじるためにそれぞれのメソッドを呼びたいからです。
class Cは、
class C {
private:
A a;
B b;
public:
A& getA( void ) { return a; }
B& getB( void ) { return b; }
};
publicに晒すのは良くないらしいので、これでも良いのですがどのようにしたらいいと思われますか?


342 名前:デフォルトの名無しさん :2005/05/14(土) 01:54:55
>>341
それは包含(composition)という手法で、has-a関係を表すのによく使われる。
ポインタにするか参照にするかは、実行途中で包含しているクラスの実体を
切り替えたいかどうかで決めればよい。どちらにしても仮想関数はちゃんと動く。

それから、実体の参照を返すくらいだったら、包含にせず、外で実体を持った
方が良い。あくまでもprivateで外に見せない事を前提にメンバにしているのだ
から、外から操作できたら意味的に本末転倒だ。

343 名前:デフォルトの名無しさん :2005/05/14(土) 01:57:08
>>341
>質問1
問題ない。
>質問2
メンバ変数をpublicにしない方が良いと言われるのは、
公開した場合、包含クラス(この場合C)が被包含クラス(A, B)を使って
実装されているという事実が、包含クラスのインタフェースに表れるのを嫌っての事。
従って、この点では、メンバ変数の参照を返すメンバ関数を公開するのは、
メンバをpublicに置くのと大して変わらない。

344 名前:デフォルトの名無しさん :2005/05/14(土) 02:13:13
>>336
ttp://www.tietew.jp/cppll/archive/10659

345 名前:デフォルトの名無しさん :2005/05/14(土) 02:31:35
>>342>>343 お返事ありがとうございます。
この場合、Cにaやbを持たせず、
C::func( A &a, B &b )として外から引数で与えようかとも悩みました。
いちいち引数に指定するのが面倒なのでメンバに置いたのですが…
C++は悩みが尽きません。

346 名前:デフォルトの名無しさん :2005/05/14(土) 02:42:24
>>345
そういう事なら、包含だとは思わず、publicメンバで持ってしまえばよい。
ま、しかし、そういう設計をする事はあまりないので、他人が貴方の作った
クラスを見てどう思うか、それを意識しないで済むのなら自由なんですが。

クラスCに関連するクラスAとクラスBのローカルな実体を持って、なおかつ
それを外部に公開するとなると、CがA及びBに意味的に縛られている限り、
外部からAやBを自由にされてしまうと、その都度Cのコンディションを把握
しなければならないようになり、余計な心配が増えるだけ。

かと言って継承を使うとなると、AとBからの多重継承になり、これまた
頭が痛いですね。

347 名前:デフォルトの名無しさん :2005/05/14(土) 02:44:47
私だったらAとBはprivateもしくはprotectedにし、細かいアクセサを付けて
外部からの操作を徹底的に制限する方向に行きます。

348 名前:デフォルトの名無しさん :2005/05/14(土) 08:40:28
例えばAやBが座標値のような汎用のクラスなら、
const参照を返すようには作るなぁ。
これなら外部から変更される心配が大幅に減る。

349 名前:デフォルトの名無しさん :2005/05/14(土) 23:32:05
>>346-348 お返事ありがとうございます。
クラスを協調させるクラスは必要だと思うので、すっきりした方法があると思うのですが…
AやBの設計が間違っているのかなぁ。手間はかかっても>>347さんの設計がいいのかなぁ。

350 名前:デフォルトの名無しさん :2005/05/15(日) 01:57:24
>>349
CがAやBの内容を見て動くのならば、AとBでCをfriendとして宣言したら
どうだろうか?これもあまり勧められた方法ではないけど、一応役目は
果たすんじゃない?

351 名前:デフォルトの名無しさん :2005/05/15(日) 02:02:47
それか、これはデザパタの話になってしまうけど、Strategyパターンを起用する手もある。
サブクラスがいたずらに増えるのを防止して、CからAやBを自由に切り替えて使える
ように出来る。

352 名前:デフォルトの名無しさん :2005/05/15(日) 02:11:29
まともに議論するには情報足りなすぎ。
想像であーだこーだ言っててもしょうがない。

353 名前:デフォルトの名無しさん :2005/05/15(日) 02:16:27
>>352
まあな。C++はいくら自由度が高いと言っても、ある程度ルールに乗っ取った
クラス階層にしないと、Cのポインタの使いすぎと同じで可読性が著しく下がる。
当然メンテナンス性も大幅に低下する。

継承を使うべきでない所に無理に継承を使ったり、カプセル化の大原則を
無視して意味不明なプログラムを作る香具師大杉。

354 名前:デフォルトの名無しさん :2005/05/15(日) 13:23:43
C++ の iostream は実装が重いから使わないほうがいい、って本当ですか?

355 名前:デフォルトの名無しさん :2005/05/15(日) 13:50:11
>>354
現状、 cstdio を使って実装されていることがほとんどなので、
cstdio に比べて重い実装が多いのは本当。
使わないほうがいいかどうかは、使う側で判断するべし。

356 名前:デフォルトの名無しさん :2005/05/15(日) 14:42:17
iostream の遅さがプログラムの動作に致命的な影響を与えるなら使わない (使えない)
そうでないならご自由に。

357 名前:デフォルトの名無しさん :2005/05/15(日) 18:27:37
クラスのメンバ関数から、自分自身をdeleteするようなことは
できるのでしょうか?

358 名前:デフォルトの名無しさん :2005/05/15(日) 18:30:47
>>357
規格では明確になっていないと思うが、現実問題としてできるし、
多用されている。ただし delete した後はメンバに触らないように
注意ね(即 return するのがお奨め)。

359 名前:デフォルトの名無しさん :2005/05/15(日) 18:35:08
VS.NET2003で、付属の標準STLでのことですが、

typedef struct {
int x, y;
}POS;

const int ARRAY = 5;
std::map< string, POS[ARRAY] > BBBmap;

POS a[ARRAY];
// BBBmap["HOGE"] = a;// 配列operator= 未定義なので×
// BBBmap["HOGE"][2] = a[2];// intからPOS[5]に変換できません

て出るので

std::map< string, POS > BBBmap[ARRAY];

を使ってるんですが、これは前者のmapをスムーズに使いたきゃ
配列operator 定義しろやゴルァってことでしょうか。

360 名前:デフォルトの名無しさん :2005/05/15(日) 18:49:41
>>359

std::map< string, POS[ARRAY] > BBBmap;

を、

std::map< std::string, std::vector<POS> > BBBmap;

にしろ。そしてSTLスレに行け。

361 名前:357 :2005/05/15(日) 18:55:35
>>358
レスどうもです。
するってえと、

delete *this;

こんな感じですかね。

362 名前:357 :2005/05/15(日) 18:59:18
あ、違うな。

delete this;

でいいのかな?

363 名前:359 :2005/05/15(日) 19:08:23
360さん、どうもです、そしてすみません。
以後気をつけます。

364 名前:デフォルトの名無しさん :2005/05/15(日) 19:55:24
調べてみたけど、コンテナの要素に配列を入れるのは、規格外のようだね。
§23.1.3
The type of objects stored in these components must meet the requirements of CopyConstructible types (lib.copyconstructible),
and the additional requirements of Assignable types.

365 名前:デフォルトの名無しさん :2005/05/15(日) 20:36:46
>>360,363 http://pc8.2ch.net/test/read.cgi/tech/1104898734/562

366 名前:デフォルトの名無しさん :2005/05/15(日) 22:53:14
>>362
ok

367 名前:341 :2005/05/16(月) 00:19:48
template< typename IMP1_, typename IMP2_ >
class Driver {
public:
IMP1_ &imp1;
IMP2_ &imp2;
Driver ( IMP1_ &imp1_, IMP2_ &imp2_ );
void shori() {
...
imp1.shori( imp2 ); //処理を委譲
...
}
};

template< typename POLICY1, typename POLICY2 >
class IMP1 {
private:
MEM1 mem1;
MEM2 mem2;
public:
POLICY1 t1;
POLICY2 t2;
template< typename X > void shori( X &x ) {
x, mem1, mem2, t1, t2 を使って処理;
}
};

(続く)

368 名前:341 :2005/05/16(月) 00:20:38
class IMP2;

int main( int argc, char *argv[] ) {

IMP1< POLICY1, POLICY2 > imp1;
IMP2 imp2;

Driver< IMP2, IMP1< POLICY1, POLICY2 > > driver( imp2, imp1 );
...
driver.shori();
...
}

IMP2, POLICY1, POLICY2 は 取り替え可能としたい。
IMP1を見て頂いたらわかると思いますが、publicにPOLICY1,POLICY2をおいています。
たまに、imp1.t1.hoge(), imp1.t2.hoge()等とメソッドを呼んで動きを調整したいのです。この場合、IMP1に細かくアクセサを作っていくとIMP1がPOLICYの数だけできて嫌な感じになると予想して躊躇しているところです。
何かいい方法はないものでしょうか?
(続く)

369 名前:341 :2005/05/16(月) 00:25:16
と整理していましたら道が見えてきた気もします(まだ巧く表現できません)。

>>352 さんの仰る通り、問題を簡単にしようと情報を切りすぎていました。
申し訳ございません。

370 名前:デフォルトの名無しさん :2005/05/16(月) 00:26:31
>>368
Stateパターンとか。

371 名前:デフォルトの名無しさん :2005/05/16(月) 00:30:55
>>367-369
もしかして template 覚えたてだったりするか?
速度に対する要求がシビアなプログラムでもなければ、
template 使いすぎの悪い例に見える。

372 名前:341 :2005/05/16(月) 00:36:08
template覚えたてです…

373 名前:341 :2005/05/16(月) 00:45:16
stateパターンってこの場合に使えるんですか?
ちょっと考えてみます。>>370さんありがとうございます。

374 名前:デフォルトの名無しさん :2005/05/16(月) 00:54:28
>>372
じゃぁ template の使いすぎに注意して考え直してみるべきじゃないかな?
もうすこしすっきりすると思うぞ。

375 名前:デフォルトの名無しさん :2005/05/16(月) 00:55:53
>>370 何を根拠に・・・・

376 名前:デフォルトの名無しさん :2005/05/16(月) 01:16:10
>368
つ [Modern C++ Design]
普通にStrategy/Stateパターン使ってもいいけどね。

377 名前:デフォルトの名無しさん :2005/05/16(月) 01:50:37
こやつにModern C++ Designを読ませるのは、火に油を注ぐようなものだと思うが。

378 名前:デフォルトの名無しさん :2005/05/17(火) 07:53:50
下記のテストプログラムをbcc32でコンパイルした場合、
1=32,2=24,3=4 になってしまうのですがこれはC++Builderのバグでしょうか?
gccだと1=28,2=24,3=4になります。

#include <stdio.h>

typedef struct {
signed long long a, b, c;
unsigned long d;
} test1;

typedef struct {
signed long long a, b, c;
} test2;

typedef struct {
unsigned long d;
} test3;

int main(void){
printf("1=%d,", sizeof(test1));
printf("2=%d,", sizeof(test2));
printf("3=%d\n", sizeof(test3));
return 0;
}


379 名前:デフォルトの名無しさん :2005/05/17(火) 07:58:48
その辺はコンパイラの勝手なのでバグじゃない。

380 名前:デフォルトの名無しさん :2005/05/17(火) 08:19:31
ちなみにbccには"long long"という型は無い。

381 名前:378 :2005/05/17(火) 08:44:59
>>379,380

なるほど…
ありがとうございました。


382 名前:デフォルトの名無しさん :2005/05/17(火) 11:44:54
>>378
-a4スイッチつければbccでもtest1は28バイトになる。(デフォルトは-a8で8バイト境界になってる)

383 名前:デフォルトの名無しさん :2005/05/18(水) 12:01:26
BohYoh.comのFAQに間違いがあるのが気になる・・・問い合わせは受け付けてないし・・・

384 名前:デフォルトの名無しさん :2005/05/18(水) 12:46:31
>>383
専用スレ立てようか?

385 名前:デフォルトの名無しさん :2005/05/18(水) 17:32:17
>>383
どの間違い?柴田先生には相当傾倒している俺としては気になる。

386 名前:デフォルトの名無しさん :2005/05/18(水) 19:55:43
C++ FAQ
> デストラクタを明示的に呼び出すことはできますか。
>
> できません。

かな。


387 名前:デフォルトの名無しさん :2005/05/18(水) 20:13:05
>>386
サンクス。
あーそりゃ完全な間違いだわ。

388 名前:デフォルトの名無しさん :2005/05/20(金) 00:06:00
typedef void (*testProc)(int);

class testClass{
static testProc proc;

public:
testClass(testProc ProcAddress){
proc = ProcAddress;
}

static void CallProc(){
proc(0);
}
};
ってやるとprivate: static void (*testProc)(int)が未解決ですって出るんだけど、
どうすればいいかな

389 名前:デフォルトの名無しさん :2005/05/20(金) 00:16:42
実体を用意する

390 名前:デフォルトの名無しさん :2005/05/20(金) 00:17:29
>388
適当なcppファイル中に
testProc testClass::proc;

391 名前:デフォルトの名無しさん :2005/05/20(金) 00:27:19
"class内のstatic変数は宣言であって定義ではない"って
感じのことをcppll(だと思う)で見つけたけど、それと同じこと?

392 名前:デフォルトの名無しさん :2005/05/20(金) 00:40:01
>>391
>>390が答えを書いているが、要するにクラスのstaticメンバはクラス外で
定義しないといけんのよ。理由はわからんが、多分クラスのインスタンス
がいくら増えても、あるいはインスタンスが一つもなくても、staticメンバは
一つきり実体があるためかも。

393 名前:388 :2005/05/20(金) 00:41:36
ありがとう、無事解決できた。

394 名前:デフォルトの名無しさん :2005/05/20(金) 01:44:12
>>392
アドレス比較するぐらいしか思いつかんのだけど、インスタンスの実体は
(コンパイラ作る人からすれば楽そうだし)スタック(もしくはそれに類するも
の)に置いたりしてるんじゃないかな。

static変数やstaticなメンバ、グローバル変数等はひとくくりに
扱える気がする(実体ひとつだと領域が確定しているし)

・・・にしても別にclass宣言内で初期設定できるような規定?でも良かったよ
うな気もする。でもそうなってないなら従うしかないか

微妙に思えるのはローカル関数内(mainもそう分類されるのか知らん)のstatic
なクラスのインスタンスやグローバルなクラスのインスタンス。

まあでもこれだって、サイズは(コンパイラに)わかってるわけだし、初期化前
にインスタンスの領域を確保しないだけ・・・・と推測してみる。
(一回だけ構築するように関数埋め込むのかもしれん。この方がデストラクタ
呼ぶ時も分かりやすそうだ。インスタンス用に1つレジスタ裂けたらこっちが良さげ鴨)

・・・長々と空想ごめん。もう寝る。

395 名前:デフォルトの名無しさん :2005/05/20(金) 02:07:54
>>394
class内で初期設定できるのはstatic const intだけだね。
しかしその理由を[C++の設計と進化]の中で探したが、見つけられなかった。
P367にはどこかに置くとしか書いてないし。探し方が足りないかもしれない。
俺も眠いから寝る。 (つ∀-)オヤスミー

396 名前:デフォルトの名無しさん :2005/05/20(金) 11:25:41
基底クラスのコンストラクタをそのまま派生クラスで使いたいのですが

class A{
public:
 A(int n);
 A(int n1,int n2,int n3);
 A(char *s);
};

class B : public A{
public:
 B(int n) : A(n) { }
 B(int n1,int n2,int n3) : A(n1,n2,n3) { }
 B(char *s) : A(s) { }
};

やっぱりこういうふうに、すべてのコンストラクタについて
定義し直さなければなりませんか?
(すべてのコンストラクタをそのまま使えるようにしたい場合)

コンストラクタの数が多いとめんどくさいので、
宣言を省略する(もしくはより短く表記する)方法があれば嬉しいのですが…。

397 名前:デフォルトの名無しさん :2005/05/20(金) 11:29:57
>>396
class B : public A{
public:
 B(A const& base) : A(base) {}

望むものとは違うかもな。

398 名前:デフォルトの名無しさん :2005/05/20(金) 11:37:57
>B(int n)
>B(char *s)
(;`Д´)・・・・・

399 名前:デフォルトの名無しさん :2005/05/20(金) 11:41:57
>>397
なるほど。暗黙の変換がされるわけですね。
引数の数が1以外だと使えませんが…。

でも引数の数が1つのことは多いので役に立ちそうです。
ありがとうございます。

>>398
例として挙げただけです。
曖昧さが生じることはあんまりないと思いますが。


400 名前:デフォルトの名無しさん :2005/05/20(金) 12:26:16
map<string, hoge>とした場合、デフォのless<string>では大文字小文字が区別されますが
区別しないバージョンは標準には無いんでしょうか?
自分でちょちょいと書くしかないのかな(´・ω・`)

401 名前:デフォルトの名無しさん :2005/05/20(金) 12:44:38
>>400
標準には無いよ。
でも、いろんな人が書いてるからどっかから拾ってこれるかもしれない。
ん? boost::algorithm になんかありそうだな。

402 名前:デフォルトの名無しさん :2005/05/20(金) 13:09:28
プラグインの開発用に公開したいヘッダーファイルがあって、
その中にあるクラスの宣言は公開したいけど、中身は公開したくないってとき
どうすればいいかな。

クラスの中に実際のしょりを書かないでソースファイル内への関数のポインタで初期化しようかと考えたけど
それだとソースファイル内の関数群のtypedef宣言しなきゃいけないし、構造体でいい事になりますよね

それにクラスで宣言すると、VCだと(他のソフトは使ってないからわからない)ナビが出てわかりやすいと思うんですよ。
もっとスマートな方法ってありますか

403 名前:デフォルトの名無しさん :2005/05/20(金) 13:12:01
公開したくない部分をクラス化しておいて
公開しても良い部分のクラス内で↑のを使う。このクラスを公開する。
そうすれば公開したくない部分は、パブリックなメンバ関数しか見えない。


404 名前:デフォルトの名無しさん :2005/05/20(金) 14:09:43
>>400
つEffective STL

405 名前:デフォルトの名無しさん :2005/05/20(金) 14:10:31
>>402
よくわからんがPImplとかそういう話?
この話題もFAQだよなー。


406 名前:デフォルトの名無しさん :2005/05/20(金) 15:29:56
>>403
//----公開するヘッダ----
class A{
public:
 Proc(int x){
  B::bProc(x);
 }
};

//----公開しないヘッダ----
class B{
public:
 bProc(int x){
 }
};

//----プラグイン側ソース----
A a = new A();
a.Proc(0);

こういうこと?
B::bProc(x);この文でコンパイルエラーになりそうだけど

407 名前:デフォルトの名無しさん :2005/05/20(金) 15:53:23
>>406
おまいの頭には「公開しないソース」という概念は存在しないのか。

408 名前:デフォルトの名無しさん :2005/05/20(金) 17:13:01
>>402
こうやるんだよ(←高圧的な物言い)

公開するヘッダ
class A {
public:
 static A* CreateInstance();
 virtual void Proc(int x);
};

公開しないソース
class AImpl : public A {
 virtual void Proc(int x) { ... ;};
};
A* A::CreateInstance() {
return new AImpl;
};

プラグイン側ソース
A* a = A::CreateInstance();
a->Proc(0);

409 名前:デフォルトの名無しさん :2005/05/20(金) 17:13:39
仮想デストラクタ忘れてた・・・

410 名前:デフォルトの名無しさん :2005/05/20(金) 17:14:49
つーか、プラグインの形態にもよるがCOMとか経由せずにDLLとかでC++のクラスを公開するのは非常に面倒なんでやめとけ。
ABIがらみとかでハマりたいならとめんが。

411 名前:デフォルトの名無しさん :2005/05/20(金) 17:35:09
Jana風なコーディングしてる人に聞きたいのですが、
名前空間の名前はどのようにつけていますか?
NameSpace? nameSpace?

412 名前:デフォルトの名無しさん :2005/05/20(金) 18:28:13
>>401
ない。

413 名前:デフォルトの名無しさん :2005/05/20(金) 19:12:12
>>411
namespace jp{ namespace co{ namespace company{ namespace product{ namespace module{
} } } } }
にでもしやがれ

414 名前:デフォルトの名無しさん :2005/05/20(金) 20:48:14
すいません、質問お願いしたいんですけどいいでしょうか?
BorlandでC++ Compiler 5.5というのをダウンロードしたんですがこれだけでは使えないんですか?
まだ初心者なものでくだらない質問ですいません。

415 名前:デフォルトの名無しさん :2005/05/20(金) 21:13:09
PC自体の初心者の場合、
・店行ってVC++.net 2003 Standardを買ってきてインストール
・Dev-C++あたりを日本語の解説見ながらインストール&日本語化
・BCCを解説ページ読みながら自力で設定
のどれが一番簡単なんだろうな?

416 名前:デフォルトの名無しさん :2005/05/20(金) 22:44:23
>>415
・店行ってVC++.net 2003 Standardを買ってきてインストール
これが一番簡単だと思う…。
インストールして、プロジェクト作って、ソース書いて、ワンクリックでビルド。
俺、もうVC無しじゃ生きていけない。

417 名前:デフォルトの名無しさん :2005/05/20(金) 23:02:00
学生ならthe Spokeね。

418 名前:デフォルトの名無しさん :2005/05/20(金) 23:34:51
学生でないなら、
Borland C++Builder 6 Personalの方が安い?

419 名前:デフォルトの名無しさん :2005/05/20(金) 23:59:39
あるクラス(A)の処理で別のクラス(B)を引数に持つときに
Aより先にBを宣言しないとダメっぽいんだけど
関数のプロトタイプ宣言みたいに宣言だけ最初にまとめて記述ってできないのかな

420 名前:デフォルトの名無しさん :2005/05/21(土) 00:00:17
class B;

421 名前:デフォルトの名無しさん :2005/05/21(土) 00:03:44
>>420
それはやってみたんだけど認識できない型でコンパイルエラーなんだよね

422 名前:デフォルトの名無しさん :2005/05/21(土) 00:05:26
ポインタか参照で持て

423 名前:デフォルトの名無しさん :2005/05/21(土) 00:14:44
>>414
単独で使用するときに、必要な知識とか設定。
http://ykr414.com/dos/
http://www.birdport.jp/CPre/free/

よくわからんのなら、
http://www.vector.co.jp/vpack/filearea/win/prog/c/index.html

CPad for Borland C++Compiler 2.31
BCC Developer 1.2.21
setbcc 1.5
のどれかを使えばなんとかなるんでない?

あと、BCCはこっち。
タダで使えるBorland C++ Part4
http://pc8.2ch.net/test/read.cgi/tech/1091066805/

424 名前:デフォルトの名無しさん :2005/05/21(土) 02:17:09
endl と \n の違いがよくわかりません。どのような状況では endl を使ったほうがいいのでしょうか?

425 名前:デフォルトの名無しさん :2005/05/21(土) 02:22:05
>>424
std::endl は '\n' と std::flush をいっぺんに突っ込む。
エラーの起こる可能性の有る処理の前、
時間のかかる処理の前に出すメッセージ、
など、画面への表示を確実に完了させたいときに使う。

426 名前:デフォルトの名無しさん :2005/05/21(土) 04:32:14
関数の引数として渡されたポインタ変数がdeleteできるかどうか
確かめる方法ってありますか?
あるいはdelete[]じゃないとやばいかどうかとか知りたいんです。
もしくはdelete及びdelete[]できない型を渡せなくするとか。

427 名前:デフォルトの名無しさん :2005/05/21(土) 04:34:31
>>426
できん。
その分、newの際にできるだけ使用するヒープ量を減らす事にしたのだから。

428 名前:デフォルトの名無しさん :2005/05/21(土) 05:03:41
deleteできるかどうかも渡したらいいんじゃない?

429 名前:デフォルトの名無しさん :2005/05/21(土) 05:06:19
>>428
それはdeleteした後にポインタ変数に0を入れておくなどの用心しかない。
できるだけクラスにして、デストラクタに始末させると綺麗に書けるんだけどね。
そうしたくない場合が多いからね。

430 名前:426 :2005/05/21(土) 07:41:52
すみません、書き方がまずかったかもしれません。
具体的にはクラスのポインタをハッシュテーブル化することを想定した
テンプレートクラスで、要素を削除したときインスタンスも一緒に削除
したいんですが、仮に以下のようにstd::mapで実装したとして

  template< typename keyT, class valueT >
  class HashContainer {
    typedef std::map< const keyT, valueT * const > container_t;
    container_t *m_container;
    〜中略〜
  public:
    void Delete(const keyT& key) {
      container_t::iterator result = m_container->find(key);
      if (result != m_container->end()) {
       delete (*result).second; //←■問題の箇所■
       m_container->erase(result);
    〜以下略〜

HashContainer< int, int > などとされて int a = 10; の &a なんかを
渡されちゃうと、問題の箇所でぶっとんじゃうのをなんとかしたいんです。
問題のある型でインスタンシエイトできなくするか、問題が無い場合だけ
deleteするか、何か良い方法はないでしょうか?

431 名前:デフォルトの名無しさん :2005/05/21(土) 08:31:11
>>430
変数のアドレスを渡すなとコメントに書くしかない。

ただstd::auto_ptrやboost::shared_ptrにすればnew使えという意思がソースからも読み取れるようにはなると思う。

432 名前:デフォルトの名無しさん :2005/05/21(土) 12:51:14
>>430
ポインタを渡しただけなのに、その指している先を削除してしまうコンテナは実装がまずいといえる。
deleteしない、deleteする、delete[]する、の3種類の動作が分けられるスマートポインタを提供し、
さらにそれを格納するコンテナを提供するのが筋。

433 名前:デフォルトの名無しさん :2005/05/21(土) 12:52:11
×実装がまずい
○設計がまずい

俺は何を言ってるんだ・・・。

434 名前:デフォルトの名無しさん :2005/05/21(土) 13:16:29
すまぽ
すまぽ
ぬるぽ

435 名前:426 :2005/05/21(土) 15:04:22
なるほど… 実体の無いインターフェース用意して
それを継承したクラスしか渡せないとかダメかな?
 class IDeletable {};
として
 std::map< const keyT, IDeletable * const > m_container;
みたいな

これでもスタックに確保された配列とか渡されたらダメか…
>>432氏の方法を考えてみます

436 名前:デフォルトの名無しさん :2005/05/21(土) 15:14:19
クラスがdeleteされるときに呼ばれる関数をクラスの中に組み込めますか?

437 名前:デフォルトの名無しさん :2005/05/21(土) 15:16:17
>>436
何も問題ないと思うけど?

438 名前:デフォルトの名無しさん :2005/05/21(土) 15:17:39
ファンクタ使えばできる。
shared_ptrとかもそうしてはず。
GC使えばいいのに...

439 名前:デフォルトの名無しさん :2005/05/21(土) 21:32:25
>>436
デストラクタからなにか関数を呼ぶということだと思うけど、
自身の仮想関数を呼ぶと愉快な動作をしてくれる。

440 名前:デフォルトの名無しさん :2005/05/21(土) 21:49:49
>>439
デストラクタというんですね。ありがとう
自分の無知さがはずかしい

441 名前:デフォルトの名無しさん :2005/05/21(土) 21:51:04
話がかみ合ってないのに情報が伝わっててワラタ

442 名前:デフォルトの名無しさん :2005/05/21(土) 22:57:10
ええと。ホームページで携帯からアクセスを禁止にしたいのですがどうすればいいのか分からないんですけど・・・
どなたかお願いします。

443 名前:デフォルトの名無しさん :2005/05/21(土) 23:00:55
+激しくスレ違い+

444 名前:デフォルトの名無しさん :2005/05/21(土) 23:52:40
むしろなぜここに質問しようと思ったのか全く理解できないくらいスレ&板違い

445 名前:デフォルトの名無しさん :2005/05/22(日) 01:44:06
メソッド内で定義したローカルクラスのポインタを返すのって、C++ の言語仕様的に
やっても大丈夫なのかな・・・。
あるいは言語仕様的には OK でもちゃんとコンパイルできない処理系があるとか・・・。
とりあえず g++ ではうまくいったわけだが。

---以下サンプルコード---

#include <iostream>

struct Giko {
 virtual void gorua() { std::cout << "ゴルア" << std::endl; }
};

struct Hoge {
 Giko* createGiko() {
  struct FusaGoko : public Giko {
   virtual void gorua() { std::cout << "フサフサ" << std::endl; }
  };
  return new FusaGoko();
 }
};

int main() {
 Giko* giko = Hoge().createGiko();
 giko->gorua();
 delete giko;
 return 0;
}


446 名前:デフォルトの名無しさん :2005/05/22(日) 01:44:54
>>445
OK

447 名前:445 :2005/05/22(日) 01:45:40
プログラムの動作そのものには関係しないけど、FusaGoko → FusaGiko ですた・・・。

448 名前:445 :2005/05/22(日) 01:48:31
>>446
どうもサンクスでつ。

449 名前:デフォルトの名無しさん :2005/05/22(日) 01:50:14
Visual C++ 6.0でコンパイルをするとリンク中と表示されたままで進まないことが以上に多いんですけど、これってどうしようもないんですか?教えてください。

450 名前:デフォルトの名無しさん :2005/05/22(日) 01:53:27
スレ違い

★初心者にVisual C++を教えるスレ★ Part19
http://pc8.2ch.net/test/read.cgi/tech/1116209988/

451 名前:デフォルトの名無しさん :2005/05/22(日) 18:27:55
かつてCで書いたプログラムを、勉強+将来のGUI化に向けて、C++に書き直しています。

この中で、調べてもよくわからないところがありましたので質問させていただきます。
C言語(stdio.h)のfscanfとかfseekに相当する関数は、C++(fstream.h)ではどれにそうとするのでしょうか?
また、C言語とC++との違い・対応がわかりやすいサイト・書籍がありましたらご紹介願います。
// テンプレ嫁といわれてしまいそうですが_| ̄|○

わかりにくい文章かもしれませんが、よろしくお願いします。

452 名前:デフォルトの名無しさん :2005/05/22(日) 18:35:07
>>451
fscanf は各型の operator >> が対応していると言えなくも無いかな。
fseek は読み込みなら seekg だろうな。
無理に fstream を使わなければ、そのまま動くはずだけど。
あと、 fstream.h は fstream にしとけよ。
最後に、テンプレ嫁。

453 名前:デフォルトの名無しさん :2005/05/22(日) 18:37:37
>>451
ttp://www.kurumi.sakura.ne.jp/~kumicyou/cplusplus/main.html

454 名前:デフォルトの名無しさん :2005/05/22(日) 18:46:20
>>452-453
レス、サンクスです。
これで、がんばれそうです。

455 名前:デフォルトの名無しさん :2005/05/22(日) 18:48:25
>>451
現在のC++ではfstream.hは存在しないから将来も何もない。

どうしてもわからなければsed::getline()でstd::stringに読み込んでから<cstdio>のstd::sscanfを使う方法もあるさ。

456 名前:デフォルトの名無しさん :2005/05/23(月) 10:27:52
>C言語(stdio.h)のfscanfとかfseekに相当する関数は、C++(fstream.h)ではどれにそうとするのでしょうか?
やはりここは、
C++(cstdio)のstd::fscanf()とかstd::fseek()が相当します。
と答えたくなるな。

457 名前:デフォルトの名無しさん :2005/05/23(月) 10:59:19
newで返されるポインタの型をキャストするときは
static_castですか?それともreinterpret_castですか?
ポインタの型は論理変換でしたっけ?

458 名前:デフォルトの名無しさん :2005/05/23(月) 11:00:48
>>457
やりたいことを具体的に示せ。

459 名前:デフォルトの名無しさん :2005/05/23(月) 11:12:32
operator newをオーバーロードしたいのですが、

そのオーバーロード関数内で
MyClass *p;
p = ????_cast<MyClass*>( new char[chunk] );

の場合は、どのキャストがベストですか?

460 名前:デフォルトの名無しさん :2005/05/23(月) 12:14:49
reinterpret 以外あり得ない

461 名前:デフォルトの名無しさん :2005/05/23(月) 12:24:25
staticとreinterpretと両方見かけたことがあるんですよね。
Effective C++ P.63には

Airplane *newBlock = static_cast<Airplane*>(::operator new(BLOCK_SIZE * sizeof(Airplane)) );

とあるんですが、このケースは違う?

462 名前:デフォルトの名無しさん :2005/05/23(月) 12:38:08
>>461
void *からT *へはstatic_castが使える。
char *からT *へは使えない。

463 名前:デフォルトの名無しさん :2005/05/23(月) 13:14:12
>>462
なるへそ。
ということは
new ???
こういう書式だと、???の型のポインタが返されるけど
operator new(size_t)
この書式だと、コンパイラは型がわからないからvoid*型が
返されるってことかな?

464 名前:デフォルトの名無しさん :2005/05/23(月) 14:22:00
.Netではあるクラスを初期化するときに
new ClassA(a, b, new ClassB() );
といったように別のクラスを引数としてとる事がありますが
これはC++だとdeleteされないからメモリリークを起こしますよね

465 名前:デフォルトの名無しさん :2005/05/23(月) 14:35:48
それってClassAのデストラクタでClassBをdeleteすればいいんじゃないの?

466 名前:デフォルトの名無しさん :2005/05/23(月) 14:59:53
たとえばnew Brush(new Color(255,255,255));みたいに
Brush側でColorがこの後利用するかどうかって判断つかない場合もあると思うんですよ

467 名前:デフォルトの名無しさん :2005/05/23(月) 15:02:51
>>466
Colorみたいなものは値渡しだからどうでもいいとして、

初期化がどうとかいう話ではなく、「GCがないから
いらなくなったら自分で delete しないとメモリリークを起こしますよね」
っていう話のような気がする。

468 名前:デフォルトの名無しさん :2005/05/23(月) 15:05:43
そらC++なら当たり前だ
shared_ptrでも使えば?

469 名前:デフォルトの名無しさん :2005/05/23(月) 16:07:47
GCが防いでくれるのは多重開放であってメモリリークではない。

470 名前:デフォルトの名無しさん :2005/05/23(月) 16:36:10
reinterpret の読み方って 「りんたぷれっと」 でいいの?

471 名前:デフォルトの名無しさん :2005/05/23(月) 17:03:51
リインタプリトって読んでいる。
interpreter = インタプリタから。

472 名前:デフォルトの名無しさん :2005/05/23(月) 17:04:19
リインタプリトって読んでいる。
interpreter = インタプリタから。

473 名前:デフォルトの名無しさん :2005/05/23(月) 17:21:54
引数が省略可能とする時は、プロトタイプ宣言にてデフォルトを記述しますが、
引数が構造体の場合は、デフォルト値はどのように記述すれば良いのですか?

474 名前:デフォルトの名無しさん :2005/05/23(月) 17:46:04
>>473
構造体にコンストラクタを設けて、デフォルト引数を一時オブジェクト作成にすればよい。

struct A
{
    int x;
    A(int x) : x(x) {}
};

void f(A a = A(0));


475 名前:デフォルトの名無しさん :2005/05/23(月) 17:49:13
>>474
ありがとうございました

476 名前:デフォルトの名無しさん :2005/05/23(月) 20:12:57
class A { };
class B : public A { };

//////////

B* x = new B();
A* y = x;  // ← これは大丈夫なのに

B** z = &x;
A** w = z; // ← これは駄目なのはどうしてなのでしょうか?

477 名前:デフォルトの名無しさん :2005/05/23(月) 20:24:32
>>476
どうして?と聞かれても、仕様だ!と答えるしかないな。
その変換を認めると、

A **w = z;
*w = new A;
// ここで*zを使う

のようなコードで、Bのつもりでアクセスした実体が実はAだった、ということがおきる。
つまり、その変換は安全じゃないから、禁止されている。

478 名前:477 :2005/05/23(月) 20:27:08
// ここで**zを使う
ね。

479 名前:デフォルトの名無しさん :2005/05/24(火) 01:56:25
http://www.research.att.com/~bs/

禿・・・

480 名前:デフォルトの名無しさん :2005/05/24(火) 02:02:53
いつも思うのだが
Bjarne Stroustrup
これは正確にはなんと発音すればいいんだ?
俺はうまく発音できなくて禿げ禿げでごまかしてるんだが。

481 名前:デフォルトの名無しさん :2005/05/24(火) 02:18:32
>>480
情報処理用語の読み方を確認するスレ
http://pc8.2ch.net/test/read.cgi/tech/1056173956/l50


482 名前:デフォルトの名無しさん :2005/05/24(火) 02:32:17
情報処理用語かよw

483 名前:デフォルトの名無しさん :2005/05/24(火) 02:32:39
ビアルネだったのか・・・ビヤーンだと思ってた。
つか情報処理用語なのかこいつの名前は。

484 名前:デフォルトの名無しさん :2005/05/24(火) 02:52:41
継承して欲しくないクラスを明確にする為に

#define final_class class
final_class foo {
};

みたいな事するのって気色悪いですか?
用語はまあsealed_classとかでもOKなんですが
デストラクタをvirtualにしないだけじゃ設計ミスみたいだし…

485 名前:デフォルトの名無しさん :2005/05/24(火) 02:59:01
俺はデストラクタがvirtualでなければ継承禁止の意思表示に取るけどね
マクロ使うぐらいならコメント一言入れとけば?

486 名前:デフォルトの名無しさん :2005/05/24(火) 04:39:39
>>484
class foo { // 継承したら肛門童貞奪うぞ
};

((( ;゚Д゚)))ガクガクブルブル

487 名前:デフォルトの名無しさん :2005/05/24(火) 09:46:17
>>480 ttp://www.research.att.com/~bs/bs_faq.html#pronounce

488 名前:デフォルトの名無しさん :2005/05/24(火) 09:50:01
>>486
肛門が童貞じゃないお兄さんなら継承しても平気なわけだ。

489 名前:肛門童貞じゃない :2005/05/24(火) 10:32:32
おねいさんはだめですか?

490 名前:デフォルトの名無しさん :2005/05/24(火) 10:36:13
ビヤーンネ・ストローストロップが正しいのか。

491 名前:デフォルトの名無しさん :2005/05/24(火) 10:44:05
それを言い出すとカナ表記しようとする段階で間違い。

492 名前:デフォルトの名無しさん :2005/05/24(火) 11:50:14
>>486を受けると
>>490
ビヤーンネ・スカトローストロップが正しい。

493 名前:デフォルトの名無しさん :2005/05/24(火) 13:10:20
イヤーネ・スカトローストリップ?

494 名前:デフォルトの名無しさん :2005/05/24(火) 14:56:20
イヤーン・スカトロストリップ?

495 名前:デフォルトの名無しさん :2005/05/24(火) 16:02:09
ファイル名が指定されているときはそのファイルに、
ファイル名が指定されていないときは標準出力に、
それぞれ出力したい場合:

void f(const string &filename="") {
  ostream &fout = (filename != "") ? *(new ofstream(filename.c_str())) : cout;
  fout << "hello, world" << endl;
  if (&fout != &cout) delete(&fout);
}

というように書けばいいんでしょうか?


496 名前:デフォルトの名無しさん :2005/05/24(火) 16:11:11
>>495
そんな感じでいいと思うよ。
俺だったらconst char *版もオーバーロードするけど。

497 名前:デフォルトの名無しさん :2005/05/24(火) 16:29:22
void f(const string& str) {
 ofstream ofs( filename.c_str() );
 f( ofs );
]

void f() {
 f( cout );
}

void f(ostream& os) {
 os << "hello" << endl;
}

498 名前:デフォルトの名無しさん :2005/05/24(火) 16:32:59
>>497
それだったらデフォルト引数にcoutを書けばいいだけじゃねえかよ。

499 名前:デフォルトの名無しさん :2005/05/24(火) 16:36:11
漏れだったらstd::stringのconst参照ではなくconst char *をとるようにするなぁ。

500 名前:デフォルトの名無しさん :2005/05/24(火) 16:52:53

俺ならおとなしくこう書くかな。

void f(const string &filename) {
if(filename.empty()){
ff(cout);
}
else{
ofstream ofs(filename.c_str());
ff(ofs);
}
}

void ff(ostream &os)
{
  os << "hello, world" << endl;
}



■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.