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


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

C++相談室2
251 名前:デフォルトの名無しさん :01/09/11 20:41
>>245が正解なので、>>224がコンパイル通らないのです。

252 名前:デフォルトの名無しさん :01/09/11 21:01
>>245
そうなんですか。勉強になりました。
Javaのprotectedとは意味が違うんですね。
C++では同じクラス同士のみで参照したいメンバは
作れないんですか?

253 名前:デフォルトの名無しさん :01/09/11 21:13
同じクラス同士、ならprivateでもprotectedでもいい、と、思、う。
派生がからむとややこしいけど…。

…自信なし。

254 名前:デフォルトの名無しさん :01/09/11 21:20
>>252
いや、同一クラスならアクセスできます。派生クラスだとアウト。

class A
{
protected:
  int xxx;
public:
  void func(A* ptr)
  {
    std::cout << ptr->xxx << std::endl;
  }
};

255 名前:デフォルトの名無しさん :01/09/11 21:58
>>255
じゃあ、ダウンキャストしてからだとOKですか?

256 名前:デフォルトの名無しさん :01/09/11 21:59
あれ??そうなると、224がコンパイルできないのは、Aのprotectedメンバを指しているからではないんですね。ではやっぱり236が正しいということ??

257 名前:デフォルトの名無しさん :01/09/11 22:00
すいません、コメントに「。」をつけますか?

258 名前:デフォルトの名無しさん :01/09/11 22:02
つまり、同一クラスのオブジェクトは一種の派生クラスと考えられるってことでいいですね??

259 名前:デフォルトの名無しさん :01/09/11 22:13
>>258
よくわからん。

260 名前:デフォルトの名無しさん :01/09/11 22:29
ん?
たとえば、
クラスAのオブジェクトとしてobj1とobj2があるとすると、
obj1のprotectedメンバにobj2からアクセスできるの?

261 名前:デフォルトの名無しさん :01/09/11 22:34
>>260
できるよ。
Privateでも。

262 名前:デフォルトの名無しさん :01/09/11 22:36
>>260
それはできる。

class Test
{
protected:
 int xxx;
};

void Test::func(Test* t1)
{
 this->xxx = t1->xxx;
}

263 名前:デフォルトの名無しさん :01/09/11 22:37
じゃあ、基底クラス型オブジェクトのprotectedに派生クラスから
アクセスできないの?

264 名前:デフォルトの名無しさん :01/09/11 22:47
>>256
>>224 の B は 「Aの派生クラス」 であって、A ではないよね。
だから A のインスタンスの protected メンバにはアクセスできない。
でも B の別のインスタンスの
(A から継承した) protected メンバにはアクセスできるから、
下のようにすればコンパイルは通る。

class A {
protected:
 int xxx;
};

class B : public A {
public:
 void func(B* ptr); // B へのポインタを受け取るようにする。
};

void B::func(B* ptr) {
 cout << ptr->xxx;
}

265 名前:デフォルトの名無しさん :01/09/11 22:58
-----------------------------------------------------
<html><head><title>クラスのアクセス</title></head><body>
<table><tr><td>派生の仕方\基本</td><td>Public</td><td>
Protected</td><td>Private</td></tr><tr><td>Public</td><td>
Public</td><td>Protected</td><td>参照不可</td></tr><tr>
<td>Protected</td><td>Protected</td><td>Protected</td><td>
参照不可</td></tr><tr><td>Private</td><td>Private</td><td>
Private</td><td>参照不可</td></tr></table><p>表の中にある
のは、派生した後の派生クラスから見たメンバの状態 </p>
</body></html>
-----------------------------------------------------
HTMLで保存して、見なさい。

(多分あってると思う・・・間違ってたら指摘して)

266 名前:デフォルトの名無しさん :01/09/11 23:07
>>264
Aを抽象クラスとして、Aに対して処理することに意味がある場合は?
例えば、CompositパターンのCompositオブジェクトから
基底クラスのprotectedへアクセスしたい場合とか。

267 名前:デフォルトの名無しさん :01/09/11 23:15
同じ派生クラス型の異なるインスタンス間においては、相手のインスタンス
のリファレンスやポインタを受け取ることによって、相手のすべてのメンバ
(派生クラスのメンバ)にアクセスできるし、相手の基底クラス
のprotectedメンバ以下(protectedとpublic)のメンバにもアクセスでき
る。ただし、一方が派生クラスのインスタンスで、他方がその基底クラスの
インスタンスである場合、派生クラス側が基底クラス側のインスタンスの
リファレンスやポインタを受けとっても、その基底クラスのprotectedメンバ
以上(protectedとprivate)のメンバにはアクセスできない。

>>224 でエラーが出たのは、派生クラスが基底クラスのポインタを受けとって
いたから、protectedメンバにアクセスできなかったということで、
もし派生クラスのインスタンスを受け取るように設計してれ
ば、インスタンスが異なっていても基底クラスのprotectedメンバにアクセス
できるということ。

268 名前:デフォルトの名無しさん :01/09/11 23:17
>>266
いっそパブリックにしたらぁ?

269 名前:デフォルトの名無しさん :01/09/11 23:22
>>266
派生クラスを経由して基底クラスにアクセスすると何か不具合
でもあるの?

270 名前:256 :01/09/12 00:02
>>264-267
よーくわかりました。丁寧な解説ありがとうございました。
これで、サルから原人レベルになれました。

271 名前:256 :01/09/12 00:12
しかし>>265さんの、htmlのソースを載せる書き方は初めて見ました。おもしろいっす斬新っす

272 名前:デフォルトの名無しさん :01/09/12 01:46
C++でもデバイスドライバ書けますか?

273 名前:デフォルトの名無しさん :01/09/12 02:14
STLで質問ですが、
class a{
int b;
int c;
}
vector < vector<a> > d;
とした場合、
d[10][8]という配列を新規に確保したい場合、どうすればよいのでしょう。

274 名前:デフォルトの名無しさん :01/09/12 02:14
書ける>272

275 名前:デフォルトの名無しさん :01/09/12 02:33
>>273
vector< vector<a> >型の[10][8]の配列が必要なら
vector< vector<a> > d[10][8];
で普通に確保できるぞ?
いまいち質問の意図が読めんが。

276 名前:デフォルトの名無しさん :01/09/12 02:42
>275
説明不足ですいません。動的に確保する必要があるのです。

void E(int x,int y){
//ここで動的にd[x][y]の配列を確保したい
}

このような場合です。

277 名前:デフォルトの名無しさん :01/09/12 03:18
>>276
new使って動的に配列確保すれ。
つか、vector4つ重ねたほうがいいと思うが。

278 名前:  :01/09/12 03:32
”d[x][y]の配列”ってのが意味不明だが、
vector<vector<vector<vector<a> > > > d(x);
for(int i=0;i<x;++i) d[i].resize(y);
もしくは、
vector<vector<a> > **d = new vector<vector<a> > *[x];
for(int i=0;i<x;++i) d[i] = new vector<vector<a> >[y];
こんなもん?

279 名前:デフォルトの名無しさん :01/09/12 03:36
resizeってなかったっけ?

280 名前:エロ画像 :01/09/12 03:47
http://www.himawari.sakura.ne.jp/%7Eloveseat/Adu/index0.html

281 名前:デフォルトの名無しさん :01/09/12 17:05
vector< vector <int> >をクラスのメンバにしてファイルに書き出した場合、読み込みも自動的にvectorメンバの範囲を読み取ってクラスのインスタンスのメンバに格納されるのでしょうか。
それとも、自分でassignしなければならないのでしょうか。また、その場合どうやってやればいいのですか。

282 名前:sage :01/09/12 18:55
>>281
内側の個数がわかっているなら、外側のvectorのiteratorを順に回して、内側のvector<int>のresize/assignをしときなさい。
わかっていないなら、vector<int>を一個ずつ追加でもしながら、assignしていきなさい。

283 名前:デフォルトの名無しさん :01/09/13 00:49
質問です。
シングルトンなどで使用されるようなstaticなメンバの開放ってしなくていいんでしょうか?
クラスのデストラクタ(?)みたいなものってあるのかな?

284 名前:デフォルトの名無しさん :01/09/13 02:22
>>283
下でどうでしょ?

#include <iostream>
#include <string>
template <class T>
class Singleton {
 static T *instance;
 static int count;
protected:
 T* create();
public:
 Singleton() {
  if (count == 0) {
   instance = create();
  }
  count++;
 }
 ~Singleton() {
  count--;
  if (count > 0) {
   cout << "逝ってよし" << endl;
  } else {
   cout << "オマエモナー" << endl;
   delete instance;
  }
 }
 T& operator *() { return *instance; };
};
template <class T> int Singleton<T>::count = 0;
template <class T> T* Singleton<T>::instance = 0;
string* Singleton<string>::create() { return new string("モナー"); };
int main() {
 Singleton<string> s1;
 Singleton<string> s2;
 cout << "s1:" << *s1 << ", s2:" << *s2 << endl;
 return 0;
}
けど、スタティックなメンバー位なら、(free信者みたいに)あんまり
解放を気にしすぎると健康に悪いと思う。
また、そいつが他の資源を握ってるんなら、
デストラクタにとは別のメソッドで明示的に解放すべきだと思う。

285 名前:デフォルトの名無しさん :01/09/13 07:28

わけがわからん

286 名前:誤爆人 :01/09/13 09:00
BCC5.5で試してみた。
・include後に
using namespace std;
を加える。
・string* Singleton<string>::create() { return new string("モナー"); }; を
template<> string* Singleton<string>::create() { return new string("モナー"); };
に変更。
で動いたよ。勉強になった。thx

287 名前:デフォルトの名無しさん :01/09/13 09:35
ほんとかよ!

288 名前:デフォルトの名無しさん :01/09/13 15:30
単にクラスのメンバーに定数を定義したいのですが
class A
{
 const int i = 1;
 const CString str = "abc";
};
等とすると、コンパイルエラーとなってしまいます。
関数定義の中だと問題ないのですが、
クラス内では、このような定義はできないのでしょうか?

289 名前:デフォルトの名無しさん :01/09/13 15:37
>>288
enumを使うか初期化子使え。

290 名前:デフォルトの名無しさん :01/09/13 15:58
>>289
初期化子、はじめて使いました。
まだまだ厨房、、、

291 名前:デフォルトの名無しさん :01/09/13 20:57
>>288
組み込み型はstatic constな場合に限りclass宣言内で定義できる。
よって以下のように書くこともできるyo

// A.h
class A
{
 static const int i = 1;
 static const CString str;
};

// A.cpp
const CString A::str = "abc";

292 名前:デフォルトの名無しさん :01/09/14 20:31
>>291
> 組み込み型は
"整数は"の誤りだな。以下のコードはコンパイルを通らない。

class A
{
 static const float f = 1.0;
};

293 名前:デフォルトの名無しさん :01/09/14 21:26
>>291 >>292
Visual C++ みたいにアホい(というか仕様が古い?)コンパイラでは、
整数でも宣言時初期化はエラーになるんです。

294 名前:デフォルトの名無しさん :01/09/14 21:46
gcc では以下はコンパイルできたよ。

class A {
static const int i = 0;
static const float f = 0.0;
static const double d = 0.0;
static const char* const s = "abc";
};

295 名前:デフォルトの名無しさん :01/09/15 00:22
CStringとchar *は全然違うだろ

296 名前:デフォルトの名無しさん :01/09/15 06:50
>>295

>> 組み込み型は
>"整数は"の誤りだな。以下のコードはコンパイルを通らない。

のあたりを試してみたんだけど?

297 名前:デフォルトの名無しさん :01/09/15 14:05
>>294
確かにgcc(2.95.3)だと通った。これってgccの拡張仕様なのかな。
手元にあるプログラミング言語C++第3版には、整数でないとダメと書いてある。
それとも本が古いの? 誰か教えれ。

298 名前:defalut :01/09/15 15:00
MS VisualC++Ver6で
Windows9x,NT,2000 が終了する際に
cookie をすべて削除するプログラムを作りたいとおもうのですが、
どうやればいいでしょうか?

299 名前:デフォルトの名無しさん :01/09/15 15:08
>>298
常駐してWM_ENDSESSIONが来たらcookieの保存されてるフォルダ内容をすべて消す。

300 名前:defalut :01/09/15 15:35
まだ、Visualcでソフトを作ったことがありません
1 常駐させる方法
2 フォルダの内容をすべて消す
方法教えてください。

301 名前:デフォルトの名無しさん :01/09/15 15:38
300の作ろうとしているソフトは怖いです

302 名前:デフォルトの名無しさん :01/09/15 16:02
VBAしか扱ったことがありません。
VBAですと、イベントハンドラたとえば、ボタンを押したタイミング
で、プログラムが動作します。

VisualCの場合は メッセージを単位ににしてプログラムが動作
するようになるのでしょうか?

303 名前:デフォルトの名無しさん :01/09/15 16:09
>>302
>VBAしか扱ったことがありません。
>VBAですと、イベントハンドラたとえば、ボタンを押したタイミング
>で、プログラムが動作します。
人のことなめてる?(いろんな意味で)

>VisualCの場合は メッセージを単位ににしてプログラムが動作
>するようになるのでしょうか?
あなたは Win版 HelloWorld からはじめてください。

304 名前:293 :01/09/15 16:17
>>297
ちょっと気になったので調べてみました。
私の手元には1996年のドラフト2のPDFしかないんですが、
(ちょっと古いですかね...)それによると、

> If a static data member is of const integral or
> const enumeration type, its declaration in the class
> definition can specify a constant-initializer which
> shall be an integral constant expression (5.19).

とあります。「整数または enum の場合はできる」と
書かれていますが、それ以外の型の場合については
「できる」とも「できない」とも書かれていませんね。

ちなみに、整数だけ通して、他の型ではエラーになる
コンパイラとしては、CodeWarriar があります。

305 名前:デフォルトの名無しさん :01/09/15 16:22
>>302
「ボタンを押したタイミング」ってのは、「メッセージを単位」にしてるってこと、
もしかしてわかってない?

まずイベントドリブンって言葉から、勉強しましょう。

306 名前:デフォルトの名無しさん :01/09/15 16:50
>>298
とりあえず、お前の求めている機能を実現するのにVCでプログラム書く必要はない。
autoexec.batに以下の1行を追加するだけだ。

del C:\Windows\Cookies\*.txt

307 名前:  :01/09/15 17:11
ソダネ.

308 名前:  :01/09/17 19:00
本についてですが、
プログラミング言語C++第3版という本の姉妹本みたいなの
ありますよね。同じアスキーで赤い背表紙の本で、OOPに関するものや
STLに関するものや、あとはC++第3版の問題の解答集みたいなのとか。
あのあたりの本はいいのでしょうか?それともC++第3版に便乗して
売ろうとしてるただの本なのでしょうか。言語仕様の本とはべつに
OOPやSTLあたりの本も読もうと思ってるのですが・・・。

309 名前:デフォルトの名無しさん :01/09/17 23:25
>>308
Effective C++ と More Effective C++ は読んでおいた方が良いと思う。

310 名前:デフォルトの名無しさん :01/09/18 00:53
>>309
同意。必須です。

311 名前:デフォルトの名無しさん :01/09/18 01:35
分厚いやつでは最近出たSTLのリファレンス的なやつに目を通せば
よいと思うけど。あとは疑問視。

>>309 の次くらいにExceptional C++とか。
GotWの記事直接見てもよいが。

312 名前:デフォルトの名無しさん :01/09/18 04:45
フォントファイルに関しての質問です

フォント名(MS ゴシック など)が解っていて、それに対応する
*.TTF あるいは *.TTC のファイル名を得るにはどうすればいいでしょうか。
またその逆に
*.TTF等のファイル名が分かっていて、それに対応するフォント名
を得るにはどうすればいいでしょうか。

MS VC++ 5
Windows 98

313 名前:デフォルトの名無しさん :01/09/18 05:55
class A {
 const int data[2];
public:
 A(int d1, d2);
};

A::A(int d1, int d2) : data[0](d1), data[1](d2) { }

constのメンバ配列を初期化したいのですが、出来ないのでしょうか?

314 名前:デフォルトの名無しさん :01/09/18 11:39
ちょっと質問があるんですが。
Cで制御系のプログラムを組んでたんだけど、今度C++で組むことに
なったのです。
で、本買って勉強したり、サンプルとか見せてもらったんだけど、データの
部分に関してはクラスを使うのは分かるんだけど、何でもかんでもクラス
にするものなの?
メインで無限ループで受信待ちの部分なんて、クラスにする必要あるの?
制御系のプログラムを組む時、どこまでクラスで設計するものなのか
良く分からないんですけど、いい本とか、いいサイトはありますか?

315 名前:デフォルトの名無しさん :01/09/18 11:50
>>314
メインループは唯一のインスタンスを持つアプリケーション全体のクラス
として設計しる。
含まれるメソッドは初期化、メインループ、例外処理。

316 名前:309 :01/09/18 12:41
そういえば Effective C++ の著者が Effective STL というタイトルの書籍を出したけど、
誰か読んだ人います?

http://www.amazon.co.jp/exec/obidos/ASIN/0201749629

あと個人的には Modern C++ Design: Generic Programming and Design Patterns Applied
も気になってる。

http://www.amazon.co.jp/exec/obidos/ASIN/0201704315

317 名前:デフォルトの名無しさん :01/09/18 13:44
>>312
レジストリを漁れば見つかるはず。でも、スレ違い

318 名前:デフォルトの名無しさん :01/09/18 13:49
>>313
こんなやり方はどう?
class A {
 const int* data;
public:
 A(int d1, int d2);
 ~A(void) { delete[] data; }
};

A::A(int d1, int d2) {
 int* temp = new int[2];
 temp[0] = d1, temp[1] = d2;
 data = temp;
}

319 名前:デフォルトの名無しさん :01/09/18 14:04
>315 レスありがとうございます。
なるほど、C++では何でもクラスで作っておけということでしょうか。
それによるメリットは、後々使いまわしがきくということですか?

320 名前:typename C++::books :01/09/18 15:36
>>316
> あと個人的には Modern C++ Design: Generic Programming and Design Patterns Applied
> も気になってる。
>
> http://www.amazon.co.jp/exec/obidos/ASIN/0201704315

これめちゃ面白いよ。template炸裂。
Effective C++, More Effective C++, Exceptional C++の次に必読。

// templateが原始帰納関数計算できるって知ってた?

321 名前:Bear in mind :01/09/18 16:56
>>316
Effective STL読んでます。今item37。
あと一週間待って。

322 名前:309 :01/09/18 21:10
>>320
Thanks. よし、買おう。

> // templateが原始帰納関数計算できるって知ってた?
Game Programming Gems で template 使って行列計算するサンプルを読んで、
初めて template の記述能力の高さに気づきました。あそこまでいくと、もはや、
コンパイル時に評価されるインタプリタ「言語」ですね。

>>321
レビュー、期待しております :)

323 名前:デフォルトの名無しさん :01/09/18 21:58
>>322

ちょっとサンプル見せて

324 名前:309 :01/09/18 22:28
>>323
行列だと長いから、フィボナッチ数列のサンプルで良い?

template<unsigned N> struct Fib
{
  enum
  {
    Val = Fib<N - 1>::Val + Fib<N - 2>::Val
  };
};

template<> struct Fib<0> { enum { Val = 0 }; };
template<> struct Fib<1> { enum { Val = 1 }; };

これで、ソース中に Fib<8>::Val と書くと、フィボナッチ数列の 8 番目
の数値が得られます。

325 名前:  :01/09/18 23:21
やはりみなさんは「プログラミング言語C++」を通して
お読みになられたのでしょうか?

326 名前:typename C++::books :01/09/19 00:05
>>323
> ちょっとサンプル見せて

http://cseng.aw.com/book/0,,0201704315,00.html
ここからloki.zipを取得せよ。ちょと強引なのもあるけどね。template萌え萌え

// 標準に追い付いてないg++でcompile出来ない…

327 名前:デフォルトの名無しさん :01/09/19 00:19
>>324
うぁ、すごいね。
これを見ると、とてもC++を使いこなしているとは言えないなぁ

328 名前:デフォルトの名無しさん :01/09/19 00:22
>>324
関数型言語みたいな感じやね

329 名前:typename C++::books :01/09/19 00:37
Lisp、ML、Haskelで培った型やマクロに関する知見を、
compile-timeという制約を課して開花させていると思われ

最近良く使うのは、

template <class T> struct UnConst { typedef T UnConstT; }
template <class T> struct UnConst<const T> { typedef T UnConstT; }
…UnConstT<var>…

というようなpattern matchを使ったconst, &, *外し。

「引数がポインタ型だった時だけ」というようなtemplateも書ける。

330 名前:テンプレートマンセー :01/09/19 01:28
最近のお話のものは、テンプレートメタプログラミングで
引けばいろいろ出ると思われ。

ttp://www.oonumerics.org/oon/
ttp://extreme.indiana.edu/~tveldhui/papers/techniques/

昔のCマガにも出てたことあり。

331 名前:デフォルトの名無しさん :01/09/19 02:11
>>324
よくもわるくも馬鹿すぎ。
よいほうの理由は説明は略するとして、
悪いほうは「それって単なるCの引数つきマクロと同じレベルじゃん」。
その理屈でいえばマクロ的なことをなんでもやらせられるという安直な結論になるだけだ。

332 名前:デフォルトの名無しさん :01/09/19 02:28
>>331
> 「それって単なるCの引数つきマクロと同じレベルじゃん」
マクロは C/C++ を理解しない単なる文字列置換しかできませんが、template
関数/クラスは C++ の文法を 100% 理解できますから、記述能力が全く違い
ますよ。

それと >>324 で挙げられているような単なる数値計算に限っても、実行時では
なくコンパイル時に値を確定できる利点があります。数値シミュレーションや 3D
ゲームのエンジンを記述する時には、十分に実用的なテクニック。

> その理屈
どの理屈?

333 名前:デフォルトの名無しさん :01/09/19 03:10
マクロは字句解析レベルで置換を行うプリプロセッサ
テンプレートは構文解析レベルで置換候補を作っておいて、
リンク時に解決を行うプリ/ポストプロセッサって感じがする。
(実際は違うんだろうけど)
なんかC++の言語本体からは遊離しているような印象。
それが使いやすくもあり、使いにくくもある。

JavaのJSR-14とかだと、もうちょっと言語よりになっているような..
reflectできるし、interface指定できるし

334 名前:デフォルトの名無しさん :01/09/19 03:21
lispのマクロみたいね。

335 名前:デフォルトの名無しさん :01/09/19 07:19
>>331
知ったか厨房決定。
テンプレートをよく知らないと思われ。

336 名前:デフォルトの名無しさん :01/09/19 11:32
>355
いや、ただの厨房でしょ。

337 名前:325 :01/09/19 18:45
みなさん無反応なんですが・・・(汗

やはりあんな分厚い言語仕様本を通して読むのはバカげてますかね・・。

338 名前:デフォルトの名無しさん :01/09/19 20:09
>>337
そんなことない。1回は読んどくべきと思う。
‥とかいいつつ、漏れもまだ20章あたりまでしか読んでないが(w

339 名前:325 :01/09/19 20:37
そうですか。読む勇気が沸いてきました(w。
まだ5章です。
あの大きさは、電車とかで読むのにはちょっとキツイですな。
それがネックになっています。

340 名前:馬鹿 :01/09/19 20:49
>>337
読んだよ。

341 名前:教えて君。 :01/09/19 21:16
g++-3.0.1ではg++-2.95.3で通ったC++のコードをコンパイルしてくれません。
なぜですか。

342 名前:それはね :01/09/19 23:05
2.95.3 では通るけど、3.0.1 では通らないコードを
コンパイルしようとしているからです。

343 名前:デフォルトの名無しさん :01/09/20 01:07
「Standard Template Libraryプログラミング」επιστημη と
「C++標準ライブラリチュートリアル&リファレンス」の
どっちがおすすめですか?

344 名前:デフォルトの名無しさん :01/09/20 01:24
struct A {
 A();
 virtual void method();
};

struct B : public A {
 B();
 virtual void method() { puts("called"); }
};

上記のようなクラス定義で、
1 A::A() { method(); }
2 B::B() { method(); }

1の呼び出しが無効なのは分かるのですが、
2の呼び出しが正常に行われる保証はあるのでしょうか?
Bのコンストラクタが開始した時点で仮想関数は確実に呼び出せる状態にあるのでしょうか?

BCCでは呼び出せたのですが、処理系依存なのか分からないので・・・

345 名前:struct? :01/09/20 01:52
>>344
コンストラクタ内での関数呼び出しは不定なので
初期化用メソッドを別に用意するのが普通です。
コンストラクタでの処理は、メンバの初期化などで留めましょう。

346 名前:デフォルトの名無しさん :01/09/20 02:15
>>345

返答ありがとうございました。
初期化メソッドもvirtualで継承してきているので、
そうなるとまたもうひとつ初期化メソッド用意するということですね。
なんか、カッコ悪い(^^;

>struct?
public:を省略して記事量を抑えるためですが(^^;

347 名前:デフォルトの名無しさん :01/09/20 02:52
クラス設計で質問です。

戻り値がvoidのメソッドを作るのなら、
自分への参照を返す方が賢い気がするのですが、
実際どっちが良いんでしょう?

348 名前::01/09/20 07:22
>>322
Effective STL終わりました。

内容は、More Effective C++より平易だと思います。
しかしSTLの中身を少し覗いたことがないと分からないと思われる記述も多いです。
また所々に標準についてのほほうと思う文が散らばっています。
「vector<bool>は標準化委員会の失敗作だ」
では買いなのかといわれると、More Effective C++より役に立つ機会は多いと思います。

>>344
保証はあると思います。

349 名前:- :01/09/20 07:36
モロ、無修正画像サイト発見!

http://www.sex-jp.net/dh/01/
http://www.sex-jp.net/dh/02/
http://www.sex-jp.net/dh/03/
http://www.sex-jp.net/dh/04/

350 名前:デフォルトの名無しさん :01/09/20 10:04
>>347
>自分への参照を返す方が賢い気がするのですが、
この根拠は?どんな用途を想定しているの?

351 名前:デフォルトの名無しさん :01/09/20 10:26
>>345
大嘘付かないよーに

各コンストラクタ中の仮想関数呼び出しは、自分自身の仮想関数
テーブルを用いて行われるので、どのクラスの仮想関数が呼ばれ
るかを特定できる

>>344
>1の呼び出しが無効なのは分かるのですが、

無効というのは、B::methodが呼ばれないという意味?
そういう意味では真だが、A::methodが呼ばれるのは保証される

352 名前:デフォルトの名無しさん :01/09/20 12:05
コンストラクタ内では、自分はまだ作りかけで
オブジェクトとしては(コンパイラに)認知されていないから、
仮想関数は部分オブジェクトとして構築済みの
基底クラスのそれが呼ばれるのだ。

仮想じゃない関数を介してコンパイラをだますことは
できるけれど、あくまで自分は作りかけなので
それを承知の上での処理をしないといけない。

んだよね?

353 名前:C--=A :01/09/20 14:34
ファイルをios::inでopenしたりした時にそんなファイルが無かったりした場合などのようにI/O関係でのエラーで例外を投げてくれないのは?
一々状態チェックするの嫌なんだけど。。。

354 名前:デフォルトの名無しさん :01/09/20 15:57
>>324あたりのテンプレート
いろいろやってみるも実際は意図した結果になかなかならないなー
結局ループしてたりw

あとテンプレートの引数が複数あって、片方だけ専門化できるようにならんのかな

355 名前:デフォルトの名無しさん :01/09/20 20:17
>>314

最初っから何でもかんでもクラスにするこた無いかも。

・とりあえず // と const と inline と namespace に萌えてみる
・関連の強い構造体と関数をクラスにまとめてってみる
・ユーザー定義型を作ってみる
・標準ライブラリを覚える
・全部オブジェクトにする(シングルトンとか使って)
・クラスライブラリを作ってみる
・テンプレートライブラリを効率を意識しながら作ってみる

みたいに段階を踏んだ方が、実行時効率を問われる世界から来た場合はやりやすい
んじゃなかろーかと。
例えば、関数オブジェクトを知らないでクラスライブラリ作ろうとしたりすると、
効率と柔軟性のトレードオフな物しか書けない訳で。

356 名前:デフォルトの名無しさん :01/09/20 22:39
>>352
> コンストラクタ内では、自分はまだ作りかけで
> オブジェクトとしては(コンパイラに)認知されていないから、
> 仮想関数は部分オブジェクトとして構築済みの
> 基底クラスのそれが呼ばれるのだ。

そんな仕様聞いたことないよ。
A::f()とB::f()が宣言されてる時にBのスコープ内で単にf()としたら、
B::f()が呼ばれるのが自然じゃない?

リファレンスやポインタを介さない関数呼び出しはコンパイル時に静的に決定できる
ので、仮想関数の仕組みは必要ないと思うんだけど。

357 名前:356 :01/09/20 22:51
で、結局 >>344 の例だと、
void hoge(void){
 B b;
 // 何か
}
とした時、Bの構築時は、まず基底クラスAのデフォルトコンストラクタA::A()が呼ばれ、
その中でA::method()が呼び出され、その後でB::B()が呼ばれ、B::method()が呼ばれる
という順番になると思うんだけど‥。少なくともうちのgccではそうなったよ。
これが保証されないんなら怖くて継承とか仮想関数とか使ってられないよ。

358 名前:デフォルトの名無しさん :01/09/20 23:32
>>357
確かに実際にはその順番になるんだけど…。

B b;
ってしたときに、A::A() の中で B::method() ではなく A::method() が
呼ばれてしまう実装ってダサいと思わないか?
しょっちゅう間違えてハマるんだけど、俺。(w

359 名前::01/09/21 00:28
12.7

-3- Member functions, including virtual functions (class.virtual),
can be called during construction or destruction (class.base.init).
When a virtual function is called directly or indirectly from a constructor
(including from the mem-initializer for a data member) or from a destructor,
and the object to which the call applies is the object under construction or destruction,
the function called is the one defined in the constructor or destructor's own class or
in one of its bases, but not a function overriding it in a class derived from the constructor or destructor's class,
or overriding it in one of the other base classes of the most derived object (intro.object).
If the virtual function call uses an explicit class member access (expr.ref) and the object-expression refers to the object
under construction or destruction but its type is neither the constructor or destructor's own class or one of its bases,
the result of the call is undefined. [Example:

352さんはどうやら分かっているが誤解をまねく記述をしている模様。
んで358さんへの答えは352さんがしているという再帰。

360 名前:sage :01/09/21 00:30
>>358
もっと勉強してから偉そうなこと書いてくれ

361 名前:345 :01/09/21 00:34
>>351
あう〜、大嘘はひどいモナー(AA略)、というわけでザッと探してきた
http://www1.kcn.ne.jp/~robe/cpphtml/html02/cpp02017.html
http://www.sun-inet.or.jp/~yaneurao/rsp/rspA1toA8.html
(逆に叩かれたりして(w

うーん、VCだけなのかなぁ。でも…昔のBCCも仮想関数呼び出し前に
派生クラスのコンストラクタ呼んでくれなかったような…。

あとコンストラクタ内で重い処理するとマズイみたいな話無かったっけ?
それにグローバルでやるとなんたらとか……全部記憶が曖昧だ(^-^;

全部ひっくるめて適当に答えたのは謝ります。ごめんね〜 >>344

362 名前:345 :01/09/21 00:36
>>359
おっと書いてる間に…よく読んどこ

363 名前:typename C++::books :01/09/21 01:39
>>354
コンパイラ古くない?

>>337
読んでるよ。仕様書も必要なところは。
仕様書のcode断片例はいいと思う。仕様は曖昧じゃないしさ。

364 名前:デフォルトの名無しさん :01/09/21 02:40
>>361
yaneuraoあげると余計ややこしくなる

365 名前:デフォルトの名無しさん :01/09/21 03:11
質問です
クラス A がクラス B へのポインタを持ち、クラス B の機能を
利用するのですが、クラス A の派生クラス AA はクラス B の
機能では満足できないのでクラス B の派生クラス BB を利用します.

クラス A ではクラス B へのポインタを設定する関数
SetProxy( B * pB ) を宣言しているのですが、
クラス AA はクラス BB の機能を利用するため SetProxy のポインタを
クラス BB 以下の派生クラスに限定したいのですが
クラス A の SetProxy インタフェースを維持しつつ、
クラス AA の SetProxy ではクラス BB 以下の派生クラスへのポインタを
限定して受け取るように設計するにはどうしたら良いのでしょうか?
あと、初心者なのでこういう設計になれていないので
良い設計がありましたら、教えてほしいのですが…。

class B {
public: void doHogeHoge();
};

class BB : public B {
public: void doFooBar();
};

class A {
protected: B * PointerB;
public: void SetProxy( B * pB) { PointerB = pB; } };

class AA : public A {
protected: BB * PointerBB;
public: void SetProxy( BB * pBB) { PointerBB = pBB; } };
???

366 名前:358 :01/09/21 07:44
>>359
いや、だからC++ってその辺ダサくない?って言ってるんだが。
「そういうもんなのです」って答えっスか?

367 名前:デフォルトの名無しさん :01/09/21 09:34
>>366
この結果のどこがダサイですか?
Bの部分であるAをconstructする時に、Aに任せるのは当たり前では?
何か勘違いしてませんか?

$ cat virtual.c
#include <iostream>

using namespace std;

struct A {
A() { method(); }
virtual void method() { cout << "A's method() called" << endl; }
};

struct B : public A {
B() { method(); }
virtual void method() { cout << "B's method() called" << endl; }
};

int main(void) {
A a; B b;
return 0;
}
$ g++ test.c
$ ./a.out
A's method() called
A's method() called
B's method() called
$

368 名前:358じゃないよ :01/09/21 10:42
>>367
派生クラスによる追加部分が未構築な段階で、
基底クラスの構築子から派生クラスの仮想メソッドを呼べてしまうと、
その仮想メソッドが派生クラスの未構築なメンバをもしもアクセス
すると動作が異常になるので、言語仕様では安全サイドに振って
一律に派生クラス側のメソッドを呼べないようにしているわけだが、
コンパイラとリンカが神のごとく賢ければ、未構築なメンバを
アクセスする仮想メソッドの呼び出しに対してはエラーを、
さもなくば呼び出し可能としても良いわけで、>>358 はそれを
ダサいと言っているのであろう。
逆にプログラマ責任サイドに振って、派生クラスの仮想メソッド
を呼び出しOKにして、未構築なメンバをアクセスするような
仮想メソッドの場合は「未定義の動作」とする手もあったと思う。
C++の場合、この手の選択では「未定義の動作」とする場合が
多いのだが、そうしなかったのは仮想テーブルの設定を行う
実装が難しくなるからかな。

369 名前:javaの場合は :01/09/21 11:20
>>368 の続き
ちなみに、Java は基底クラスの構築子の中から、
派生クラスの仮想メソッドが呼べてしまう。

その時点では派生クラスで追加したフィールドは派生クラス
の構築子による設定前なので、デフォルトの0(null)が埋まっている。
C++のように「デフォルトは不定」ではないので、深刻な問題は起きない。
もちろん、0(null)がプログラマが意図した結果であるかどうかは別問題。

------------(インデントはスマン)
class A {
A() { v(); }
public void v() { System.out.println("A#v"); }
}
class B extends A {
String s;
B() { s="hello"; v(); }
public void v() { System.out.println("B#v s="+s); }
}

public class test {
public static void main(String[] argv) {
// A a = new A();
B b = new B();
}
}

$java test
B#v s=null
B#v s=hello
------------

C# ではどうなるのかな。

370 名前:351 :01/09/21 11:20
>>361
ええ。叩かせて頂きまふ(w

上のURLの方は、説明してる事は*ほぼ*正しいんですが、
>仮想関数はコンストラクタ内では正しく働かない。
という表現が間違ってますな。

下のURLの方は、>>358と同じ勘違いをしてるんでしょう。
何処を勘違いしてるかは、>>352>>367が書いてるから省略。

仕様を調べたわけじゃないから不正確だけど、危ないのは
初期化構文で仮想関数を呼んだ場合。(B() : A(method()) { })

仮想関数テーブルが初期化作業は、初期化構文を抜けて、
コンストラクタの関数部分({})に入る直前に行われるから、
この場合は何が起こるかわからない。(bcc32.exeだと落ちた)

371 名前:デフォルトの名無しさん :01/09/21 12:07
>>370 何が起こるかわらない…って違うだろ。>>359 を良く読め

372 名前::01/09/21 12:46
>>367-369
残念ながら恐らく>>366さんはそんなことをダサいと言っているのではないです。

模範解答

C++のコンストラクタは、"コンストラクタ"だからである。
コンストラクタとメモリ管理を密接に結びつけることによって
コンパイラ実装者は、コンストラクタに、オブジェクトを作成するための
多種多様なメモリ管理の意味を与えることができる。

Javaにおいては、
メモリの割り当て及びメンバ変数の初期化を、コンストラクタと切り離すことによって
基底クラスコンストラクタが実行される前に、
派生クラスオブジェクトのメンバ変数が初期化済みであることを保証することができる。

373 名前:358=366 :01/09/21 13:32
いや残念ながら俺が言いたかったのは、>>368氏が例としてあげた
> 逆にプログラマ責任サイドに振って、派生クラスの仮想メソッド
> を呼び出しOKにして、未構築なメンバをアクセスするような
> 仮想メソッドの場合は「未定義の動作」とする手もあったと思う。

こういう仕様の方が自然だったんじゃないか?ってこと。
仮想関数を呼んだときに実際に呼ばれる関数が
コンストラクタ配下で"だけ"他の場合と異なるってのは
違和感があるっつーか何というか。


> コンパイラ実装者は、コンストラクタに、オブジェクトを作成するための
> 多種多様なメモリ管理の意味を与えることができる。

ゴメン俺あんまり理解できてない模様。今の場合だと

  C++のコンストラクタ ∈ メモリ管理
→ vtableの構築も"コンストラクタ"の仕事
→ 派生クラスコンストラクタより先に基底クラスコンストラクタが呼ばれるので
→ 基底クラスコンストラクタ中ではvtableは整って無くて当然

ってことでしょか?

374 名前:358=366 :01/09/21 13:36
「整ってなくて」って言い方はマズいかな。
「まだ派生クラスのものになっていなくて」 くらいに修正…。

375 名前:デフォルトの名無しさん :01/09/21 13:44
>>365
実装とインターフェースを分離すれば?

struct A
{
  virtual ~A() {}
  virtual void doSomethingWithB() = 0;
};

struct AA : public A
{
  virtual ~AA() {}
  virtual void doSomethingWithBB() = 0;
};

class AImp : public A
{
  B* m_imp;
public:
  AImp() : m_imp(NULL) {}
  void SetProxy(B* imp) { m_imp = imp; }
  void doSomethingWithB() { m_imp->doHogeHoge(); }
};

class AAImp : public AA
{
  BB* m_imp;
public:
   AAImp() : m_imp(NULL) {}
  void SetProxy(BB* imp) { m_imp = imp; }
  void doSomethingWithB() { m_imp->doHogeHoge(); }
  void doSomethingWithBB() { m_imp->FooBar(); }
};

376 名前: :01/09/21 14:46
スタティックライブラリのファイルサイズって
実行速度に影響するんですか?

377 名前:デフォルトの名無しさん :01/09/21 15:03
>>376
質問が大雑把過ぎて、何が言いたいのが良くわかりませんが。

純粋に実行コードのサイズの話なら、ワーキングセットがキャッシュメモリの
サイズを越えるかどうかが問題。実行ファイルが 100KB でも 1MB でも、あ
る時間内に頻繁に実行される部分が L1 キャッシュに収まるなら、実行速度
は変わらない。

あとスタティックライブラリのファイルサイズが大きくても、それが全て実行ファ
イルにリンクされるわけじゃない。必要な部分だけリンクされる。

378 名前: :01/09/21 16:05
>>377
ありがとうございます
数値計算で使うパッケージが全部で14Mくらいなんで
どうなんだろうかと思っていましたが
ちょっと安心しました

379 名前:365 :01/09/22 05:06
>>375
ありがとうございます。勉強になります。
クラスAAは派生クラスBBを受けるので、引数の異なるSetProxy()を
定義することになっちゃいますよね。ポリモルフィックの見方からすると
それで良いのかなと思いまして。
共通のSetProxy()を宣言して、ダウンキャストできるか調べる方法も
ありますよね。それとどちらが良いのかなとも。
OOP は難しいです…。(^^;)

380 名前:デフォルトの名無しさん :01/09/22 05:32
>>379
> 共通のSetProxy()を宣言して、ダウンキャストできるか調べる方法も
> ありますよね。それとどちらが良いのかなとも。
他のクラスがどのように A, AA と関わってくるかによって最適解は違ってきますが、
こちらの方法だとコンパイル時にエラーを検出できないのが悲しいですね。

> OOP は難しいです…。(^^;)
クラス階層の設計に関しては、必ずしも「正しい」解答がないですからね。

ただし、経験から生み出された定石があって「デザインパターン」と呼ばれています。
C++ では言語レベルでな継承・集約をサポートしていますが、これに加えてデザイン
パターンも習得すると、設計の柔軟性が格段に上がります。

参考文献
 オブジェクト指向における再利用のためのデザインパターン 改訂版
 ガンマ,エリック ヘルム,リチャード ジョンソン,ラルフ ブリシディース,ジョン
 ソフトバンクパブリッシング (1999)ISBN:4797311126

デザインパターンの骸骨たち
http://www11.u-page.so-net.ne.jp/tk9/ys_oota/mdp/

381 名前::01/09/22 06:14
>>373
そのような実装も許されるということです。(ARM 10.9c)
未構築の派生クラスオブジェクトに対する仮想関数の呼び出し自体が定義できません。

>こういう仕様の方が自然だったんじゃないか?ってこと。
標準化委員会はそう思わなかったようです。
Javaは、基底クラスコンストラクタの呼び出しの前に、
派生クラスオブジェクトのメンバ変数は初期化されているので
実はこの判断と独立できます。
その説明が、>>372です。

382 名前:379=365 :01/09/22 06:43
>>380
素早いレスありがとうございます。とても早かったのでちょっとびっくりです。

>こちらの方法だとコンパイル時にエラーを検出できないのが悲しいですね。
そうですよね。見た目なんとなく、すっきりするのですが
コンパイルエラーでチェックできないので…
あまり良くないかもしれないです。
こういうときに使うもの、ではないのかも…。

>これに加えてデザインパターンも習得すると、
>設計の柔軟性が格段に上がります。
デザインパターンはまだ未開拓の土地です。(^^;)
C++をまだ十分理解できていないので難しいかな?と
思いまして。(^^;)
設計する上で先人の勉強は大切ですよね。この機会に
DPのほうも一緒に勉強してみます。
役立つリンクをご教示いただいて、ありがとうございます。(多謝)

383 名前:デフォルトの名無しさん :01/09/22 13:44
-********/////////////////////--------------------------------------------------------------------------
あなた達には分からないでしょうが、Rubyは素晴らしい言語です。
オブジェクト指向スクリプト言語として他のスクリプト言語を圧倒する性能と美しい言語仕様を持っています。
例えば、SchemeやSmallTalkなどは比較的美しい言語だと言われていますが、後発である優位さでRubyは
さらなる美しさと実用性を備えています。
もちろんPerlやPythonなど問題外です。
日本語との親和性ではRubyしか選択肢がないでしょう。

LinuxのディストリビューションもRubyの採用例が増えてきています。
1年後には全てのディストリビューションがRubyを標準採用するでしょう。
Rubyは未来のスクリプト言語なのです。

長くなりましたが、コピペではありません。
賛同していただける方はRubyの事を分かっていただけない人に出会ったら、
この発言をコピペしていただければ幸いです。
C++なんて問題外ですが。

384 名前:  :01/09/22 14:03
じゃあなんで
Ruby Ruby Ruby Ruby Ruby Ruby Ruby Ruby Ruby Ruby Ruby Ruby
とかやる荒らしが出る?

385 名前:デフォルトの名無しさん :01/09/22 14:06
>383はDelphiスレとかにも似た奴貼り付けてる。
放置。

386 名前:1Rubyユーザ :01/09/22 14:14
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。
C++なんて問題外です。

387 名前:デフォルトの名無しさん :01/09/22 14:41
俺はどっちも好きだ。どっちもいい言語だよ。
けど、Rubyの話は別スレでやってくれよ。

Rubyは好きだけどRubyバカは勘弁してくらはい。
お前らにRubyを語られたらゆきひろがかわいそうだろ?

388 名前:デフォルトの名無しさん :01/09/22 16:52
Rubyはクソです。ゴミ箱逝きです。

いじょ

389 名前:デフォルトの名無しさん :01/09/22 18:07
>>383
Linuxは何言語で作られているか分かってるんだろうかわらぃ

390 名前:かな :01/09/22 18:16
どなたかマージソートで重複を削除する
プログラムを教えていただきませんでしょうか??

391 名前:デフォルトの名無しさん :01/09/22 18:33
>>390
それ C++ の話なんですか? ともかく、宿題は麻衣ちゃんに教わって下さい。

お兄ちゃんの宿題、私が答えるよ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=982853418

392 名前:かな :01/09/22 18:37
C言語です。
ありがとうございます。
さっそく聞いてみます。

393 名前:デフォルトの名無しさん :01/09/22 18:37



Rubyはクソです。ゴミ箱逝きです。

いじょ
この発言をコピペしていただければ幸いです。

394 名前:Ruby野郎は、 :01/09/22 19:46
Javaスレにも出没していたな。
そんなに素晴らしいのなら、他言語と比較するアカデミックなスレでも立てて、他人を納得させてみなさい。まぁ、叩かれるのがオチだろうがな。

395 名前:デフォルトの名無しさん :01/09/22 23:59
>>388
( ´∀`) ナイスお茶。

396 名前:デフォルトの名無しさん :01/09/23 02:28
マジレス希望なんですけど
new演算子で確保したメモリに対してエラーチェックってしたほうがいいんでしょうか?

if( ( int *pNum = new int ) == NULL ) {
/* エラー時の処理 */
}

っていう感じに

397 名前:デフォルトの名無しさん :01/09/23 02:38
new は失敗すると std::bad_alloc という例外を送出するナリ
例外を送出して欲しくなければ new(nothrow) なんてするナリ

398 名前:デフォルトの名無しさん :01/09/23 02:40
new(std::nothrow) かな?

399 名前:デフォルトの名無しさん :01/09/23 02:50
>>397さん早いレスありがとうございます、
例外って意外と便利なんですね。

400 名前:デフォルトの名無しさん :01/09/23 06:38
#include <iostream.h>

int main(void)
{
char c;
int i=0;

while(cin.get(c)) {
i++;
}

cout << i << endl;

return(0);
}
これで、入力した文字数をカウントして表示するプログラムを作成したつもりですが、
これでは、文字数が表示されません。どこが間違っているのか教えてください。

401 名前:デフォルトの名無しさん :01/09/23 09:53
>>400
文字の入力が終わるのはいつだ?

402 名前:デフォルトの名無しさん :01/09/23 10:31
>>400
C++以前の問題。
わからんかったらプログラム書くな。

403 名前:デフォルトの名無しさん :01/09/23 10:34
>>396
set_new_handlerも調べておけ。

404 名前:デフォルトの名無しさん :01/09/23 11:20
>>399
ただし、落とし穴もあるので注意な。

void foo()
{
  int *p1, *p2;

  p1 = new int;
  p2 = new int;
  // do something
  delete p2;
  delete p1;
}

このプログラムで p2 = new int に失敗すると、そこで例外が投げられて関数
を抜けてしまうため p1 = new int で確保したメモリを開放する機会が失われ
る。

C++ の例外に絡んだ落とし穴は色々あるので、実用的なプログラムを書くなら
Effective C++, More Effective C++, Exceptional C++ の三冊は必読。

405 名前:デフォルトの名無しさん :01/09/23 13:37
>Effective C++, More Effective C++, Exceptional C++ の三冊は必読。
おいらはこのうちの一冊も読んでないナリ。
読んだのは、プログラミング言語C++ と ARM だけです。
実用的なプログラムを書くのは無理ですか?(藁

406 名前:デフォルトの名無しさん :01/09/23 13:48
>>405
その読んだって2冊の読み方によるけど、
仕事で使ったりするんだったら、
読んでないとロクでもないソフトが完成してしまうと思います。

っていうか、出来れば読みたくない訳?
C++でコード書きたかったらがむしゃらに読んどけ。

407 名前:デフォルトの名無しさん :01/09/23 14:04
>その読んだって2冊の読み方によるけど、
思うんだけど、プログラミングの初心者じゃない人で
その2冊読んでダメならなに読んでもダメなんじゃない?

408 名前:デフォルトの名無しさん :01/09/23 14:07
あと、C++ の解説書ばっかしいくら読んでも
スキルは上がらんよ。

409 名前:デフォルトの名無しさん :01/09/23 14:10
何度もゴメソ

>Effective C++, More Effective C++, Exceptional C++ の三冊は必読。
ちなみにこの3冊が良い本なのは確かだと思いまふ。
読んでないけど。

以上、暇だったのでからんでみました。

410 名前:デフォルトの名無しさん :01/09/23 14:11
そうそう。Rubyができないと一人前とは言えないね。

411 名前:デフォルトの名無しさん :01/09/23 14:19
>>410 ワラタ
でも氏ね

412 名前:デフォルトの名無しさん :01/09/23 14:52
>>410
   λ
   ( ヽ  / ̄ ̄ ̄ ̄ ̄
  ( ゚Д゚ )< Rubyはクソです。ゴミ箱逝きです。 いじょ
 (____) \_____
   ヽ(´ー`).ノ
     (  へ)
      く



                      - = ≡三  λ
                  _ = ≡三     ( ヽ  / ̄ ̄ ̄ ̄ ̄
       (´ー`)          = ≡三    ( ゚Д゚ )< この発言をコピペしていただければ幸いです。
      ( ヽ ヽ)         - = ≡三   (____) \_____
      /  >             - = ≡三

413 名前:デフォルトの名無しさん :01/09/23 15:04
>>397
VC6は投げないという話があったような。VC持ってないから間違ってたら失礼。

try { delete[] new char[-1]; } catch (const std::bad_alloc& e){ std::cerr << e.what(); }
こんなんで確認出来るだろうか?(one-liner失敬)
保護の弱い環境だとクラッシュするかも。

414 名前:デフォルトの名無しさん :01/09/23 15:12
Effective C++, More Effective C++, Exceptional C++
これらの本はC++のどのような本なんですか?
OOPとかですか?

415 名前:Ruby! :01/09/23 15:19
OOPならRubyだね。

>C++
>いろいろと有名なオブジェクト指向言語であるC++と
>Rubyを比較すると:

>* C++なぞ問題外.^^;;;

http://www.ruby-lang.org/ja/compar.html

Rubyを知ってもらうためにもこの文をコピペしてください。

416 名前:デフォルトの名無しさん :01/09/23 15:20
ttp://www.ascii.co.jp/books/detail/4-7561/4-7561-1808-9.html
ttp://www.ascii.co.jp/books/detail/4-7561/4-7561-1853-4.html
ttp://www.mmjp.or.jp/pearsoned/washo/prog/wa_pro34-j.html

417 名前:デフォルトの名無しさん :01/09/23 15:21
>>415 いまさらですが、ひとつに偏るのは良くないです。

418 名前:デフォルトの名無しさん :01/09/23 15:41
>>414
「プログラミング言語C++」は、コンパイラ作成者向けに書かれた仕様書を、利用者
向けに咀嚼した書籍だけど、上の三冊は仕様書の狭間にある陥穽や、仕様書には直
接は書いていない言語仕様策定者の意図に踏み込んで解説している。

実践で得られた知見をまとめた Tips 集、というのが近いかな。

Exceptional C++ も似たようなものだけど、こっちは Gru of the Week の記事が元に
なっている。英語が苦手でなければ、Web で公開されている記事をどうぞ(というか
私は GoW しか読んでない)。

Gru of the Week
http://www.gotw.ca/gotw/

419 名前:デフォルトの名無しさん :01/09/23 17:34
                       

――――――――――――――――――――――
番組の途中ですが、臨時ニュースです。
「Rubyはクソです。ゴミ箱逝きです。 いじょ 」
この発言をコピペしていただければ幸いです。
___________   __________
             ‖ \|________   
             ‖ | ON AIR.|
             ‖  ̄ ̄ ̄ ̄
        ./ ̄ ̄θ Λ_Λ
      .../   //(´∀` )/|
     ./      ̄/⊂    ||_/
     | ̄ ̄ ̄ ̄ ̄|  (  ━┳┛
     |_____| /ヽ」┘┻

420 名前:デフォルトの名無しさん :01/09/23 18:03
             ‖ | ON AIR.|
             ‖  ̄ ̄ ̄ ̄
        ./ ̄ ̄θ Λ_Λ
      .../   //(´∀` )/|
     ./      ̄/⊂    ||_/
     | ̄ ̄ ̄ ̄ ̄|  (  ━┳┛
     |_____| /ヽ」┘┻

421 名前:デフォルトの名無しさん :01/09/23 18:04
             ‖ | ON AIR.|
             ‖  ̄ ̄ ̄ ̄
        ./ ̄ ̄θ   Λ_Λ
      .../   //(´∀` )/|
     ./      ̄/⊂    ||_/
     | ̄ ̄ ̄ ̄ ̄|  (  ━┳┛
     |_____| /ヽ」┘┻

422 名前:デフォルトの名無しさん :01/09/23 18:08
             ‖ | ON AIR.|
             ‖  ̄ ̄ ̄ ̄
        ./ ̄ ̄θ  ∧_∧
      .../   //(´∀` )/|
     ./      ̄/⊂    ||_/
     | ̄ ̄ ̄ ̄ ̄|  (  ━┳┛
     |_____| /ヽ」┘┻

AA調整実験中

423 名前:デフォルトの名無しさん :01/09/23 18:09
――――――――――――――――――――――
何故か耳がズレる
___________   __________
             ‖ \|________  
             ‖ | ON AIR.|
             ‖  ̄ ̄ ̄ ̄
        ./ ̄ ̄θ ∧_∧
      .../   //(´∀` )/|
     ./      ̄/⊂    ||_/
     | ̄ ̄ ̄ ̄ ̄|  (  ━┳┛
     |_____| /ヽ」┘┻

424 名前:デフォルトの名無しさん :01/09/24 00:56
この間から騒いでるRuby厨房は、当然Rubyも理解できてないと思われ。

425 名前:デフォルトの名無しさん :01/09/24 02:16
参照はどう使うと
きれいにコーディングできますか?
以前Javaをやっていて、VC++もやってみようと思い
現在C++猛勉強中です
JavaからC++に移行する際に注意する点等もありましたら
教えてもらえるとうれしいです
多重継承と、virtualをつけないとオーバーロードできない点が
なんか違うなーと感じてます

426 名前:デフォルトの名無しさん :01/09/24 02:16
オーバーライドですね

427 名前:デフォルトの名無しさん :01/09/24 02:51
参照は & と * があるよ
& はいまいち好きじゃない。値渡しと見た目で区別できないから。
でもコピーコンストラクタやテンプレートで必須になるんだよね。

428 名前:C++厨 :01/09/24 02:56
>>425
左辺値を返すとき、たとえば
代入演算子のオーバーロードをするとき。
virtualがないものはクラス名で修飾された、
単なる関数で第一引数にthisが渡っていると
考えて良いそうな。
デストラクタの実行はスコープがあれば
その終わりに順ずる。
コンテナと例外をうまく使えばごみ集め
の手間はかからない。

429 名前:C++厨 :01/09/24 11:37
C++(gcc)でシグナルハンドラからlongjmpするとコアダンプ
するんだけど、仕様的にはこれでいいんだっけ?
もうひとつ、allocaってC++で使っていいのかってこと。
例外とデストラクタが絡むから、ヤバイ気がする。

430 名前:デフォルトの名無しさん :01/09/24 12:01
>>429
おいおい、シグナルハンドラからどこへ longjmp するんだ?

>例外とデストラクタが絡むから、ヤバイ気がする。

そこまでわかってるならやばくないように
使うこともできるのでわ?
まあ c++ ならあんま必要ないしね。

gcc 限定なら int a[n] (iは非定数)なんてことができて
これは alloca と等価。

431 名前:デフォルトの名無しさん :01/09/24 12:02
×:(iは非定数)
○:(nは非定数)

432 名前:  :01/09/24 14:02
Visual C++7.0っていつでますか?

433 名前:デフォルトの名無しさん :01/09/24 14:41
>>432
激しくスレ違い。

434 名前:デフォルトの名無しさん :01/09/24 14:48
visualC++で
一般保護法違反がでてPCが固まったんですけどなんででしょうか?

435 名前:デフォルトの名無しさん :01/09/24 14:52
>434 ははは・・・キミの上司ならもしかして理由の想像は判るかもしれないね。
    でもたぶん・・・・・

 PCを固めるのはコールバック系の処理中に変な事するとか
 まあ色々方法はあるけどね

436 名前: :01/09/24 15:12

コールバック系?
リアルジュークボックスを起動しながらやっていたせいかなぁ?

437 名前:デフォルトの名無しさん :01/09/24 16:26
>>429
ISO/ANSIでは、C++における(POSIX) signalについて何も保障してない。
環境依存だから、compiler, libraryのmanualを読め。

ただ、longjumpはregister周りをいじって大域脱出を実装するので、
destructorが呼ばれるなんて事は金輪際ないと思うぞ。

signal→例外という機構がまだないんだなー。UNIXには。
Windows(SEH&__try)にはあるのになー。

438 名前:  :01/09/24 16:27
関数内ででかい配列を宣言すると飛ぶよ。
gnucも飛ぶ。

439 名前:デフォルトの名無しさん :01/09/24 16:39
シグナルハンドラ内で閉じている longjmp は、
たぶん機能するんじゃないかと思います。
ただしスタック巻き戻すときにデストラクタなんかは動かないでしょう。
(なので覚悟の上じゃないとちょとアレ)

シグナルハンドラてのは、プログラム本体とは無関係に
非同期に動くものなので、シグナルハンドラの外へ longjmp するのは
あるスレッドで setjmp した場所へ、別のスレッドから
longjmp しようとするようなものです。

飛ぶでしょ?普通。

440 名前:デフォルトの名無しさん :01/09/24 16:44
>(なので覚悟の上じゃないとちょとアレ)
かわりにC++ではthrow/catchを使うべきだですよね。

441 名前:デフォルトの名無しさん :01/09/24 17:15
>>440
シグナルハンドラから throw するのも、保証されてるかどうか怪しいな。
環境依存だからマニュアル読んでね、としか言えないけど。

442 名前:デフォルトの名無しさん :01/09/24 18:54
ソダネ
そもそも本筋で throw してる最中にシグナルハンドラが
呼ばれて、そんなかで throw しようとしたらえらいことになるかも?

443 名前:デフォルトの名無しさん :01/09/24 22:41
>>436
ばーか。
そんなこと逝ってるようなやつが質問すんな。

444 名前:デフォルトの名無しさん :01/09/24 22:52
>>443
恐怖恐怖恐怖!!
443引見陰険隠見隠顕淫ビ
443最低
いじめかこわるい
ださ
さいあく〜〜〜〜
ちょーーーーーーー
ぼーーーーーーーーーーーーーーーーーー
ぶーーーーーーーーーーー
ってか厨房
あほ
だぼ
さヴぉ

445 名前:デフォルトの名無しさん :01/09/24 22:53
しったかぶり
        ∧ ∧   ∧ ∧
   /⌒~~~⌒\                       (   ,,)   (,,・Д・)
 / ( ゚?д?゚ )y─┛~~                〜(___ノ  〜(___ノ ,γ_
(_ ノγ U  ∩_∩)   THANK YOU 2ch     ┌───────┐   \
  α___J _J         and          (| ●        ● |      ヽ
  / ̄ ̄ ̄ ̄\  GOOD-BYE 2ch WORLD! /.| .┌▽▽▽▽┐ .|____|__||_| ))
 /     ●  ●、                   ( ┤ .|        | .|□━□ )
 |Y  Y       \ またどこかで会おうね  \.  .└△△△△┘ .|  J  |)
 |.|   |       .▼ |                 | \あ\      | ∀ ノ
 | \/        _人|∧∧∩゛冫、 .∧_∧      |    \り.\     . |  - ′
 |       _/)/)/( ゚Д゚)/ `  . (´∀` )..ヽ(´ー`)ノ  \が\ .   |  )
 \    / 〔/\〕 U  / ∩∩ (    ) (___)    \と.\ .|/
  | | | c(*・_・)  |  |ヽ(´ー`)ノ_|  |  | |   |〜 /\.\う\| (-_-)
  (__)_) UUUU /∪∪ (___)(_(__) ◎ ̄ ̄◎─┘ .└──┘.(∩∩)


 ママ〜 2chでスレたてたよ〜
 \__  ______
      ∨    ∧_∧
           " ,  、 ミ   / ̄ ̄ ̄ ̄ ̄
            ゝ∀ く  < いい子ね、後で見てみるわぁ
           ∧_∧  |   \_____
        三  (    とノ
      三   /   つ |
     三  _ ( _  /|  |
        (_ソ(_ソ(_ )

446 名前:デフォルトの名無しさん :01/09/24 22:53
テレビにニュース速報が入る。
俺は慌ててパソコンを立ち上げ、そして気付く。
「あぁ、2chは閉鎖したんだっけ……」
テレビからは現場の慌しい状況が伝わってくる。
もし2chがあったら、どういうスレが立っているのだろう。
重複スレが沢山できて、それで荒らしとかやってきて……
テレビでは相変わらず、レポーターが必死で現場の状況を伝えている。
可愛いレポーターだ。俺は、頭の中で「萌え〜」というレスを
つけている自分を想像した。
後ろの群集がテレビに向かって挑発的なポーズを取っている。
「なんだ、あのドキュソ」「厨房氏ね」……
俺はたまらなくなり、無いとは分かっていながら再び2chにアクセスした。
しかし、画面には一言「閉鎖したのです。。。」とだけしか表示されない。
何度リロードしても変わらない。あの日以来、2chは止まったのだ。
どうやら犯人が逮捕されたようだ。相変わらず可愛いレポーターが
その状況を伝えている。
「さよなら、にちゃんねる」
俺はお気に入りから2chを削除し、そして騒がしいニュースを冷めた目で
見るのであった。
         

447 名前:デフォルトの名無しさん :01/09/24 22:54
            ⊆ニ(二(ニニ⊇   ⊆ニ(二(ニニ⊇
        ./ ̄ ̄ ̄ ̄ ̄/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ヽ
       / ____/_________________ヽ
      ,/ ̄ ̄ ┏━, / ̄ ̄ ̄|| ||. ̄ ̄ ̄ ̄ |||  ̄ ̄ ̄ ̄ ̄ ̄ ̄...| |
     ,/ ∧ ∧. i┸i //. ∧ ∧ || / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    _.,/. (・Д・ ) | :::|// (゚Д゚ ) < >>443を迎えにきました。措置入院です!!
   |/,,,,,へ⊂ ヽ  .//  ,/  ノ/ ||\______________
  ,/ ̄ ̄ ̄ ̄ ̄ ̄//|_/ ̄ ̄ ̄|  ̄ ̄ ̄ ̄ ̄ | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
  |~ ゜ ̄゜ ̄ ̄ ̄~~| ̄ ̄   =。|┃       |━━━━━...............|
  |______: |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,|,,,,゜,,,,,,,,,,,,,,,,,,,,,,,,,|,,,東京精神病院,,,,,[|
 ._|]0::∴:::0::[二二il:]    ,-―-、 ,,|         |       .     [|
 |====== ;...........|  /,  ̄ヽ |~~|.        |  /,  ̄ヽ |     {|
 ヽニ[_]ヾニニヽ''''''|―-|.(※)|':|''''|.'''''''''''''''''''''''''''''|''''''''|.(※)|:|'''''''''''''''''/
     ゞゝ三ノ ̄ ̄ ̄ ゞゝ_ノ ̄ ̄ゞゝ三ノ ̄ ̄ ̄ ゞゝ_ノ

448 名前:デフォルトの名無しさん :01/09/24 22:55
while(){
printf("きしょ");
}

449 名前:デフォルトの名無しさん :01/09/24 22:57
━┓                                                  ____
] ┃                                                /    /
  ┃                                               / 2ch  /
] ┃                                             /Λ_Λ  /
  ┃    ゲキトツスルゾヌッ!!                               / (´∀` ) /
] ┃                                          / ∧∧    )/
  ┃                                         /  (゚Д゚ ) ̄ ̄ /
] ┃      _______________________/    U U ̄ ̄/ _
  ┃    /         ・・・・・|_|・・・・・ Λ_Λ ∩∩  /)_/) i⌒――⌒i       ̄ | __
] ┃   />   <  2ch Airlines (・∀・ ) (・x・)ノ (,’ー’) (´(Å__)` ) / ̄ ̄ ̄ ̄ ̄/
  ┃  /         _          _  (     ) ノ|x| _( U__U) /ヽ / /_ノ ヽ  ̄ ̄ ̄ / ̄
] ┃ | ▼      |_|・・・・・・・・・・|_|・・・・・・ ・・ |_|・・・・_・・・・|_|・・・/_/ |_|((.l_ll)))  /
  ┃ |_人_  (-_-)ヽ(´ー`)ノ/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄/ ̄ ̄ ̄ ̄ ̄ / (lロ-ロl) /
] ┃  \   (∩∩)(___)\==  / ̄ ̄ ̄ /|| ̄| ̄|\/ ̄ ̄   ヽ ∀ノ/
  ┃    ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄| ̄|\/ ̄||  |  |  |  ̄ ̄ ̄ ̄ ̄ ̄ ̄
] ┃                     ||  |  | |   ||  |_|/
  ┃                     ||  |_|/    ̄ ̄
] ┃                       

450 名前:デフォルトの名無しさん :01/09/24 22:57
参照を使った戻り値について質問なんですが
int &f(){return value;}
という関数があるとして、
f()=5;
という使い方できる事以外では
int f(){return value;}
と同じでしょうか?

451 名前:デフォルトの名無しさん :01/09/24 22:57
   ||
 ∧||Λ
( / ⌒ヽ
 | |>ALL|
 ∪ / ノ
  | ||
  ∪∪

452 名前:デフォルトの名無しさん :01/09/24 22:58
          正直、スマンカッタ!!
     \\  正直、スマンカッタ!! //
 +   + \\ 正直、スマンカッタ!!/+
     .   ___ .  ___  . ___   +
        /. ――┤  /. ――┤ . /. ――┤+
      ./(.  = ,= | ./(.  = ,= | ./(.  = ,= |
 +  .  |||\┏┓∩|||\ ┏┓∩|||\┏┓/  +
   ((  (つ   ノ  (つ   丿 (つ   つ ))
       ヽ  ( ノ   ( ヽ ノ   )  )  )
       (_)し    し(_)   (__)__)

453 名前:?r?????l???????? :01/09/24 23:05
参照を使った戻り値について質問なんですが
int &f(){return value;}
という関数があるとして、
f()=5;
という使い方できる事以外では
int f(){return value;}
と同じでしょうか?

454 名前:kago :01/09/25 00:04
(先ほどの人、コメントありがとうございます。それではここで。)
最近linuxでC++を始めたんですが、関数一覧表、みたいなものはネット上にどこかないんですか? GNUのGCCを使っていますが。GNUのぺーじには、一覧表、みたいなものは見つけられませんでした。
perlとかphpとかだと、日本語のページでけっこう簡単に見つかって参考にしているんですが、C++はどうにも見つかりません・・・。
みなさんはある機能を使いたいと思った時、どのようにして調べるのでしょうか? 参考までに教えて下さい。

455 名前:>454 :01/09/25 00:10
システムコールは載ってないけどね
http://www.microsoft.com/japan/developer/library/vclang/vclanghm.htm

456 名前:デフォルトの名無しさん :01/09/25 10:25
>>453
いいえ違います、同じではありません

457 名前:デフォルトの名無しさん :01/09/25 18:42
言語機能やSTLについて調べたいときは、
VC++やBCBのオンラインマニュアルを参照してます。
OSやライブラリの機能については、
それらのマニュアルを調べます。
あとはサンプルプログラムをgrepするとか。

458 名前:デフォルトの名無しさん :01/09/25 18:49
>>453
戻り値に参照を返すのは鬼門。
EffectiveC++第2版の31項を参照。

459 名前:デフォルトの名無しさん :01/09/25 19:03
>>404

void foo()
{
  auto_ptr<int> p1(new int);
  auto_ptr<int> p2(new int);

  // do something
}

こうすれば例外が出てもリークしません。
p2の確保に失敗したときですら、p1だけがうまくデストラクトされます。
auto_ptrを使え、ということではなく、自動変数(スコープ)をうまく使えということです。
vectorやlistを使ってもいいし、何かのクラスのメンバになっていてもいい。
要はdeleteが無ければいい。deleteをまき散らしているやつはまだ厨房。

460 名前:デフォルトの名無しさん :01/09/25 19:47
>>459
404 は、それを知ってて敢えて *ダメなサンプル* として、あのコードを出ただ
けだと思うが。More Effective C++ の項目9が、そのものスバリだし。

> deleteをまき散らしているやつはまだ厨房。
同意

461 名前:厨房 :01/09/25 19:49
正直、すまんかった。

void foo()
{
  int* p1 = NULL;
  int* p2 = NULL;

  try {
    p1 = new int;
    p2 = new int;

    // do domething
  }
  catch (...) {
   delete p2;
   delete p1;
   throw;
  }
}

462 名前:厨房 :01/09/25 19:53
それじゃ、うまくいった場合にメモリリークだ。(笑)

463 名前:厨房 :01/09/25 19:56
以上、はまるパターンのサンプルでした。(てへっ)

464 名前:デフォルトの名無しさん :01/09/25 20:41
>>450
まあ大体はそれでいいと思うが、アセンブラだと

; int& f();
mov eax,offset value
ret

; int f();
mov eax,[value]
ret

という感じだと思われるから、その後のアクセスなど考えると前者が軽いかもしれん。
要は、戻り値がintでなくint&だから、一般的実装ではポインタ的に動きそうだと。
でもインライン化されるなら話は全く変わる。

どっちにしても、個人的にint& f();みたいな関数を書きたい局面は滅多に無いと思う。
でもMyClass& f();みたいにクラスを返すなら話は全く変わるし、頻繁に使ってる。

つーか組込型への参照を返す場面ってほとんど無いんじゃ。
クラスメンバアクセサとかなら、半端な隠蔽せんで読みと書きに個別の関数作るしな。

>>458
いや、どう見ても自動変数じゃないから鬼門ではなかろ。
int& f() { int value; return value; }
なら即自滅だが。

465 名前:デフォルトの名無しさん :01/09/26 10:45
>>464
自動変数じゃなかったとしても、EffectiveC++29項、30項に引っかかる。
C++とオブジェクト指向を両方とも深く知った人が理由あって使うならともかく、
普通は使用禁止と考えたほうがいい。

466 名前:デフォルトの名無しさん :01/09/26 14:01
VBで作ったDLLをVCで呼び出す必要が出てきたのですが、VB側で

Public Function Show(XXXX as Collection)

となっている場合、VC側での引数はどうすればよろしいのでしょうか?

LPDISPATCH aaa;
XXXDLL->Show( &aaa ) ;

だと、ビルドは通っても、実行時に
「ハンドルされていない例外はXXX.EXEにあります。0x0000005:Access Violation」
となってしまうのですが・・・。
BSTRのときのSysAllocStringみたいに、何かしてあげないといけないのでしょうか?

467 名前:デフォルトの名無しさん :01/09/26 15:25
C++でコンストラクタ中のエラーを例外投げずに通知するには一般にどうやってるの?
とりあえずコンストラクトは成功させて後でGetLastError()メソッドでエラーチェックさせるとか?

468 名前:デフォルトの名無しさん :01/09/26 15:38
>>467
「一般には」例外を投げる。

どうしても例外を投げたくなければ、オブジェクトのコンストラクトと初期化用の
メソッドを分離して、後者の戻り値で判断させるのが手だと思うが。グローバル
なデータ領域を使って成/否を記録しておくのは、ネストできなくなるから、や
めたほうがいい。

CFoo foo;
if (!foo.Init(...)) {
  // 初期化失敗
}

469 名前:デフォルトの名無しさん :01/09/26 16:39
これって合法?
class Foo{
public:
 static void foo(char *message)
 {
  puts(message);
 }
};

void (*bar)(char *message);

int main(int argc, char* argv[])
{
 Foo::foo("xxx");
 bar = Foo::foo;

 bar("yyy");
 return 0;
}

実行結果
xxx
yyy

470 名前:これじゃ駄目かね? :01/09/26 18:39
#include <string>
#include <stdio>
#include <stdlib>
using namespace std;
class IBar
{
 public:
  virtual void Write(const string &message) = 0;
};

class Foo : public IBar {
public:
 virtual void Write(const string &message)
 {
  puts(message.c_str());
 }
};

int main(int argc, char* argv[])
{
 Foo foo;
 foo.Write("xxx");

 IBar *bar = &foo;
 bar->Write("yyy");
 return EXIT_SUCCESS;
}

471 名前:デフォルトの名無しさん :01/09/26 20:53
typedefって使う意味あるんですか?

472 名前:デフォルトの名無しさん :01/09/26 20:57
>>471
typedefの役割と意味を調べれば自明。

473 名前:デフォルトの名無しさん :01/09/26 20:59
実際にそういう使い方して役に立った?

474 名前:デフォルトの名無しさん :01/09/26 21:01
>>471
とりあえず林晴比古本でも見るよろし

475 名前:デフォルトの名無しさん :01/09/26 21:27
インスタンスが無いと、メンバ関数って呼べない・・・

476 名前:469 :01/09/27 00:19
>470
駄目なんです。
コールバックを登録するCのライブラリの
ラッパーを作っていてその部分を隠蔽したいのです。

まあstaticメソッドを普通の関数としてクラスの外に
追い出してしまえばいいのですが、もし合法なら
staticでやりたいなということです。

477 名前:ポコニャン :01/09/27 03:12
>>476

そーゆーことなら469のまんまでも問題ないっしょ。

つまり469でのbarが実際にCで叩かれるアドレスなのねぇ。

478 名前:デフォルトの名無しさん :01/09/27 03:20
関数ポインタとstaticメソッドの代入互換ってどこで説明されてる?

479 名前:470 :01/09/27 09:59
うむ、C言語のライブラリの都合なら仕方があるまい。

>>478
いろいろなところで言われていると思うが……。
こういうケースでstaticメソッドを使うのは常套手段でしょう。
ポインタを1つ渡せる場合は、thisを渡すとかいうのも。

class Foo{
private:
 static void foo(void *p) {
  Foo *t = reinterpret_cast<Foo *>(p);
  t->Write();
 }
 int hdl;
public:
 virtual void Write() { puts(msg); }
 Foo() {
  hdl = set_callback(foo, this);
 }
 ~Foo() {
  remove_callback(hdl);
 }
};

480 名前:デフォルトの名無しさん :01/09/27 10:44
static void* hInstance

class Foo
{
public:
Foo(){
hInstance = this;
}
static void foo(char* message){
typedef void (Foo::*CallbackProc)(char*);
Foo* pObj = (Foo*)hInstance;
CallbackProc pProc = &Foo::Write;

(pObj->*pProc)(message);
}
protected:
virtual void Write(char* message){
puts(message);
}
};

481 名前:  :01/09/27 22:36
参照型を返す関数ってどんな使い方があるのですか?
やはり
func(0) = 1;  //funcの戻り値は参照型
といった感じですか?

x = func(0);
という使い方なら別に参照型を返さなくてもいいのですよね?
でも
int& a = func(0);
とすればちょっとは意味あるのかな?

とまぁいろいろ悩んでいるのですが・・・。

482 名前:>481 :01/09/27 22:56
class A {
  ・・・
  string m_Name;
  const string& getName() {
   return m_Name;
  }
}

みたいにconst参照を返すのはよく使う、俺は。
というか、返値として使う場面はそれ以外にないな。

483 名前:  :01/09/27 23:11
>>482
それって呼び出し側はどういった使い方になるんですか?
ただのconst string型を返すのではダメなんすか?

484 名前:デフォルトの名無しさん :01/09/27 23:19
>>483
それだと、インスタンスのコピーが発生するからコストがかさむ。

485 名前:デフォルトの名無しさん :01/09/27 23:26
return this の時はたいてい参照で返すYO!

486 名前:  :01/09/27 23:49
で・・・、そのconst string&型を返す関数をどうやって使うのですか?
関数呼び出しを左辺にするのですか?
それとも戻り値を何かに代入するのですか?
結局参照を返すのはコスト削減のためだけなのですか?

487 名前:デフォルトの名無しさん :01/09/27 23:56
>>486
従来の C 言語の経験があるなら、ポインタを返すタイミングで参照を返す(こともある)
で分かると思うが。理由は、主に次の二つ。

- 右辺値としてアクセスしたい場合に、オブジェクトをコピーするコストを削減する
- コピーではなく、実体にアクセスしたい場合に使う

もし分からないなら、少し実際のプログラム読んだほうが良いと思われ。

488 名前:デフォルトの名無しさん :01/09/28 00:57
>>481
参照を返す関数といえば、これ

ostream& operator<<(ostream& os, 〜);

489 名前:デフォルトの名無しさん :01/09/28 01:19
仮想関数+テンプレート
の関数の実行効率が異常に悪いのですが、心当たりあります?

490 名前:デフォルトの名無しさん :01/09/28 01:27
>>489
それ自体がそれほどパフォーマンスを落とすことはないと思われ。別な原因でわ?

491 名前:デフォルトの名無しさん :01/09/28 01:37
>>489
とりあえず、お約束ということで。
プロファイルはとりましたか?

492 名前:デフォルトの名無しさん :01/09/28 01:54
>>491 いやとっていません。みても何がなんだかさっぱりで。

493 名前:デフォルトの名無しさん :01/09/28 02:11
>>483
コピーに伴うコストが高くつく

494 名前:デフォルトの名無しさん :01/09/28 02:14
>>492
それだと、ほんとにボトルネックが「仮想関数 + テンプレート」にあるのかどうか
分からん気がするが。

495 名前:おでん屋 :01/09/28 05:12
すみません。以下のようなプログラムで継承元のクラスBの仮想関数を
オーバーライドするにはどうしたら良いでしょうか?
昨日から考えているのですがコンパイルエラーの連続で...
よければどうかお助け下さい

class A { public: virtual void method(void); }
class B : public A { ... };
class C : public A, public B {
 virtual void Cmethod(void);
 // ここで B の仮想関数 method をオーバーライドして
 // Cmethod()を使いたいのですが、書き方が分からないです。
};

void C::B::method(void) { Cmethod(); } // これはダメみたいです

496 名前:デフォルトの名無しさん :01/09/28 05:24
なにしたいんだかわかんないけど

void C::Cmethod() {
// 必要ならなんか
B::method();
// さらに必要ならなんか
}

たぶんもっと基本的なことちゃんと勉強した方が良いと思われ。

497 名前:デフォルトの名無しさん :01/09/28 05:24
>>495
クラス階層が明らかに変だけど。クラス C で B だけでなく A も直接継承している
のは何故?

あと「クラスBの仮想関数をオーバーライド」という意味が良く分からんのだけど、
もしかして

C* p;
static_cast<A*>(p)->method();
static_cast<B*>(p)->method();

それぞれで、別の処理を行うことを想定してます?

498 名前:おでん屋 :01/09/28 06:00
>>496,497氏
レスありがとうございます。

ほんと構造が変です。こんな変な構造になったのは...
基底クラスのデストラクタでファイルの後始末処理をしているのですが
基底のデストラクタでは派生クラスの仮想関数はすでに使えないので
(ファイルの操作はこれに頼っているので、困ってしまいます)
派生クラスで書かないといけないですよね?
でも、この派生クラスをさらに派生すると...?

延々と続く問題になってしまいまして、それを解決しようとしたのが
クラスAで、派生クラスの後始末側にAの仮想関数を呼び出すようにして
Aの仮想関数で後始末をできるようにしました。

CのAはCを面倒みて、BのAはBを面倒みるような形にすると
こんな問題がでてしまいました。
さらに、呼び出すにもCのAなのか、BのAなのか明確にしないと
いけないです。さらにまずいです。

まったくもって勉強不足を痛感しております。
このような問題はどう解決したらいいのでしょうか...。

499 名前:デフォルトの名無しさん :01/09/28 06:23
>>498
> 基底クラスのデストラクタでファイルの後始末処理をしているのですが
> 基底のデストラクタでは派生クラスの仮想関数はすでに使えないので
> (ファイルの操作はこれに頼っているので、困ってしまいます)
この段階で設計が間違ってるなぁ。

これだけだと何とも言えんから、各クラスの処理の概要とファイルの後始末
に関して、少し詳しく書いたほうがいいと思う。

500 名前:おでん屋 :01/09/28 06:43
お世話になっております。説明が少し下手ですが宜しくお願いします。(ぺこり)

概要はこんな感じです。
重要でない細かい部分は端折らせていただきますね。

class AbstructFile {
public: Open() = 0, Close() = 0, Read() = 0, Write() = 0; // 純粋仮想メソッドです
public: ~AbstructFile() { Close(); }
 // 閉じ忘れ防止にデストラクタでファイルを閉じる処理はしておきたいです
}

AbstructFile は多種に派生してその一種に AbstructFile2 があります。
これもデストラクタで閉じたいのですが基底のデストラクタの Close(); は
邪魔になります。それをどうにか解決しても、AbstructFile2 から派生した
AbstructFile3 でさらに AbstructFile2 のデストラクタ処理が邪魔になりました。

正しい設計にするにはどうしたら良いのでしょうか...。


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