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


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

C++相談室
501 名前:デフォルトの名無しさん :2001/05/25(金) 12:30
>>500
struct B;
class A {
struct B *hogehoge();
};
struct B {
A foobar;
};

502 名前:デフォルトの名無しさん :2001/05/25(金) 14:07
>>501
ああ、なるほど!
さんきゅ〜〜!

503 名前:デフォルトの名無しさん :2001/05/25(金) 15:34
> v(^・^)v

殺したい。

504 名前:デフォルトの名無しさん :2001/05/25(金) 19:25
設計をみなおす。相互参照は少ないほどよい。

どうしても必要であれば、「前方宣言」で調べてみるべし。

505 名前:デフォルトの名無しさん :2001/05/25(金) 20:34
>>504
それで設計見直してたらオブジェクト志向
の精神からはずれてしまうと思われ

506 名前:デフォルトの名無しさん :2001/05/25(金) 21:53
>>498
一部がインラインアセンブラになるくらいで書けます。
C++でRTOSを自作したことはあるから、
あとはこれの規模を大きくするだけです。
BeOSもC++じゃなかったっけ?
またWindowsNTのモジュールの多くはC++です。
カーネル部分は知らないけど。

507 名前::2001/05/26(土) 01:59
>>497
>なるほど私は、ただ踊らされているだけのようだ。
そう感じられましたら申し訳ありませんでした。
ただ、言われたことを鵜呑みにしても仕方が無いですから、自分でも調べられる
ことは調べて、それでも分からないこととか、見落としている点、勘違いしている
点を指摘してもらう。
そんな意図で色々と書いたりしています。

thisポインタの問題など、ためになる情報は非常にありがたいです。
できましたら、また疑問が浮かんだときには、ご協力願います。

508 名前:504 :2001/05/26(土) 13:07
>>505
うーん「ソフトウェアが表すもの(オブジェクト)が相互参照しているなら、
ソフトウェアも相互参照するべきだ」という主張なんだよね。
その主張自体はもっともだと思うけど、その理由"だけ"で相互参照を許すのは
あまり良くないと思うよ。
相互参照によって起こりやすいモジュール密結合の問題点をしっかり認識した
うえで採用するなら、もちろん何の問題もありません。

最終的な目標は良いソフトを作ることであって、オブジェクト思考や相互参照
の排除はそのガイドラインのひとつだよね。それぞれのガイドラインが相反する
としたら、それぞれの長所短所を比較してバランスをとる必要があると思うのね。

505氏はわかっているだろうけど、初心者が見て相互参照の問題点を理解せずに
「オブジェクト思考でOKだから、相互参照はOKなんだ」と思うと良くないと
思うので、意見しておきます。

509 名前:509 :2001/05/27(日) 19:43
Visual C++でプログラミングを始めた者です。

coutで指数表記を使う場合、3.15e+004のように指数部が3桁で表示されてしまいます。
これを指数部が2桁になるように書式設定することは可能でしょうか?
マニュアルにはなさそうだったのですが、ご存知の方はお教え願います。

510 名前::2001/05/27(日) 20:30
>>509
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main(int argc, char* argv[])
{
double f;
f = M_PI;
cout << setprecision(3) << f << endl;
return 0;
}
というようにする。
ttp://www.page.sannet.ne.jp/mtoga/lang/cp/bih-p_09.htm
なんか参照。

511 名前::2001/05/27(日) 20:31
あ、指数部?失礼、間違えた。

512 名前:509 :2001/05/27(日) 20:40
はい、「3.15e+04」のように表示したいのです。
仮数部であれば、cout << setprecision(n); ですね。

<< をオーバーロードするしかないのでしょうか。

513 名前:デフォルトの名無しさん :2001/05/31(木) 20:05
delete[] a;
ってどーゆーこと?
deleteが拡張されてるの?

どんな定義がされているとこーゆー使い方できるの?

514 名前:デフォルトの名無しさん :2001/05/31(木) 20:09
>>513
配列をnewで構築したときはdelete[]で破壊すべし。

例)
    new a = int[100];
      :
      :
    delete[] a;

515 名前:デフォルトの名無しさん :2001/05/31(木) 20:10
激鬱
int* a = new int[100];

イッテクル

516 名前:デフォルトの名無しさん :2001/06/01(金) 09:56
>>514,515
なんか別の言語でそんな表記するのかと思ったYO!

517 名前:G-4 :2001/06/01(金) 11:53
ネットワーク上に共有されているCD-Rドライブや、
MOドライブの状態(読み込み中、待機中、開閉状態等々)
が分かるような簡単なアプリを作ろうかなと思ってるんですが、
どんな風にすればいいですかねぇ?
アイデア下さい。

518 名前:Install :2001/06/01(金) 13:58
本を探しています。
Install Shield For Visual C++6.0
大沢文孝/著
ネットサーブ/監修
出版社 アスキー
価格 3400円(税抜き)

新宿近辺で見かけた方いませんか???

519 名前:デフォルトの名無しさん :2001/06/01(金) 14:15
>>514-515
親切な人
ありがとう

520 名前:デフォルトの名無しさん :2001/06/01(金) 14:47
c++でプログラミングしたいですと、javaが好きな先生に言った。
オブジェクト指向が分かんないと意味ないから、始めにjavaを勉強して、
そのあと、オブジェクト指向が分かればc++、分からなければCにすればと言われた。
そんな感じでしたが、皆さんどう思われ?

521 名前:デフォルトの名無しさん :2001/06/01(金) 16:45
>>520
妥当だと思われ。

522 名前:デフォルトの名無しさん :2001/06/02(土) 16:05
>>517
C/Sにするのが一般的。
S側でデバイスを監視するデーモンを起動しておいてCでリモート。

523 名前:デフォルトの名無しさん :2001/06/02(土) 19:39
vcでstringに+演算子が無いんだけど、なんで?

524 名前:デフォルトの名無しさん :2001/06/02(土) 20:22
>>523
vcだから

525 名前:a :2001/06/02(土) 20:35
C++全然わかりません。
+演算子って一時オブジェクトを作って返す?あってる?
じゃあそのオブジェクトの寿命はいつまで?
例えば

MyString a, b, c;
a = b + c;

b + cの部分で一時オブジェクトが作られるの?
a に代入するまでそれは生きてるの?
試してみたら不正な処理って出るんですけど。
誰かおしえてくださいませ。

526 名前:デフォルトの名無しさん :2001/06/02(土) 20:42
>>524
粘着だね。アンチMFCキティ君(w
ここは荒らさないでね。

>>525
C++では演算子の挙動も自分で記述できる。
そのクラスの演算子がどう定義されているか調べて見れ。

527 名前:デフォルトの名無しさん :2001/06/02(土) 20:43
MyStringがどういうものだわからないけど
ちゃんと代入演算子定義した?

528 名前:527 :2001/06/02(土) 20:53
申し訳ない。
>>526の方が正確だわ
代入演算子だけでなく他の演算子(>>525の例だと+演算子)
が必要。(かどうかはMyStringによるが・・・)

529 名前:a :2001/06/02(土) 20:53
>>527
たぶんちゃんと定義したと思うんですが。
MyString &operator=( const char *string);
MyString &operator=( const MyString &string);
こんな感じの代入演算子は作りました。動作確認済み。

んで、+演算子は
friend MyString operator+( const MyString &left, const MyString &right);
なんですけど。

デストラクタでprintfしてみたら代入前に解放してる?

530 名前:デフォルトの名無しさん :2001/06/02(土) 20:57
コピーコンストラクタは?

531 名前:a :2001/06/02(土) 21:00
>>530
あります。

532 名前:デフォルトの名無しさん :2001/06/02(土) 22:10
>>531
あとは定義の内容かなぁ。

533 名前:デフォルトの名無しさん :2001/06/02(土) 22:42
>>529
コピーコンストラクタは?

534 名前:533 :2001/06/02(土) 22:43
ひらに失礼

535 名前:a :2001/06/02(土) 23:04
あ!
MyStringを受取る方のコピーコンストラクタの定義が無かったです。
定義したらちゃんと動きました、ありがとうございます >ALL

で、+演算子は一時オブジェクトを返すってのは正しいのでしょうか?

536 名前:527 :2001/06/02(土) 23:39
>+演算子は一時オブジェクトを返すってのは正しいのでしょうか?

正しくありません。
返すのは一時オブジェクトのコピーです。
最適化のされかたによっては一時オブジェクトは
作成されないかもしれませんが、その辺は私も
あまり詳しくありません。

537 名前:ミトコンドリ子 :2001/06/03(日) 01:08
>>535
Effective C++, More Effective C++を読むとここらへんの理解は進むわよ。

でも自分で簡単なテストプログラムを書いて自分で確かめてみるべきだと思うわ。
コンストラクタ、デストラクタ、コピー、代入の各関数にプリントを入れてみて
動作を追跡してみたらどうかしら。

538 名前:デフォルトの名無しさん :2001/06/03(日) 01:12
>>535
よかったな。がんばれよ。
こういう向学心に燃える奴にならいくらでも協力してやるんだけどなぁ。
課題丸投げ厨に爪の垢煎じて飲ませてやりたいよ。

539 名前:デフォルトの名無しさん :2001/06/05(火) 14:33
こんにちは。C から C++ に移行しつつある者です。
クラスの中に、関数 func と、関数へのポインタ *myfunc を定義して、
C 言語ライクに myfunc=func と記述したところ、エラーがでます。

具体的には、
#include <stdio.h>

class Hoge{

public:

double func1(double a){fprintf(stdout,"hoge\n");};
double (* myfunc)(double);

void setfunc(void){ myfunc = func1; }

};

というソースをコンパイルすると、

no matches converting function `func1' to type `double (*)(double)'
candidates are: double Hoge::func1(double)

てな感じでエラーがでるのです。

myfunc が func1 を指すようにしたいのですが、
C++ ではどの様に記述すればいいのか、お教え頂けないでしょうか?

540 名前:ミトコンドリ子 :2001/06/05(火) 15:22
結論から言うと、できないわ。

double Hoge::function( double ); (メンバ関数) と
double ::function( double ); (グローバル関数)
は違うものよね。
そしてfunc1は前者だし、myfuncは後者を指すポインタを表している。
なのでコンパイラがエラー報告しているわけ。

myfuncの定義をメンバ関数へのポインタに修正してあげれば良いわ。
class Hoge {
 double (*Hoge::myfunc)(double);
public:
 double func1(double a);
 void setfunc(void) { myfunc = func1; }
 double callfunc(double a ) { return( (this->*(myfunc))(a) ); }
...
};
とすれば通ると思うわ。

でも、C++で関数へのポインタを使いたくなったときには一度立ち止まって考えてみて。
仮想関数を使うほうが、アナタのやりたいことを効率的で型安全で保守性を保って
行うことができることが多いわよ。
がんばってね。

541 名前:デフォルトの名無しさん :2001/06/05(火) 16:09
double (*Hoge::myfunc)(double);

でなく、 hoge::*myfunc でそ

542 名前:デフォルトの名無しさん :2001/06/05(火) 16:26
VC++ではOKだけど G++ だと
アドレス代入の行 myfunc = func1 で

warning : assuming & on `Hoge::func1'

ってなwarningが出るんですが、 消すにはどうしたらいいんでしょう?

543 名前:ミトコンドリ子 :2001/06/05(火) 16:28
>>541 そのとおり。ゴメンなさい。

544 名前:ミトコンドリ子 :2001/06/05(火) 16:32
>>542
myfunc = &func1; にすればいいんじゃないかしら。

でもそれはエラーメッセージを読めば想像がつかないかしら?

545 名前:ミジン子 :2001/06/05(火) 16:43
すいません、G++使い始めたばかりで英語メッセージわからないんです

辞書引いたら assumingって でしゃばったって意味なんだけど どういうことなんでしょ?

VC++だと & つけるとエラーが出ます
G++は 有っても無くても動く。なぜぇぇぇぇ???

546 名前:SAGE :2001/06/05(火) 17:21
>>545
辞書は assume で引いたほうがよいかと。「仮定する・推量する」

547 名前:ミジン子 :2001/06/05(火) 17:48
Thanx。VC++だと 仮想関数のアドレスを取ろうとしました ってエラーなのは
なんでかなぁ、、、どっから仮想関数が出てくるんだ?

548 名前:539 :2001/06/05(火) 19:19
皆様レスありがとうございます。
以下のソースで g++ でコンパイル&実行ができました。
(VC++ は手元にないのでちょっと確認できません。)

仮想関数の方が良い、という御指摘ですが、
それはこれから勉強して行きたいと思います。

#include <stdio.h>

class Hoge {
double (Hoge::*myfunc)(double);
public:
double func1(double a){return a;};
void setfunc(void) { myfunc = &Hoge::func1; }
double callfunc(double a ) { return( (this->*(myfunc))(a) ); }

};

int main(){

Hoge hoge;

hoge.setfunc();

fprintf(stderr,"%lg\n",hoge.callfunc(1));

}

549 名前:デフォルトの名無しさん :2001/06/05(火) 19:32
ちょっと相談です。
Windowsでラップクラスを作ってるんですけど・・・

やってる事を一言で言えば
GetWindowLongとSetWindowLongでインスタンスのポインタを保存して
メンバ関数をプロシージャのようにしています。
このクラスはHWNDに関わるAPIをラップした基本クラスから派生させています。
ちょっと長いですが。

class CBaseWnd{
private:
  m_hWnd;
public:
  CBaseWnd() : m_hWnd(NULL){}
  virtual LONG GetWindowLong(int nIndex){ return ::GetWindowLong(m_hWnd, nIndex) }
  virtual LONG SetWindowLong(int nIndex, LONG dwNewLong){ return ::SetWindowLong(m_hWnd, nIndex, dwNewLong) }
};

class CRegistWnd : public CBaseWnd{
private:
  static CRegistWnd* m_lpThis;
  static LRESULT _WrapWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    /* 最初のメッセージ受信時はm_lpThisの値を::SetWindowLong(hWnd, 0, (LONG)m_lpThis)で格納*/
    /* 以後はGetWindowLongでインスタンスのポインタを取得し、MainWndProcメンバ関数を呼ぶ*/
  }
  LRESULT MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
public:
  ATOM RegisterClassEx( /* 省略 WNDCLASSEXの値を引数で*/)
  {
    /* 内部でWNDCLASSEXに値設定&登録、その際cbWndExtraにはsizeof(CRegistWnd*)を入れている*/
    /* プロシージャとしては_WrapWndProcを登録 */
  }
  HWND CreateWindowEx( /* 省略 CreateWindowExの引数と同等*/ )
  {
   /* ::CreateWindowEx実行 m_lpThisにthisを入れておく*/
  }
};

相談内容につづく

550 名前:549 :2001/06/05(火) 19:33
上記CRegistWndを使って自己登録ウインドウを作成するクラスにしようと思っています。
この時、cbWndExtraをインスタンスの保存で使っているので、上記クラスを使用する場合
このままではcbWndExtraを利用できません。

そこで、CRegistWndのRegisterClassExの引数としてcbWndExtraの値を設定可能にするために
この関数の内部で、引数で指定されたcbWndExtra + 指定のcbWndExtraの値 + sizeof(CRegistWnd*)
のようにポインタ分のメモリをを内部で余計に取るようにします。

そして、SetWindowLong等をこのクラスから普通の感覚で使えるようにするために
SetWindowLongとGetWindowLongをオーバーライドして、
nIndexの値が正の数の場合に、指定された数よりsizeof(CRegistWnd*)を足して
外見上ほぼ同等の動作をさせるようにしました。


このようなクラス設計はダメダメな設計でしょうか?
実際にこのクラスを使う場合、CRegistWndからさらに派生して使う事になるのですが、
その時にSetWindowLong等をオーバーライドして違う動作をさせた場合に
問題が発生する可能性があります。

オーバーライドした物の内部でCRegistWnd::SetWindowLongを
呼び出してくれれば良いのですが、人にこのクラスを使ってもらう場合
直接::SetWindowLong等を呼び出してしまうかもしれません。

習慣的には同等の動作をさせる場合は、出来るだけ派生元クラスの関数を
呼び出すものかとは思うのですが・・・

どなたかご教授お願いします。

551 名前:ウツダシノウ :2001/06/05(火) 21:00
メンバ関数のポインタの話 の続きなんですが、クラス外からの呼び出し方法についてなんですが

class hoge{
public:
void (hoge::*pFunc)();
hoge(){ pFunc = func; }
void func(){printf("omaemona" ); }
}

とこんな感じでポインタに入れたのをメイン関数から呼ぶのどうすればいいんでしょう?
main(){
hoge instance;
(instance.*pFunc)();
}
かとおもったら pFuncが定義されないってエラーがでます

552 名前:デフォルトの名無しさん :2001/06/05(火) 21:03
>>551
pFuncが定義されてないんじゃない?

初期化してない普通のポインタ使おうとしてもそうなるでしょ?

553 名前:デフォルトの名無しさん :2001/06/05(火) 21:10
>>551
ttp://puyon.pns.to/program/afl/h0002.html
これは?

554 名前:デフォルトの名無しさん :2001/06/05(火) 21:22
>>551

>void (hoge::*pFunc)();
「hoge::」いらないんじゃない?

555 名前:ウツダシノウ :2001/06/05(火) 21:28
あぁ .*演算子の右辺は左辺のメンバにアクセスするのと違うんですね
よく考えたら当たり前

(instance.*instance.p)() でokでした。でもなんか間抜け。もっとダイレクトにかけないのかしらん

556 名前:ウツダシノウ :2001/06/05(火) 21:30
>>554
ちょっと上に出てるけど、クラス内のメンバ関数のポインタの場合は必要です
いらないのは C の場合(後staticメンバ関数の場合)

557 名前:デフォルトの名無しさん :2001/06/05(火) 21:34
C++で関数へのポインタが必要なときは、
設計を間違えたときだけ。

558 名前:デフォルトの名無しさん :2001/06/05(火) 23:27
>>557
んなこたぁ、ないよ。

559 名前:sage :2001/06/05(火) 23:56
>>557
同意

560 名前:デフォルトの名無しさん :2001/06/06(水) 12:31
すみません、Cのランタイムや生のDLLを呼ぼうとしてました。
これからはSTLやCOMを使いますので許してください。

561 名前:デフォルトの名無しさん :2001/06/06(水) 17:41
こんにちは。昨日に引続き、C から C++ に移行しつつある者です。
new 演算子で、二次元配列を確保する方法に関して質問です。

C の malloc の様に、動的に二次元配列を確保する際、
配列サイズを変数 NX、NY で制御したいのですが、うまくいきません。
具体的には、以下のようなソースのコンパイルに失敗します。

class Pixel{

public:
int v;
Pixel(int i=0){v=i;};

};


class Image{

public:
int NX,NY;
Pixel **p;
Image(int myNX=1,int myNY=1){
NX=myNX;
NY=myNY;
Pixel (*p)[NY] = new Pixel[NX][NY];
};

};

NX、NY ではなく、具体的な数でやれば成功するのですが、
NX、NY を用いて確保したいのです。
ご存知の方はお知らせ頂けないでしょうか?

562 名前:デフォルトの名無しさん :2001/06/06(水) 18:02
>>561
そりゃCからC++に以降以前の問題。
mallocでも無理だろう。
Cの基本部分すら理解していないようなので、一からやり直すべし。

563 名前:561 :2001/06/06(水) 18:10
>>562
malloc 使えば、

p = (Pixel **)malloc(sizeof(Pixel *)*NX);

for(i=0 ; i<NX ; i++){
p[i] = (Pixel *)malloc(sizeof(Pixel)*NY);
}

で、できますが…。

564 名前:デフォルトの名無しさん :2001/06/06(水) 18:39
>>563
それなら、

p = new Pixel*[NX];

for(i=0 ; i<NX ; i++){
p[i] = new Pixel[NY];
}

とすればよいだけのような...。pは2次元配列なのか配列へのポインタなのかはっきりすべし。

565 名前:デフォルトの名無しさん :2001/06/06(水) 19:45
誰か「Pixelをクラスにするのはやりすぎだよ」って
教えてあげれば良いのに。

566 名前:デフォルトの名無しさん :2001/06/06(水) 19:46
>>561

2次元配列なんか不要。
ポインタの配列のぶんだけメモリ消費量も激しいし、速度も遅くなる。

#include <vector>
using namespace std;

class Pixel {
 int v;
public:
 Pixel(int i=0) : v(i) {}
 int Set(int c) { return v = c; }
};

class Image
{
private:
 int NX, NY;
 vector<Pixel> m_Pixel;
public:
 Image(int myNX = 1, int myNY = 1)
 : NX(myNX), NY(myNY), m_Pixel(myNX*myNY)
 {
 }
 Pixel &Dot(int x, int y) { return m_Pixel[y * NX + x]; }
};

Image img(50, 50);
img.Dot(10, 10).Set(crRed);

567 名前:デフォルトの名無しさん :2001/06/06(水) 19:51
マイナー次元の要素数が決定していないと
多次元配列にはアクセスできないよ。
NX*NYの1次元配列として確保して
Pixel[myNX*NY+myNY]とかしないとダメ。

568 名前:デフォルトの名無しさん :2001/06/06(水) 19:56
>>561
論点ずれるけど2次元配列なんか使うより、
フラットに使った方がスマートでないかい?
[ ][ ]は使えないけど。

class Image {
int NX, NY;
public:
 Pixel *p;
 Image(int myNX=1,int myNY=1) : p(new Pixel[NX * NY]) {};
 Pixel operator()(x, y) { return p[x * NY + y; };
};
NYを2の倍数にすると吉。

569 名前:561 :2001/06/06(水) 19:57
>>565
Pixel は例えでして、本当は、2次元格子上に細胞モデルを配置した
数学モデルを考えています。ただ、逆に混乱させてしまったかも知れません。

>>566
一次元配列を二次元にマップするのはわかりましたが、
vector<Pixel> の部分 (テンプレート?) がまだ勉強不足で
わかりませんので、今晩検討してみます。

570 名前:568 :2001/06/06(水) 19:58
>>566
かぶったスマソ

571 名前:561 :2001/06/06(水) 19:59
再び 561 です。

569 を書いている間に、さらに 2 人の方のレスが。
ありとうございます。

みなさん一次元配列を使うべし、というところは
共通しているようですね。試して見ます。

572 名前:デフォルトの名無しさん :2001/06/06(水) 23:24
>>568
ブラケットどうしても使いたいのであれば、

template <class T> class CArray2D { // エラーチェック省いてます
T** pptAry;

public:
CArray2D(void) : pptAry(NULL) {}
~CArray2D() { Free(); }

operator T**() { return pptAry; }

void Alloc(int nWidth, int nHeight) {
Free();

pptAry = new T*[nHeight];
pptAry[0] = new T[nWidth * nHeight];

int nY;
for (nY = 1; nY < nHeight; nY++)
pptAry[nY] = pptAry[0] + nY * nWidth;
}

void Free(void) {
if (pptAry != NULL) {
if (pptAry[0] != NULL) delete[] pptAry[0];
delete[] pptAry;
pptAry = NULL;
}
}
};

というテンプレートクラスを作って、
CArray2D<Pixel> aPixel;
aPixel.Alloc(16, 16);
aPixel[0][0].Set(...);
とか。

573 名前:デフォルトの名無しさん :2001/06/06(水) 23:56
>>572
そこまでして[]を使う意味があるの?
(x,y)でええやん。

あとC++では0をdeleteしても大丈夫です。
だから無効なポインタには0を入れましょう。
処理系によってはNULLが0ではない可能性があるので、
NULLは使わないようにしましょう。

574 名前:568 :2001/06/07(木) 00:08
>>572
サンクス。
列分の配列が増えちゃうね。下でどうだ。
#オペレータオーバーロード萌え〜

template <class T> class Array2D {
 const int rawWidth;
 T* array;
 struct Raw {
  T* raw;
  Raw(T* nRaw) : raw(nRaw) {};
  T& operator[](int x) { return raw[x]; };
 };
public:
 Raw operator[](int y) { return Raw(array + y * rawWidth); };
 Array2D(int w, int h) : rawWidth(w), array(new T[w * h]) {};
 ~Array2D() { delete[] array; }
};

int main() {
 Array2D<Pixel> aPixel(16, 16);
 aPixel[0][0].Set(1);
 return 0;
}

575 名前:デフォルトの名無しさん :2001/06/07(木) 00:13
>>574
そこまでやるなら、いっそのこと2次元イテレーターとかを作って、
汎用コンテナにしてはどうか。
X方向にY=3でソートとかできると便利かも。

576 名前:568==574 :2001/06/07(木) 00:15
>>573
>そこまでして[]を使う意味があるの?
>(x,y)でええやん。
普段Java好きだから同意。
けど2次元配列使ったソースをコンパイルし直すだけで、
リユースできれるから無意味でもないと思う。

> あとC++では0をdeleteしても大丈夫です。
> だから無効なポインタには0を入れましょう。
そうだったのか。
コンパイラに起こられるからではないのですね(Javaちゃうって)

> 処理系によってはNULLが0ではない可能性があるので、
> NULLは使わないようにしましょう。
それはどこかの馬鹿がどこかで
#undef NULL
#define -1
とかしているのでは?
0で良いは同意だけどNULLでも悪かないでしょ?
#include <stdlib.h>とかすれば

577 名前:デフォルトの名無しさん :2001/06/07(木) 00:32
>>573
内部では0では無い事が、多々ありますが、
Cの中では、NULL==0は保証されてたと思いますよ。
576さんが言われるとおり、誰かが0以外にしない限り…。

578 名前:573 :2001/06/07(木) 00:33
>>576

ANSI規格で、0のdeleteが安全であることは保障されています。
一方、NULLが0であることは保証されていません。

それだけのことだよ。

579 名前:デフォルトの名無しさん :2001/06/07(木) 01:16
CはNULL==0は保証されていないけど
C++はNULL==0が保証されてるんじゃなかったっけ?
間違ってたらスマソ

580 名前:デフォルトの名無しさん :2001/06/07(木) 01:23
>>ALL
NULLの話をすると長くなりそうなので、やめませんか?

581 名前:デフォルト引数について質問です :2001/06/07(木) 01:37
#include <string>
using namespace std;

void f(string p1, string p2);

の関数にデフォルト引数を設ける場合、

void f(string p1 = string(), string p2 = string());
という書き方ではまずいでしょうか?

VC++ だとコンパイルエラーになりした。GCC g++ だと
コンパイルエラーになりませんでした。

582 名前:デフォルトの名無しさん :2001/06/07(木) 01:44
>>581
まずくないです。
ANSI準拠のC++なら通ると思います。

583 名前:デフォルトの名無しさん :2001/06/07(木) 01:52
#include <string>
のstringで引っ掛かったのでは?

584 名前:デフォルトの名無しさん :2001/06/07(木) 01:52
>>582
最近おとなしいね。アンチMFCキティ君(藁

585 名前:デフォルトの名無しさん :2001/06/07(木) 01:52
>>583
アフォウ

586 名前:デフォルト引数 :2001/06/07(木) 02:04
>>582
ありがとうございます。言語仕様上問題無いという
裏付けが中々見つからず、頭を痛めておりました。

>>583
string型でないケースでも同様でした。例えば、

class T{
public:
T();
};

void f1(T p1 = T(), T p2 = T());
→ error C2062: 型 'class T (__cdecl *)(void)' は不要です。
というエラーになります。(VC++)

ただ、
void f1(T p1, T p2 = T());
はコンパイルエラーになりませんでした。(VC++)

587 名前:デフォルトの名無しさん :2001/06/07(木) 02:09
>>586
こういうときはANSI準拠に依存する必要があるかどうかをまず十分に検討せよ。

588 名前:デフォルトの名無しさん :2001/06/07(木) 05:47
>>587
> こういうときはANSI準拠に依存する必要があるかどうかをまず十分に検討せよ。
というのはなんだかなあ…。
C++の問題かVC++の問題かを切り分けるべきだろう。

589 名前:デフォルトの名無しさん :2001/06/07(木) 07:38
VCのANSI対応云々は荒れるからここではおいとくとして、
そのデフォルト引数の使い方はどうかと思うけどな。
関数呼び出しがヘッダ側にあるというのはどうにも保守しにくそうで。

590 名前:問題です :2001/06/07(木) 09:55
例外処理について200字以内で簡潔に説明してください。
これがわかるほどの人はここにはいないか〜

591 名前:デフォルトの名無しさん :2001/06/07(木) 12:23
590が課題でないことを200字以内で簡潔に説明してください(5点)。
人にたよって課題を終わらせようとする590が、将来真人間になる
可能性を200字以内で簡潔に説明してください(95点)。

592 名前:デフォルトの名無しさん :2001/06/07(木) 13:08
>>590
http://piza.2ch.net/test/read.cgi?bbs=tech&key=991726421&nofirst=true&st=16&to=16

593 名前:デフォルトの名無しさん :2001/06/07(木) 14:35
>>590
このスレを頭から読み返してみなよ。

594 名前:590 :2001/06/07(木) 15:04
>>591 - 593
わからないならレスをつけないでくださいよー

595 名前:590 :2001/06/07(木) 15:09
この板バカばっかりでだめいたなのかもね
こんなとこで得られるものなんてなにもないなー

596 名前:デフォルトの名無しさん :2001/06/07(木) 15:10
>>590
例外処理: C++では例外はthrowしてcatchする。

597 名前:596 :2001/06/07(木) 15:11
>>596
我ながら簡潔で素晴らしい。

598 名前:デフォルトの名無しさん :2001/06/07(木) 15:23
>>590
みんなを煽って宿題をやらせようとしているヴァカ

もしくは相談室を何か違うものと勘違いしているヴァカ

599 名前:デフォルトの名無しさん :2001/06/07(木) 15:32
>>594
http://piza.2ch.net/test/read.cgi?bbs=tech&key=991726421&nofirst=true&st=16&to=16

600 名前:590 :2001/06/07(木) 15:50
>>598
できないならできないと素直にいえよー
だいたい宿題だとしても人にやってもらって何が悪いんだ
おまえだってできない仕事を人に押し付けてるくせに

601 名前:デフォルトの名無しさん :2001/06/07(木) 15:54
>>600
ヴァーカヴァーカ

ピューピュー

602 名前:590 :2001/06/07(木) 15:56
>>601
おまえがだろー
わかんないっていえよー
おらー

603 名前:デフォルトの名無しさん :2001/06/07(木) 15:56
>>600 だいたい宿題だとしても人にやってもらって何が悪いんだ
本気でそう思ってるの?
授業料どぶに捨てるのも個人の自由と言われれば何もいえないけど。

604 名前:デフォルトの名無しさん :2001/06/07(木) 15:57
レベルの低い罵りあいだな(藁

605 名前:デフォルトの名無しさん :2001/06/07(木) 16:16
例外処理くらいgoogle一発だと思うが
小学校で辞書の引き方を習わなかったんだろうな
登校拒否のヒッキーの末路か……

606 名前:デフォルトの名無しさん :2001/06/07(木) 16:26
例外処理
C++ではthrowとcatchを使う。
throwを実行するとcatchに飛ぶ。goto文の変種である。
gotoと違って他の関数に飛べる。
滅多に使われないから例外処理と呼ばれている。

607 名前:デフォルトの名無しさん :2001/06/07(木) 16:43
>>600
http://piza.2ch.net/test/read.cgi?bbs=tech&key=991726421&nofirst=true&st=16&to=16

608 名前:デフォルトの名無しさん :2001/06/07(木) 16:43
>>606
ワロタ

609 名前:デフォルトの名無しさん :2001/06/07(木) 17:22
今まで僕の中でもやもやとわだかまっていたものがすっきりとしました
606サン本当にありがとうございました。

610 名前:デフォルトの名無しさん :2001/06/07(木) 17:37
>>603
個人の自由じゃないです。
他人に宿題やらせて卒業して社会人になると社会全体が迷惑しますから。

611 名前:610 :2001/06/07(木) 18:01
>>610
おまえの存在自体が社会の迷惑なんだよ
高卒がー

612 名前:デフォルトの名無しさん :2001/06/07(木) 18:13
元気だね、課題丸投げ厨。
2ch読んでるヒマあったら勉強しろこのクソガキが。

613 名前:590 :2001/06/07(木) 18:30
>>612
かよわい妹の宿題を手伝ってくれないなんて。。。
おにいちゃんのいじわる。。

614 名前:593 :2001/06/08(金) 00:27
>>594
>わからないならレスをつけないでくださいよー

同じ事を同じスレで言いたくないから、
>>593と言ったのだ。

615 名前:デフォルトの名無しさん :2001/06/08(金) 01:12
>>614
わかってないのはお前ただひとりだよ。
http://piza.2ch.net/test/read.cgi?bbs=tech&key=991726421&nofirst=true&st=16&to=16

616 名前:615 :2001/06/08(金) 01:12
誤爆。
×614
○613

スマソ>>614
鬱氏

617 名前:デフォルトの名無しさん :2001/06/08(金) 08:42
Singletonパターンを、全てのメンバ変数やメンバ関数をstaticにする事で代用する事は可能ですか?

618 名前:デフォルトの名無しさん :2001/06/08(金) 10:48
>>617
オブジェクト指向における再利用のためのデザインパターン 第3版より
「Singletonパターンと同等の機能を提供する別の方法として、
クラスオペレーション(C++における静的メンバ関数、Smalltalkにおけるクラスメソッド)を
用いることもできる。しかし、このような言語上のテクニックで対処する方法では、
クラスのインスタンスを1つ以上に変更する場合に困難にになる。
さらに、C++における静的メンバ関数は仮想関数にすることができないので、
サブクラスにポリモルフィックにオーバーライドすることはできない。」

class A; ← Singleton
class B : public A;

A a;
B b;

Aは1つ、Bも1つ、AとBは共存、としたい場合にどうよ。

619 名前:デフォルトの名無しさん :2001/06/08(金) 10:52
>>617
やってみて、出来たら出来る。
出来なかったら、出来ない。

620 名前:デフォルトの名無しさん :2001/06/08(金) 11:53
>>618
class Bの書き方に気をつけないと、Singletonじゃなくなるぞ
Singletonパターンを作りたい場合は基本的に継承禁止にすべきだと思うが

621 名前:デフォルトの名無しさん :2001/06/08(金) 13:23
C++でクラスのコンストラクタにつけることができる、
explicit修飾子が良くわかりません。
一応、MSDNの日本語解説は読んでみたのですが、
引数の暗黙の型変換は一切ゆるしませんという宣言と思
えばよいですか?

622 名前:デフォルトの名無しさん :2001/06/08(金) 14:19
SLTのコンテナをヒープに作ることはできますか?

623 名前:617 :2001/06/08(金) 15:07
>>618
良くわかりました。どうもありがとうございます。

624 名前:593 :2001/06/08(金) 23:08
>>620

>Singletonパターンを作りたい場合は基本的に継承禁止にすべきだと思うが

実装を複雑にして流用しやすくするか、
流用できなくてもいいから実装を単純にするか、
それは状況に応じて選べばいいと思う。
staticメンバ関数でやるというのも一つのやり方だろう。

>>621

explicit修飾子の機能的な面に目を奪われているようだね。
暗黙の型変換についてよく考えてみよう。
この機能は、何が良くて、何が悪いのか、
まだよくわかってないんじゃないか?
理解できれば、explicitの使い方は教わらなくても自然にわかるようになる。

>>622
できます。

vector<int> *p = new vector<int>();
vector<int> *p = new vector<int>(16);
vector<int> *p = new vector<int>;

だけど、こんなのgotoより使わないだろ。
何かのクラスのメンバにいれておけばいい。
class A
{
 vector p;
};
コンテナは何がしかのクラスがきっちり管理しておくべき。
コンテナの責任者は誰なのか明確にしておかないといけない。
複数のクラスが共同で管理しようとすると破綻するよ。

625 名前:デフォルトの名無しさん :2001/06/11(月) 12:50
「この機能」は「暗黙の型変換」をさしているのですか?

626 名前:デフォルトの名無しさん :2001/06/11(月) 12:56
>>625
explicitの機能を指してるのかと思われ。

627 名前:デフォルトの名無しさん :2001/06/11(月) 13:03
鉄則:explicitの意味がわからないやつは単一引数コンストラクタにはすべてexplicit付ける事。

628 名前:621 :2001/06/11(月) 16:54
知らなかった……

class a
{
public:
a() {m_i=0;};
a(int i) {
m_i=i;
};

protected:
int m_i;
};

void func(class a)
{
}

func(1);

629 名前:デフォルトの名無しさん :2001/06/11(月) 20:55
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

630 名前:デフォルトの名無しさん :2001/06/11(月) 20:55
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

631 名前:デフォルトの名無しさん :2001/06/11(月) 20:55
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

632 名前:デフォルトの名無しさん :2001/06/11(月) 20:55
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

633 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

634 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

635 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

636 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

637 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

638 名前:デフォルトの名無しさん :2001/06/11(月) 20:56
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

639 名前:デフォルトの名無しさん :2001/06/11(月) 21:22
とりあえず落ち着け

640 名前:デフォルトの名無しさん :2001/06/11(月) 21:53
>>639
大爆笑

641 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

642 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

643 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

644 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

645 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

646 名前:デフォルトの名無しさん :2001/06/11(月) 22:04
int &Fact()
{
int a = 10;
return a;
}

int main()
{
int a = Fact();
cout << a << endl;

return 0;
}
これはだめなんでしょうか
結果は

10

ってなったんですが

647 名前:デフォルトの名無しさん :2001/06/12(火) 00:17
落ち着いたみたいだね。

さて、結論から言えば駄目です。
ローカル変数の参照を返すのは全て駄目です。
何でも動けばいいってもんじゃない。

648 名前:デフォルトの名無しさん :2001/06/12(火) 10:44
MFCのQueryInfoStatusCodeで取得できるStatusCodeを
MFC使わずに取得したいのですが、何か方法ございますでしょうか?

649 名前:デフォルトの名無しさん :2001/06/12(火) 10:55
うんち。

650 名前:デフォルトの名無しさん :2001/06/12(火) 12:17
>>648
(何がしたいのかイマイチよくわからんが)
ソケット開いて GET 要求出したあと、
帰ってきた 1 行目(だったかな?)に書いてある。

telnet で 80 につなげて GET 要求出してみりゃ、すぐわかる。

651 名前:651 :2001/06/12(火) 15:52
thisってどうして自分のポインタを返すのですか?

652 名前:デフォルトの名無しさん :2001/06/12(火) 16:12
thisの意味を英和辞典で調べるように。

653 名前:653 :2001/06/12(火) 16:28
>>651
thatだと相手のポインタかな…って思っちゃうでしょ?

654 名前:デフォルトの名無しさん :2001/06/12(火) 17:57
>>651 仕様です

655 名前:651 :2001/06/12(火) 19:08
仕様なのでしようがないのですか?

656 名前:デフォルトの名無しさん :2001/06/12(火) 19:19
>>655
そのオチが言いたいために質問したのですか?

657 名前:82 :2001/06/12(火) 19:21
>>655
はい
ごめんなさい

658 名前:デフォルトの名無しさん :2001/06/12(火) 19:24
おい、82、
クッキー残ったままだぞ。

659 名前:デフォルトの名無しさん :2001/06/12(火) 20:32
>>658
クッキーってなんですか?

660 名前:デフォルトの名無しさん :2001/06/12(火) 20:32
>>658
クッキーってなんですか?

661 名前:デフォルトの名無しさん :2001/06/12(火) 21:33
クッキーとビスケットとサブレとクラッカーの違いはなんですか

662 名前:デフォルトの名無しさん :2001/06/12(火) 23:58
あたり前田のクラッカー。

663 名前:デフォルトの名無しさん :2001/06/13(水) 00:12
ポケットビスケットつ

664 名前:デフォルトの名無しさん :2001/06/13(水) 00:12
ポケットビスケットつ

665 名前:デフォルトの名無しさん :2001/06/13(水) 02:49
VCでクラスに初チャレしたんですが、
externで他のソースの関数を使うみたいに
他のソースのクラスにあるpublic関数を使う方法って
無いんでしょーか?
厨房な質問ですんまそん

666 名前:デフォルトの名無しさん :2001/06/13(水) 03:12
publicなら、そのクラスの定義をincludeすれば使えよう。

667 名前:RIP_MAPIRO :2001/06/13(水) 03:14
>>665
使用するクラスのヘッダをインクルードすればよいだろう。
メンバ函数をさもグローバル函数のごとく使おうと思っているのなら
設計レベルの話しになるが。

668 名前:デフォルトの名無しさん :2001/06/13(水) 13:32
>>667
>メンバ函数をさもグローバル函数のごとく使おうと思っているのなら
できるの?

669 名前:デフォルトの名無しさん :2001/06/13(水) 13:55
>>668
staticにする。が、いきなりやると自動的に、メンバになってる意味があるか
どうかとかの検討(葛藤)が始まって気持ち悪くなるので、設計時によく考えて
実装すべし。

670 名前:RIP_MAPIRO :2001/06/13(水) 14:02
>>669
代弁してくれた。
>>668
まぁ要求するものによっていろいろあると思うけど、
はじめからグローバル函数にするとか、namespaceも考慮するとか、
static函数にするとか、同じ機能をもつ函数だけど名前をかえるとかなど。

671 名前:デフォルトの名無しさん :2001/06/13(水) 23:01
>メンバ函数をさもグローバル函数のごとく使おうと思っているのなら
>設計レベルの話しになるが。

激しく同意。

綺麗に設計されていれば、C++の機能を素直に使って実装できる。
あれこれテクを駆使しなければならないときは、たいてい
設計に問題がある。

俺もC++を使い始めた頃は他のクラスの関数を流用したいと思った。
こういう制限が出てきたときは、そのクラスの使い方を間違っているか、
そのクラスの設計に問題があるかのどちらか。

672 名前:ぷらぷら厨房 :2001/06/15(金) 11:55
C++Builder5で

class TDataModule1 : public TDataModule
{
public:
__declspec(dllexport)long hoge1(AnsiString, AnsiString *);
BOOL hoge2( char * , double * );
};

__declspec(dllexport) long TDataModule1::hoge1(AnsiString hogeStr1,AnsiString* hogeStr2
)
{
hoge2(charhoge1,doublehoge1);
}

BOOL TDataModule1::hoge2( char* hogechar1, double* dwhoge1 )
{
return true;
}

とすると、『外部シンボルhoge2がプロジェクト名.objで未解決です』という
リンカエラーになってしまいます。どこが悪くてエラーになるのか分からず
困っております。低レベルなミスとは思いますが、解決法あれば教えていただけないでしょうか。

673 名前:デフォルトの名無しさん :2001/06/15(金) 13:55
>>672
まさか return true;-->return TRUE;
でOKってことはないよね。

674 名前:ぷらぷら厨房 :2001/06/15(金) 14:03
>>673
大丈夫、無かったです(^^;

675 名前:デフォルトの名無しさん :2001/06/15(金) 20:04
charhoge1とdoublehoge1ってなに?
TDataModule1::hoge2(char*, double*)しかないから
グローバルのhoge2()を探してるんじゃないの。

676 名前:デフォルトの名無しさん :2001/06/15(金) 20:31
hage

677 名前:デフォルトの名無しさん :2001/06/16(土) 05:29
>672
__declspec(dllexport)
はヘッダーにあればインプリメントの方には要らんのと違うの?(あんまし自信無し)

678 名前:ぷらぷら厨房 :2001/06/18(月) 09:38
>>675
その通りでした(^^;
変数渡ししてる部分とかをいじったら
コンパイル通りました。型が合わなくて
見つけてなかったんですね。

>>677
そうなんですか?何かC++の参考書見てもヘッダーか実体かどっちか
書いてないので一方なのか両方なのか分かりません。
これに限らずDLLの作成及び外部(特にVBからの)呼び方について
詳しいサイトなどあれば教えて頂けないでしょうか。

679 名前:ぷらぷら厨房 :2001/06/18(月) 09:40
しまった、さげちゃった(^^;

680 名前:ぷらぷら厨房 :2001/06/18(月) 14:00
続けてすみません。
DLLのコンパイルをしようとすると、
『非パブリックシンボル symbol をエクスポートしようとした』
のリンカ警告が出ます。ヘルプの説明に従って、
・_export をプロトタイプと関数定義両方に書く。
・スペルミスのチェック
・関数名を大文字にする
全てやりましたが警告が消えません。

また、それと直接関係あるのか分かりませんが、
VBからこの関数を呼ぼうとすると『DLL〜にメソッド〜が見つかりません。』
と言うエラーになってしまいます。

警告の理由、及び外部からの呼び出し方法についてご助言頂きたく。

681 名前:デフォルトの名無しさん :2001/06/18(月) 16:00
 なんでprivateなメンバ関数をエクスポートしようとするかな。
 privateの意味をしらねーんじゃねーの(ワラ
ってコンパイラに言われているんだヨ。

それとクラスをエクスポートするのは、互換性の問題が多すぎるヨ
素直にCOMオブジェクトにしろヨ。

682 名前:ぷらぷら厨房 :2001/06/18(月) 19:13
>681
あ、もちろんpublicにして(るつもりでい)ます。
COMオブジェクトですか?
調べてみます。どうもありがとう御座いました。
はぁ、ほんま厨房・・・。

683 名前:デフォルトの名無しさん :2001/06/18(月) 20:52
680 (というかリンカ)が言ってるのはそういう意味の "private"
じゃないと思う。

declspec(__dllexport) じゃないよん、って程度のことでは。
動作に支障ないと思うけど。蛇足:どんな名前で export されたかは
dependancy walker で見るとすぐわかる。

684 名前:デフォルトの名無しさん :2001/06/20(水) 01:25
>>681
672にpublic と書いてあるっての。なんでウソ答える?
「(ワラ」って付けるのにロクなの居ない。
>ぷらぷら厨房
多分呼び出し名があっていない。警告は多分平気。
VBからクラスオブジェクトそのものを使用するのはCOM使うが、1メソッドだけなら
extern"C"__declspec(dllexport) long hoge1Func(AnsiString hogeStr1,AnsiString* hogeStr2)
{
return TDataModule1::hoge1(hogeStr1,hogeStr2);

}
こんな風にしてhoge1Func()を呼べばいいんちゃう?

685 名前:デフォルトの名無しさん :2001/06/20(水) 01:29
>>681
COMオブジェクトが素直だとは到底思えない。

686 名前:デフォルトの名無しさん :2001/06/20(水) 01:38
>>685
でもまぁ、バイナリ互換性を保持するためには COM 使ったほうが良いと思う。
C++ のクラスを DLL 化すると、プライベートなメンバ変数一つ増やしただけで
バイナリ互換性が崩れるから、COM にするかスタティックリンクライブラリにし
た方が身のため。

687 名前:デフォルトの名無しさん :2001/06/20(水) 02:13
ここでは、C++のクラスをVBから使いたいって話じゃないのか?
それなら、普通、COM使うって事になるはずだが。

688 名前:デフォルトの名無しさん :2001/06/20(水) 02:57
>>684
それだとstaticなメンバ関数しか呼べない様な気がするけれど。
わざわざクラスにせずに、普通の関数で実装しろよ‥‥

689 名前:デフォルトの名無しさん :2001/06/24(日) 11:02
下がりすぎ、あげ

690 名前:デフォルトの名無しさん :2001/06/24(日) 19:08
いつになったらCみたいに処理系と分けて話が出来るようになるのかな。
現状じゃまだ個別の話がメインになってしまうなぁ。

691 名前:デフォルトの名無しさん :2001/06/24(日) 19:56
質問。
C++で、メソッドのポインタを取得して
メソッドコールするにはどうすればいいのでしょう?

// test.cpp
class Foo {
public:
void func() {}
};
int main(void)
{
Foo obj;
void (Foo::ptr)() = obj.func;
ptr(); // ←この部分で下記のエラー
return 0;
}

test.cpp: In function `int main()':
test.cpp:9: object-dependent reference `func' can only be used in a call
test.cpp:9: to form a pointer to member function, say `&Foo::func'
test.cpp:10: pointer to member function called, but not in class scope

692 名前:691 :2001/06/24(日) 19:59
上のソース、ちょっと修正。
void (Foo::ptr)() = obj.func;
    ↓
void (Foo:*ptr)() = obj.func;
です。

693 名前:691 :2001/06/24(日) 20:02
あ、また間違えてる。アホだ俺は。
正しくは void (Foo::*ptr)() = obj.func; です。

694 名前:デフォルトの名無しさん :2001/06/24(日) 20:54
>> 691
static でないとダメなはず。

695 名前:デフォルトの名無しさん :2001/06/24(日) 20:56
>>691
どうしてもインスタンスメソッドを呼びたければ
関数クラスみたいなものを作ってやればオケー。

696 名前:デフォルトの名無しさん :2001/06/24(日) 20:59
>>691
何でそんなことしたがるんだ???
C++なら継承使えばいいだけじゃないか・…
C++わかってる?

697 名前:デフォルトの名無しさん :2001/06/24(日) 21:08
この話題も定期的に出るね。
クラスのメソッドを外から呼び出したい場合、メソッドを外から呼ぶ方法を
考える前にまずそのクラスの設計を見直すべき。
・本当にそのメソッドを外から呼ぶ必要があるのか。
・そのメソッドはクラスに含まれている必要があるのか。

設計を適当にやり過ごして、対症療法的にstaticを乱造するなんてのは
もってのほか。

698 名前:>691 :2001/06/24(日) 21:33
C++はまともなOOPLの進化から取り残されているので
method delegationをスマートに実装することができず
694-697のように泥臭い解決法しかありません。

ついでに大半のC++ユーザーはその価値を理解していません。
言語が思考を制限してしまうよい例ですね(藁

699 名前:デフォルトの名無しさん :2001/06/24(日) 21:51
>>698
ん・・・だから、どうしてもデリゲートしなきゃいけないのか設計を見直せ
ってことになると思うんだが。
エンベッドにすると設計が泥臭くなって手に負えないが、デリゲートなら
設計はスッキリする(そのかわりC++では実装が泥臭くなる)という場面
があまり想像できないんだけど。

700 名前:sage :2001/06/24(日) 23:30
こんなのでたけど、どうよ?

class Foo {
public:
void func() {}
};

class Bar {
Foo *pobj;
void (Foo::*pfunc)();
public:
Bar(Foo *p) { pobj = p; }
void SetPtr(void (Foo::*ptr)()) { pfunc = ptr; }
void Call() { (pobj->*pfunc)(); }
};

int main(void)
{
Foo obj;

/* 1 */
void (Foo::*ptr)() = obj.func;
(obj.*ptr)();

/* 2 */
Bar bar(&obj);
bar.SetPtr(obj.func);
bar.Call();

return 0;
}

701 名前:デフォルトの名無しさん :2001/06/24(日) 23:33
C++では、関数ポインタテーブル的なものは完全抽象関数の
サブクラスでの実装を呼び出すようなインスタンスの
コレクション構造にすべきじゃない?

STLのmapの呼び出し方とか、細かい事忘れちった(今は専らJava
プログラマなおいら)けど、だいたいこんな感じにするとか、
どうでしょ?

class AbstractFunc {
public:
virtual void func() =0;
}

class Func1 :public AbstractFunc{
public:
virtual void func();
}//同じように実装いっぱい作ってちょ

class FuncTable{
private:
static FuncTable* instance__;//singleton instance handler
map<string*,AbstractFunc*> _functionmap;
public:
static FuncTable& getInstance();//instance getter
void setFunction(string*,AbstractFunc*);
AbstractFunction getFunction(string*);
}

//登録方法
FuncTable::getInstance().setFuntion("Func1",new Func1());

//呼び出し方法
FuncTable::getInstance().getFuntion("Func1")->func();

702 名前:デフォルトの名無しさん :2001/06/24(日) 23:51
>>698
俺はデリゲートがスマートな実装だとは思えないな。
テンプレートを実装できない/したくない言語が、
苦肉の策で実装するもの。あまり綺麗には見えない。
実際、多重継承もテンプレートもあるC++にデリゲートは不要だとおもう。
C++の機能の範囲で必ず綺麗に実装できるよ。

703 名前:デフォルトの名無しさん :2001/06/24(日) 23:59
>>691
これじゃあ駄目なわけ?

class IFoo{
virtual void func() = 0;
};

class Foo1 : public IFoo{
virtual void func() { cout << "foo1" << endl; }
}

class Foo2 : public IFoo{
virtual void func() { cout << "foo2" << endl; }
}

int main(void)
{
 Foo1 obj1;
 Foo2 obj2;
 obj1.func();
 obj2.func();
 sub(obj1);
 sub(obj2);
}

int sub(IFoo &f)
{
 f.func();
}

704 名前:>702 :2001/06/25(月) 00:14
>>691の例題程度なら何でもいいけど
デリゲートするメソッドがインスタンスあたり数個〜2・30個あって
さらに実行時に飛び先が変わってくるようなケースでも
きれいに実装できる?

705 名前:デフォルトの名無しさん :2001/06/25(月) 00:17
>>704
mapのキー検索条件を、そのとび先を決定する条件にすれば、
別にいくつあろうと問題ないと思うけど、そういうわけにも
いかないのでせうか?

706 名前:デフォルトの名無しさん :2001/06/25(月) 00:37
http://saki.2ch.net/test/read.cgi?bbs=qa&key=993396409

707 名前:>705 :2001/06/25(月) 00:56
やりたいのは単なるクラス版関数ポインタなわけで、
単にCの関数ポインタ呼び出すときに
頭にthisポインタ埋め込めればいいだけ。
これは言語レベルでサポートすべきだと思う。
# サポートされていない現状でどう実装すべきかはあんまり興味ない。

それを>701の実装みたいにメソッドオブジェクトnewして
文字列キーにしたmap持ち込むってのは大げさ過ぎると思う。

# そういやMFCのGUIオブジェクト->イベントハンドラへの
# メッセージの伝播ってどうやってんの?

708 名前:デフォルトの名無しさん :2001/06/25(月) 01:16
->*
.*
使えって。

709 名前:デフォルトの名無しさん :2001/06/25(月) 02:03
>>707
Windows伝来の邪法ながら、COMの秘技を用いれば、
インスタンスメソッドを、「第一引数がインスタンスポインタな関数」
に格下げすることができる、と聞きまする。

ちなみに、MFCは hWnd->CWmd変換テーブルを引いてthisを解決し、
メッセージハンドラマクロで巨大なswitchを生成して、msg -> func
をディスパッチしていたように記憶している。

710 名前:デフォルトの名無しさん :2001/06/25(月) 03:52
C++で関数ポインタ使う人は、
unionとかも使ったりするんでしょうか?

711 名前:デフォルトの名無しさん :2001/06/25(月) 04:02
たとえばwindowsとかだと APIを叩いたときに

typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;

こんなの使うことも多々あり。
C++でOSやハードよりの泥臭いところをさわろうとすれば
必ずunionとか、必要になってくるよ。

712 名前:デフォルトの名無しさん :2001/06/25(月) 04:38
>>710
あ、いや、Cレベル(あ、PASCALか?)APIしか持たないOS
にアクセスする時や、
組み込みみたいに資源の制約があるときに
関数ポインタやunionを使うのは仕方ないと思います。

でも、自分の設計するclassで
FunctionObjectやPolymorphizmが大げさすぎるという理由で、
関数ポインタやunionを使ったりする人がいるのかな〜
と思ったもので。

713 名前:デフォルトの名無しさん :2001/06/25(月) 04:51
そういうケースも有りでしょう。
Cのようにメモり効率重視のデータ格納を行う
クラスがあってもおかしくないです。

714 名前:691 :2001/06/25(月) 12:42
うぉ、予想以上にレスが多くてありがたいです

>>694
staticでかつメンバにアクセスする場合は
static void func(Foo *_this) という感じの関数を作るわけですよね
エレガントにメンバにアクセスしたいのでそれは避けたいかな・・・

>>700
(obj.*ptr)() ってこんな書き方ありですか?
一応clでコンパイル&実行できました(gccだとコンパイルエラー)

715 名前:691@C++わかってない :2001/06/25(月) 13:46
元々Cのソースで関数をテーブルにしてコールする処理を
C++化しようとして>>691の例を作ったのですが、
本来は下のようにしたかったわけです。

class Foo {
private:
void func0() {};
void func1() {};
public:
void call(int no) {
void (Foo::*table[])() = {func0, func1};
table[no]();
}
};

C++だとメソッドポインタは動的に変化する可能性があるから
静的なテーブルは作れないということですか。
でも実行時にテーブルを作っても table[no]() の部分はコンパイルが
通らないし、結局 static void func0(Foo *self) しか方法はないのかな。

あと >>703 のvirtualにする方法はテーブルにしたい場合にどのような
メリットがあるのかちょっとわかりません。

716 名前:デフォルトの名無しさん :2001/06/25(月) 14:01
デリゲート関係ないんじゃん(藁
>>715
だから設計を見直せ。
本当に本当にクラスのメンバである必要があるか?
staticにしてもメンバのアクセスのためにthis受け取るならグローバルだって
構わないと思わないか?

717 名前:デフォルトの名無しさん :2001/06/25(月) 16:07
>>715
なんだよー、それって要するに

void call(int no){
switch(no){
case 0:func0();return;
case 1:funcl();return;
}
}

を関数ポインタでの呼び出しに無理矢理している
だけじゃないけ。そういうのは、C++では継承つか
ってswitchしないようにするって言うのがセオリー
でしょうが・・・セオリーに逆らう理由は何ナノよ?

718 名前:RIP_MAPIRO :2001/06/25(月) 17:32
>>697 == >>699 ?
がんばってるねぇ。支持するよ。

719 名前:691@C++わかってない :2001/06/25(月) 22:17
>>716
設計を見直せと言われてもなぁ(w
継承しないからクラスのメンバである必要はないし、
グローバルなthisを受け取る関数するのも構わない。
でも、それだとC++にしたメリット(thisを隠せる)がないような。
そういうものなのかな。

>>717
うーーん、そのセオリーの意味がよくわかんないわ。スマソ。
例の補足だけど実際は funcX() は全部で30個ぐらいあるんですよ。

720 名前:デフォルトの名無しさん :2001/06/25(月) 22:46
>>719
そいつはただのブローカーだ。中間流通であくどく儲けてるだけ。

Commandパターンを使えに一票。

721 名前:デフォルトの名無しさん :2001/06/25(月) 23:08
つーかC++なんだから生の関数ポインタはやめようや。
これからは関数オブジェクトです。

722 名前:デフォルトの名無しさん :2001/06/26(火) 01:51
初心者です。
学校の授業で以下のプログラムを説明せよという宿題が出たのですが、
病気で休学していたので、さっぱりです。
どなたか簡単にせつめいしていただけないでしょうか。
まことにぶしつけなのは承知ですがどうかお願いします
分かっていることは、ペイントソフトのプログラムみたいです。

void_fastcall TForm1::BtnCLsClick(TObject *Sender)
{
Image1->Picture->Bitmap->Width=320;
Image1->Picture->Bitmap->Height=240;
Image1->Picture->Bitmap->Canvas->Pen->Color=clWhite;
Image1->Picture->Bitmap->Canvas->Brush->Color=clWhite;
Image1->Picture->Bitmap->Canvas->Rectangle(0,0,320,240);
PaintBox1->Canvas->CopyRect(ClientRect,Image1->Picture->Bitmap
->Canvas,ClientRect);
}



723 名前:デフォルトの名無しさん :2001/06/26(火) 01:53
友達に聞けよ。いるだろ?

724 名前:722 :2001/06/26(火) 01:54
>>723

休学していたので全然親しくないんです。
っていうか電話も知らない。提出明後日なのに。

725 名前:デフォルトの名無しさん :2001/06/26(火) 02:02
ヒントだけね。CopyRectで検索かければわかるよ。

726 名前:デフォルトの名無しさん :2001/06/26(火) 02:07
>>722
 ていうかこのアロー演算子の羅列に誰か何か言うことはないのか?

727 名前:デフォルトの名無しさん :2001/06/26(火) 02:07
学校でC++Builderか〜

728 名前:デフォルトの名無しさん :2001/06/26(火) 02:13
> PaintBox1->Canvas->CopyRect(ClientRect,Image1->Picture->Bitmap->Canvas,ClientRect);
PaintBox1->Canvas->CopyRect(PaintBox1->ClientRect,Image1->Picture->Bitmap->Canvas,
Rect(0, 0, Image1->Picture->Bitmap->Width, Image1->Picture->Bitmap->Height);
では?

729 名前:デフォルトの名無しさん :2001/06/26(火) 02:16
>>728
残念ながらコンパイルエラーです。

730 名前:デフォルトの名無しさん :2001/06/26(火) 03:23
Builerてこうなるんですか。
わかりやすくていいな。

731 名前:デフォルトの名無しさん :2001/06/26(火) 03:32
>>730
やっぱりDelphiがいいよね。

732 名前:デフォルトの名無しさん :2001/06/26(火) 03:34
授業でこんな基本的な事を教わるのってすっげーもったいないと思う。
せっかくだから秘伝とか教えてもらえればいいのにね。

733 名前:sageる :2001/06/26(火) 03:58
void_fastcall TForm1::BtnCLsClick(TObject *Sender)
{
Image1->Picture->Bitmap->Width=320;

絵の幅は320だ。

Image1->Picture->Bitmap->Height=240;

絵の高さは240だ。

Image1->Picture->Bitmap->Canvas->Pen->Color=clWhite;

絵をいじるときに使うペンの色は白だ。

Image1->Picture->Bitmap->Canvas->Brush->Color=clWhite;

塗りつぶすときのブラシの色は白だ。

Image1->Picture->Bitmap->Canvas->Rectangle(0,0,320,240);

(0,0)の点と、(320,240)の点で作成される矩形を書くぞ。

PaintBox1->Canvas->CopyRect(ClientRect,Image1->Picture->Bitmap
->Canvas,ClientRect);

ペイントボックスにコピーするぞ。

}

734 名前:sageる :2001/06/26(火) 03:59
って所だと思う。

735 名前:デフォルトの名無しさん :2001/06/26(火) 05:14
(320,240)は含まれないってところは引っかけか?

736 名前:デフォルトの名無しさん :2001/06/26(火) 06:08
>>709
メッセージハンドラマクロで巨大なswitchを生成しているのはATLで
MFCは、メンバ関数へのポインタの配列を使っている。

>>717
>を関数ポインタでの呼び出しに無理矢理しているだけじゃないけ。
あなたの主張がまさにATLのMFCに対する皮肉だ。

>>691
同じことを何度言ったか覚えているが
メンバ関数へのポインタはオブジェクトを介してのみ呼び出すことができる。
(ptr_to_obj->*ptr_to_mfct)(10);

class Foo {
private:
void func0() {};
void func1() {};
public:
void call(int no) {
void (Foo::*table[])() = {func0, func1};
(this->*table[no])();
}
};

「あるオブジェクトを介したメンバ関数へのポインタ」をオブジェクトと
して扱うことは許されていない。しかしながら、表記の通り、
「オブジェクト」と「メンバ関数へのポインタ」のペアがそれを容易に代替できる。
仮想関数に満足できない場合、一般的に使われる方法である。
実際、メンバ関数へのポインタは、仮想関数の論理的な実装の一部と言える。

737 名前:デフォルトの名無しさん :2001/06/26(火) 09:36
>>717
セオリーに逆らう理由は何ナノよ?

ウィンドウズのメッセージの数だけ vitrual 関数を用意すると、
vtbl が肥大化するうえに、結局根っこの WndProc ではさらにさらに
巨大な switch 文 (map とか引いても良いけどさ) が必要になるから。

738 名前:691@C++わかってない :2001/06/26(火) 09:51
>>720
意味わからんわ。

>>691
あんたスゲーよ!
>(this->*table[no])();
この方法でコンパイル&実行できたし!
これでthisを受け取る関数をボコボコ作る必要は無くなった。感謝。

あと少し補足。
メソッドポインタをテーブルに置く部分は、
func0 から &Foo::func0 に変更すると
gcc でもコンパイルが通るようになりました

739 名前:691@C++わかってない :2001/06/26(火) 12:52
↑なんで自分にレスしてんだアホ。
>691じゃなくて>>736へのレスです

740 名前:デフォルトの名無しさん :2001/06/26(火) 17:39
>>737
http://puyon.pns.to/program/afl/h0003.html
こういうのは?

741 名前:デフォルトの名無しさん :2001/06/26(火) 20:55
すごくまっとうな意見の >>721が無視されてたから書いてみました。
#include <vector>
#include <iostream>
class Foo {
 struct FuncT { virtual void operator()(void) = 0; };
 vector<FuncT*> table;
 struct Func0 : FuncT { void operator()(void) {cout <<"itte";}; };
 struct Func1 : FuncT { void operator()(void) {cout <<"yosi";}; };
public:
 Foo() {
  table.push_back(new Func0());
  table.push_back(new Func1());
 };
 void dispatch(int no) {
  FuncT* f = table[no];
  (*f)();
 };
};
main() {
 Foo foo;
 foo.dispatch(0);
 foo.dispatch(1);
}
ファンクションオブジェクトに名前をつけなきゃいけないのが好きくない。
Javaだったらanonymousクラス使うのに

742 名前:デフォルトの名無しさん :2001/06/26(火) 22:41
>>741
701との違いが見えないけど?

743 名前:デフォルトの名無しさん :2001/06/27(水) 00:04
>>741
コンパーイルエラー

744 名前:デフォルトの名無しさん :2001/06/27(水) 05:06
>>742
おっ、そんなのあったんか。
同じっす。考え方は。>>701>>703
普通の発想なのに>>691に無視されてるのはなぜ?

そもそも、数字をキーに関数を呼ぶってのがカタギの発想じゃないなぁ
状態マシン(しかも動的に遷移図が変わる)でもつくってるのかな?

>>743
どっか変かな。g++だと通りますよ。ただし全角空白->半角空白で。

745 名前:701 :2001/06/27(水) 13:37
おいらがmapでsingletonで書いてるから、そこに目がいって無視されたらしい
なあ。そこは単なる例で、枝葉の話であって、要は関数オブジェクトのコレクション
にするのがC++のセオリーって事なんだけどー。

こういうやり方の時って、関数オブジェクトを作ったり消したり繰り返すような
ことは普通ない(普通は初期化時にやるわな)から、STATIC関数と比較して
メモリ上のコストやオブジェクト生成のCPUコストなんかそんなに意識する必要
がないと思うけど。特に今どきのマシン環境なら。

呼び出す時に、

コレクション検索→クラスメソッドコール→VPTRテーブル参照→関数実体コール

という流れと、

添字番号による配列からの関数ポインタ検索→関数ポインタによる直接コール

との間で段数が違う分だけ、オーバーヘッドが有るだろうけどね。

ただ、そんなもんが気になるなら、そもそもなんでC++つかってんのよ?と思う
けど。CかASMででもでやればよいジャン。

746 名前:デフォルトの名無しさん :2001/06/27(水) 13:54
>>715で本人がいってるけど、要するに30個もクラスつくりたくね〜って
事じゃないかな。或いは、ディスパッチされたメソッドで、thisを弄りたい
とか。
 個人的には、「マクロで生成された、switch使うディスパッチ関数」
って奴の出番だと思うけどな。

747 名前:デフォルトの名無しさん :2001/06/27(水) 15:47
有限状態オートマトンというか状態遷移マシンを素直に実装する
ときには、メンバ関数へのポインタでも十分じゃあないかなあ。
過ぎたるは及ばざるがごとし、ってことわざもあるし。
(大は小を兼ねるともいうけど)

748 名前:デフォルトの名無しさん :2001/06/27(水) 19:39
>>747
そのようなC-styleが素直と言う人もいるとは思うけど、
わざわざメンバ関数にするメリットはないのでは?
名前空間分ける目的なら、namespaceつかえば良いし。

C-styleで何十ステートもある状態マシンやるなら、
いっそのことyaccでも使った方がお手軽だと思う。

C++でOOなら素直に一状態、一オブジェクトでしょう。
感覚的にも解りやすいし、使い回しが簡単になる。
遷移ヒストリー機能を付けたりとか、undo機能をつけるとか、
やりたくなったときにすぐに対応出来る。
なにより、遷移図がUMLで描けるのが嬉しいはずでは?

# なんか>>691から話が離れていってる。スマソ

749 名前:デフォルトの名無しさん :2001/06/27(水) 20:55
>>741
リーク

750 名前:741 :2001/06/27(水) 21:44
晒し上げされちゃったよ〜

>>749
すんまそん。マジどこかわからないっす。
newしっぱなしなのは勘弁して下さい。
Java厨なもんでdelete使えないです。


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