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


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

C++相談室 part11
501 名前:500 :02/10/03 17:41
>map<string string>をtypedef
あ、これならスペースが無いとコンパイル通らないかも

502 名前:483=495 :02/10/03 18:03
>500
重ね重ね申し訳ないです。

>書き分けは意味なし気分次第でしょう
ま,マジですか…これで一週間悩んでますた。

だって,ポインタの説明の章で
int *p ,int* p のどちらの書き方でもかまわないが
本書では,int *pで統一します ってわざわざ断り書きしてあったの。
で,Vertex* これは何だ?と。
小○俊夫タンめ〜ヽ(`Д´)ノ

でもおかげでいろいろ勉強になりました。
コレ以上厨質問すると怒られそうなので,また自習に戻ります。
またどうしようもなくなったら来ますのでよろしくお願いします。

503 名前:デフォルトの名無しさん :02/10/03 21:53
声を録音するにはどうすればいいのでしょうか


504 名前:デフォルトの名無しさん :02/10/03 21:57
ラブホテルにコンクリートマイクを持ち込むといいんじゃないでしょうか


505 名前:デフォルトの名無しさん :02/10/03 23:15
>>503
馬鹿質?

506 名前:デフォルトの名無しさん :02/10/04 00:11
ヘッダファイルの基本的な書き方を教えてください。
実装とインタフェイスを分けて、実装が変わっても大丈夫なようにする
ハンドルを使うのが一般的なんでしょうか?

507 名前:デフォルトの名無しさん :02/10/04 00:13
>>503
スタート→プログラム→アクセサリ→エンターテイメント→サウンドレコーダ

508 名前:503 :02/10/04 00:16
もっと気の利いた回答を期待したのだがな。
洒落のわからんやつばかりだ。
もてねーだろ、おめーら。

509 名前:デフォルトの名無しさん :02/10/04 01:08
市ね508


510 名前:デフォルトの名無しさん :02/10/04 01:11
>>506
>実装とインタフェイスを分けて、実装が変わっても大丈夫なようにする

>ハンドルを使うのが一般的なんでしょうか?
の繋がりがよーわからん。

511 名前:デフォルトの名無しさん :02/10/04 01:13
ヘッダファイルの書き方とクラス・インターフェースの設計は別問題だとオモワレ

512 名前:デフォルトの名無しさん :02/10/04 01:21
>>506
「pimplイディオム」で検索すれ。

513 名前::02/10/04 06:20
あーMFCもままにならないままC#は出るしよお
DirectXはquaternionだしよ、わからねえっつうの
寝転がったままオナーニしたら精子飛び散るしよお
P4ねえからSSE2命令使えねえしデザパタも全然まだだし
かなりやることがあるのに全然消化できてない
鬱だよぉ(=;ω;)

514 名前:371 :02/10/04 06:35
誰か相手してクリ
>>371

515 名前: ( ´-`).。oO(なんでだろう……) :02/10/04 17:35
stlport\config\stl_msvc.hの中の
#define _STLP_NO_USING_FOR_GLOBAL_FUNCTIONS
をコメントアウトしたら、>>448のコードがコンパイルできるようになった。ほっほっほ。

516 名前:デフォルトの名無しさん :02/10/04 19:40
テンプレートの引数に応じて、コンストラクタの引数の数を変えることは可能ですか?
template<int N>
struct A
{
 template<int M>
 A();
 template<> A<1>(int x){}
 template<> A<2>(int x, int y){}
 A<N>;
};

A<2> a(1,2);
見たいなことなんですが。

517 名前:デフォルトの名無しさん :02/10/04 19:44
>>516
コンストラクタの多重定義、もしくはデフォルト引数では不足なのか?

518 名前:デフォルトの名無しさん :02/10/04 19:51
>>517
ベクトルを扱うクラスを自作してるんですが、
内部に持ってる変数をv[N]と定義してるため、
v[1]に対しA(int x, int y)が呼ばれてしまうのは都合が悪いです。


519 名前:デフォルトの名無しさん :02/10/04 20:51
WAVEファイルで取り込んだファイルの各瞬間の音の高さを知りたいのですが
なにか方法をご存知ですか?

520 名前:黒飴なめなめ♪ :02/10/04 21:02
知らん

521 名前:デフォルトの名無しさん :02/10/04 21:05
俺も知らん

522 名前:デフォルトの名無しさん :02/10/04 22:33
フーリエ変換しる!

523 名前:516 :02/10/04 23:26
>>517
+継承でそれっぽいのができました。
ありがとうございました。

524 名前:デフォルトの名無しさん :02/10/05 00:12
「C言語なら俺に聞け」スレで聞いたのですがC++じゃないか?と言われたので
ここで質問させてもらいます。

人から貰った関数の引数に double *&a というのがあるのですが、これって
どういう意味なんでしょうか?

525 名前:デフォルトの名無しさん :02/10/05 00:13
doubleポインタの参照

526 名前:デフォルトの名無しさん :02/10/05 00:47
>>525
thx!

527 名前:デフォルトの名無しさん :02/10/05 01:41
>>523
還元してください。

528 名前:516 :02/10/05 02:45
>>527
還元できるほどの大した事はやってないです。
派生先にB(int x) : base(x)、B(int x, int y) : base(x,y)…を用意して
基本クラスにN個とるコンストラクタが無ければエラーが出るようにしただけです。


529 名前:デフォルトの名無しさん :02/10/05 04:41
>>528
結果の重要性はともかく、
質問した時と同じくらいの情報が、そんなふうに結論として出ると、
なんとなく収まりがいいもんですな。

530 名前:デフォルトの名無しさん :02/10/05 07:24
解決した時に,たとえ自分のくだらないミスであったとしても
きちんと報告するのが良い質問者の姿勢です

531 名前:デフォルトの名無しさん :02/10/05 13:49
Linux で C++ を使い始めたのですが、シグナル処理のことで判らない
ことがあるのでお訊きします。

class foo {
...
void A();
void B(int signum);
...
};

void
foo::B(int signum)
{
(シグナル処理)
}

void
foo::A()
{
...
signal(SIGTERM, B);
...
}

というような構成ですと、コンパイル時に
no matches converting function `B' to type `void (*)(int)'
という文句を言われてしまいます。B を class foo の外の
関数にすると何も言われずにコンパイルが通ります。

foo 内だと何故駄目なのかよく判らないのですが...

532 名前:デフォルトの名無しさん :02/10/05 13:57
int n;

cin >> n;

cout << n << endl;

aを入力したら,変な数値が出てきたんだけど・・・
なぜに?

533 名前:デフォルトの名無しさん :02/10/05 14:02
>>532
単にnの初期化されて無い値がそのままでたんでは?
int n=893;とするとどうよ。

534 名前:532 :02/10/05 14:04
不正な入力があったら,値が代入されないんですね

535 名前:デフォルトの名無しさん :02/10/05 14:11
マニピュレータって覚えています?
あんまり必要なさそうなんで,やりたくないんですが

536 名前:デフォルトの名無しさん :02/10/05 14:30
>>535
大抵のマニピュレータは単なるシンタクスシュガーだ。
必要無さそうだと思うならやらなくて良し。


俺は使うけどな。

537 名前:デフォルトの名無しさん :02/10/05 14:34
>510
えーと、ハンドルクラスを使うと依存関係が少なくなると
いうのを本を読んだのですが、クラスの数が増えるのと
ややこしくなるため、ほんとにこんなことするのかなって
おもたのです。

>512
どうもありがとうです。

538 名前:デフォルトの名無しさん :02/10/05 14:47
>>531
一旦staticメンバ関数あるいは単なる関数で受けないとダメ

539 名前:デフォルトの名無しさん :02/10/05 15:29
>>531
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-32.2

540 名前:デフォルトの名無しさん :02/10/05 16:27
ファイル exception.h
(ここには例外処理が書いてある)。

ファイル classA.h
#include "exception.h"


ファイル main.cpp
#include <iostream.h>
#include "classA.h"
#include "exception.h"

みたいな事をしていいのでしょうか?
この場合、exception.hファイルがmain.cppに2回インクルードされていることに
なり、おかしなことになりますか?
何かいい方法があれば教えてください。

また、include等を詳しく説明したサイトがあれば、教えてくれると助かります。

541 名前:デフォルトの名無しさん :02/10/05 16:34
>>540
ちなみに、

#include <iostream.h>
#include <iostream.h>

とかやってみな。おかしくなんないだろ ?

<iostream.h> の最初の方に、

#ifndef _INC_IOSTREAM
#define _INC_IOSTREAM

と書いてあるので、上みたいに2回呼ばれた時にこれがどういう動作するのかよく考えましょう。

542 名前:デフォルトの名無しさん :02/10/05 16:35
インクルードガードでぐぐる。

543 名前:540 :02/10/05 16:41
>>541
てことは、exception.hは
iostream.hみたいにうまいこと書かなければ、なにかおかしいってことですか?

>>542
インクルードガードとは?

544 名前:540 :02/10/05 16:47
インクルードガード。初めて聞きました。
ありがとうございます。
検索して調べて、理解できました。

545 名前:デフォルトの名無しさん :02/10/05 16:48
>>543
> インクルードガードとは?

>>542 は、親切にもインクルードガードで「ぐぐる。」って書いてあるんだから、まずはその通りにしたら ?

546 名前:  :02/10/05 17:02
じさ

547 名前:デフォルトの名無しさん :02/10/05 19:11
>>545
ちょっと遅かったね

548 名前:540 :02/10/05 21:49
>545
すいませんした。

ついでに、またまたくだらない質問でもうしわけないですが・・・

class Samp
{
private:
int m;
double *p;
public:
Samp(){ m = 0; p = new double; }
Samp(int i) { m = i ; p = new double [i] }
~Samp() { delete [] p }
};

とやった場合、引数なしコンストラクタでのpを開放しようとしたら、

delete p;

となるが、上記のデストラクタでは、なっていない。
これは合法ですか?

549 名前:  :02/10/05 22:04
>>548
デストラクタでmで判定してdelete演算子を使い分ける。
もしくはSTLを使う。

550 名前:540 :02/10/05 22:06
>549
おお!使い分けですか!
単純なことなのに全然気づきませんでした。
ありがとうございます。

STLでうまいことできるんですか。調べてみます。

551 名前:デフォルトの名無しさん :02/10/05 22:08
>>548
double なら多分大丈夫だけど、クラスだったりしたらまずいと思う。

まあ、

Samp::~Samp()
{
 if(0 < m){
  delete [] p;
 } else {
  delete p;
 }
}

とするか、引数無しの時も m = 1 にして配列を確保してしまうのがいいかと思う。

552 名前:デフォルトの名無しさん :02/10/05 22:12
mがnew[]したかnewしたかを記録するためのものとは限らない。
そうしたいならせめてconst bool m;とかにしといてよ。

別にnew[]で統一すればいいのでは?


553 名前:552 :02/10/05 22:14
あ、mは配列の数なのね。const bool mは無し。


554 名前:  :02/10/05 22:23
mが確保したオブジェクトの数ならこうすべきでは?
Samp(){ m = 0; p = null; }
mが1で初期化されるときとmが0で初期化されるときで
オブジェクトの個数が同じく一つであることに問題が生じる
可能性があるかも。

555 名前:554 :02/10/05 22:26
または、
Samp(){ m = 1; p = new double[1]; }


556 名前:540 :02/10/05 22:40
>551
>552
ご意見ありがとうございます。

クラスならまずいということですが、次の場合はどうなんでしょう。

class Array{
private:
int m;
double *p;
public:
Array(){ m = 0; p = NULL }
Array( int i ) { m = i; p = new double [i] }
~Array(){
if( p != NULL) { delete [] p }
}
}

class ArrayDX{
private:
int m;
Array *p;
public:
ArrayDX( int i ){ m = i; p = new Array [i] }
~ArrayDX(){delete [] p}
}

何かいろいろし、ArrayDXのインスタンスを作成し、
メンバのArrayの配列もきちっと作成する。
の場合。ArrayDXでインスタンスを作成し、破棄したら、メンバのArray *pの
デストラクタはきちっと行われるのでしょうか。

557 名前:デフォルトの名無しさん :02/10/05 22:52
>>556
> ArrayDXでインスタンスを作成し、破棄したら、メンバのArray *pの
> デストラクタはきちっと行われるのでしょうか。

delete [] p; なら行われる。

つーか、new [] で確保したら delete [] するのが基本。
double で多分大丈夫と言ってるのは、大方の実装が大丈夫そうだからと言うだけのこと。
規格上はまずいよ。

558 名前:540 :02/10/05 22:56
>>556
ありがとうございます。

それは、オブジェクトポインタがスコープからはずれたら、
デストラクタが呼ばれて、そのなかにあるオブジェクトポインタ
のデストラクタもよばれて・・・・でいいのでしょうか?

559 名前:デフォルトの名無しさん :02/10/05 23:02
>>558
> >>556
> ありがとうございます。

自分に礼かよ !! と言う突っ込みは置いといて...

> それは、オブジェクトポインタがスコープからはずれたら、
> デストラクタが呼ばれて、そのなかにあるオブジェクトポインタ
> のデストラクタもよばれて・・・・でいいのでしょうか?

オブジェクトとポインタ って ? よくわかんないけど、

void foo()
{
 ArrayDX X(100);
 ...
}

で、foo() の終了時のこと言ってるなら、その通り。

560 名前:デフォルトの名無しさん :02/10/05 23:04
>>558
スコープから出れば「オブジェクト(を指している)ポインタ」のデストラクタは呼ばれるが、
「オブジェクトポインタの指すオブジェクト」のデストラクタは呼ばれない。

561 名前:531 :02/10/05 23:12
>>538-539
どうも有り難うございます。FAQ なんですね。適当な C++ の本を買って
きて手許に置いたほうがいいのでしょうかね。

562 名前:540 :02/10/05 23:13
>>559
あ・・・。ほんとだ、自分に・・・

>>559
>>560
ってことは

void foo()
{
ArrayDX *X = new ArrayDX(100);
...
delete [] X;
}

の場合は正確でしょうか?

すんません。おなじようなことばっかで

563 名前:デフォルトの名無しさん :02/10/05 23:23
>>562
X は配列を指していない。
この場合は
delete X;
が正しい。

564 名前:デフォルトの名無しさん :02/10/05 23:57
いい加減STLの使用をデフォルトにしようぜ。
必要なところだけ自分でメモリ管理すればいいじゃん。
Cでいちいち標準関数再実装してるようなバカがいないのを見習おう。

565 名前:デフォルトの名無しさん :02/10/06 01:32
double* p = new double [0];

NULLじゃないけどアクセスできないポインタ・・・鬱だ

566 名前:デフォルトの名無しさん :02/10/06 01:55
>>565
しかも、使えないのに delete[] p; としないとメモリリークになる。
なお鬱だ・・・・

567 名前:デフォルトの名無しさん :02/10/06 01:57
スマソ。pに何か別のポインタを代入しない限りメモリリークとは
言わないんですた。

解放し忘れとでも言うのかな。

568 名前:デフォルトの名無しさん :02/10/06 01:59
解放し忘れとメモリリークの違いを小一時間ほど講義していただきたい

569 名前:デフォルトの名無しさん :02/10/06 02:01
参加希望者ですが、
講義の場所と日時と費用を教えてください。

570 名前:デフォルトの名無しさん :02/10/06 02:08
>>565
そうなの???

571 名前:デフォルトの名無しさん :02/10/06 02:30
>>568
小一時間も解説するほどではないが。Effective C++にしつこいほど
繰り返し書いてある。

簡単に説明するとすれば、ある領域を指しているポインタがあり、いつ
でも解放できる状態であればメモリリークとは言わないらしい。

有効なポインタが他の値を代入することによって、その元のポインタ
が指していた領域を解放する手段が永久的に失われてしまった時、
初めてメモリリークと言うそうだ。

572 名前:デフォルトの名無しさん :02/10/06 02:39
配列の添字にマイナスが使えるようにする方法ってありませんか?


573 名前:デフォルトの名無しさん :02/10/06 02:41
>>571
で、解放し忘れとの違いは・・・

574 名前:デフォルトの名無しさん :02/10/06 03:05
>>573
解放し忘れであれば、deleteを書いてやればよい。しかし、メモリリークが
起きたポインタをdeleteすると、何が起きるかわからない。

575 名前:デフォルトの名無しさん :02/10/06 03:06
>>572
operator[] をオーバーロード。配列はクラスにする。

576 名前:デフォルトの名無しさん :02/10/06 03:07
>>574
自己レスです。「メモリリークが起きたポインタをdeleteしても、解放できない。」
でした。

577 名前:デフォルトの名無しさん :02/10/06 05:55
>>574意味がサッパリ。

578 名前:デフォルトの名無しさん :02/10/06 08:15
>>577
俺はなんとなく分かったけど…。

579 名前:デフォルトの名無しさん :02/10/06 08:26
>>578
deleteできないならもう開放済みなんじゃ?

580 名前:デフォルトの名無しさん :02/10/06 09:18
>>579
例えばの例。

char* p = new char[100];
p = 0;

pが指していたchar[100]の領域は、p = 0; とすることによって恒久的に
解放できなくなった。

581 名前:デフォルトの名無しさん :02/10/06 10:13
>>580
それ自体をメモリリークといいます

582 名前:デフォルトの名無しさん :02/10/06 10:17
ああ、「解放し忘れ」は行為で「メモリリーク」は状態か

583 名前:デフォルトの名無しさん :02/10/06 10:18
>>581
だからそう言っているのでは?

584 名前:デフォルトの名無しさん :02/10/06 10:20
char* p = new char[100];
// ここは(ある意味)開放し忘れ


p = 0; // この瞬間からメモリリーク

ということなのだと思われ。

585 名前:デフォルトの名無しさん :02/10/06 10:23
こう書けばいいかな?

char* p;
{
  p = new char[100];
}
// 開放し忘れ

---------------------------

{
  char* p = new char[100];
}
// メモリリーク

586 名前:デフォルトの名無しさん :02/10/06 10:24
インスタンスとオブジェクトの違いって何ですか?

587 名前:デフォルトの名無しさん :02/10/06 10:25
何度もすまん。
開放→解放

588 名前:デフォルトの名無しさん :02/10/06 10:45
>>586
インスタンスはクラスから生成されるもの
オブジェクトはクラスやインスタンスの総称

589 名前:デフォルトの名無しさん :02/10/06 10:56
>オブジェクトはクラスやインスタンスの総称

ほんと?


590 名前:デフォルトの名無しさん :02/10/06 11:03
objectとinstanceを英和辞典で引けば自ずとわかるかと。

591 名前:デフォルトの名無しさん :02/10/06 11:20
違ってたら恥ずかしいんだけど
クラスは「クラスというオブジェクト」という意味でしょうか?
お馬鹿な俺に教えてちょ。

592 名前:デフォルトの名無しさん :02/10/06 11:27
>>591
お!そこまで想像できるなら問題ないのでは。
JavaとかC#とかを触るとクラスもオブジェクトだなーというのが
実感できまっせ。

593 名前:デフォルトの名無しさん :02/10/06 11:32
インスタンスはメモリ上に確保されたオブジェクトの実態。
これであってる?

594 名前:デフォルトの名無しさん :02/10/06 11:38
>>593
誤解を恐れずに言うと、クラスはインスタンスの工場で、
生成されたインスタンスがどんなものかを全部しってる。

メモリに確保されるかどうかは言語や処理系次第ッス

595 名前:デフォルトの名無しさん :02/10/06 12:18
>>592
あ,合ってるんですか。嬉しいです。
C++だけの時はオブジェクト=インスタンスだったんですけど
Reflection触ってから>>591と思うようになったのです。

596 名前:デフォルトの名無しさん :02/10/06 12:34
>>594
メモリ上に確保されないインスタンスとは具体的に
どんなやつ?

597 名前:デフォルトの名無しさん :02/10/06 12:45
ある本でこんな説明を見たことがある

生地からドーナツを切り抜くところを連想してください。
この場合、生地がメモリ。
ドーナツを切り抜く型がクラス。
切り抜かれた部分そのものがインスタンス。
切り抜かれた部分にドーナツと名前を付けました、名前であるドーナツが
オブジェクト。

598 名前:デフォルトの名無しさん :02/10/06 12:46
ポリフォーリズムについて
これって何?

599 名前:デフォルトの名無しさん :02/10/06 12:48
>>596
(;´Д`)いやその・・・この手の話って
クラスにしろインスタンスにしろ、操作にたいする振る舞い、あるいは
それらどうしの関係についての話でしかないですヨ。

どのように実装するかについては各言語あるいはフレームワークで決めていただくと。
lisp系ならクラス定義もcell内の情報だろうし(違うかも)、
C++だとクラスそのものは実体が確保されないこともあるわけで。

600 名前:デフォルトの名無しさん :02/10/06 12:50
ポリフォーリズムに萎え

601 名前:ミッターマイヤー :02/10/06 13:32
C++でデザパタのファクトリーメソッドってどうやるのですか?
デザパタ本はJavaばっかりなので、わかりません。
既出だったらごめん。

602 名前:デフォルトの名無しさん :02/10/06 14:32
>>597
最後の一行だけ嘘っぽい・・・

603 名前:デフォルトの名無しさん :02/10/06 16:00
ポリフォーリズムage

604 名前:デフォルトの名無しさん :02/10/06 16:00
int data(int a,int b);
int data(int a, int b,int c=100);

data(100,200);

どうなりますか?

605 名前:デフォルトの名無しさん :02/10/06 16:15

[]演算子はオーバーロードできますが

double ClassA::operator[][](int i, int j)
ってできますか?

もしくはそれに類するクラスを2次元配列のように
あつかう方法とかありますか?

606 名前:デフォルトの名無しさん :02/10/06 16:16
>>604
どっちを呼び出せばいいかわからないから、コンパイルエラーになる。

607 名前:デフォルトの名無しさん :02/10/06 16:16
失敗するとゼロ、成功するとゼロ以外が返ってくる事がわかっている関数の返値で
(例えば文字列中にある文字が存在するか調べる関数)
失敗したかどうか条件判断を行いたい場合、比較とビット反転とどちらがスマートなんでしょうか?

int result = hoge(arg);
if (!result) cout << "ERROR" << endl; //ビット反転と
if (result == 0) cout << "ERROR" << endl; //比較

608 名前:デフォルトの名無しさん :02/10/06 16:22
>>607
==0 のほうがスマート
失敗すると偽、成功すると真が返ってくる関数なら ! のほうがスマート

609 名前:デフォルトの名無しさん :02/10/06 16:24
>>607
ビット反転演算子は、'!' じゃないよ、'~' だ。'!' は、論理否定演算子。

[A] > if (!result) cout << "ERROR" << endl; //ビット反転と
[B] > if (result == 0) cout << "ERROR" << endl; //比較

俺なら、成功した時の戻り値が数値的な意味をもっている (例えば文字列中にある文字が存在するか調べる関数で、成功した時は何文字目かを返すとか) なら、[B]
そうでない (単純に成功/失敗しか返さない) なら [A] でコーディングする。

まあ、好みの範疇だと思うよ。

610 名前:デフォルトの名無しさん :02/10/06 16:26
>605
二次元までで良いなら、今既にある配列クラスを
その配列クラスを返す[]演算子を持ったクラスで包む

class node //既にある配列クラス
{
 詳細略
 double operator[](int index);
};

class MyArray //既にある配列クラスを包括する二次元配列クラス
{
 詳細略
 node& operator[](int index);
 node m_node;
};


>605でやりたかったであろうアクセスを行うと、以下のように解釈される

MyArray[1][5] → (node)[5]

611 名前:605 :02/10/06 16:28
>>610
なるほど。ありがとうございます。

自己解決ですが、こんなんありました。

()演算子をオーバーロードする。
operator()(int i, int j)

こんな感じ

612 名前:デフォルトの名無しさん :02/10/06 17:22
「かならず継承してから使って欲しいクラス」ってC++的に書けますか?
デフォルトの振る舞いとかは全部あるんですけど、
絶対に包括じゃなくて継承して使って欲しいんです
もちろん基底クラスのメソッドを直コールするのもNGな雰囲気で・・・

無理なら無理でOKです

613 名前:デフォルトの名無しさん :02/10/06 17:25
>>612
コンストラクタをprotectedにする

614 名前:デフォルトの名無しさん :02/10/06 17:29
>>612
純粋仮想関数を基底クラスで作る。

615 名前:デフォルトの名無しさん :02/10/06 17:29
無料掲示板http://gooo.jp

616 名前:デフォルトの名無しさん :02/10/06 17:30
>>612
class ダミー派生クラス : public 直接使われたくない既定クラス {};


ダミー派生クラス obj;
obj.結局直接呼ばれる既定クラスのメソッド();

とかされてもOKですか?

617 名前:デフォルトの名無しさん :02/10/06 17:31
>>613
それだと
class Test :public base
としたとき
Test->base::hoge()
とかで基底クラスのメソッドを呼べちゃいませんか?
どうしてもTest->hoge()とさせたいんです

かといって、virtual base::hoge() = 0; では困るんです

618 名前:デフォルトの名無しさん :02/10/06 17:32
>616
そうですそうです
結局基底クラスが呼ばれていようと、派生クラスのメソッドにアクセスしてるように見えたいのです

619 名前:デフォルトの名無しさん :02/10/06 17:33
>>617
注文の理由が訳ワカメ。

620 名前:デフォルトの名無しさん :02/10/06 17:39
インターフェースと実装を分離すればいいんじゃない?

621 名前:デフォルトの名無しさん :02/10/06 17:39
>>617
Test->hoge();は桶で
Test->base::hoge();は駄目か・・・

全部のメソッドをprotectedで継承して
派生クラスでpublicなラッパを提供するしか漏れには考え付きませんが。

622 名前:612 :02/10/06 17:41
class Base
{
public:
 int hoge() {return 1};
};

class Test :public Base
{

};

int main (){
 Base A; //これはコンパイルエラーにしたい
 Test B;
 cout << B.Base::hoge(); //これもコンパイルエラーにしたい
 cout << B.hoge(); //これはSTDOUTに1を流したい
}

ということです

623 名前:612 :02/10/06 17:42
やっぱりかなり強引なことをしないと無理っぽいですか・・・
まだ設計段階なので無理なら無理でOKなんです

624 名前:デフォルトの名無しさん :02/10/06 17:45
クラスで、標準ライブラリの iterator(反復子)のように
*演算子関数を定義したとき、その演算子関数の戻り値のメンバに
-> を使ってアクセスすることは、可能ですか?

class X
{
public:
int m_x;
};

class Y
{
public:
X m_y;

X& operator*() { return m_y; };
};

Y y;

(X&) *y; //普通にアクセス ○
(*y).m_x; // X のメンバ にアクセス。○

y->m_x; //こういう書き方は可能 ?

625 名前:デフォルトの名無しさん :02/10/06 17:46
>>612
そういう設計にせにゃならない理由を是非お伺いしたいであります。

626 名前:デフォルトの名無しさん :02/10/06 17:46
>>624
無理じゃないかな・・・operator ->()が別にあるし

627 名前:デフォルトの名無しさん :02/10/06 17:49
>>623
> やっぱりかなり強引なことをしないと無理っぽいですか・・・
> まだ設計段階なので無理なら無理でOKなんです

何でそんなことが必要なん ?

628 名前:612 :02/10/06 17:53
>>625,>>627
自由度を狭める事で、逆にインターフェースを簡潔にできないかという目論みです
カスタマイズされることが大前提のクラスなので、なんでもできてしまうのはちょっと困るのです

629 名前:デフォルトの名無しさん :02/10/06 17:56
>>626
なるほどー
ありがとうございました。

630 名前:デフォルトの名無しさん :02/10/06 18:02
>>628
> カスタマイズされることが大前提のクラスなので、なんでもできてしまうのはちょっと困るのです

そのわりには、「結局基底クラスが呼ばれていようとも...」なの ?

一体誰から何を守りたいのかよく考えた方がいいと思うよ。

631 名前:デフォルトの名無しさん :02/10/06 18:04
class TestImpl{
public:
int hoge(){ return 1;}
virtual void LONGLONG_MEANLESS_FUNCTION() = 0;
}
class Test : protected TestImpl{
public:
virtual void LONGLONG_MEANLESS_FUNCTION() {};
};
で、Testを継承させるのはどうだ。

632 名前:デフォルトの名無しさん :02/10/06 18:05
カオスヘッダーから地球を守るにきまっとるだろうがヴォケが!

633 名前:デフォルトの名無しさん :02/10/06 18:05
>>630
多分

class Test : public Base
が、後々の変更で
class Test : public CustomizedBase
になる可能性もあるから、
直接
pTest->Base::hoge();
とかやられると、
基底クラスを変更したときに困る、とかじゃないかな

634 名前:デフォルトの名無しさん :02/10/06 18:06
あ、純粋仮想メソドの名前は、
THIS_CLASS_CANT_BE_INHERITED_DIRECTLY()
とかの方がいいかな。

635 名前:デフォルトの名無しさん :02/10/06 18:07
> 基底クラスを変更

ガクガクブルブル

636 名前:612 :02/10/06 18:15
>>630
誰からかは不明瞭ですが、守りたいのは「簡潔さ」です
「利用者の大半がカスタマイズするだろうし、もしかしたら自分もそのうちカスタマイズするかもしれんから
とりあえず継承しておけ」というクラスなんですが
かといって、「とりあえず継承はしたけど、どうせここは基底クラスを使ってるんだからTest->Base::hoge();でいいや」
とやられないようにしたい
後で結局カスタマイズした場合に、その部分を直し忘れてエラーになったりしないように

もちろん>>633みたいな怖ろしい事は考えていません

637 名前:デフォルトの名無しさん :02/10/06 18:18
>>631
そっちの話 (かならず継承してから使って欲しいクラス) は、>>613 で OK だと思う。
問題は、「基底クラスのメソッドを直コールするのもNG」の方だろ。

>>632
話の内容についてこれないなら書き込むな、ヴォケ。

>>633
クラスの仕様書に、「直コールは止めてくれっ。」と書いておけば、規定クラス名が変更された時に困るのは変なことしてる奴なんだから別にいいと思う。
どっちにしても、基底クラス名を変更したら継承している所は修正しないといけないしね。
そもそも、基底クラス名なんてそんな簡単に変更しないと思う。

638 名前:633 :02/10/06 18:22
まぁ、普通のクラスで基底クラスを変更するのはまれだろうけど、
Modernなtemplateプログラムしてると当たり前のように基底クラスは変わるよ。
あんまり怖がりなさるな、おのおの方。

639 名前:デフォルトの名無しさん :02/10/06 18:23
>637
「基底クラスのメソッド直コール」ってのは
> cout << B.Base::hoge(); //これもコンパイルエラーにしたい
ってことだろ。
なら、
class Test : protected TestImpl{

640 名前:デフォルトの名無しさん :02/10/06 18:24
あ、BaseとTestを間違えてたな。
class BaseImpl{...};
class Base : proteced BaseImpl{...};
class Test : public Base {...} ;
ってことで。

641 名前:デフォルトの名無しさん :02/10/06 18:34
>>638
> Modernなtemplateプログラムしてると当たり前のように基底クラスは変わるよ。

だから ? template 使ってるって自慢 (にもなってないけど) したいだけなのか ?

642 名前:612 :02/10/06 18:38
すみません、雲行きが怪しくなってきたので「多重継承とかしないと無理」って事で諦めます
何か修飾子付けるだけとか簡単な解決方法はあるのかなーと思っただけですので・・・

643 名前:デフォルトの名無しさん :02/10/06 18:38
>>641
635と636が怯えてるから、よくあることだと書いたまでですが

644 名前:デフォルトの名無しさん :02/10/06 20:36
おまいら、CppUnitとか使ったりしてますか。

645 名前:デフォルトの名無しさん :02/10/06 20:48
CppUnit+cocuppaこれ最強。


646 名前:デフォルトの名無しさん :02/10/06 22:59
3次元配列の領域を動的に確保する方法を
知っている方教えて下さい。お願いします。

647 名前:デフォルトの名無しさん :02/10/06 23:16
>>646
double*** p;

p = new double**[10];
for (int i = 0; i < 10; i++) {
p[i] = new double*[20];
for (int j = 0; j < 20; j++)
p[i][j] = new double[30];
}

double[10][20][30] が使える。

648 名前:デフォルトの名無しさん :02/10/06 23:22
>>646
もう少し簡単な方法。

double (*d)[20][30];

d = new double[10][20][30];

649 名前:646 :02/10/06 23:27
>>647
有難うございます。
2次元配列と同じ感じなんですね。
やはりポインタの理解が足りないな…


650 名前:デフォルトの名無しさん :02/10/06 23:28
すまん…ネタだと思ってた(鬱

651 名前:デフォルトの名無しさん :02/10/06 23:33
ここはC++スレですので、C++らしい解決をお願いします

652 名前:デフォルトの名無しさん :02/10/06 23:44
vector< vector< vector< double > > >か?
template< int N > class Nd_vector;を自作する話か?

653 名前:デフォルトの名無しさん :02/10/07 00:12
std::string の操作についてお聞きしたいのですが、

char hoge[10] = { ... };
string s( 10, '\0' );
memcpy( &s[0], hoge, 10 );

というのは有効な操作ですか? 有効である場合、これは

s.assign( hoge, 10 );

と同じ効果が得られるでしょうか。

654 名前:デフォルトの名無しさん :02/10/07 00:22
>>653
なんか2ちゃんでもcppllでもそんな話題ばかり見かけるなぁ。
なんでmemcpyなんてしたいんです?

> char hoge[10] = { ... };
なぜに { } なんだと小一時間…



655 名前:デフォルトの名無しさん :02/10/07 00:25
>>653
memcpyした場合の結果は保証されません。
push_backもしくはback_inserterを使うようにしましょう。

656 名前:デフォルトの名無しさん :02/10/07 00:34
やはりstd::vector使った方が楽でいいや。operator[]をオーバーロード
して多次元配列のクラス作ろうとしたけど、よくわからん。

std::vector<std::vector<std::vector<double> > > v;

v.resize(10);
for (int i = 0; i < 10; i++) {
v[i].resize(20);
for (int j = 0; j < 20; j++)
v[i][j].resize(30);
}

for (int i = 0; i < 10; i++)
for (int j = 0; j < 20; j++)
for (int k = 0; k < 30; k++)
v[i][j][k] = i * 600 + j * 30 + k;

for (int i = 0; i < 10; i++)
for (int j = 0; j < 20; j++)
for (int k = 0; k < 30; k++)
std::cout << v[i][j][k] << ' ';

657 名前:デフォルトの名無しさん :02/10/07 00:36
せっかくsize()メンバ関数があるのだから、このように書いた方がいいな。

v.resize(10);
for (int i = 0; i < 10; i++) {
v[i].resize(20);
for (int j = 0; j < 20; j++)
v[i][j].resize(30);
}

for (int i = 0; i < v.size(); i++)
for (int j = 0; j < v[i].size(); j++)
for (int k = 0; k < v[i][j].size(); k++)
v[i][j][k] = i * 600 + j * 30 + k;

for (int i = 0; i < v.size(); i++)
for (int j = 0; j < v[i].size(); j++)
for (int k = 0; k < v[i][j].size(); k++)
std::cout << v[i][j][k] << ' ';

658 名前:デフォルトの名無しさん :02/10/07 00:40
>>653
memcpyじゃなくてstd::copy

659 名前:デフォルトの名無しさん :02/10/07 00:43
非コンストにも使えるfor_eachって欲しくねぇ?
resize一気にかますときとか

660 名前:デフォルトの名無しさん :02/10/07 00:47
>>657
vector<vector<vector<double> > > v(10 ,vector<vector<double> >(20, vector<double>(30)));

661 名前:デフォルトの名無しさん :02/10/07 00:50
>>659
こんなのはダメなのか?

void square(int& elem)
{
elem *= elem;
}

std::for_each(coll.begin(), coll.end(), square);

標準C++ライブラリp317〜318より

662 名前:デフォルトの名無しさん :02/10/07 00:51
>>660
へえ〜、コンストラクタの結果をクラスの型として返せるのか。初めて知った。

663 名前:デフォルトの名無しさん :02/10/07 00:52
boost::multi_array<double, 3> array3d;


664 名前:デフォルトの名無しさん :02/10/07 00:53
>>662
どういう意味ですか?

665 名前:デフォルトの名無しさん :02/10/07 00:53
>>660
んー勘違いしていました。コンストラクタの結果をコンストラクタに
引き渡しているんですね。

666 名前:653 :02/10/07 00:55
>>654
つまり、memcpy と同じインタフェースを持つ関数があって、
それを使って string の内容を更新したいということなんです。
いったん、配列なり vector なりで受けてから、それを
string にコピーすればいいんでしょうが、2回コピーすることに
なるのがちょっといやかな、と思ったので。

>>655
s.resize(10) しておいてから memcpy でもだめなんでしょうか。
vector みたいに、&s[0] が配列を指す、という保証はないのかな。

667 名前:デフォルトの名無しさん :02/10/07 00:55
>>662
ん?
単に要素の初期化をしてるだけだけど。

668 名前:653 :02/10/07 01:16
>>655,>>658
ああ、そうか、std::copy なら begin() とか back_inserter() が
返すイテレータを使えるんですね。
やっぱり古くさいインタフェースを持つ関数は捨てて、ちゃんとした
ライブラリを作り直そうかな。

669 名前:デフォルトの名無しさん :02/10/07 01:58
コンストラクタにテンプレート使う↓のってOKですか?
class X {
publuic:
template<class T> X(T t){ ... }
};


670 名前:デフォルトの名無しさん :02/10/07 02:02
あり

671 名前:デフォルトの名無しさん :02/10/07 02:03
>>670
さんくす


672 名前:  :02/10/07 02:50
void int_return(const int &rf);

とかいう風にconstつけたりします?
っていうかconstついているようなものか
書いていてそう思いました

673 名前:デフォルトの名無しさん :02/10/07 02:53
>>672 一時オブジェクトを渡す可能性があるならconst必須
void hoge(const std::string& str);

...

hoge("this generates temporary obj.");

とかいう話ではなくて?


674 名前:デフォルトの名無しさん :02/10/07 03:01
>>673
そうか。
参照は,値を書き換えてもいいんでしたね。
constは,必要か
ポインタで渡すのは,文字列か構造体ですしね

675 名前:デフォルトの名無しさん :02/10/07 03:02
>>672
リファレンス渡しは値渡しよりも効率が良いが、呼び出し先で引数に
代入してしまうと呼び出し元の変数まで変更されてしまうので、
constをつけて、値が変わる危険性を避けつつ効率を維持できる。

676 名前:デフォルトの名無しさん :02/10/07 03:16
関数の引数ならconstポインタでもいいと思うがなぁ。

677 名前:デフォルトの名無しさん :02/10/07 03:18
>>676
呼び出し元で引数に&を付ける必要があるけどな。

678 名前:デフォルトの名無しさん :02/10/07 03:20
NULLを渡せないから参照なんて嫌だー!

ってそれがメリットか?

679 名前:デフォルトの名無しさん :02/10/07 03:21
>>677
それを言ったら、newしたオブジェクトを参照渡しするときは
*をつけなきゃいけないじゃん。

680 名前:デフォルトの名無しさん :02/10/07 03:35
漏れは値渡しの最適化とみなせる場合と例外のcatchの場合、それに
構文上必要な場合(コピーコンストラクタや演算子定義)はconst
参照にして、ポリモーフィズムを使う場合やオブジェクトの同一性
が問題になる時はポインタ渡しにしている。
このくらいが妥当じゃないかなあ。

681 名前:デフォルトの名無しさん :02/10/07 05:16
>>680
あと>>678も言ってるけどnullが来ることを許可したい時。

682 名前:デフォルトの名無しさん :02/10/07 05:19
>>678
またヌルヌル論争になるから null pointer って書いてくれ


683 名前:デフォルトの名無しさん :02/10/07 08:46
>>676-679
演算子のオーバーロードするときに、いちいち
&つけるのかっこ悪いじゃん。

684 名前:デフォルトの名無しさん :02/10/07 10:42
漏れも680とおんなじ感じかな。
構造体の場合はほとんど全部"値渡しの最適化"とみなせるのでたいていは参照、
std::stringとかみたいな値重視のクラスも参照、
ポリモーフィックなクラスの場合ポインタ使ってるっぽい。

685 名前:デフォルトの名無しさん :02/10/07 21:04
例えば

template<typename value_type>
value_type TypeAdjast(const (void*)& value) {
 return boost::lexical_cast<value_type>(value);
}

int a = 100;
string s;
s = TypeAdjast(a);

みたいにして、関数の返値が格納される先(左辺値)の型に応じて
返す型を変える関数って作れるものなんでしょうか?

686 名前:デフォルトの名無しさん :02/10/07 21:08
そもそもC++は
int foo();と
string foo();は同時に存在できなかったはずだけど、、

687 名前: :02/10/07 21:25
>>685
s = TypeAdjast<string>(a) のように呼べば作れるけど、
そういうことじゃないよね?

688 名前:デフォルトの名無しさん :02/10/07 21:35
>>687
やっぱりそうなりますか・・・

テキストで保存してあるデータを
型に合わせてロードする関数を考えているんですが
std::string LoadDataAsStr();
int LoadDataAsInt();
unsigned int LoadDataAsUInt();


みたく型毎に関数用意したり、とか
やたら型キャスト使ったり、とかが鬱陶しいので
できるだけスマートに書けるようにしたいのであります

やっぱり左辺値の型情報を渡して
それに合わせてロードするようにするのが一般的ですか

689 名前: :02/10/07 21:45
>>688
TypeAdjast(s, a) とすればいいんじゃ?
adjastってのもかなりかっこ悪いが。

690 名前: ◆hMJAPH9PWA :02/10/07 21:54
>>688
IOStream風でいいじゃん。

class mystream;

template <typename Target>
mystreamr& operator >>(mystream& s, Target& target)
{
// ...
return s;
}

void f(mystream& s)
{
int i;
std::string str;
s >> i >> str;
}

691 名前:デフォルトの名無しさん :02/10/07 22:26
1| 10
2| test string
3| 5.003

というデータに対して

string s1 = GetData(1行目);
string s2 = GetData(2行目);
int a = GetData(1行目);
float f = GetData(3行目);

としたときに

s1 = "10"
s2 = "test string"
a = 10
f = 5.003f

とできるようなGetData()の実装は「無理」って事ですか?
もちろん

int b = GetData(2行目);

は「危険なキャスト」として例外投げてかまわないんですが・・・

692 名前:デフォルトの名無しさん :02/10/07 22:34
>>691
危険なキャストっていうか、「不可能なキャスト」と決めつけてしまってもOKなわけですが

693 名前:デフォルトの名無しさん :02/10/07 22:37
GetDataの戻り値をVariantな型にして、
そのVariantな型から各型へのキャストを
書けば、実現できるかも。
つまり、
class Variant { string data;
public: operator int(){ ...}
operator double(){ ...}
};
で、Variant GetData(int line);とか。

694 名前:デフォルトの名無しさん :02/10/07 22:47
なぜNULLを「ぬる」と読むのかさっぱりわからない。
ずっと「なる」だと思っていたし、周りに聞いてもみんなそう言う。
「ぬる」はここへ来て初めて知った・・・ドイツ系の人が広めたのでしょうか?

695 名前:デフォルトの名無しさん :02/10/07 22:48
↑ネタですぅ

696 名前:デフォルトの名無しさん :02/10/07 22:48
>>693
ごめんなさいわかりません・・・
最終的な利用方法は
string s = (int)GetData(1行目)
ということですか?

この関数の目的の大部分は、キャストしないで利用できるようにすることなので
もし上記のようなら無理に1つの関数にまとめる必要は無いのです・・・

697 名前:デフォルトの名無しさん :02/10/07 22:49
>>694
NULLの所へback_inserterと読みます。
「ぬるぬるの所へバックから差し込む」

698 名前:デフォルトの名無しさん :02/10/07 22:51
694の想像力 = NULL;

699 名前:デフォルトの名無しさん :02/10/07 22:52
おれはNumberをヌムバーと読んでいる。

700 名前:デフォルトの名無しさん :02/10/07 22:56
>>699
「ぬむべる」の間違いでは?

701 名前:デフォルトの名無しさん :02/10/07 23:05
>696
せめてこれくらいのテストはしてから、そういうことを言ってほしい。

#include <stdio.h>
struct Variant{
 operator int() { return 1;}
 operator double() { return 2.0;}
};
int main(){
 Variant v;
 int i = v;
 double d = v;
 printf("%d, %f", i, d );
}

702 名前:デフォルトの名無しさん :02/10/07 23:05
一生懸命考えて必死に質問してるのに
クソどうでもいいレスに流されるとホント腹が立つ





はっ・・・漏れの質問も同じくらいどうでもいいのか・・・

703 名前:デフォルトの名無しさん :02/10/07 23:05
>>700
すげー

704 名前:デフォルトの名無しさん :02/10/07 23:07
>>702
申し訳ない。ところで君の質問はどれよ。

705 名前:デフォルトの名無しさん :02/10/07 23:08
>>701
おお・・・すみません・・・

ということは、それくらい明らかな実装だと
既に標準ライブラリや準標準ライブラリに
同じ様な汎用型に関する取り扱いがあったりはしないのですか?

「自分のコードが一番信用できない」ってのがポリシーなので
既にあるならそっちを使いたいです

706 名前:デフォルトの名無しさん :02/10/07 23:10
>>704
>>685からの一連のヤツです・・・

707 名前:デフォルトの名無しさん :02/10/07 23:14
>>706
すでに>>690までで解決しているのかとおもてた。

708 名前:デフォルトの名無しさん :02/10/07 23:15
>>706
ちゃんと流されずに詳しい人にレスもらえてるじゃん。
おれはパスだが、、

709 名前: :02/10/07 23:26
>>693
つーことは、

class GetData {
 const char *s;
public:
 GetData(const char *s_) : s(s_) {}
 operator int() const {return boost::lexical_cast<int>(s);}
 operator float() const {return boost::lexical_cast<float>(s);}
 operator double() const {return boost::lexical_cast<double>(s);}
 operator const char*() const {return s;}
 //operator std::string() const {return boost::lexical_cast<std::string>(s);}
 // 以下省略
};

とかやっておけば、

int i (GetData("123"));
double j (GetData("234"));
std::string k (GetData("345"));

てな感じで呼べるわけやね。

710 名前:デフォルトの名無しさん :02/10/07 23:29
ややこしくなってまいりました・・・
じっくり理解して実装してみます
ありがとう

711 名前:デフォルトの名無しさん :02/10/07 23:35
なぜそこでテンプレートを思いつかないかなぁ。

template<class T>
operator T() const { return boost::lexical_cast< T > ( s ); }

712 名前: :02/10/07 23:41
>>711
通らないタコなコンパイラがあるんだからしょうがないだろ。

713 名前:デフォルトの名無しさん :02/10/07 23:47
>712
boostは通るのに、711のテンプレートは通らないと?

714 名前: :02/10/08 00:03
>>713
なんといってもVC++だからな。VC6だと全く動かないコードになら
コンパイルできるが、VC7はコンパイルさえ通らん。

715 名前:名無しさん@Emacs :02/10/08 00:04
>>705
>「自分のコードが一番信用できない」ってのがポリシーなので
>既にあるならそっちを使いたいです
ワラタ

716 名前:はt :02/10/08 00:49
EXEからDLLに関数をエクスポートする場合
双方のライブラリをリンクしなきゃいけないと思うんですが
どうやってライブラリを作るんでしょうか?

717 名前:デフォルトの名無しさん :02/10/08 00:54
BCB なら、コマンド・ラインから、
implib hoge.dll


718 名前:デフォルトの名無しさん :02/10/08 00:54
>>705
CppUnit をお使いなさい。


719 名前:デフォルトの名無しさん :02/10/08 00:56
>>716
C++では名前のマングリングが起こるので、序数で呼び出す方がいいかも
しれない。
どうしても名前で呼び出すには、一度アセンブル出力して、そのラベル名
を書く。

720 名前: :02/10/08 01:12
>>716
最初はリンクでエラーになるが、.libは出来ているという罠。

721 名前:デフォルトの名無しさん :02/10/08 01:16
そういう時は素直にGetProcAddressつかおうよ

722 名前:デフォルトの名無しさん :02/10/08 01:27
class variant {
public:
 variant(const std::string& in_value) :value(in_value) {}
 ~variant() {}
 operator const char*() const { return value.c_str(); }
 template <typename value_type>
 operator value_type() const {
  return boost::lexical_cast<value_type>(value);
 }
private:
 const std::string value;
};

variant GetData(データ格納先) {
 return variant(データ);
}

という実装を試してみたんですが

int a = GetData(データ格納先); // safe
string s = GetData(データ格納先); // abnormal termination
const char* lpstr = GetData(データ格納先); // lexical_cast内部でコンパイルエラー

となってしまいした・・・
引数の場合はテンプレートに対して型を明示してやればオーバーロードできたのですが
キャストオペレータ(て言うのかな)の場合はうまく特殊化できないようなのです
なにか解決策はありますか?

環境はBCC5.5.1+BCC添付のSTL+BOOST1.28

723 名前: ◆hMJAPH9PWA :02/10/08 01:45
ソースを見れば分かるけど、lexical_castでポインタ型には変換できないよ。

//少しだけ簡略化してます
template<typename Target, typename Source>
Target lexical_cast(Source arg)
{
std::stringstream interpreter;
Target result;
if(!(interpreter << arg) || !(interpreter >> result) ||
!(interpreter >> std::ws).eof())
throw bad_lexical_cast();
return result;
}

メモリを確保していないchar*型の変数resultには代入できないからね。

解決策はoperator char*()を定義して中でnew[]すればいいんだけど、
operator char*()を(暗黙的でも)呼び出した場合に必ずdelete[]しなきゃいけないのは大変だから、
std::stringだけ使っておくってのが正解かもね。

724 名前:デフォルトの名無しさん :02/10/08 01:55
>>723
それは理解しています(というか身を以て体感しました・・・)
なので、>>722の5行目で

 operator const char*() const { return value.c_str(); }

として、ポインタを要求された場合はvalueの直データを渡すようにさせたいのですが

 const char* lpstr = GetData(データ格納先);

と明示的にconst char*型を要求しても、テンプレートが適用されてエラーになってしまう
という問題です
さらに具合が悪いことに、

 operator std::string() const { return value; }

としても、やはりテンプレートが適用されてしまいます

どうしたらいいんでしょうか・・・

725 名前:デフォルトの名無しさん :02/10/08 01:56
ちなみに今boost::anyで実装できないか試していて更に混乱中・・・

726 名前:デフォルトの名無しさん :02/10/08 01:57
>>724
template<> char const* operator char const*() const{ return value.c_str(); }

とかでできない?想像だけれども

727 名前:デフォルトの名無しさん :02/10/08 02:06
>>726

 エラー E2036: 変換演算子には戻り型を指定できない

コンパイラがおっしゃる意味を理解できないのがツライ・・・

728 名前:デフォルトの名無しさん :02/10/08 02:10
>>727
わぉ
すまんすまん
template<> operator char const*() const{ return value.c_str(); }

729 名前:はt :02/10/08 02:10
>>721
たとえばEXE の中で
void Func(int,int);
と宣言されてたら、
void (*PFunc)(int,int);
と宣言して
PFunc = (void (*)(int,int))GetProcAddress( naninani , "Func");
とする。

こんなんですか?

730 名前:デフォルトの名無しさん :02/10/08 02:22
いいえちがいます

731 名前:デフォルトの名無しさん :02/10/08 02:23
>>728
ダメです・・・template<typename value_type>が適用されまする・・・

732 名前:デフォルトの名無しさん :02/10/08 02:27
そういうテンプレートの使い方をしてはいけないコンパイラだったと
諦めて、 operator long() ... operator char()... operator double()...と
列挙するとか。コンパイラ代えてみるとか。

733 名前:デフォルトの名無しさん :02/10/08 02:30
>>729
__stdcall

734 名前:デフォルトの名無しさん :02/10/08 02:31
>>729
どうするかは場合によりけりだと。

俺はDLLをプラグインとして使うことが多いから、
DLL内の関数はEXE側がGetProcAddressを使って自力で取得、
その関数を経由してEXE側の関数をEXEに渡す、てのをよく使う。

個々の関数をいちいちGetProcAddressすんのは面倒だから、
エクスポートすんのは、DLLの全機能を提供するクラスのインスタンスを返す関数ひとつだけにして、
あとはそのインスタンス経由でいろいろするのが楽。

735 名前:デフォルトの名無しさん :02/10/08 02:32
>>732
了解しました・・・
型列挙で対応します
(BCCタダで使わせてもらってるから文句は言えない・・・)

736 名前:デフォルトの名無しさん :02/10/08 02:38
VCなんで試せませないのと、boostわからんのでLokiですが、

template<typename T>
operator T()
{
 return Loki::TypeTraits<T>::isPointer ? spec_ptr<T>() : boost::lexical_cast<T>(value);
}

template<typename T>
T spec_ptr()
{
 return 云々;
}

のようにエラー起きるのだけ特化させるのはどうですか?

737 名前:736 :02/10/08 02:58
× VCなんで試せませないのと
○ VCなんで試せないのと

boostだと、
template<typename T>
operator T()
{
 return boost::is_pointer<T>::value ? spec_ptr<T>() : boost::lexical_cast<T>(value);
}
ですかね。

738 名前:デフォルトの名無しさん :02/10/08 03:03
あら・・・タイプトレイツって実行時に判断できるんですか・・・
コンパイル時チェックだと思いこんでた

739 名前:736 :02/10/08 03:23
>>738

コンパイル時チェックですが、関数もテンプレートなので・・・
なので、コンパイル後条件式は消えます

740 名前:デフォルトの名無しさん :02/10/08 03:23
おまいら、C++でなにつくってるんだ?

741 名前:デフォルトの名無しさん :02/10/08 03:41
>>739
三項演算はマクロじゃないので実行時に判断されませんか?

742 名前:デフォルトの名無しさん :02/10/08 04:10
三項演算は定数扱う限りはOKだと思うけど。

743 名前:デフォルトの名無しさん :02/10/08 10:21
>740
自己を満足させる心


744 名前:デフォルトの名無しさん :02/10/08 12:47
デストラクタで delete 処理するのはいいのですが、割り込み等などで
終了させられた場合、メモリはちゃんと解放されるのでしょうか

745 名前:名無しさん@Emacs :02/10/08 13:07
>>744
SIGKILLのことですか?
だとしたらOSがメモリを強制的に開放するんじゃなくて?

746 名前:744 :02/10/08 14:16
>>745
すみません、環境を書いていませんでしたね。おっしゃるとおり UNIX 系での
シグナルを想定していました。

やはり OS が解放してくれるのでしょうか。そうでないと安心できない気がしますが。
C で書いていた頃はそうでもなかったのですが、C++ で書くようになって気になり
始めました。自動的にデストラクタを呼んでいるわけでもなさそうですし。

あるクラスのインスタンスを一つ生成し、それがイベントループを廻し続けるような
プログラムを書いているのですが、この場合デストラクタが呼ばれることがあるので
しょうか。

747 名前:デフォルトの名無しさん :02/10/08 14:17
メモリリークなんてなぁプロセスが終了しちまえば一発で解決なんだぁよ
制限がキツイとか常駐ソフトとかでもないかぎりあんま気にすんなぁ

748 名前:名無しさん@Emacs :02/10/08 14:44
むしろ個別にFreeすると終了処理が長引くので、
Freeしないで終わるようにする定石もあるらしい。
Windowsだとちょっと心配だけど、UNIXなら問題
ないのではないでしょうか?

749 名前:デフォルトの名無しさん :02/10/08 14:52
ま た m a l l o c & f r e e で す か。

deleteは忘れるなよ。

750 名前:デフォルトの名無しさん :02/10/08 14:59
borland c++ から c++builderへ.rcファイルごと移行したいのですが、どうすれば良い
ですか?


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