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


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

C++相談室 Part3
501 名前:デフォルトの名無しさん :01/11/26 15:59
小心者は一時領域にオブジェクトをコピーしてから非constメソッドを呼べ(藁

502 名前:デフォルトの名無しさん :01/11/26 16:12
class Base{
public:
Base(){
init();
}
virtual void init()=0;
};
class Derived:public Base{
public:
void init(){
}
};
こういう使い方したいなー

503 名前:デフォルトの名無しさん :01/11/26 16:15
>>502
コンストラクタから派生クラスの仮想メソッドを呼びたい、って話?

504 名前:デフォルトの名無しさん :01/11/26 16:18
継承はやめて、集約に直しとけ

505 名前:デフォルトの名無しさん :01/11/26 16:32
>>502
Delphiなら出来るけど、あの仕様はバグの温床だ。

506 名前:仮想コンストラクタ? :01/11/26 19:10
>502
ちょうど知人に、最近、「あなたはオブジェクト指向に詳しいですか?」と、これに
ついて尋ねられ、オブジェクト指向のオの字しか知らない自分は、答えに窮した(゜ε ゜

コンストラクタのオーバーライドは、オブジェクト指向的にイケてるのか、という話。

507 名前:506 :01/11/26 19:14
あれ? 良く見たら、そんな話しやないやん。逝きます。

508 名前:デフォルトの名無しさん :01/11/26 20:47
派生クラスでコンストラクタを新たに書きたくないってこと?

509 名前:デフォルトの名無しさん :01/11/26 21:22
だから集約にしとけって

510 名前:485 :01/11/26 22:01
>>495
引数の部分でクラス生成出来るのは便利だなぁ
ちなみに、よくわからないけど const 付けないでもコンパイル出来たよ。
あと Color color は Color& にしなくていいのかな?

511 名前:デフォルトの名無しさん :01/11/27 01:05
>>428
http://www.kuzbass.ru/docs/isocpp/lib-iterators.html
24.3.2 -4 を見ると
class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*,std::ptrdiff_t,_vwrap**,_vwrap*&> {
とかできそうなんだけど。gcc-3.0.xならいけるか?

iterator作るのが目的なら
class _vrtx_itr {
public:
typedef bidirectional_iterator_tag iterator_category;
typedef _vwrap **pointer;
typedef _vwrap *&reference;
typedef _vwrap *value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
 … あといっしょ
でどう?

512 名前:デフォルトの名無しさん :01/11/27 01:09
>>495
なんじゃそりゃ
>>510
本読め

513 名前:デフォルトの名無しさん :01/11/27 01:13
ただの一時オブジェクト...

隠れた動作がおおいっての、C++の悪い面だよなあ。

514 名前:デフォルトの名無しさん :01/11/27 01:17
マジで困っています。cに詳しい方、助けてください!!
6000個のデータが入ったテキストファイルを1000個のデータ(double)の入った6つのテキストファイルに分割したいのですが、やり方がわかりません。
元のファイル名はdata.txt、新たに作られるファイルはそれぞれdata1,data2,data3....という名前をつけなければいけません。
どなたか達人の方、教えてください。
お願いします。

515 名前:デフォルトの名無しさん :01/11/27 01:19
>>514
データ形式がどうなっているかわからんとわからん。

516 名前:514 :01/11/27 01:28
データ形式は
123.234,
456.435,
92.412,
4.23,
-2.35,
0,
12,26,

という感じです、すいません、うまく説明できませんがよろしくお願いします。

517 名前:デフォルトの名無しさん :01/11/27 01:30
宿題用のスレは別にあったと思うが?

518 名前:デフォルトの名無しさん :01/11/27 01:37
perlとかでちょいちょい、の話だと思うがな‥‥
というわけで、見事なワンライナー募集に変更すべし。

519 名前:デフォルトの名無しさん :01/11/27 01:43
>>516

区切り文字は','なの?

520 名前:デフォルトの名無しさん :01/11/27 01:43
1行に複数のデータがある場合もあるの?

”ある場合もある”って日本語変じゃないですか?

521 名前:514 :01/11/27 01:46
>>520さん あります、二個ある場合があります。
>>519さん 区切りは","です。

522 名前:デフォルトの名無しさん :01/11/27 01:47
>>521

",\n"を区切り文字としてstrtok()で分割しちゃえば?
コピーするだけだから数値に変換する必要はないな。

523 名前:522 :01/11/27 01:48
おっと、ここはC++のスレだった。。。

524 名前:デフォルトの名無しさん :01/11/27 01:53
>522
一行に二個ある場合もあるので、 ",\n"じゃだめだと思うの。

525 名前:デフォルトの名無しさん :01/11/27 01:54
>>524

strtok()の説明を見た?

526 名前:525 :01/11/27 01:57
あ、でもよく考えてみたら、
12,43,
34

これは3つじゃなくて4つに分割されるな・・・・

527 名前:デフォルトの名無しさん :01/11/27 01:58
PerlでやれPerlで。

528 名前:524 :01/11/27 01:59
見ていない。

529 名前:デフォルトの名無しさん :01/11/27 02:01
ていうか、改行無視して','で切ればいいんでないの?

530 名前:デフォルトの名無しさん :01/11/27 02:02
>>529

そうだな・・・・
一行一行やるのが一番だね。。。。

531 名前:デフォルトの名無しさん :01/11/27 02:20
暇つぶしに

#include <stdio.h>

#define NUMDATA 2
#define NUMFILE 6

main(){
char from[] = "data.txt";
char *r = "r";
char *w = "w";
char to[] = "data0.txt";
FILE *ff, *tf;
int n, k, c;

if((ff = fopen(from, r)) == NULL) return;
n = 1;
do{
to[4] = n + 48;
if((tf = fopen(to, w)) == NULL){
fclose(ff);
printf("can't open %s\n", tf);
return;
}
k = 0;
do{
c = getc(ff);
if(c == EOF) break;
if(c == ',') k++;
putc(c, tf);
}while(k < NUMDATA);
fclose(tf);
n++;
if(c == EOF) break;
}while(n <= NUMFILE);
}

532 名前:デフォルトの名無しさん :01/11/27 02:21
#define NUMDATA 1000
にしといてくだされ。
空白行がうざければ適当に処理してくだされ。

533 名前:514 :01/11/27 02:33
531さん、どうもありがとうございました。実行してみましたがばっちりです!!
一緒に考えてくださった、他の皆さんもどうもありがとうございました。
2ch初心者なので不安でしたが、世の中にはたくさん親切な人がいるんだなぁと思い感激です。
ありがとうございました。

534 名前:デフォルトの名無しさん :01/11/27 05:43
>>531
カコイイ!!
俺もサクッと回答できるようになりたい・・・

535 名前:デフォルトの名無しさん :01/11/27 06:18
RubyはC++に学ばなかった。
ナゼダカワカルカイ?ハクチドモ

536 名前:ハクチドモ :01/11/27 06:29
Rubyって何よ?

537 名前:デフォルトの名無しさん :01/11/27 06:54
っる胃bふbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうるbyさいこー補は簿言語の湯0−座hじゃしね。!!!

538 名前:428 :01/11/27 11:58
>>511
class _vrtx_itr : public iterator<>
で定義するのはg++2.95以前だと(今の書き方だと)やっぱり駄目みたい。
2.96以上では通るんだけど。

それで>>511書かれていたように継承なしで定義するようにしました。
これだとg++(2.95,2.96)でもVC++(v6sp2)でも通るみたいです。
これでいきます。どうもありがとうございました。

539 名前:デフォルトの名無しさん :01/11/27 13:12
継承する必要がないときは、継承しちゃいけないよ。
がんばってね

540 名前:デフォルトの名無しさん :01/11/27 18:18
class A:public virtual B{}
ってやる事のデメリットってなんですか?

541 名前:デフォルトの名無しさん :01/11/27 18:43
>>540
一番致命的なのはやはり、派生クラスへのキャストだね

542 名前:(・Λ・)ワカラナイ・・・ :01/11/27 19:40
16進数から10進数への変換を行う関数を考える。
16進数の各桁を文字列の各文字として定義して、その文字を受け取りint型を
返すような関数を定義せよ。
関数名、仮引数および返値は以下のよに定義すること。
int htod(char hex[]){...}

上の問題ですが、全然わかりません。
文字列自体、習ったばかりです・・・。
誰かやりor答えを教えてください。

543 名前:デフォルトの名無しさん :01/11/27 19:53
>>542
スレ違い。宿題スレを探して、そっちで聞け。

544 名前:デフォルトの名無しさん :01/11/27 20:03
>>542

int hrod(char hex[])
{
 int n;
 sscanf(hex, "%x", &n);
 return n;
}

545 名前:デフォルトの名無しさん :01/11/27 20:52
派生クラスにキャストできないの!?

546 名前:通りすがり :01/11/27 21:08
クラスのあたりでもう飽きてしまいました。
コンストラクタだの仮想関数だのって、、。

なにか飽きないで勉強できるネタない?

547 名前:デフォルトの名無しさん :01/11/27 21:10
楽しくゲームでも作ってみたら?

548 名前:通りすがり :01/11/27 21:15
>>547
そうだな。
取り合えずなんか作るわ。

549 名前:デフォルトの名無しさん :01/11/27 21:19
>>545
仮想継承した場合、基底クラスと派生クラスで vtbl の配置が変わってしまう(ような実装が一般的だから)
規格でも仮想基底クラスから派生クラスへのキャストは NG になってる。

550 名前:九州の学生 :01/11/27 21:48
独自挿入子を使ってストリームに情報を出力したいのですが、
Bの所で+演算子の返すオブジェクトをcoutで出力しようと
して@,AのようなオーバーロードをするとBCC(Ver5.5.1)に

「エラー E2094 ref.cpp 20: << 演算子が使われたがクラス
ostream では MX 型のための定義が存在しない(関数 main() )」

といわれてしまいます。g++でも出来ませんでした。しかし、
VC5では何の問題もなくコンパイルできます。<<演算子は@の
ところでオーバーロードしているので、コンパイルできると
思うのですがどうなのでしょうか。なお、Aのところを参照
を返すように変更すればなぜかコンパイルできるのですが、
そうすると動的な配列が存在する場合にデストラクタによっ
てメモリが開放されてしまいます。(元のソースでは"d"はポ
インタになっていてコンストラクタで"new"している。)
どなたかよい方法、又はこのソースの間違いを教えてください。

#include <iostream>
using namespace std;

class MX{
  double d;
public:
  MX(double x){d = x;}
  MX(MX &m){d = m.d;}
  MX &operator+=(MX &m){d += m.d; return *this;}
  friend ostream &operator<<(ostream &o, MX &m) // @
    {o << m.d; return o;}
  friend MX operator+(MX &lm, MX &rm) // A
    {return MX(lm) += rm;}
};

int main()
{
  MX m1(1.0); MX m2(2.0);
  cout << m1+m2 << endl; // B
  return 0;
}

551 名前:デフォルトの名無しさん :01/11/27 21:52
>>550
そういう場合はグローバル定義の演算子オーバーロードするんじゃなかったっけ?

552 名前:デフォルトの名無しさん :01/11/27 21:58
>>549
なるほど
ありがとうございます

553 名前:デフォルトの名無しさん :01/11/27 22:04
>>550
friend 関数は、そこに実装を書くことはできないはずだ!

554 名前:551 :01/11/27 22:06
あ、そこに実装してたのか。
frendはアクセス指定であって、関数定義じゃないよ〜

555 名前:デフォルトの名無しさん :01/11/27 22:08
>>550
> そうすると動的な配列が存在する場合にデストラクタによっ
> てメモリが開放されてしまいます。(元のソースでは"d"はポ
> インタになっていてコンストラクタで"new"している。)

このように実装すれば良い。

class MX{
  double* d;
public:
  MX(double x){ d = new double; *d = x; }
  MX(const MX& m){ d = new double; *d = *m.d; }
  ~MX(){ delete d; }
  MX& operator=(const MX& m){ *d = *m.d; return *this; }
};

556 名前:九州の学生 :01/11/27 22:21
>>551-555
迅速なレスありがとうございます。こんなに早く答えていただける
とは思いませんでした。
555さんのとおりconstをつけたらコンパイルできました。
C++では型のチェックが厳しいのを忘れておりました。

557 名前:デフォルトの名無しさん :01/11/27 22:31
これって、演算子は問題ないの?

558 名前:551 :01/11/27 23:31
>>554
あ、俺が間違い?
friend 宣言と同時に実体の定義もできるみたいだね。(VC6,g++)
知らなかった・・・

559 名前:デフォルトの名無しさん :01/11/28 09:02
>>545
ダイナミックキャストは出来る

560 名前:デフォルトの名無しさん :01/11/29 10:56
>>381
遅いレスで恐縮ですが、

> 実験してみたよ。
> VC++ だと、catchが参照なら、コピーコンストラクタ呼ばれない。
> catchが実体なら、コピーコンストラクタ呼ばれる。

これは、throw A(); というようにインスタンス生成と同時に throw
しているから、最適化が施されたんでしょうね。意味論上は、C++Builder
の場合と同じです。(g++ は C++Builder と同じ動作をした)

ふつうの関数でも

A foo()
{
  retunr A();
}

とやると、律義にデフォルトコンストラクタとコピーコンストラクタを
使うというようなことはせず、呼び出し側が用意したインスタンスの領域を
直接コンストラクトするような最適化がなされることがあります。

ちなみに、

void f()
{
 A a;
 throw a;
}

とやると、VC++ でもちゃんと(?)デフォルトコンストラクタとコピー
コンストラクタが呼ばれるようです。

561 名前:BUGMAKER :01/11/29 19:10
自クラスのインスタンスを明示的に他のクラスに
渡すのってどうすれば良いでしょうか?
Javaでいうところの、
OtherClass.setMyClass(this);
みたいにしたいのですが・・・

562 名前:デフォルトの名無しさん :01/11/29 19:26
>>561
C++ でも、それで良いけど。NULL チェック省くために参照にして

class OtherClass
{
public:
  void setMyClass(Foo& foo)
  {}
};

OtherClass.setMyClass(*this);

としたり、コンストラクタで渡すと吉。ただし Java と違って GC ないから、どこで
delete するかは要注意ね。

563 名前:デフォルトの名無しさん :01/11/29 20:06
>>561
C++ でも this 使えますが?
なにかマズイんですか?

564 名前:デフォルトの名無しさん :01/11/29 20:10
>>562
>C++ でも、それで良いけど。NULL チェック省くために参照にして

参照をそういう使い方してNULLチェックが省けるってのは、
考え違いだろ。
ポインタにNULLが入ってれば、参照でも結局クラッシュするし。

565 名前:デフォルトの名無しさん :01/11/29 20:12
>>564
そりゃあ NULL をデリファレンスしたヤツが悪い。

566 名前:デフォルトの名無しさん :01/11/29 20:17
>>565
言語と実行時環境で強制はしていないから、一種の紳士協定だわな。
ただしポインタを引数にとるメソッドでは、

- メソッドを呼び出す側、メソッド側どちらで NULL に対応すべきか明確ではない
 (ふつうはドキュメントに書いておく)

のに対して、参照だったら

- メソッドを呼び出す側が NULL をデリファレンスしないようにすべき

というのは明白になる。NULL が入ったポインタ p に対して *p ってコードを書いた
時点で、そいつのチョンボなのは間違いない。

567 名前:デフォルトの名無しさん :01/11/29 22:13
メソッドって、ひとつのメソッドを数箇所から呼び出すよね。
個人的にはメソッド側でチェックする方がスマートに感じるけどね。

568 名前:デフォルトの名無しさん :01/11/29 23:13
俺は参照の場合はヌルチェックしない。

ポインタの場合は、仕様からして NULL が正常値な場合はそれでいいとして、
そうでない場合は assert 書いてる。

569 名前:デフォルトの名無しさん :01/11/29 23:45
>>567
C++ でスマートといったら、スマートポインタ。

570 名前:デフォルトの名無しさん :01/11/29 23:48
スマートポインタじゃないけど、auto_ptr って、あまり使えないな。
こんなものわざわざ標準化した理由は何?

571 名前:デフォルトの名無しさん :01/11/30 00:02
>>570
exceptional C++読んでみて

572 名前:570 :01/11/30 00:17
ナニソレ?

573 名前:デフォルトの名無しさん :01/11/30 00:18
>>570
オブジェクトの寿命をスコープで管理しないと、例外に対して堅牢なクラスを作るのが
面倒だから。

auto_ptr が微妙に使いづらい面があるのは確かで、Boost.org でも shared_ptr, scoped_ptr,
shared_array, scoped_array なんてクラスを提供しているし、ATL だと CComPtr という COM
用の独自のスマートポインタクラスを提供している。用途によって自分でスマートポインタを
作るのは、常套手段ではあるよね。

574 名前:クロスゆるして(マルチ?) :01/11/30 00:21
今更だけど、ISAPIフィルタ作りたい。
良い資料/WEB等、無い???
作りたいのは、認証システム。
doc, xlsファイルとかだと、直にURLたたかれたら、ユーザチェック
できないでしょ?普通。
あ、win統合認証とかは使えない。
ユーザIDとパスワードたちは、DBに入ってるし。。。

MSのUSサイトいっても、イマイチ情報が古いし。

575 名前:デフォルトの名無しさん :01/11/30 00:23
>>574
っつか、スレ違い。

576 名前:デフォルトの名無しさん :01/11/30 00:27
>>574
単純に、直に URL を叩かせなければ良いんでわ。

577 名前:573 :01/11/30 00:27
ごめん、
どこいけばいいの???

578 名前:デフォルトの名無しさん :01/11/30 00:30
>>577
WebProg 板か、VC スレと思われ。

579 名前:デフォルトの名無しさん :01/11/30 00:46
あ、ここC++ってことはVCとはかぎらんのか。。。
逝ってきます

580 名前:デフォルトの名無しさん :01/11/30 03:55
環境: Win32 + STLport
スレッドAの関数a: コンテナfooに値を挿入/削除(クリティカルセクションCで保護)
スレッドBの関数b: コンテナfooの全ての要素にイテレータを使って順次アクセス/操作
コンテナfooはスレッドA&Bで共有。
aは任意のタイミングで呼び出され、bは定期的に呼び出される。

の場合、スレッドBの関数b全体をクリティカルセクションCで保護しなければ
ならないのでしょうか? 関数bがすぐ終わるならいいのですが、関数aがそれなり
に頻繁に呼び出され、bによってブロックされるのが好ましくないような場合、
bが長い時間かかると困ります。コンテナ全体の要素にアクセスしている途中で
イテレータが無効になったらそれを判断できればいいのですが。
他方、bのようにするのをやめてコンテナfooの要素それぞれがスレッドを持つ
ようにしたりすると効率上問題であると思います。
このような場合どうすればいいでしょうか。

581 名前:デフォルトの名無しさん :01/11/30 04:11
>>580
コンテナに格納する要素数と比較して、挿入/削除される要素数が少ないのなら

> スレッドAの関数a: コンテナfooに値を挿入/削除(クリティカルセクションCで保護)

これをスレッドAで直接行わず、挿入/削除するコマンドを生成して一旦キューに
貯めて、スレッドBで処理を開始する前にコマンドを実行するようにします。

ロックする単位を、要素数が多いコンテナから比較的要素数が少ないコマンドキュー
に移すわけです。

582 名前:580 :01/11/30 04:20
>>581
なるほど... コマンドキューへの出し入れを排他ロックするだけで
よくなるわけですね。キューなら個数だけ調べて先頭をポップする
だけで済むので、イテレートする必要もなくていいですね。
ありがとうございます。

583 名前:デフォルトの名無しさん :01/11/30 07:35
関数b で、コンテナ foo をコピーしてから使うという手もあるぞ。
コピーする一瞬はクリティカルセクションだけど、
コピーしてしまえばどんなに時間かけても大丈夫。
設計問題に絡むけど。

584 名前:デフォルトの名無しさん :01/11/30 07:46
両方のスレッドで同じキューを使っていたら、
キューに対する排他が必要だぞ。

585 名前:デフォルトの名無しさん :01/11/30 12:54
こんにちは、メモリの解放で悩んでいます。

取得は、、、
char* szBuf;
szBuf = new char [1024];

subFunc(szBuf);


で、sub()側で解放します

subFunc(char* pBuff)
:
:
delete [] pBUff;

ここで、deleteの後 []を付ける事は問題ないのでしょうか?
charの配列用のメモリを取得して、
charのポインタの配列用で取得したメモリを解放する。
これって問題ありますか?

586 名前:デフォルトの名無しさん :01/11/30 12:56
>>585
問題ないです。

587 名前:iku :01/11/30 13:09
はじめまして,ikuといいます。
いつも参考にさせて頂いています。
PathFileExistsでファイル検索をしたいのですが,
過去ログも拝見させて頂きまして,
MSも見て下記の様な記述をしたのですが
リンカーエラーPathFileExistsAが未解決といったエラーが生じて
しまいました。
他に何が必要なのか検討がつきません。
大変申し訳ないのですが,教えて頂けないでしょうか?

#include <windows.h>
#include <iostream.h>
#include "Shlwapi.h"
char chrPath[100];

sprintf(chrPath,"%s",Edit1->Text);
bool status = PathFileExists(chrPath);

588 名前:デフォルトの名無しさん :01/11/30 13:10
>>586
おお、即レスありがとうございます

589 名前:iku :01/11/30 13:25
こんにちは,ikuです。
PathFileExists(chrPath);
の件ですが,解決しました。
下記が原因だったようです。
お騒がせしました。
#includeプリプロセッサ指令はコンパイル前にその場所へ
そのファイルを挿入する指令です。

<shlwapi.lib> はテキストファイルではないので
#include で 取り込むことはできません。
これは shlwapi.dll を暗黙で使うためのインポート
ライブラリなので リンカに渡す必要があります。

C++Builderではリンクに使う指令があります
#pragma link "shlwapi.lib"
とソースファイル中に書くことによってリンカに
渡されます。

ただ、このままだと"shlwapi.lib"へのパスが
正しく張られていないので
[プロジェクト|オプション][ディレクトリ/条件]
の[ライブラリパス]に
$(BCB)\Lib\PSDK
を追加してください。

590 名前:デフォルトの名無しさん :01/11/30 13:25
>>587
shlwapi.libをリンクする必要があると思われ。

591 名前:亜美ちゃん ◆WOLFps4M :01/11/30 13:40
既出かもしれませんが、C言語しかしらないのにC++を使う仕事に今度入ります。
どのようなフローで勉強していくのが正しいでしょうか?

592 名前:デフォルトの名無しさん :01/11/30 13:53
>>591
優良書籍を紹介してるスレがあるから、そこでC++とオブジェクト指向の
本を探して読む。

593 名前:iku :01/11/30 14:03
こんにちは。
C++BuilderのTQueryについて教えて頂きたいのですが,
Databaseコンポーネントの様に
TQueryコンポーネントでSQLServerのUserIDとPasswordを設定する事はできないのでしょうか?

594 名前:デフォルトの名無しさん :01/11/30 15:04
>>591
デスマーチにはいりたくなかったら、現在出ている予定工数の1/5位を
C++の勉強に割り当てなさい。

習熟度に従って、開発効率やバグの発生頻度が大きく変わるからね。

595 名前:580 :01/12/01 00:03
>>583
>関数b で、コンテナ foo をコピーしてから使うという手もあるぞ。
>コピーする一瞬はクリティカルセクションだけど、
>コピーしてしまえばどんなに時間かけても大丈夫。

コピーにもそれなりの時間がかかりますので(コンテナの
要素全てがコピーされるので下手すると全要素をイテレートする
のと同様かそれ以上の時間がかかります)。
それにコピーされた要素に操作を行っても元のコンテナへ変更を書き
戻す手間が発生してしまいます。

>>584
>両方のスレッドで同じキューを使っていたら、
>キューに対する排他が必要だぞ。

581さんの話は両方のスレッドでコマンドキューを共有しな
ければ無意味な話だと思うんですが...?
これは582で
>なるほど... コマンドキューへの出し入れを排他ロックするだけで
と述べているように了解済みです。詳しく書けば、関数bでの先頭要素
の参照が終わった段階でのpopと、関数aで行われるpushとを排他する
ということです。

596 名前:デフォルトの名無しさん :01/12/01 00:38
>>585
問題はないですが、例外に対して脆弱になるのと delete[] を間違えて delete
と書くと検出しにくいエラーになるので、STL の vector や string を使うのが
おすすめです。

string というと「文字列」という印象がありますが、多くの実装では参照回数計
測によって不要なコピーを押さえた可変長配列として使うことも出来ます。

あと、標準ライブラリではないですが boost::shared_array も便利ですよ。
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

597 名前:デフォルトの名無しさん :01/12/01 00:40
メモリの解放で悩むレベルだったら、
とりあえず、new/delete malloc/freeでも
いいんでないかい?

598 名前:デフォルトの名無しさん :01/12/01 10:39
while(1)とwhile(true)とfor(;;)のどれが一番いいんですか?
どれも同じなのかな?

599 名前:デフォルトの名無しさん :01/12/01 11:10
独学で学んでるちびっこです。
たぶんものすごい初歩的な質問ですみません。

int a[5]
while(1) {
scanf("%d",&a[i])
i++
}

配列変数のサイズを超えても構わないような方法を教えて下さい。
別の int b[6] を用意して、a からそっくり移せばいいのでしょうか。

600 名前:599 :01/12/01 11:11
一応600ゲットしておきます。

601 名前:デフォルトの名無しさん :01/12/01 11:12
>>599
配列をたくさん取っておく

602 名前:Kusakabe Youichi :01/12/01 11:13
>>598 デフォルトの名無しさん wrote:
> while (1)とwhile (true)とfor (;;)のどれが一番いいんですか?
> どれも同じなのかな>

1つめと2つめはlintが文句いいますね。
出てくるコードはどれも同じでしょうけど。

603 名前:599 :01/12/01 11:15
>>601
ありがとうございます。
それ以外の上手い方法はないのでしょうか。

604 名前:Kusakabe Youichi :01/12/01 11:15
>>599 デフォルトの名無しさん wrote:
> int a[5]
> while(1) {
> scanf("%d",&a[i])
> i++
> }
> 配列変数のサイズを超えても構わないような方法を教えて下さい。
> 別の int b[6] を用意して、a からそっくり移せばいいのでしょうか。

だからscanfなんか使うな。

605 名前:デフォルトの名無しさん :01/12/01 11:15
>>598
どれも同じ。
while(1)は警告を出す処理系があるので、for(;;)がよい。
と思うが、なぜかwhile(1)が良いという人も根強くいる。

606 名前:デフォルトの名無しさん :01/12/01 11:16
>>599
vectorを使う。

607 名前:デフォルトの名無しさん :01/12/01 11:20
>>604
使ってもいいが戻り値は見ろ、だろ。
ボケ

608 名前:Kusakabe Youichi :01/12/01 11:22
> 607 デフォルトの名無しさん wrote:
> >>604
> 使ってもいいが戻り値は見ろ、だろ。
> ボケ

ぼけは自分でしょう。戻り値見ればscanf使ってもいいと思っているんだから:)

609 名前:デフォルトの名無しさん :01/12/01 11:22
>>607
戻り値見てもどうしようもない事もある。

610 名前:599 :01/12/01 11:29
申し訳ありませんが、「vector」についてもう少し詳しく教えてください。
検索しても例のページばっかり引っかかっちゃって。

611 名前:デフォルトの名無しさん :01/12/01 11:30
stl という単語を追加すれば?

612 名前:デフォルトの名無しさん :01/12/01 11:35
vector <int> a
while(1) {
a.push_back()
scanf("%d",&a[i])
i++
}

613 名前:599 :01/12/01 11:37
>>611
ありがとうございます。引っかかりました。

#include <vector>
vector<型> ベクタ名(サイズ);
ベクタ名.resize(サイズ);

これで解決しますでしょうか。
さっそく試してみます。

と思ったら >>612さんわざわざありがとうございます。
「push_back()」のあたりを調べてみます。

614 名前:599 :01/12/01 12:05
vector.hがないです。
VC++ 6.0なのですが。
どういうことでしょう。

615 名前:デフォルトの名無しさん :01/12/01 12:08
C++の標準ヘッダは拡張子つかないのが基本。
拡張子なしのvectorなら確実にあるはずだが。

616 名前:599 :01/12/01 12:13
ごめんなさい、vectorありました。

using namespace std;
この文を加えたらエラーが減ったんですが。
どうやら必要みたいですね。

617 名前:デフォルトの名無しさん :01/12/01 12:13
>>613
stl のリファレンスとして、オレはよく

ttp://www-scc.jst.go.jp/riyou/users/users_guide/ucoma/FJcompiler/C++/stdlib/stdref/index.htm

を利用させてもらってる。

618 名前:デフォルトの名無しさん :01/12/01 12:14
c:\Program Files\Microsoft Visual Studio\VC98\Include\VECTOR

619 名前:599 :01/12/01 12:33
>>617
参考になりました。ありがとうございます。
おかげさまで一応完成しました。
ただ>>612さんの方法で
a.push_up() にすると
「関数が不正な 0 個の実引数をともなって呼び出されました。」になっちゃいます。
カッコの中に適当な数を入れたらエラーはでなくなりましたが。
それがちょっと気持ち悪いですね。

620 名前:デフォルトの名無しさん :01/12/01 12:37
>>619
>それがちょっと気持ち悪いですね。

vector <int> a
while(1) {
int n;
scanf("%d",&n)
a.push_back(n)
}

621 名前:デフォルトの名無しさん :01/12/02 00:48
突然ですが暗黙な型変換を防止するには
どうやればいいんでしょうか?

ヒントだけでもいいのでおねがいします。(ペコリ

622 名前:名無しさん@Emacs :01/12/02 00:57
>>621
explicit の事か?
それとももっと本質的なところか?

623 名前:621 :01/12/02 01:05
>>622
レスありがとうございます

いや例えば、

void (bool test);
とかでfalseとかtrueとかを引数として持たすとして
普通の定数を入れてもコンパイル側はワーニングとして
でるじゃないですか。だからそれをエラーとして
コンパイルできなくしたいんです。
VCとかでそういう設定をかける以外ってないんでしょうか?

624 名前:デフォルトの名無しさん :01/12/02 01:09
>>623
cl のオプション /WX を使う。

625 名前:621 :01/12/02 01:23
>>624
すいませんclって何処の設定ですか?
探したんですけどみつからないです…

626 名前:デフォルトの名無しさん :01/12/02 01:35
>>625
cl.exe は Visual C++ のコンパイラ実行ファイル。

Visual C++ 統合開発環境で設定するなら、メニューから [プロジェクト] [設定]
を開いて、[C/C++] タブ [カテゴリ] 一般を選択、表示されるダイアログにある

[警告をエラーとして扱う]

にチェック入れる。もしくは [プロジェクトオプション] に直接 /WX って書いても
良いけど(ここに書いた文字列が cl.exe に渡される)。

627 名前:621 :01/12/02 01:41
>>626
ありがとうございます
無事できましたー

628 名前:名無し募集中。。。 :01/12/02 01:53

すいません、C++とVC++って何が違うんでしょうか・・・

629 名前:デフォルトの名無しさん :01/12/02 01:55
ビタミン入りかどうかの違い

630 名前:デフォルトの名無しさん :01/12/02 01:58
>>628
C++は言語の種類だがVC++は特定の商品の略称。
それともアレか? VC++のC++標準非準拠部分が知りたいのか?

631 名前:デフォルトの名無しさん :01/12/02 02:03
VC++はC++にWindowを付けたもの。

632 名前:名無し募集中。。。 :01/12/02 02:04
>>630
いや、単純にVC++ってVBみたいなのかなーとか思ったりしたもんで・・・
VC++でC++の開発もできるんですねー
ありがとうございます

633 名前:デフォルトの名無しさん :01/12/02 02:06
_

634 名前:デフォルトの名無しさん :01/12/02 02:16
>>632

最強のC++開発環境とうたっているしな。
あと、もちろんCのソースもコンパイルできるよ(でなければあんなの使わない)

635 名前:  ボーランドマンセー      :01/12/02 02:36
一般版とアカデミック版の価格差に
むかついているのでボーランドマンセーです。

636 名前:デフォルトの名無しさん :01/12/02 02:40
>>635

VS6.0Ent(アカデミック版)がVC++6.0Pro(通常版)の半値以下(笑)

637 名前:  ボーランドマンセー      :01/12/02 02:47
>>636
そうなんだよねー。
それで買う気が失せました。
学生を5000円でスカウトしようと
したら怪しまれて終わりました。

638 名前:デフォルトの名無しさん :01/12/02 15:17
constの使い方がいまいちよくわかりません。
誰かご教授おねがいできないでしょうか?

639 名前:Kusakabe Youichi :01/12/02 15:29
>>638 デフォルトの名無しさん wrote:

> constの使い方がいまいちよくわかりません。
> 誰かご教授おねがいできないでしょうか?

K&R 2ndにわかりやすく解説してありますよ。

640 名前:デフォルトの名無しさん :01/12/02 15:32
template <class T>
const T foo  :fooオブジェクト
const T &foo :fooオブジェクト
const T *foo :fooポインタの指すオブジェクト
T *const foo :fooポインタの位置
const T*const foo:上の両方
T::method() const :インスタンス変数
を、変更禁止とします。
(同時にconst_castなしでconstを剥がす事も禁止されます)

641 名前:デフォルトの名無しさん :01/12/03 00:00
テンプレートの export って、g++ でも VC++ でも、まだサポートされて
ないみたいだけど、テンプレートの定義を .cpp のほうにおきたいときって、
みなさん、どうしてますか?

やっぱり、ダミーの関数かなんかを作って、その中で、必要なテンプレート
引数を持った型を生成しておく、とかするんでしょうか。


foo.h:
template<class T> class Foo;

foo.cpp:
#include <foo.h>
template<class T> class Foo { .... };

void dummy()
{
  Foo<int> fooInt;    // 型 Foo<int> が生成される
  Foo<char> fooChar;   // 型 Foo<char> が生成される

}

642 名前:デフォルトの名無しさん :01/12/03 00:15
>>641
foo.cpp:
template<class T> class Foo { .... };

bar.cpp:
#include "foo.cpp"
void dummy() …

643 名前:642 :01/12/03 00:21
と軽くボケといて

test.h:
template<class T> class Foo {public: void test();}

test.cpp:
#include "test.h"
template<class T> void Foo<T>::test() {}

void dummy()
{
  Foo<int> a;
  a.test();
}

とかってこと?


> テンプレートの export って、g++ でも VC++ でも、まだサポートされて
> ないみたいだけど

「まだ」つーことは、そういう予定があるの??

644 名前:デフォルトの名無しさん :01/12/03 00:48
>>642
さらに、別の翻訳単位からも呼び出して、リンクできるようにしたい
わけです。

hoge.cpp:
#include "test.h"

int main()
{
  Foo<int> a;
  a.test();
}

とか。

> 「まだ」つーことは、そういう予定があるの??

「プログラミング言語 C++ 第3版」の p413 には、

他の翻訳単位からテンプレート関数にアクセスできるようにするためには、
テンプレート定義に明示的に export を宣言しなければならない

という一文があります。

645 名前:デフォルトの名無しさん :01/12/03 23:09
class A{
private:
int age;
double sage;
public:
A(int =0, double =0.0);
}

(1)のパターン
A::A(int a, double s): age(a), sage(s){}

(2)のパターン
A::A(int a, double s){
age = a;
sgae=s;
}

(1)と(2)はどう違うんですか?
またどっちを使った方がいいのですか?

646 名前:デフォルトの名無しさん :01/12/03 23:19
>>645
別に違わないが、(1)ならクラス内での宣言順通りに初期化しないと
コンパイラが警告くれる場合がある(ので(1)の方が厳格)

647 名前:デフォルトの名無しさん :01/12/03 23:29
>>645
(1)はメンバオブジェクトのコンストラクタで初期化。
(2)はoperator=で代入。

intにdoubleじゃどっちでも変わらんような気もするが。

648 名前:デフォルトの名無しさん :01/12/03 23:30
>>647
int,double以外の何だったら変わるんですか?

649 名前:デフォルトの名無しさん :01/12/04 00:08
>>648
コンストラクタ中で例外が発生すると、デストラクタが呼ばれない、ってのは
知ってる?

650 名前:デフォルトの名無しさん :01/12/04 00:09
(2)の場合、メンバ変数はデフォルトコンストラクタで構築された後、operator=で代入されるので、
デフォルトコンストラクタのコストが高いような場合だと差が出るかも。

651 名前:デフォルトの名無しさん :01/12/04 00:10
>>645
Effective C++ の12項を参照。

652 名前:デフォルトの名無しさん :01/12/04 00:49
>Effective C++ の12項を参照。

漏れなら Efficient C++ 2.4 をすすめるけどな

653 名前:デフォルトの名無しさん :01/12/04 02:36
exportが有効になるということは
プリコンパイル済みヘッダにテンプレートヘッダいれると
コンパイル早くなるということなんだが
結局exportが有効になっても大してコンパイル早くならないとおもふ。

654 名前:デフォルトの名無しさん :01/12/05 01:01
プリコンパイル済みヘッダ、云々の話は、正直よくわからないけど、
いい太古とはよくわかる。(IMEのバカめ)

使いたい型が最初から決まっている場合は、やはり、あらかじめ
生成しておくべき、ということでいいのかな。

655 名前:デフォルトの名無しさん :01/12/05 22:11
ちょっとあほな質問で申し訳無いが、
class A:
{
public:
 const int b;
};
のbってどうやって初期化するの?

656 名前:655 :01/12/05 22:12
まちがったage

657 名前:デフォルトの名無しさん :01/12/05 22:13
コンストラクタで初期化せえよ>>655
諦めてC言語でもやっとけ

658 名前:デフォルトの名無しさん :01/12/05 22:14
class A
{
public:
 const int b;
 A::A() : b(100){}
 A::A(int n) : b(n){}
};

659 名前:まちがい :01/12/05 22:14
class A
{
public:
 const int b;
 A() : b(100){}
 A(int n) : b(n){}
};



660 名前:655 :01/12/05 22:27
そうだった!どうもありがとう。
他に方法ないようねぇ?

661 名前:デフォルトの名無しさん :01/12/05 22:34
>>660
const_cast
mutable

662 名前:デフォルトの名無しさん :01/12/05 22:38
コレでconst_cast/mutableつかうのやつにはカワズ掛け。

663 名前:デフォルトの名無しさん :01/12/05 23:22
>>662
じゃ、こういうのはどうだ?

template <int NUM>
class A
{
public:
  enum { b = NUM };
  A()
  {}
};

A<100> a;

コンパイル時に値が確定してる必要があるけどね。

664 名前:655 :01/12/05 23:38
mutableってのがよくわからんー
なんで
mutable const int *a;
は出来て、
mutable const int a;
は出来ないわけ?

665 名前:デフォルトの名無しさん :01/12/05 23:42
const int を指すポインタ a は mutable である。
a は intで const で mutableである。

後者は矛盾しているが、前者は、そうでもない。

mutable int * const a;
はエラーになるだろ?
(未確認)

666 名前:デフォルトの名無しさん :01/12/05 23:55
>>665
mutable const int *a;

const は int にかかってるけど、mutable は a にかかってるのがミソだね

667 名前:デフォルトの名無しさん :01/12/05 23:59
記憶クラス指定子と同じ扱いだっけ?
ごめん、きちっとした規格書会社にしかおいてない。

668 名前:655 :01/12/06 00:00
なんとなく分かったが…
ややこしいなぁ。
って、655で言った
const int b;
の初期化ってmutableでは無理ってこと??
まぁコンストラクタかconst_cast使えば言い訳だけど。

669 名前:デフォルトの名無しさん :01/12/06 02:33
class A{
class B{
};
};
こういうクラス宣言があったとして。
この宣言をしてあるヘッダファイルを読み込まずに他のクラスでclass Bを使う(先行宣言する)の
ってできるのかな?

class A; //先行宣言
class A::B; //先行宣言?
class C{
A* a; //OK
A::B* b; //NG
};

670 名前:デフォルトの名無しさん :01/12/06 09:23
やってみたよ。
const int a;
const int *b;
mutable int c;
mutable int *d;
// const mutable int e;
const mutable int *f;
// const int * mutable g;
// mutable int * const h;
const int * const i;

671 名前:デフォルトの名無しさん :01/12/06 14:18
分かっていない質問で恐縮ですが、
コンストラクタとかデストラクタの定義をクラス外部に置いたとき、
inline付ける意味ってあるのでしょうか。
概念的に付けるのはおかしいのでしょうか。

672 名前:デフォルトの名無しさん :01/12/06 14:27
>>669
だめみたいだね。これに似てるけど、g++ だと、

template<class T> void foo()
{
 typedef T::B b;
}

なんてのも、templateのパース時にエラーになってしまう。
VC++ なら通るのに。

673 名前:669 :01/12/06 15:42
>>672
駄目なんかなあ。
その例だけど、
typedef typename T::B b;
ってやったら通らない?

674 名前:デフォルトの名無しさん :01/12/06 20:45
>>671
inline付けないとヘッダ(もちろんクラス定義の外ね)に書けない。複数のオブジェクト大るを
リンクするときに二重定義扱いされてしまう。それだけ。

675 名前:674 :01/12/06 20:46
オブジェクト大る>オブジェクトファイル

676 名前:デフォルトの名無しさん :01/12/06 21:09
>>671
class A{
public:
 inline A();
 inline ~A();
};
inline A::A()
{
}
inline A::~A()
{
}
って、こんな感じ?全然おっけーなはず。

inline 付ける意味は当然「我はインライン展開を望む」ってなことで、
外部に置くと何が嬉しいかというと、
クラス定義が多少見やすくなるってことかな・・・?

677 名前:デフォルトの名無しさん :01/12/06 21:40
>>676
class A {} の中の方には inline は不要

678 名前:デフォルトの名無しさん :01/12/06 21:40
>>676
> 外部に置くと何が嬉しいかというと、
> クラス定義が多少見やすくなるってことかな・・・?
A のメソッド中で B を使い、B のメソッド中で A を使うようなコードを書ける。

679 名前:671 :01/12/06 21:43
どうもありがとう。
私の目的はまさに>>676の最後の行なんですが、

1. クラスの中で定義した内部関数は自動的にinline関数になる。
2. 内部関数をクラス外部で定義する場合はinline関数にならない。
3. 2の場合、定義の方にinlineを付けるとinline関数になる。

だったような気がしていたのですが、最近友人に
『クラスの内部関数は自動的にinline関数になる』(外部で定義しても、という文脈)
と言われて、なにやらこんがらがってしまいました。
それでコンストラクタやデストラクタはどうなんだろうと思い
ウェブ上のソースファイルをいろいろ漁ってみたのですが、
コンストラクタとデストラクタをクラス外で定義して、
さらにinlineを付けているというものは見つけられず、
一般的ではない(無意味な)のかなぁと思っていた次第です。

とりあえず>>674を踏まえたら『付けないと駄目』みたいですね。

680 名前:デフォルトの名無しさん :01/12/06 21:50
>>679

inlineキーワードは、inline展開をするかどうか、
コンパイラがヒントとして使う。

つけないとダメかどうかは、コンパイラの性質による。

また、
コンパイラによっては付いていても展開しないし
コンパイラによっては付いていなくても展開する。
付いていても複雑な関数は展開しないし
付いていなくても単純な関数は展開する。

本当にinline展開されるのかどうかは、
つまり、コンパイルをしてみないと分からない、ということだ。

681 名前:デフォルトの名無しさん :01/12/06 21:55
>>677
ども。確信できなかったんで両方に付けてみた。
>>678
あぁ、そうか。そういえばそうだ。指摘サンクス。

682 名前:674 :01/12/06 21:58
でもとりあえず付けておけばコンパイル時に二重定義でエラーが出ることは
ないですよね?
# 自分の場合、たまたまクラスにtemplateを使っていたので
# inlineを付けなくても二重定義のエラーはでませんでした。
# もちろんtemplateがどうやって展開されるかもコンパイラ依存だと思いますが・・・。

683 名前:674 :01/12/06 22:16
>>682
「あれ? 俺何時の間に書いたっけ?」と思たーよ
>とりあえず付けておけば
だぁね。逆にソースの方に書く場合はinline付けない。

>>680
ちなみにMSVCだと__forceinlineてなキーワードもある。コンパイラオプション
でインライン展開の制御もできる。

684 名前:デフォルトの名無しさん :01/12/06 22:19
知ってるが、ここはまあ、一般的なことを話す場ということで

685 名前:デフォルトの名無しさん :01/12/06 23:04
デストラクタにインラインはやめとけ

686 名前:デフォルトの名無しさん :01/12/06 23:18
>>685
なんで?

687 名前:デフォルトの名無しさん :01/12/07 09:05
virtualにするから?

688 名前:671 :01/12/07 09:54
>>683
ごめんなさい。>>682を書いたのは671です。

>>685
もう一つ疑問が生まれました。
派生クラスを基底クラスとして扱った場合(base_class* base_ptr=new derived_class)、
デストラクタをvirtualにしておかないとうれしくないことが起こる、
というのは分かるのですが、この場合

class A{
 virtual ~A();
};

inline A::~A(){}

とするのは可なのでしょうか。

689 名前:デフォルトの名無しさん :01/12/07 09:59
>>680 おいおい、ヘッダ上のクラス外メンバ関数定義には
inlineつけないとダメだろ?リンクエラーじゃん。

付けても付けなくても実際にインライン展開されるかどうかは
コンパイラ次第というのはその通りだけどさ。

690 名前:デフォルトの名無しさん :01/12/07 10:08
>>688 それはヘッダ上の話かい?
ヘッダ上の話として「inline可」かつ「inline必須」だよ。
実際にはインライン展開されることは無いけどな。

でも普通は、class A { virtual ~A() {} }; と書くか、
CPP上に、inlineなしで A::~A() {} と書く。

691 名前:デフォルトの名無しさん :01/12/07 10:25
>>690
virtual なデストラクタのインライン展開は、スタティックバインドできる
なら可能なような気がするんだけど、どうでしょうか。

692 名前:671 :01/12/07 10:38
>>690
ヘッダ上の話です。すみません。

とりあえず胸のつかえが取れた気分です。
どうもありがと〜。

693 名前:672 :01/12/07 12:05
>>673
通った! そっかぁ、typename が必要なんだ。
勉強になりました。ありがとう。

694 名前:デフォルトの名無しさん :01/12/07 15:54
# include<stdio.h>

int aho( int i1 , int i2 , int i3 );

int main(int argc, char* argv[])
{
int iRet = 4 ;
int iRet2 = 0;
int iRet3 = 0;
int iVal = aho( iRet , iRet2 , iRet3 );

printf( "iRet = %d \n",iRet );
printf( "iRet2 = %d \n",iRet2 );
printf( "iRet3 = %d \n",iRet3 );
return 0;
}

int aho( int i1 , int i2 , int i3 )
{
i2 = i1 + 1;
i3 = i1 + 2;

printf( "i1 = %d \n",i1 );
printf( "i2 = %d \n",i2 );
printf( "i3 = %d \n",i3 );
return 0;
}

で、ahoの第2引数と第3引数に結果をmainに渡したいのだけど、
渡す方法がわかりません。どうすれば引数としてmainに戻せますか?
もちろん、戻り値で戻すのは知ってます。引数として値を戻したいん
です。

695 名前:デフォルトの名無しさん :01/12/07 16:00
>>694
C++なら、int aho(int a, int& b int& c)とすればいいよ。

696 名前:デフォルトの名無しさん :01/12/07 16:07
ネタニマジレスカコワルイ

697 名前:695じゃないが・・・ :01/12/07 16:23
>>696
おいおい、なんの話だ?694か?ネタ?あれ。

698 名前:690 :01/12/07 16:58
>>691 そだね。スタティックバインド可能な場合は
inlineつけとけばインライン展開される*かも*しれん。
でも、virtualデストラクタとしたクラスは、
普通は基底クラス型のポインタ経由で扱いたいわけで、
それで扱う限り、スタティックバインド可能な機会が無い。

699 名前:デフォルトの名無しさん :01/12/07 21:07
>>697
>>696がネタ、それにマジレスしている君はカコワルイ

700 名前:デフォルトの名無しさん :01/12/08 07:07
>>699
>>697がネタ、そ

701 名前:デフォルトの名無しさん :01/12/08 09:24
>>700
記念すべき700で何噛んでんだよ!

702 名前:デフォルトの名無しさん :01/12/08 11:40
>>701
>>700がネ(略

703 名前:デフォルトの名無しさん :01/12/08 16:49
かなりしらけたところで技術的な話に戻しましょう

704 名前:デフォルトの名無しさん :01/12/09 01:04
CからC++に移ってconst指定リファレンスはconst指定メソッドしか
呼べないというにハマって一時はめんどくせ〜って思ったけど、
const があるお陰でソースの可読性が飛躍的に上がった。

705 名前:デフォルトの名無しさん :01/12/09 01:08
可読性と同時にショボイミスが減るだろ。

706 名前:デフォルトの名無しさん :01/12/09 04:40
class B : public A {};
の B が、シングルトンになるような A は、どう書けばいいんですか?

707 名前:デフォルトの名無しさん :01/12/09 05:25
>>706
A、Bのコンストラクタは隠蔽して、Aにシングルトンインスタンス
用のハンドル置いておいて、Aの代理コンストラクタでBを作るよう
にすれば?

708 名前:706 :01/12/09 10:24
>>707
やってみました。動いてるみたいです。
こんな感じで良いんでしょうか?
できれば、もっと B の負担を減らしたいです。

Windows98 Mingw1.1 で確認しました。
とりあえずエラーチェック無しです。

#include <iostream>

class A
{
public:
  virtual ~A () { m_instance = 0; }

protected:
  A () {}
  static A* getInstance (A* (*newInstance) (void))
  {
    if (!m_instance)
      m_instance = newInstance ();
    return m_instance;
  }

private:
  static A* m_instance;
};
A* A::m_instance = 0;

class B : public A
{
public:
  static B* getInstance (void)
  {
    return dynamic_cast<B*> (A::getInstance (newInstance));
  }
  const char* getName (void) { return "B"; }

private:
  B () {}
  static A* newInstance (void) { return new B; }
};

int main (void)
{
  B* b = B::getInstance ();
  cout << "My name is " << b->getName () << "." << endl;
  delete b;
  return 0;
}

709 名前:デフォルトの名無しさん :01/12/09 14:20
そのメソッド名キモイ

710 名前:デフォルトの名無しさん :01/12/09 14:32
>>706
私なら template 使って書くかな。

template <typename T>
class Singleton
{
  static bool m_IsAlive;
protected:
  Singleton()
  {
    assert(!m_IsAlive);
    m_IsAlive = true;
  }
  ~Singleton()
  {
    assert(m_IsAlive);
    m_IsAlive = false;
  }
};

template <typename T> bool Singleton <T>::m_IsAlive = false;

template <typename T>
class A : public Singleton<T>
{};

class B : public A<B>
{};

711 名前:デフォルトの名無しさん :01/12/09 14:35
>>706-708
意図がよく分からん。何か、これだと、

B と同じような定義で class C : public A { … }; も定義すると、

C::getInstance();

は、先に生成した B のインスタンスを返してくれちゃうけど。

712 名前:デフォルトの名無しさん :01/12/09 14:48
>>711
いや、dynamic_cast やってるから、NULLだな・・・と、さりげなく突っ込んでみたり。
意図がわからんのは同感。

713 名前:706 :01/12/09 20:13
>>709
get〜 とかですか? instance や name の方が良いんでしょうか?

>>710-712
継承するだけでシングルトンになるクラスがほしかったんです。
>>707 さんの方針に従ってエラーを潰していくうちに、こうなって行ったので、
dynamic_cast とか良く分からないままです。
自分で考えていた時には、コンパイルも通っていませんでした。
複数のクラスで継承できないのは、継承したクラスのほうで dynamic_cast が 0 なら、
例外でも投げようと思っていましたが、出来ないのは変ですね。
template も良くは分かりませんが、何とかしてみます。

ありがとうございました。

714 名前:デフォルトの名無しさん :01/12/09 20:49
>>713
> 継承するだけでシングルトンになるクラスがほしかったんです。

こんなテンプレートでどう?

template<class T> class Singleton : public T {
private:
  static T *m_instance;

public:
  static T *instance();
};

template<class T> T* Singleton<T>::m_instance = 0;

template<class T> T* Singleton<T>::instance()
{
  if (!m_instance)
    m_instance = new Singleton<T>;
  return m_instance;
}

class B;
int main()
{
  B* b = Singleton<B>::instance();
  ……;
  delete b;
  return 0;
}

715 名前:714 :01/12/09 20:54
>>714
あれ? なんで new Singleton<T>; にしてたんだろ。

  m_instance = new T;

で問題ないよなあ。

716 名前:706 :01/12/09 22:07
>>714
どうも、ありがとうございます。

でも、Singleton<B>::instance() 以外では生成されなくするには、
どうしたら良いのでしょうか?

B のコンストラクタを protected に置いてみたら、

`B::B()' is protected

と怒られました。

717 名前:714 :01/12/09 22:33
>>716
あ、その質問で new Singleton<B>; にしていたわけがわかった (^^;

B のコンストラクタを protected にすると、B 以外 (B の派生クラスも含めて)
のインスタンスからは、明示的に B を生成することは出来なくなるんです。
だから、Singleton<B> からは、new B; はできない。ということで、
new Singleton<B>; にしてたんだな。ようやく思い出した。バカだ > おれ

んで、Singleton<B> のインスタンスとかは必要ないと思うので、Singleton の
デフォルトコンストラクタも private で定義しておくのが吉でしょう。

718 名前:デフォルトの名無しさん :01/12/09 23:48
>>713
> 継承するだけでシングルトンになるクラスがほしかったんです。
じゃあ >>710 の class Singleton で良いと思うが。

719 名前:706 :01/12/10 01:47
>>717
仰る通りにしてみたら出来ました。
ちょっと思ったんですが、B のデストラクタは virtual にした方が良いんでしょうか?
それとも、Singleton には static なものしかないので、必要無いのでしょうか?

>>718
>>713 の時点で、>>710 さんのクラスで思った通りの結果が得られました。
ですが、後学のために instance () からポインタを得る方法も、
自力で template を使って実装しようと考えていたんです。
言葉足らずでした。

720 名前:デフォルトの名無しさん :01/12/10 06:56
>>719
> ちょっと思ったんですが、B のデストラクタは virtual にした方が良いんでしょうか?
いいえ。

デストラクタを仮想化する必要があるのは

class A {};
class B : public class A {};

A* p = new B;
delete p;  // p は A* 型

こういう、基底クラスへのポインタに派生クラスのインスタンスが入っている場合。このときに
デストラクタが仮想化されていないと「p は A* 型、つまり ~A() 呼べば OK」となって問題が
発生する。

Singleton() の場合には、そもそも Singleton 型のポインタに対して delete を呼ぶことはあり
えない(それを保証するためにデストラクタを protected にしてある)から、デストラクタは非
仮想で OK。

721 名前:1 v(^・^)v :01/12/10 12:25
ご機嫌いかがか下僕ども。
Modern C++ Designをもう読んだろうな。
どうやらC++はもはやクラス階層自体をテンプレートで
定義できてしまうようだ。デザインパターンコミュニティを
すっかり黙らせて、過去のイディオムをすっかりひっくり返す。
この高級アセンブラもどきが最も進化した言語であるとは皮肉だな。
この点についてご意見を伺おうか。君はC++を畏れるのか。

722 名前:デフォルトの名無しさん :01/12/10 12:31
>>721
もう少しわかりやすく言え。

723 名前:クロスボウとやら :01/12/10 14:37
質問です。Win32プログラミングにはコールバック関数ってのが
出てきますが、こいつをクラスのメンバ関数にしたいと思います。
一般的(あいまいな定義ですが)にコールバック関数はPrivate、
Publicのどちらに定義した方がいいですか?Private派、Public派
の意見が聞きたいッス。

724 名前:デフォルトの名無しさん :01/12/10 15:27
どうせstaticにすんだろ? publicの方がいいんじゃないの。
オブジェクト指向と関係ないんだし無理するこたあない

725 名前:デフォルトの名無しさん :01/12/10 15:54
> 最も進化した

進化のなれの果て、だな。
アンモナイトが絶滅するときに奇形種が
さかんに出てきたのだが、ちょうど
そういう時期に相当するのだろう

726 名前:クロスボウとやら :01/12/10 16:03
>>724
そーなんだよね。レスサンクス。

727 名前:デフォルトの名無しさん :01/12/10 16:05
>>721
その本は読んでないが、

>どうやらC++はもはやクラス階層自体をテンプレートで
>定義できてしまうようだ

(partial) specialization を駆使する、てことか?

728 名前:デフォルトの名無しさん :01/12/10 16:21
>>725
その奇形種とやらがJavaやC#ですがなにか?

729 名前:デフォルトの名無しさん :01/12/10 16:26
>>728
突然変異と奇形は違うよ

730 名前:デフォルトの名無しさん :01/12/10 16:46
>>729
Objective-C支持者の方ですか?

731 名前:729 :01/12/10 17:03
質問の意味がわからん。
Objective-Cはキメラじゃないの?

732 名前:デフォルトの名無しさん :01/12/10 17:07
>突然変異
>奇形

コレって主観的評価じゃん。同じだろ。成功すれば突然変異、失敗すれば奇形。

733 名前:デフォルトの名無しさん :01/12/10 17:15
>>722
Modern C++ Design が面白かった、と言いたいのでは? 俺も読んだけど、確かに面白かったよ。

734 名前:デフォルトの名無しさん :01/12/10 17:42
>同じだろ。成功すれば突然変異、失敗すれば奇形。

違うよ。成功、失敗というレベルでの分類じゃないもん。

735 名前:デフォルトの名無しさん :01/12/10 17:58
>>734
どういう分類か書いてないから、何ともいえんが。判断基準を明記した方が実のある議論に
なると思われ。(ならくてもいーけど)

736 名前:デフォルトの名無しさん :01/12/10 20:19
突然変異は遺伝するけど、奇形は遺伝しないってイメージがあるなぁ。

737 名前:名無しさん@Emacs :01/12/10 20:30
んで,その Modern C++ Design って訳本無いの?
探したけど無いっぽい.
# 英語読めと言われたらそれまでなんだが…

738 名前:732 :01/12/10 21:07
>>736
そら劣等種は種を残せずに淘汰されるからそもそも遺伝できないだろうよ。
だから歴史の証明を待つまでは主観的評価、歴史の判定が下った後では
客観的評価だ。

C#は、さしづめJavaがC++とVBとObject Pascalに輪姦されてできた私生児って
とこかな 笑

739 名前:デフォルトの名無しさん :01/12/10 22:10
>>738
もうちょっとまともな例えは出来ないのか?
お里が知れるよ

740 名前:1 v(^・^)v :01/12/10 22:16
降臨したぞ下僕ども。
・・・なんだこのクソレスは(゚Д゚)y
>>727以外、言語名の英単語しか言ってないじゃないか貴様ら。
>>737よ、Modern...は英語簡単なのでがんばって読めよこの(゚Д゚)バカチン。
>>733なんかまだ全部読んでないだろ!(゚Д゚)

下僕どもは年明けまでにMore Exceptional C++のレビューしておくこと!!
あ、俺はSchemeやってっから。いやほんと。んじゃ。

741 名前:デフォルトの名無しさん :01/12/10 22:22
>突然変異は遺伝するけど、奇形は遺伝しないってイメージがあるなぁ。

生物科出身の漏れにはツッコミたいところだらけだが
我慢します。

742 名前:737 :01/12/10 22:25
>740
リョカーいした.簡単なら読んでみよう.でも漏れの英語力も相当低い・・・(蔚
その前に Exceptional C++ も読んだ事無い漏れは厨房か?
日々是勉強だのぅ・・・

743 名前:デフォルトの名無しさん :01/12/10 22:42
>>740
あんた微妙にスレ違いじゃない?
推薦図書スレでやれよ

744 名前:デフォルトの名無しさん :01/12/10 22:54
>743
いや,アソコはすぐ荒れるから C++ 関係の本はこっちでやっもいいんじゃん.
・・・っつーかむしろこっちでやって欲しい・・・

745 名前:デフォルトの名無しさん :01/12/10 23:04
>>739

Java「やめてっお父さん!!!」
C++「ふふふ、怖がることはないよ、安心しなさい...」
VisualBasic「ダンナ、犯っちゃっていいんですかい? ハァハァ」
ObjectPascal「Hejlsbergさんにも感謝しなけりゃな... 変態のおいらは後ろをっと」
Java「いっ痛いッッ!!! synchronizedだなんてッッッ!!」
C++「$unめ、Forteもっと使いやすくしろよ、64ビットだけじゃ満足できねぇんだよオラオラ」
VisualBasic「ぎ、ぎもぢええ〜プロパティプロパティ」

746 名前:1 v(^・^)v :01/12/10 23:16
>>743
C++スレでC++の本語らないでな〜にを語るんだこのバカチン(゚Д゚)め!め!
あっちはこっちで紹介されてる本参照してるんだよ!
これは言葉狩りですよみなさん!!
・・・つーかこのスレ立てたの俺だった!(゚Д゚)y

お前は最悪なのでInside OLE読破の刑なー!。なー!

747 名前:デフォルトの名無しさん :01/12/10 23:22
>>746
あなたのIMEは壊れてるんですか?

748 名前:デフォルトの名無しさん :01/12/10 23:38
>>746
こんごも、そのコテハンを使いつづけるようにな。ホットゾヌの NG ワードに指定するから。

749 名前:デフォルトの名無しさん :01/12/11 00:10
俺は意外と好きなんだがな…v(^・^)v

750 名前:デフォルトの名無しさん :01/12/11 02:51
"Modern C++ design"は出てすぐに読んだ。
自分がこれほどまでにtemplateの可能性を知らなかったとは、愕然!
template好きからtemplateオタクへ


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