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


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

C++相談室 part11
251 名前:デフォルトの名無しさん :02/09/28 14:18
>248
pimpl をただの構造体として使っているとか?
メンバ関数も持たせて、処理を移譲するようにしてやると少しは
オブジェクト指向らしくなると思う。
オレは昔は純粋仮想関数からなるインタフェースクラスを継承することに
美を感じていたが、最近では多態が不要なところでそれをやるのは
ダサいと思うようになってきた。そういうところは、pimpl を使って
処理を移譲するほうが美しい。

252 名前:デフォルトの名無しさん :02/09/28 14:27
>>251
ただの構造体隠蔽として使う方がまだ美しいと感じる。

ガワと中身という違う物を実装しているとはいえ、
見てくれ(インターフェイス)が同一な物を2度作らなきゃならんのがダサいと思う。

>最近では多態が不要なところでそれをやるのは

同一の理由により、インターフェイス継承もやりたくない。


253 名前:デフォルトの名無しさん :02/09/28 15:29
pimplなんて使うのはダサい!!!
男は黙ってコンパイルせい!!
Pentium 166MHzで!!!

254 名前:デフォルトの名無しさん :02/09/28 16:22
構造体ってなんだっけ?

・・・・あ、structureのことか。
日本語キモくって最近使って無かった(w

255 名前:デフォルトの名無しさん :02/09/28 17:08
>>254
大和言葉を使いなさい

256 名前:デフォルトの名無しさん :02/09/28 17:25
>>254
国賊め!!!
北朝鮮に拉致されてしまえ!!!

257 名前:デフォルトの名無しさん :02/09/28 17:27
仮想でない関数はクラスの外で宣言できるようになっていれば、
データ構造だのprivate関数だのを外に晒す必要も無くなるだろうに。
あとメンバtypedefやメンバconstの類も。
operator newがあれば前方宣言だけでインスタンスまで作れる。

258 名前:デフォルトの名無しさん :02/09/28 17:56
>>257
そのかわり間接参照が一回増えるのが嫌…っつー時代に設計された言語だ。
そこを責めてくれるな。

259 名前:デフォルトの名無しさん :02/09/28 19:03
C++処理系には前処理だけを行なうスイッチが用意されている。

Visual C++の場合

cl /GX /P smp1.cpp -/Pスイッチで前処理だけしてsmp1.iファイルを作る


というふうに本に書いてあったのですが,意味がわからないのですが・・・



あと,cstdioとかは,ネームスペース名は,std;ではなくてどういうのになるんでしょうか?

260 名前:デフォルトの名無しさん :02/09/28 19:09
std::ostream に NULL 終端ではない char[] を指定文字数分だけ出力したいのですが、スマートな方法はありますでしょうか?

考えた方法は
1.バッファを確保し strncpy 後に NULL を追加して <<(ostream&, char*)
  うまくいくだろうけどバッファの動的確保のコストが気になる。
2.ループで指定文字数まで <<(ostream&, char)
  うまくいくだろうけど効率悪すぎ
3.std::setw
  指定文字数より長い場合には何もしてくれない
4.同期化された静的バッファにコピー後に <<(ostream&, char*)
  バッファ長より長い文字列の場合に結局ループしながら書き出さなければならない & 同期化のコストもちょっと気になる。


何か良い方法はないでしょうか?

261 名前:デフォルトの名無しさん :02/09/28 19:17
>>260
ない

262 名前:デフォルトの名無しさん :02/09/28 19:20
>>261
そんな冷たい事言わずに…
「ない」って言い切るくらい凄腕な方なら、私が考えた例よりも
効率の良い方法とかもいくつか思い浮かんだりするでしょう?
トレードオフの問題も絡めて、私の愚考よりも少しでもいい方法とかあったら
教えてください、よろしくお願いします。

263 名前:260 :02/09/28 19:21
260=262です。よろしくお願いします。

264 名前:デフォルトの名無しさん :02/09/28 19:25
>>258
スタック上にインスタンス作ったり、operator newが無かったりする時は、
クラスの定義が必要、となっていれば、別にオーバーヘッドは無いだろ。

265 名前:デフォルトの名無しさん :02/09/28 19:26
>>260
単純に
basic_ostream::write( const char_type *, streamsize )
でダメなのか?

266 名前:デフォルトの名無しさん :02/09/28 19:39
int n;


cout << (cin >> n) << endl;

なんか変な数値が出るんだけども,cin関数の戻り値が表示されてるってこと?

267 名前:デフォルトの名無しさん :02/09/28 19:49
>>262
効率の良い方法を求めてるわけ?
答えは簡単。
ostreamを捨ててどっかからファイルクラスを拾ってくる。
これ、最強。

268 名前:デフォルトの名無しさん :02/09/28 19:56
>>266
MSDNより

cin
extern istream cin;
このオブジェクトは、標準入力からバイト ストリームを抽出します。オブジェクトが生成されると、cintie() を呼び出し、&cout を返します。

269 名前:デフォルトの名無しさん :02/09/28 19:59
struct A
{
};

struct B
{
 friend void func(A& a)
 {
 }
};

struct C
{
 friend void func(A& a)
 {
 }
};

void test()
{
 A a;
 func(a);
}

これってエラーにならんのね(VC)

270 名前:デフォルトの名無しさん :02/09/28 20:15
funcはクラス外で宣言されたものとみなされるから、かな?

271 名前:デフォルトの名無しさん :02/09/28 20:24
>>270
struct B と C のどっちのfuncを呼んだのだろう?と思って
舌のようなコードにしたら、Bが呼ばれてた。

struct B
{
 friend void func(A& a)
 {
  printf("struct B\n");
 }
};

struct C
{
 friend void func(A& a)
 {
  printf("struct C\n");
 }
};

…Cのほうは?

272 名前:デフォルトの名無しさん :02/09/28 20:28
class と struct の違いって何よ?

273 名前:デフォルトの名無しさん :02/09/28 20:30
>>272
デフォルトのメンバがprivateかpublicか。

274 名前:デフォルトの名無しさん :02/09/28 20:34
>>273
+キーワードの違い

275 名前:デフォルトの名無しさん :02/09/28 21:05
>>272
structはprivateなメンバがないクラスを記述するのに使うとよい。

276 名前:デフォルトの名無しさん :02/09/28 21:48
>>264
operataor new というか、ファクトリを前クラスに定義しろって話か?

できそうな気はするが、多重定義や名前空間に絡んで、予期せぬ名前解決された
ときにリンクするまで(あるいは実行時エラーが出るまで)トラブルが判明しないとい
う嫌なバグを作り込みそうな気がする。

277 名前:デフォルトの名無しさん :02/09/28 22:03
>>271
VCがヴァカなだけでは?

278 名前:デフォルトの名無しさん :02/09/28 22:32
VC以外はどう?

279 名前:デフォルトの名無しさん :02/09/28 22:35
bcc, gcc共にコンパイルできず。
funcがすでに定義されてると。

280 名前: ◆JAPH9PWA :02/09/28 22:51
>>266
iostreamはストリームの状態を表す為にoperator void*()とoperator!()をオーバーロードしてるんだよ。
std::cout << (cin >> n) << std::endl;
この場合、istream::operator>>(istream&, T)は第一引数を参照で返すから、
(cin >> n)はcinそのものを返す、と。
で、そのあとcinを出力する為にistream::operator void*()を呼び出す為、
一見不可解な値が表示されるというわけ。


281 名前:デフォルトの名無しさん :02/09/28 22:51
こまったもんだ

282 名前:266 :02/09/29 01:24
>>280
くっ,全然わからない・・・
C++勉強し始めて,7日目だけどいつ頃になったらわかるようになるかな?

283 名前:デフォルトの名無しさん :02/09/29 01:25
最初から頭を突っ込むところじゃないと思うけど・・・

284 名前:デフォルトの名無しさん :02/09/29 01:43
>>282
あきらめろ、おまえには無理だ。

285 名前:デフォルトの名無しさん :02/09/29 01:51
>>282
最初は誰でもわからない、特にC++はCとは違って体系的な学習が
不可欠だ。

取り敢えず入門書1冊読破せよ。

286 名前:デフォルトの名無しさん :02/09/29 02:04
>>285
はるひこさんのビギナー編ファイル入出力意外全部読みました
C++やると,C言語に戻りたくないですね

287 名前:デフォルトの名無しさん :02/09/29 02:07
>>286
読むだけではなく、手間を厭わず打ち込んで試してみた?
そういう一見無駄な努力が、実はとても役に立つのだ。

288 名前:デフォルトの名無しさん :02/09/29 02:12
>>287
すごくうちまくったよ
とはいわないけど,50回くらいは,

cout << "a=" << a << '\n';
進化
cout << "a=" << a << endl;

とか打ちましたよ

まーもっと打てよぼけとか言われそうですけど

C++覚えると,就職有利になりますかね?
c/c++募集ってとこにいきたいんですけど,C言語だけしか覚えていないんですよね

289 名前:デフォルトの名無しさん :02/09/29 02:22
>>288
晴彦はどうかと思うが…。
まあ次は何かアプリ作ってみなさいってこった

290 名前:デフォルトの名無しさん :02/09/29 02:25
>>288
あとは using namespace std; を外して、std::を識別子の前に付ける
ようにすればよい。

就職は、ほとんど会社に入ってから覚えさせられる事が多いので、
まずは自分でバグ取りできるだけの力をつけるようにする。そうすれ
ば進歩が速い。

291 名前:デフォルトの名無しさん :02/09/29 03:31
>>290
クラス内でusing namespace std;とかする分には
問題ないんじゃ?

292 名前:デフォルトの名無しさん :02/09/29 03:31
あと関数内で。

293 名前:デフォルトの名無しさん :02/09/29 03:47
C#やるようになって、C++のヘッダと実装を分ける書き方がなんと美しかったことかと気づかされた。
かといってC++の#includeはいやだ・・・う〜〜む・・・

294 名前:デフォルトの名無しさん :02/09/29 04:54
>>288
> C++覚えると,就職有利になりますかね?
C++ 使う職場なら、もちろん有利になる。

295 名前:デフォルトの名無しさん :02/09/29 08:13
VC++.NETで
std::ios::noreplace
がないんだけど。
他に変わる物もみたらないのですが、どうすればよいのでしょうか?



296 名前:デフォルトの名無しさん :02/09/29 08:57
>>295
http://www.microsoft.com/japan/developer/library/vccore/_core_differences_in_iostream_implementation.htm
古いiostreamを使うのが一番手っ取り早いかと。

297 名前:デフォルトの名無しさん :02/09/29 10:11
>>293
ヘッダなんて無駄なだけだろ

298 名前:295 :02/09/29 10:24
>>296
ありがとうございます。
古いバージョン使うのあまり気が進まないです。(将来使えなくなりそうなので)
先にファイルOPENして確認するとかしかないか...。


299 名前:デフォルトの名無しさん :02/09/29 11:08
>>297
分けないとネストが深くなりすぎてみにくくなる。
まぁ、オレもC/C++の#includeはちょっと好きじゃないけど。
C++なんてnamespaceがあるんだからヘッダのネストとかで悩ませられるのはどうかと思う。


300 名前:デフォルトの名無しさん :02/09/29 18:24
ヘッダは無駄と思う。設計ミスって引数変えたり名前変えたりしたときにヘッダもいじらにゃならんし。
そもそも2度同じこと(プロトタイプ宣言とか)を書かないといけないのがスマートじゃない…。Cは仕方無いとして、
C++はなんでヘッダがあるんだろう…?



301 名前:デフォルトの名無しさん :02/09/29 19:45
>300
テンプレートライブラリのため

302 名前:デフォルトの名無しさん :02/09/30 00:43
Cというなの言語は今はありません。死に耐えました。
ただC++によってそのコードは今生かされているだけなのです。

303 名前:300 :02/09/30 03:24
>>301
いや、分かってるよ。
分かってるんだけど、もっと別の(ヘッダファイルを使う以外の)スマートなアプローチは無かったんかい、と。

304 名前:デフォルトの名無しさん :02/09/30 10:35
>>303
なら、ヘッダに全部書けよ。

305 名前:デフォルトの名無しさん :02/09/30 16:48
C++で 比較の結果が0/1であることは保証されてますか?

306 名前:デフォルトの名無しさん :02/09/30 16:48
age

307 名前:デバックの名無しさん :02/09/30 16:57
乱数はどうやって、発生できるんですか?

308 名前:デフォルトの名無しさん :02/09/30 17:13
>>307
ランダムマスターでも使え。
http://www2.toshiba.co.jp/efort/market/rmaster/index_j.htm

309 名前:デフォルトの名無しさん :02/09/30 17:18
発生器を使って。

310 名前:デフォルトの名無しさん :02/09/30 17:22
「乱数発生法」でぐぐれば一杯出てくる。
http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&oe=UTF-8&q=%E4%B9%B1%E6%95%B0%E7%99%BA%E7%94%9F%E6%B3%95

311 名前:デバックの名無しさん :02/09/30 17:23
>308
C++でやりたいんです。

312 名前:デフォルトの名無しさん :02/09/30 17:33
Mersenne Twisterは?
http://www.emit.jp/mt/mt.html

313 名前:デフォルトの名無しさん :02/09/30 17:52
boost/random
http://www.boost.org/libs/random/index.html

314 名前:デフォルトの名無しさん :02/09/30 18:27
>>305
ある意味、保証されているが、そういう認識の仕方は少し問題だと思う。


315 名前:デフォルトの名無しさん :02/09/30 18:39
>>314
どういう事ですか?
Cで比較演算の真偽値が0/非0と言うのは理解してますが、
C++だと0/1が保証されているという記事を読んだので、どうなのだろうと。

316 名前:デフォルトの名無しさん :02/09/30 18:44
>>315
厳密にはC++で比較演算の結果はbool型のtrue/falseを返す。
これを整数に変換すると1/0になるという認識が正しい。

317 名前:デフォルトの名無しさん :02/09/30 18:49
組み込みの比較演算子は保証されてるけど演算子がオーバーロード
されてる場合もあるからなあ。。


318 名前:デフォルトの名無しさん :02/09/30 18:57
>>316-317
なるほど。
サンクスコです

319 名前:デフォルトの名無しさん :02/09/30 19:25
std::fstreamの質問です

std::ofstream TestFile("./test.txt");
として
TestFile << "test message...";
とやった場合、メッセージの部分は
fstreamの内部にあるバッファへ溜め込まれているだけ
という認識でいいんでしょうか?
TestFile.flush()するまでファイルアクセスは無いですよね?

fstreamのソースみてもわけわからないです・・・

320 名前:デフォルトの名無しさん :02/09/30 19:33
やってみてファイルを見てみましょう

321 名前:デフォルトの名無しさん :02/09/30 19:36
>>319
そんなもん実装依存だよ
flushすれば確実に吐き出されることが保証されているだけ

322 名前:デフォルトの名無しさん :02/09/30 19:40
>>319
バッファが一杯になると自動的にフラッシュされる。

323 名前:デフォルトの名無しさん :02/09/30 19:41
逆に、flushしないで溜め込んでおいたバッファの内容を
参照できるような関数ってあるんでしょうか?

例えばTestFile.c_str()みたいな・・・

324 名前:デフォルトの名無しさん :02/09/30 19:44
>>323
rdbuf()

325 名前:デフォルトの名無しさん :02/09/30 19:49
>323
検索したらゾロゾロ出てきました
ありがとう

326 名前:デフォルトの名無しさん :02/09/30 19:49
>324のミス・・・

327 名前:デフォルトの名無しさん :02/09/30 19:59
rdbuf()の面白い使い方。ファイルの内容をたった一行で
全表示する。

#include <iostream>
#include <fstream>

int main()
{
std::fstream ifs("rdbuf.cpp");

std::cout << ifs.rdbuf();
}

328 名前:デフォルトの名無しさん :02/09/30 20:11
>>327
それも実装依存。


329 名前:デフォルトの名無しさん :02/09/30 20:17
>>328
327です。
ソースきぼん。
俺のソースはC++標準ライブラリ、P603、§13.9。

330 名前:デフォルトの名無しさん :02/09/30 20:19
おっとっと間違いハケーン。std::fstream→std::ifstreamにしてください

331 名前:デフォルトの名無しさん :02/09/30 22:17
標準ストリームに関する質問です

std::endl std::ends std::flush の実体ってどこで宣言(定義)されてるんでしょうか?
ヘッダファイル群にGREPしたところ、ヤツらの型が
basic_ostream& (*pf)(basic_ostream&)で受け取れるとこまではわかったんですけど
受け取ってからどうやって振り分けたものか悩んでおります


ストリームのラッパークラスなんて初心者が手を出すような領域じゃ無いのかな・・・

332 名前:デフォルトの名無しさん :02/09/30 22:21
>>331
basic_ostreamのような気がする。継承を見ていくと。

333 名前:デフォルトの名無しさん :02/09/30 22:24
>>331
実装によるのでコンパイラと使ってるiostreamライブラリぐらいは書いた方が。
今俺の手元にあるSTLPort for DegitalMarsC++ だと stl/_ostream.h にあったが。

つーか、振り分けって具体的に振り分けて何をするつもりだ?
endl をトラップして自前の改行文字を書くフィルタを作るとかか?

334 名前:331 :02/09/30 22:44
やりたい事は、ファイルオープンと同時に現在時刻の文字列をファイルの先頭に書き込んで
ファイルクローズの際に、またその時の時刻の文字列をファイルの終端に書き足すクラスで
標準ストリームのように、<<演算子で次々挿入できるようにして
endlとflushを受け取ったときに標準ストリームと同じ様な挙動にしたいなぁと

とりあえず<<演算子のオーバーロード(&受け取った型毎オーバーライド)と
endlを捕まえてバッファの内容を吐き出すところまでは実装できたんですが
そういやflush受け取ったときはどうしよう・・・と悩んでいる最中です

335 名前:331 :02/09/30 22:48
あ、えーと、そんなもんostreamのポインタなりを返す
パブリックなメンバ作ればいいじゃねぇかと言う話かもしれませんが
mystream.lpfstream << "なんたらかんたら" << endl; とかやると
↑の部分が見苦しいナァと思いまして・・・

贅沢言うな!ってとこなんでしょうか

336 名前:デフォルトの名無しさん :02/09/30 22:49
>>334
それだったら、basic_fstreamをpublic継承して、endl, ends, flushだけを
オーバライドすればいいのでは。

337 名前:331 :02/09/30 22:57
あとなんでこんなややこしい事しとるのかといいますと
fstreamってバッファがいっぱいになると勝手にファイルに書き込んじゃうらしいので
明示的に「書き込め!」って指示するまでひたすらバッファへ溜め込むようにしたいんです

>336氏の方法だと、ファイルオープン/クローズ時の
現在時刻の書き込みはどう実装すれば良いんでしょうか?

338 名前:デフォルトの名無しさん :02/09/30 22:58
basic_filebufを自分好みにカスタマイズ

339 名前:デフォルトの名無しさん :02/09/30 23:05
う〜んopen/close時までカスタマイズするとなると、basic_fstreamの
コンストラクタ/デストラクタまでオーバライドする必要があるなあ。

しかもbasic_ostreamのヘッダを覗いていたら、endl, ends, flushなど
のマニピュレータは、basic_ostreamのメンバ関数ではない様子。
そうなるとオーバライドできないですね。

やはりここは myendl, myends, myflushなど名前を変えた方がよいかも。

rdbuf(pointer)で、大きなストリームバッファは設定できるけど、
出力に合わせて拡張するストリームバッファなんてどうやって実現
していいものやらさっぱりわかりません。

340 名前:331 :02/09/30 23:13
現在の実装では、バッファにstd::stringを使っているので
可変長バッファの問題はクリアだと思います

flushをendlと同義に扱うか、もっと研究してflushの正体を暴くか
どちらかかと思うのですが・・・

ちなみに以前myendlなどで実装しようと目論んだ事がありましたが
マニピュレータのやり方がわからず、グローバルなmyendlクラスを定義して
お茶を濁すという、なんとも恥ずかしい過去がありまして
今度こそスマートに実装しようとがんばってみましたが、ちょっとお手上げ状態です・・・

341 名前:デフォルトの名無しさん :02/09/30 23:22
>>340
それだったら何とかなるかも。ユーザー定義のマニピュレータですよね。

template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
myendl(std::basic_ostream<charT, traits>& strm)
{
strm << std::endl;
// ここにさせたい処理を書く
}

のような感じでどうでしょう。

342 名前:デフォルトの名無しさん :02/09/30 23:22
flushは内部でストリームバッファクラスのpubsync()メンバーを呼んでるなり。

343 名前:デフォルトの名無しさん :02/09/30 23:23
符号付き32bit整数をリトルエンディアンで負数は2の補数表現で出力する関数を作りたいのですが
移植性を考えたときによく分からなくなってきたので質問させていただきます。

最初は以下のようにしました。
void writeInt32(std::ostream &o, long v)
{
o.write((char*)&v, sizeof(v));
}
これだと以下のようなことが気になりました。
・long*をchar*にした結果は実装依存?
・sizeof(long)が4とは限らない
・longが負の時のビットパターンが2の補数表現とは限らない

というわけでとりあえず次に以下のようにしました。
o.put(v & 0xff);
o.put((v >> 8) & 0xff);
o.put((v >> 16) & 0xff);
o.put((v >> 24) & 0xff);
ところが、putの引数はcharなんです。
プログラミング言語C++第三版の付録C.3.4(p.942)の下の方には
> void f(char c, signed char sc, unsigned char uc)
> {
> c = 255; // 限定無しのcharがsignedで8ビットなら未定義
とあります。
つまり、(v & 0xff)の結果が255の場合、o.put(v & 0xff)は未定義なのではないでしょうか?
あと、負数が2の補数表現でない場合も考えないといけなそうです。
結局標準C++の範囲内でなんとかするのは不可能なのでしょうか?


344 名前:デフォルトの名無しさん :02/09/30 23:23
あ、最後に return strm; つけて下さい。

345 名前:デフォルトの名無しさん :02/09/30 23:30
数値表現の可能性を論じてたら先に進まない。
符号付き整数の右シフトも怪しいから、

unsigned long l = (unsigned)v;
としてからo.put(l & 0xff)として書き込むのが良いかと。

346 名前:デフォルトの名無しさん :02/09/30 23:32
>>343
charに127を超えるintを代入した時だけが未定義なのであって、
(v >> 8) & 0xffをputするのは別に代入ではなくて関数の引数
だから大丈夫では?

347 名前:343 :02/09/30 23:55
>>345
>数値表現の可能性を論じてたら先に進まない。
全くその通りですね。2の補数ではない時を考えて負だったらビット反転させて1足して……とかアホなことをやろうかと思ったところで目が覚めました。

>unsigned long l = (unsigned)v;
>としてからo.put(l & 0xff)として書き込むのが良いかと。
実用上これで問題ないと思うのですが、C++標準でsigned charの範囲以上の値を使用した場合の動作が未定義となっているならちょっと怖いなと思ったもので。
どなたかこのコードでうまくいかない環境をご存じの方いらっしゃいますか?

>>346
私もその可能性はあるかなとは思いましたが、一応値渡しですし、代入していることになるのかなと。うーん……


348 名前:デフォルトの名無しさん :02/10/01 00:22
>>347
ビットパターンでの表現を絶対に保つ必要があるキャストということなら、
 o.put( reinterpret_cast<char>( l & 0xff ) );
で一応定義された範囲の動作にならんかなぁ。自信ない。

349 名前:デフォルトの名無しさん :02/10/01 03:48
>>343
普通の数学的処理(比較、商、剰余)をすればよい

350 名前:デフォルトの名無しさん :02/10/01 06:13
charが8ビットである保証はないYO


351 名前:デフォルトの名無しさん :02/10/01 09:56
c++でJavaにあるfinal( == 継承できない )と同じような事を実装できないでしょうか?
Javaにできてc++にできないのはものすごく悔しいんですが...

Singletonを応用すれば動的確保限定で継承できないclassが作れますが、
静的なインスタンスが作れないのと、カッコワイルので誰かエレガントな実装を教えてください。


352 名前:デフォルトの名無しさん :02/10/01 10:34
>>351
ヘッダに「継承したら頃す」とか書いとけ

353 名前:デフォルトの名無しさん :02/10/01 10:41
いや継承したら頃せ

354 名前:Java厨 :02/10/01 11:12
>>351

悔しいかぁ

>^_^<ぎゃははははは−(爆w

355 名前:デフォルトの名無しさん :02/10/01 11:15
char *hoge;
のときは、
hoge = new char[10];
とやればいいと思っているのですが、

char hoge[];
と宣言されている変数を初期化するには、
hoge[10]
とかやればいいの?



356 名前:デフォルトの名無しさん :02/10/01 11:34
>>351
__sealed



とか言ってみる

357 名前:デフォルトの名無しさん :02/10/01 12:55
>char hoge[];
これはコンパイル通らないのではない?

358 名前:デフォルトの名無しさん :02/10/01 16:14
>>351
コンストラクタをprivateにする。

359 名前:デフォルトの名無しさん :02/10/01 16:16
extern char hoge[];
void f(char hoge[]){
// ...
}

...って、どっちも初期化の必要は無いな。正直俺の手には負えません

360 名前:デフォルトの名無しさん :02/10/01 17:54
次のコードが "max(long double): 1.#INF" と出力するのはなぜでしょうか。

std::cout << "max(long double): " << std::numeric_limits<long double>::max() << std::endl;

gcc3.2(MinGW)です。

361 名前:デフォルトの名無しさん :02/10/01 19:29
const char* hoge() って関数で
return NULL; するのはマズいですか?
const char* const hoge() の方がいいかな・・・

362 名前:デフォルトの名無しさん :02/10/01 19:41
>>361
値返しだから前者でいいです

363 名前:デフォルトの名無しさん :02/10/01 19:42
>>361
あのー、できるだけC++ではNULLの代わりに0を使った方がいいです。

364 名前:デフォルトの名無しさん :02/10/01 19:43
>>363
ネタ?

365 名前:デフォルトの名無しさん :02/10/01 19:49
>>364
C++の時は、NULLは0になるのでしょうか。

366 名前:デフォルトの名無しさん :02/10/01 19:50
>>364
C++ thirdを読みましょう。

# ドッチデモイイキガスルケド

367 名前:デフォルトの名無しさん :02/10/01 19:54
ガイシュツだけど、STLPortは次のようになってるね。

#ifndef NULL
# if defined(__cplusplus)
# define NULL 0
# else
# define NULL ((void *)0)
# endif
#endif

ほとんどの場合 (void *)0で問題ないけど、>>57-62のような
環境もあるから、0を使った方が無難かと。

368 名前:デフォルトの名無しさん :02/10/01 20:02
>>367
62 は環境の問題じゃなくて自分で勝手に
#define NULL ((void*)0)
したせいでうまくいかなくなったって話じゃないの?

NULL は所詮マクロだから処理系依存だけど、
ほとんどの環境で 0 になってるし、なってなけりゃ自分で#defineすればいいだけの話。

むしろ

p = 0; //( p は int* )

とかなってて、この近辺でバグってるっぽい時に、
本当は *p = 0 なのか p = 0 なのかいちいち見直さなきゃいけないのは時間の無駄。
NULL はソースの可読性を上げるためのもんなんだから使ったもん勝ちでしょ、
と漏れは思います。

369 名前:デフォルトの名無しさん :02/10/01 20:06
1年ぐらい前にそういうスレがあったきがする

370 名前:デフォルトの名無しさん :02/10/01 20:14
gcc3.2(MinGW)では

/* A null pointer constant. */

#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL/* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif/* NULL not defined and <stddef.h> or need NULL. */
#undef__need_NULL

となっているから、やはり 0 になるようですね。NULLを使っても現時点の
コンパイラでは問題が出ないようになっているのかなあ。

371 名前:デフォルトの名無しさん :02/10/01 20:18
文法に
member-declaration:
 decl-specifier-seqopt member-declarator-listopt ;
 function-definition ;opt
 ::opt nested-name-specifier templateopt unqualified-id ;
 using-declaration
 template-declaration
という部分がありますが上から三番目ってなんですか?

class c {
 std::vector<int> ;
};
とかやっても結局一番上のやつが適用されているように見えます。
(まぁコンパイルエラーですが)

あと、unqualified_id に template_id が含まれているのもようわかりません。
unqualified-id:
identifier
operator-function-id
conversion-function-id
~ class-name
template-id

誰か教えて♥


372 名前:デフォルトの名無しさん :02/10/01 20:20
0はポインタとして扱うときは常にnull pointerになるのは保証されてる。
マシンによるnull pointerの実際の表現がどんな形であろうと,
ソースの方が0であれば何の問題もない。
で,NULLはnull pointerであることを明示するためのものだから,
#define NULL 0
が正解

(C++では)

373 名前:デフォルトの名無しさん :02/10/01 20:33
またNULLの話か(*´∀`)

374 名前:デフォルトの名無しさん :02/10/01 20:45
NULLの次は何?
malloc/free?

375 名前:デフォルトの名無しさん :02/10/01 20:57
null ってキーワードを作ってくれよ!

376 名前:デフォルトの名無しさん :02/10/01 21:00
Effective C++にある。nullの実装例。

377 名前:デフォルトの名無しさん :02/10/01 21:32
NULLスレの余寒

378 名前:デフォルトの名無しさん :02/10/01 21:38
null

1 無価値の,効果のない,重要でない.
2 ない,存在しない,ゼロの,ゼロに等しい.
3 〔数〕(集合で)空(くう)の
a 〜 set  空集合.
4 特徴[表情]のない,無表情な.

NULLスレの余寒

379 名前:デフォルトの名無しさん :02/10/01 21:46
でも、CのNULLとC++のNULLではカナーリ意味合いが違うよね。
俺の会社では 0 を使っているが。(C++ 3rdに従っている)

>>368氏の意見にも一理あるが、処理系が異なっても NULLの
意味合いを維持できるかちょっと心配がある。

380 名前:デフォルトの名無しさん :02/10/01 22:09
というか今時のC++コンパイラで(void*)0なんてやってる処理系無いよ

381 名前:デフォルトの名無しさん :02/10/01 22:12
>>380
そりゃ char* p; if ( p == NULL ) ...
が通らなくなるからねえ

382 名前:デフォルトの名無しさん :02/10/01 22:12
NULLスレの余寒

383 名前:361 :02/10/01 22:24
ごめんなさい ごめんなさい・・・

ぼくが聞きたかったのは、constポインタを返す関数なのに
NULLつーどこに実体があるのか知れないモノを返して良いものかという疑問なワケでして・・・
const char& hoge() だとコンパイルエラーだし、ホンマにえぇのんかっちゅー・・・

384 名前:デフォルトの名無しさん :02/10/01 22:26
NULLと聞いて思い出した素朴な疑問。
C++標準ライブラリでは全ての識別子はstd名前空間内で定義されることに
なっていると思いますが、NULLはどうしてstd::つけなくていいんでしょうか?

NULLは<cstddef>で定義されるとありますが、同じcstddef内で定義される
size_tはよくstd::size_tと書いてあるのを見ます。
でもstd::NULLというのは見たことが無いのですが……
(というか、コンパイル通りませんでした。いや、書きたくもないですが(笑))

#define NULL 0じゃstdに入れられないのは分かるけど
C++3rd 5.1.1のようにconst int NULL = 0;とかにすればできなくはないでしょうし。

このあたりのtypedefやマクロの頭につけるstd::の有無はコンパイラによって
かなりばらつきがあるみたいです。ホントのところどうなってるんでしょう?


385 名前:362 :02/10/01 22:27
>>383
いいつってんだろヴォケ
NULLの実体?アフォですか?
値返しだから関数から戻るときにコピーが作られるんだよ

386 名前:デフォルトの名無しさん :02/10/01 22:29
>>384
const int NULL = 0; ってポインタに変換できるの?
コードに直接書かれた 0 だけだと思ってたんだけども

387 名前:デフォルトの名無しさん :02/10/01 22:30
NULLスレの悪寒

388 名前:361 :02/10/01 22:37
>385
そんなもんスレ読んどりゃわかるわカス
スレがメチャクチャなりだしたから
なんであんな阿呆な質問したんか説明しに来ただけじゃドアホ

389 名前:デフォルトの名無しさん :02/10/01 22:38
ここも荒れ出したな・・・・NULLとmalloc&freeは禁句なのだろうか。

390 名前:デフォルトの名無しさん :02/10/01 22:39
NULLスレになってんのは361とは関係ないような・・・

391 名前:デフォルトの名無しさん :02/10/01 22:46
NULL NULL…(*´Д`)ハァハァ…

392 名前:デフォルトの名無しさん :02/10/01 22:47
僕のティムポが NULL NULL してきたのですが...

393 名前:デフォルトの名無しさん :02/10/01 22:55
>>386
C++3rdの5.1.1「ゼロ」の最初によると

「ゼロ(0)は、int型である。しかし、標準変換(C.6.2.3)があるので、
0はすべての整数系データ型、浮動小数点数型、ポインタ型、
メンバへのポインタ型の定数解いて使うことが出きる。……」

ってなってます。で、C.6.2.3「ポインタとリファレンスの変換」を見ると、その中に

「0と評価される定数式は、暗黙のうちに任意のポインタまたはメンバ型への
ポインタに変換できる。」

とあるので、0になる定数式ならなんでもNULLとして使うことができるのでは
ないかと思います。たぶん。


394 名前:デフォルトの名無しさん :02/10/01 22:59
寝てる妹のパンツの中に手を入れていじってたら
NULL NULL してきたのですがこれって病気でしょうか?

395 名前:デフォルトの名無しさん :02/10/01 23:04
>>393
サンクス
定数式なら桶なのねん。


・・
・・・・・・・・
char* p = ( 50+20*4 )/5 - 26 も null ポインタになるのかしらん?

396 名前:デフォルトの名無しさん :02/10/01 23:10
逆に定数じゃなきゃダメなのかしら。
int a = 1;
a--;
char *p = a;
あ、コンパイル時に無効なアドレスに変換できないからダメなのかな。


397 名前:デフォルトの名無しさん :02/10/02 00:09
>>395
当然
>>396
だめぽ

398 名前:デフォルトの名無しさん :02/10/02 00:56
>>371

class Foo
{
  template<typename T> class Bar;
};
::Foo::template Bar<int>;   // 三行目

ってことじゃないの?
見てのとおり、メンバークラステンプレートのスペシャライゼーションの
宣言だけれど。

template_id はテンプレートのスペシャライゼーションを表すものなんだから
unqualified_id に入るのも当たり前な気もするけど。

詳しく知りたいなら、一度 ISO/IEC 14882 に目を通すことを進める。


399 名前:デフォルトの名無しさん :02/10/02 02:25
メンバ関数の戻り値が下記のものはどう使い分けるのですか?

class CTest {
  :
public:
 CTest mFuncA();
 CTest& mFuncB();
  :
}
Ctest Ctest::mFuncA(){
 return *this;
}
Ctest& Ctest::mFuncB(){
 return *this;
}


400 名前:399 :02/10/02 02:36
例が分かりにくかったのでもう少し具体的に、、、
下記のコードをコンパイルしてステップ実行したのですが、
戻り値が CTest と CTest& の違いがよく分かりませんでした。
どのように使い分けるのでしょうか?

class CTest{
public:
 int a;
 CTest mFuncA() {return *this;}
 CTest& mFuncB() {return *this;}
};
int main() {
 CTest ct1,ct2;
 
 ct1.a = 10;
 ct2.a = 100;
 ct2 = ct1.mFuncA();
 
 ct1.a = 20;
 ct2.a = 200;
 ct2 = ct1.mFuncB();
 
 ct1.a = 30;
 ct2.a = 300;
 return 0;
}


401 名前:デフォルトの名無しさん :02/10/02 03:14
mFuncAはCTestのcopyを返す。mFuncBはCTestのreferenceを返す。

前者はイヤンな一時オブジェクトを生成する。
後者が返すのはthisそのもの。


# (゚Д゚;)

402 名前:デフォルトの名無しさん :02/10/02 03:16
>398
specialization というか、qualification だよね。
C++ 3rd, C.13.6 に書いてある。

403 名前:401 :02/10/02 03:19
仕様書持ってないからちょっと待って。
違うかも。

404 名前:デフォルトの名無しさん :02/10/02 03:45
>>403
合ってるよ。

referenceを返す方は当然

ct1.mFuncA().a = 20;
ct2.mFuncA().a = 30;

のような書き方ができて、元のオブジェクトのメンバを変えられる。

ct1.mFuncB().a = 20;
ct2.mFuncB().a = 30;

はエラーではないが、一時変数を変更するだけで、その値は捨て
られるので何の効果もない。

405 名前:デフォルトの名無しさん :02/10/02 03:46
スマソ。mFuncAとmFuncBは逆ですた。

406 名前:デフォルトの名無しさん :02/10/02 05:37
抽象基底クラスAがあり、class B,CをAから継承するとします。
関数funcの引数としてB,Cをとりたいとき、
1. template <typename hoge> func (hoge tmp)
2. func (A tmp)
実行速度を含めてどっちがいいんでしょうか?

407 名前:デフォルトの名無しさん :02/10/02 06:09
>>406
顔を洗って出直して来ること。
func ([const] A* tmp);が正解。
func (const A& tmp);もまあOK。

408 名前:371 :02/10/02 10:23
>>398
ありがとうございます、が意味がよくわかりません。

>::Foo::template Bar<int>;   // 三行目
のとこはクラスの外側だから「三行目」にはならないと思うんですが。
(templateもいらない(あってはならない?)ような?)

>見てのとおり、メンバークラステンプレートのスペシャライゼーションの
>宣言だけれど。
ということですが、これはなんか意味を持っているのですか?
int;
ってするのと構文的には同じ(block-declaration -> simple-declaration)
ように見えます。
実際、gcc2.95では
> declaration does not declare anything
っていわれます(templateは削って)。

>詳しく知りたいなら、一度 ISO/IEC 14882 に目を通すことを進める。
そこから文法を引用しました。本文は長いので眺めただけですが。


409 名前:402 :02/10/02 11:46
だから C++ 3rd, C.13.6 をよめって。

410 名前:デフォルトの名無しさん :02/10/02 12:12
C++3rd持ち出して偉そうに語るヤシっているけど、
C++3rd買うくらいならIS買う人もいるんだから
持ってるのが当然って言い方はどうかと :P

411 名前:371 :02/10/02 12:15
>>409
読んだけどそれとはぜんぜん違う話だと思うな

412 名前:402 :02/10/02 15:12
ああ、そうか、たしかに状況は違うね。
でも、後続する unqualified-id が template であることを明示する、
という機能では同じものかと思う。ところで、今、
template<class T> class Foo {
T::template hoge<int>;
};
とか試したけど、g++ 3.2 じゃ、エラーになるね。
ISO C++ forbids declaration of `hoge' with no type
`::hoge<int>' is not a valid declarator
とか言われる。書き方が間違ってる?

413 名前:デフォルトの名無しさん :02/10/02 15:37
>>412
typename T::template hoge<int>; とすればよい。

414 名前:371 :02/10/02 19:13
>>412
えーとつまりキーワード「template」について
nested-neme-specifier や qualified-id や上述の member-declaration で
同じ意味(次の'<'は演算子ではない)で使われているということ
を言ってるのですか?

それならその通りだと思いますが、>>371の質問の意図は「上から三番目」
がどの場面で適用されるのか?ということなので。

>>412で挙げてある例(?)に>>413の修正をしたものも明らかに>>371
「一番上」が適用されると思うし(typenameがあるから三番目にはならない)。

勘違いがあれば突っ込んでね♥

あ、あと>>371でunqualified-idにtemplate-idがなぜ含まれるのかわからん
って書いてるのはusing-declarationで使うからっていうことで自分では
納得できたので、この理解で問題なければ触れていただかなくて結構です。

415 名前:デフォルトの名無しさん :02/10/02 19:47
スレ立てるまでもない質問にも出してしまったのですが,
こっちの方が適切と思うのでこちらにだけ繰り返し
張らせていただきます.ごめんなさい
<困ってること>
継承を介してメンバ関数のオーバーロード
ではなく多重定義を狙ったのですがうまくいきません.

<詳細>
親クラスから継承して子クラスを作りました.そのとき,
親クラスで定義したSet(int)というpublicな
メンバ関数があるのですが,これと同じ関数名で
引数の違うSet(int,int)という関数を定義しました.
これで,子クラスにSet(int)とSet(int,int)という
多重定義されたメンバ関数が定義されたと思い
まして,喜び勇んで子クラスで宣言した変数a
からa.Set(int)を呼び出したらgccに
「そんなメンバ関数無いよ」と起こられました.
誰か,こんな現象について知っている方
解説お願いします.


416 名前:デフォルトの名無しさん :02/10/02 19:57
子供が親と同じ名前のメソドを宣言した瞬間、
親の関数は引数にかかわらず全て隠されてしまいます。

417 名前:デフォルトの名無しさん :02/10/02 19:59
a.親クラス::Set(int)

418 名前:デフォルトの名無しさん :02/10/02 20:01
C++の仕様で最もハマりやすいアレですな。
Exceptional C++という本にも説明があったと思う。

今実験したんだけど、virtualでも隠されるとは思わなかった・・・

419 名前:デフォルトの名無しさん :02/10/02 20:02
解決策としては子クラスに
using 親::Set;
って書けばよいです。

なぜこんなことになるかというと
オーバーロード解決はその識別子が見つかった時点で親にさかのぼるのを
やめてしまうからです。
つまり 子::Set があるので 親::Setは候補に入らないのです。
で、using-declarationによって 親::Set が 子::Set と同じレベルに置かれるので
OKになるっていうことだと。

420 名前:デフォルトの名無しさん :02/10/02 20:05
>>416,417
どうもありがとうございます.
なるほど,そうでしたか!!このように隠れてしまわない
ためにできる方法はないでしょうかね?ちなみに技術評論社
「決定版 はじめてのC++(塚越一雄)」では
これができるとし      っかり書いてありました
が,騙されたということですね.それにしても
分かってよかったです.大変お世話になりました!!

421 名前:デフォルトの名無しさん :02/10/02 20:06
g++では__nullを使うようにしてるんだけど、VC++ではそういう
適当な拡張はあるの?


422 名前:398 :02/10/02 20:09
>>408
C++標準はメンバークラステンプレートの任意のスペシャライゼーションを、
クラス定義の外部で宣言することを許している(クラス内部に存在しなければ
定義もOK)。
だから、クラス定義の外で問題ない。

>これはなんか意味を持っているのですか?
宣言だけしといて、定義しなけりゃその型のスペシャライゼーションを
抑止できるような気もするが……気のせいかもしれない。
#手元にVC7しかないので……

>そこから文法を引用しました。本文は長いので眺めただけですが。
あるなら、せめて9.2とか14.2 とか、ちゃんと読んでみてほしいな





423 名前:デフォルトの名無しさん :02/10/02 20:09
>>421
自重しる

424 名前:デフォルトの名無しさん :02/10/02 20:11
>> 418
Exceptional C++にはちゃんと書いてあったんですね!
購入を検討します.
>> 419
かっこいいですね!ちゃんと隠蔽の回避方法があるとは!

みなさん,丁寧な説明痛み入ります.ありがとう!!


425 名前:デフォルトの名無しさん :02/10/02 20:21
彼女のパンツを見たら__nullっとしたものがついてましたが病気でしょうか

426 名前:423 :02/10/02 20:21
>>421
ちなみに無い

427 名前:399 = 400 :02/10/02 20:24
>>401 >>403
>>404 >>405
おっしゃるような現象が確認できました。
(ct2.mFuncA().a = 30; の方はコンパイルエラーになりましたが、)
なんとなく違いが分かりました。どうもありがとう。

428 名前:デフォルトの名無しさん :02/10/02 20:28
>>425
あなたがback_inserterだからです


429 名前:421=428 :02/10/02 20:29
>>426
サンクスコ


430 名前:デフォルトの名無しさん :02/10/02 20:53
C++2nd r.13.1「宣言の一致」を要約すると、派生クラスのメンバと
基底クラスのメンバは異なるスコープに属しているので、両方に
同じ名前のメンバ関数があるときは多重定義されるのではなくて
派生クラスのものが基底クラスのものを「隠す」ということに
なるようです。

431 名前:430 :02/10/02 20:55
鬱死

432 名前:371 :02/10/02 21:03
>>422
もしかして自分は大前提を知らないのかもしれないので
まずひとつだけ教えてください。

スペシャライゼーションってどういう意味で使ってますか?
自分が知ってるのはクラステンプレートでは
template</* ... */> class templ_name<int> { /* ... */ };
っていうのだけなんですが、これのほかに
最初に「template」が置かれない「スペシャライゼーション」と呼ばれるもの
があるのですか?
( >>398では ::Foo::template Bar<int>; を
 「スペシャライゼーション」といってるのですよね?)


433 名前:デフォルトの名無しさん :02/10/02 21:17
すみません、VC++で、DOS窓でよいのですが、
S-JISのコードを指定して出力っていうのが、どうしても半角になってしまうんです。
どうしたら全角で出すことが出来るでしょうか?

434 名前:デフォルトの名無しさん :02/10/02 21:30
main()
{
 puts("これでも半角になるのかYO!");
}

435 名前:433 :02/10/02 21:32
>>434
ありがとうございます。
でも、変数にs-jisの文字コードをいれて、
それをs-jisだと指定して、全角で出力するにはどうするといいでしょうか?
よろしくお願いします。

436 名前:デフォルトの名無しさん :02/10/02 21:34
いみがわからんのう・・


437 名前:デフォルトの名無しさん :02/10/02 21:35
そのおかしくなるプログラムを見せてみてYO!

438 名前:デフォルトの名無しさん :02/10/02 21:47
main()
{
std::string s = "これでも半角になるのかYO!";
 std::cout << s << std::endl;
}


439 名前:デフォルトの名無しさん :02/10/02 21:58
>>435
もしかしてint型の変数に全角のコードを入れてらっしゃるとか?

440 名前:デフォルトの名無しさん :02/10/02 22:04
まさか……
putchar(0x82a0);//←「あ」
とかやってるとか?


441 名前:デフォルトの名無しさん :02/10/02 22:08
はい。

442 名前:デフォルトの名無しさん :02/10/02 22:09
cout.put('え').put('あ'); //er...uguxu

443 名前:デフォルトの名無しさん :02/10/02 22:14
putchar(0x82); putchar(0xa0);

444 名前:デフォルトの名無しさん :02/10/02 22:15

ヲ■

445 名前:デフォルトの名無しさん :02/10/02 22:27
std::cout.put(0x82).put(0xa0);

446 名前:デフォルトの名無しさん :02/10/02 23:12
エンディアーン

447 名前:デフォルトの名無しさん :02/10/02 23:21
カラの class Foo {}; があるとき、既存のclass Bar { ... };
を class Bar : public Foo { ... }; に書き換えても、
sizeof(Bar) が変化しないことって保障されていますっけ?

VC++の6では無変化かなと思うのですが。


448 名前:( ´-`).。oO(なんでだろう……) :02/10/02 23:27
// 環境: VC++7 + STLport 4.5.3
#include <cstdio>

int main()
{
std::puts("hogehoge"); // error C2039: 'puts' : '_STL' のメンバではありません。
}


449 名前:デフォルトの名無しさん :02/10/02 23:28
あの、MIDI音っていうんですかね。midiOutShortMsg。
ピアノ音みたいなのが出るじゃないですか。
で、MIDIででる、ギターとか好きな音を大体のですがどうすればいいでしょうか?
また、ピアノ音は自然に消えますよね?で、鳴らしつづけるにはどうすればいいでしょうか?

450 名前:デフォルトの名無しさん :02/10/02 23:29
>>447
Barに一つでも新しいデータメンバ or 仮想関数が付け加わったら、
サイズは大きくなるよ。sizeof()という事になるとパディングの問題も
あるけど、おおむね大きくなると見て良い。

451 名前:デフォルトの名無しさん :02/10/02 23:31
>>448
cstdio.hで全体をstdのネームスペースで包んでいない。つまり、STLPortが
適用されていない可能性あり。

452 名前:デフォルトの名無しさん :02/10/02 23:31
>>450
Barの変化でサイズが変わるのはOKです。Fooを継承したことで
サイズが変わり得るかどうかだけ知りたい感じでしょうか。

Fooは常にカラです。



453 名前:デフォルトの名無しさん :02/10/02 23:32
>>450
答えになっているのか?

454 名前:デフォルトの名無しさん :02/10/02 23:32
>>452
基底クラスに仮想関数があったら、変わるんじゃない?

455 名前:デフォルトの名無しさん :02/10/02 23:34
おもいっきり実装依存な予感

便乗だけどメンバ変数の無いクラスのsizeofの値って決まってたっけ?

456 名前:デフォルトの名無しさん :02/10/02 23:34
すごくスレ違いでスマソ。
只今、モナー版にて、「☆☆モナー海を渡る☆☆」
というスレで、その手のプロ(海外版windows等に詳しい方、
AA、モナー職人様、英語のプロ(パソコン用語詳しい方)、
などを臨時必要としています。手の空いている方、
腕に覚えのある方,興味のある方はぜひご参加くださいませ。


457 名前:447 :02/10/02 23:37
ちなみに、Cからのポーティングをやってます。
似たような構造体が大量にありまして、それ一つ一つにメソッド
書いてられません。

コーディング規約の縛りで、Cプログラマが見る可能性のある部分に
templateを使ってはだめなので、そういう構造体を一様にFooから派生
させちまえ、という作戦です。void* よりいくらかマシかなと。

Fooで受けたあと、僕の好きになる部分では、templateで各構造体への
処理を共通化する予定と。



458 名前:デフォルトの名無しさん :02/10/02 23:41
それは無理にC++化するとハマるんでない?
仮想関数は使う予定?

459 名前:デフォルトの名無しさん :02/10/02 23:42
>>458
FooにもBar(群)にも仮想関数は使わない予定。というか
両方ともメソッドなしのホントのstruct。


460 名前:デフォルトの名無しさん :02/10/02 23:44
>>459
メソッド無しのstructなら、なぜ継承しなければならないのかと小一時間。

461 名前:デフォルトの名無しさん :02/10/02 23:44
せっかくスゲェ波>>449が来たってのに、みんな無視かよ!
乗ろうぜ!乗ろうぜ!?

462 名前:デフォルトの名無しさん :02/10/02 23:46
struct Foo {};
struct Bar1 : public Foo { ... };
struct Bar2 : public Foo { ... };

class Hoge {
public: void SetBar( const Foo& foo );
};

SetBarを複数書きたくないから。 >>460




463 名前:デフォルトの名無しさん :02/10/02 23:46
うーん、うーん(;´Д`)
あとはnewとmallocが混在しなければ大丈夫・・・かなあ


464 名前:デフォルトの名無しさん :02/10/02 23:47
>>461 無視


465 名前:デフォルトの名無しさん :02/10/02 23:47
Hoge::SetBarの中でどうやってBar1とBar2を見分けるのさ?

466 名前:デフォルトの名無しさん :02/10/02 23:48
>>449は質問っぽい文章をランダムに生成するスクリプトだろ。

467 名前:デフォルトの名無しさん :02/10/02 23:50
(゚听) ツマンネ

468 名前:デフォルトの名無しさん :02/10/02 23:50
#define SetBar( s ) templateSetBar( s ) /* ここだけ C プログラマに見せる */

template< typename type > void templateSetBar( type& s )
{
}

469 名前:デフォルトの名無しさん :02/10/02 23:52
>>465
ダウンキャストすりゃわからないはずもないけど?

というか、前に書いたように、別のメソッド
private: template <typename T> void ProcessBar( const T& bar ) { ... }
に渡して、bar.member_name に直接アクセスする予定。

Bar1とBar2で、少なくとも俺が触らなければいけない部分は、
メンバ名、型ともに同一なんでね。

で、Bar1とBar2は、sizeofの値が変わるとまずいらしいのね。
多分構造体の直書きとかしてるんでしょう。Cじゃシリアライズ
も糞もないだろうから。

# なんのために説明してるんだろう。。。


470 名前:デフォルトの名無しさん :02/10/02 23:54
>>468
そうしようかな・・・・・・・

文句きそうだけど。。


471 名前:デフォルトの名無しさん :02/10/02 23:55
>>470
そんなこと(゚ε゚)キニシナイ!!

472 名前:デフォルトの名無しさん :02/10/02 23:55
>>469
ごめん。469は俺の失言。

どうしよ・・



473 名前:デフォルトの名無しさん :02/10/03 00:04
やっぱりテンプレートだけにします。
メンバ変数だけの構造体の扱いなんて すっかり忘れていた罠。
ど失礼しましたー。


474 名前:デフォルトの名無しさん :02/10/03 01:53
ビビッた・・・・
窓の辺にドスンドスン体当たりしてくる音が聞こえて開けたら
物凄いデカイ蛾だった・・・
一瞬ツバメかと重多よ

475 名前:ん? :02/10/03 01:56
3分格闘して2本の帚で挟んで外に出してやったよ。

476 名前:デフォルトの名無しさん :02/10/03 01:56
STLスレが熱い。


477 名前:デフォルトの名無しさん :02/10/03 02:01
STLスレが臭い。


478 名前:デフォルトの名無しさん :02/10/03 02:57

●●●●●●●●「オセロさえ納期内に作れない=OO役立たず 」祭り●●●●●●●
/|         |  |_____ΦΦΦΦΦΦΦΦΦΦΦ||ΦΦΦ
  |         |  | ̄ ̄ ̄ /|                    ||
  |         |  |   / /|TTTTTT   TTTTTTTTTT||TTTTT
  |        /\ |  /|/|/|^^^^^^ |三三| ^^^^^^^^^^^||^^^^^^^
  |      /  / |// / /|
  |   /  / |_|/|/|/|/|
  |  /  /  |文|/ // /
  |/  /.  _.| ̄|/|/|/         Λ_Λ
/|\/  / /  |/ /           (___)
/|    / /  /ヽ            /〔 非OO 〕〕つ
  |   | ̄|  | |ヽ/l            `/二二ヽ
  |   |  |/| |__|/   Λ_Λ     / /(_)
  |   |/|  |/      ( ´∀`)   (_)    Λ_Λ
  |   |  |/      // /  ^ ̄]゚        (`   )
  |   |/        ゚/ ̄ ̄_ヽ         ⊂〔〔 非OO 〕


479 名前:デフォルトの名無しさん :02/10/03 03:08
荒らさんと何かネタくれ。

480 名前:名無しさん@Emacs :02/10/03 06:12
がいしゅつな質問だとは思うのですが、
コピーコンストラクタと operator= のオーバーロードって
どんなときに使い分けるんですか?

どっちも同じでいいじゃん、と思うのですけど。


481 名前:デフォルトの名無しさん :02/10/03 06:26
>>480
コピーコンストラクタ:
 代入以外でも使える(引数とか戻り値)
 const なメンバが初期化できる
operator=:
 右辺が同じクラスじゃなくても使える

とか

482 名前:デフォルトの名無しさん :02/10/03 06:26
>>480
初期化と同時に複製するか、
初期化の跡に代入するか、の違い。

483 名前:デフォルトの名無しさん :02/10/03 10:26
ポインタに関する質問2点です。

ポインタが( )で囲まれている場合の
通常のポインタとの違いを教えてください。
 例
 (*Labels)[key]=Value や
 (*P).first など。

また,* が後ろについている場合の
前につく場合との違いをおしえてください。
 例 関数の戻り値が,クラス名*




484 名前:デフォルトの名無しさん :02/10/03 10:37
>>483
そんな簡単なこともわからないのかよ。だっせー。

485 名前:デフォルトの名無しさん :02/10/03 10:42
>>484
要するに答えられないわけですね(^^)

486 名前:デフォルトの名無しさん :02/10/03 10:49
>>485
そう、答えられないの。要するにお前は俺と同レベル、もしくはそれ以下(藁

487 名前:デフォルトの名無しさん :02/10/03 10:51
>>486
×要するにお前は俺と同レベル、もしくはそれ以下(藁
○要するに俺はお前と同レベル、もしくはそれ以下(藁


488 名前:デフォルトの名無しさん :02/10/03 11:06
C++というより、Cの質問だと思うけど
たしか a[] は *a よりも「くっつきやすい」ので、
カッコをつけないと

 *(Labels[key])=Value
 *(P.first)

のように解釈されてしまうんだと思う。
これは全然意味がちがっちゃうよね。

あと、char* など、 * が後ろについている場合は
それは「char*」という型名の一部、前についている場合は
演算子。

こんなとこでいいかな?

489 名前:デフォルトの名無しさん :02/10/03 11:11
>>483
1・
括弧は演算の優先順位を変えるだけ

2.
変数に付いてるなら * は常に前にある、
型なら常に後ろにある
int * p;
変数の後ろに * が来たらそりゃ積演算子だ

490 名前:483 :02/10/03 12:07
>488
初プログラムがC++の初心者なので,
Cとの差異がわからず申し訳ありませんでした。
にもかかわらずレスいただいて感激です。

まず,1つめについては +激しく理解+ です。

2つめについては…もちょっとよろしいですか?
つまり,* が後ろにあってもやはりポインタ型を表す
ということでよろしいでしょうか。

今読んでいる本から抜粋しますと
Vertex* Edge::souce()
となっており,Vertexは自作のクラスです。

491 名前:483 :02/10/03 12:13
>489
あ,返事を書いているうちに新たな回答が
ありがとうございます。
つまり,変数とクラスを判別するために,
前と後ろに書き分けるということでしょか。


492 名前:デフォルトの名無しさん :02/10/03 12:21
>>491
ここはちょっと難しいねぇ。
* には3種類の意味があるんだ
型の後ろに付いてポインタ型を表すもの
変数の前に付いて間接参照するもの(typedef含む)
変数の後ろに付いて積演算するもの

変数とクラスを判別するために前と後ろに分けるんじゃなくて
それぞれ意味が違うから書き分けるの

493 名前:492 :02/10/03 12:23
すまん
(typedef含む)は脳内消去してくれ、ちょっと意味が違う

494 名前:デフォルトの名無しさん :02/10/03 12:38
>>489
()は関数呼び出し演算子の可能性もあるYO!

495 名前:483 :02/10/03 12:38
はい,難しいです(´Д`*)
ここは,ポインタ型なんだ!と割り切った方がいいのでしょうか。
今,初心者本1冊目の最終章なのですが
例題のプログラムが急に難しい応用や
既出じゃないことが出てきたような気がして
辟易しています。

性格上,全部きっちり理解するまで次に進めないのですが
そもそも,このような勉強方法が間違っているのでしょうか(藁
もっとポインタやクラスについて詳しい本を,次々読んだ方がいいのかな。

496 名前:デフォルトの名無しさん :02/10/03 12:53
>>495
ん〜〜漏れがぴきぴきドカーンと来た説明に
変数や関数の宣言は型の右っかわに書いた式がそのまま左にある型と同じくなるように作られたってやつ。

int * p は int* 型の p というより、むしろ *p の型が int と理解すると早いです。
Vertex * Edge::source() は、Edge::source() の戻り値が Vertex* という意味なんだけれど、
むしろ *Edge::source() の型が Vertex と思ったほうがいいです。

そう理解しておくと複雑なポインタ宣言
int (*(*pfunc)(int, int))(void) = func;
みたいなのも理解しやすい

497 名前:483=495 :02/10/03 16:42
>>496
念力集チューしてみましたがだめぽ…。
ますますこんぐらがってきた!!
Vertex *p_souce がVertexクラスのオブジェクト(ポインタ)
P_souceを宣言しているということは
わかるのですが,
戻り値が Vertex* という意味がどうしてもわかりません。

>int (*(*pfunc)(int, int))(void) = func;
括弧がいっぱいですね。泣きたくなってきました。



498 名前:デフォルトの名無しさん :02/10/03 17:04
>>497
Vertex *v[];
が (array of) (pointer to) (Vertex)
って読めるのはわかるかな?
これがわかってるんなら、関数と変数を分けて考えずに、
Vertex *f();
ていうのは上の「〜の配列(array of 〜)」 が
「〜を返す関数(function retunring 〜)」に変わっただけだと考えるのはどうかな?

つまり、 * も [] も 引数を示す() も変数名(あるいは識別子)に付く「飾り」
っていうような・・。


499 名前:483=495 :02/10/03 17:34
>498
バカでごめんね。・゚・(ノД`)・゚・。。つきあってくれてありがとね。

Vertex *f();
Vertexクラスにポインタを返す関数fということでしょうか…。
そこはかとなくわかってきたような気も…。

ただ,例題のプログラムの中で *の位置を
Vertex* Edge::source();
Labels *getlabels( );
というようにわざわざ書き分けてあるので
何か意味があるのかと思っていたのですが…。

※Labels というのは,map<string string>をtypedefしたものです。


500 名前:デフォルトの名無しさん :02/10/03 17:39
>Vertexクラスにポインタを返す関数f:に=>の
クラスに返すってどこにポインタが入るのよ

>Vertex* Edge::source();
>Labels *getlabels( );
書き分けは意味なし気分次第でしょう


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