[表示 : 全て 最新50 1-99 101- 2chのread.cgiへ]
Update time : 06/01 02:39 / Filesize : 30 KB / Number-of Response : 122
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【初心者歓迎】C/C++室 Ver.54【環境依存OK】



1 名前:デフォルトの名無しさん [2008/05/14(水) 01:00:02 ]
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.53【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1208989385/l50
【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm

2 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 01:11:50 ]
前スレ>>996はstringstreamやstringの代わりに
(あるなら)wstringstreamとかwstringを使えって意味ね

3 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 01:14:32 ]
お、995はstringとstringstreamなのか。
wstringとwstringstreamだと思い込んでいた。

4 名前:前スレ995 mailto:sage [2008/05/14(水) 01:22:30 ]
STLをwstringstreamとwstringに変えてLPWSTRをLPCWSTRに変えたら出来ました。
本当にありがとうございました。

int i = 123;
std::wstringstream ss;
ss << i;
std::wstring mes = ss.str();
LPCWSTR omes = (LPCWSTR)mes.c_str();
MessageBoxW(0, omes, L"型変換", MB_OK);

5 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 02:21:48 ]
その場合キャストは要らないはず、というか
キャストでなんとかするってのは、はじめのころは
あんまし感心しないコードになることが多い気がする。

6 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 04:09:31 ]

◆6月にマネージャパン、月刊アスキー、週刊アスキーの3誌が賞金総額2000万円の「シストレFXグランプリ」を開催
system-trading.jp/news/index.php?cID=3

5月22日より登録受付開始、6月2日よりグランプリ開始の予定。賞金総額2000万円。
  デモトレードの優勝者には賞金三百万円がプレゼントされます。


▼トレード部門
初期資産500万円で、デモ取引のトレード収益を競っていただきます。
www.fx-gp.com/about/

▼賞金総額
■社長特別賞(シストレソフト買取価格) 10,000,000円
●シストレソフト部門賞 1位300万円 2位100万円 3位50万円
●トレード部門賞 1位300万円 2位100万円 3位50万円
●前期MVP賞 50万円
●後期MVP賞 50万円

7 名前:デフォルトの名無しさん [2008/05/14(水) 15:04:43 ]
どこにも情報が無いのでこちらで質問をさせていただきます。
eVC++4.0 にて組み込み開発を行っているのですがどうしても下記のwarningが出てしまいます。

class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo'

上記エラーが発生した原因はメンバインスタンス変数を static に変更し、かつ、ポインタ
ではなく実体を持つように修正したからだと思われます。

class Foo
{
public:
Hogehoge *hogehoge;
};
    ↓
class Foo
{
public:
static Hogehoge hogehoge;
};

warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。


8 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 16:07:44 ]
strncpy, snprintf, memcpy などの関数でサイズ引数を0にした場合の挙動って定義されてるんでしょうか?
やっぱり自分でチェックした方が無難?

9 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 18:20:01 ]
>>7
そのメッセージの前に警告番号とか出なかった?
あと警告やエラーはそれのみ?

>>8
それぞれの関数の仕様を確認すること。
「など」に対しては定義されてないので。
未定義や不定の条件に書いて無ければ、サイズ0もOK。
ただしサイズが負の数みたいな、
有り得ない値は逆に、何も書いてなければNG。


10 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 18:31:03 ]
size_tだから負の値はない。
それでももちろんsize_tで表現できる最大値とか明らかにおかしいだろって値は存在するけど。



11 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 18:33:43 ]
>>7
Hogeは具体的に何のクラス?
デフォルトコンストラクタがないとか値として持てないクラスじゃね?

12 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 18:34:27 ]
>>8
ありがとうございます。WG14/N843というのを拾ってきたので読んでみました。

snprintf() についてはサイズ0を指定してもよくて、その場合書き込み先バッファはNULLでもいいみたいです。
strncpy()とmemcpy()ではサイズ0の場合については何も書かれてないので、サイズ0もOKみたいですね。
サイズ0のときにバッファをNULLにしてもいいのかどうかまではちょっとわかりませんでしたが…。

あと、サイズはだいたいsize_tで指定するので負になるという心配はあまりなさそうです。

13 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 20:26:17 ]
>>12
サイズ0のときはNULLにして良いよ。
サイズ0なら、指定したバッファのアドレス自体にもアクセスしてはいけないから、
アクセスしたら関数側のバグになる。

14 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 20:55:42 ]
何も書かれてないということは、未定義動作じゃないのかね?

15 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 21:44:07 ]
派生クラスのコンストラクタから、 初期化リスト?経由で基底クラスのコンストラクタ を呼び、
そこから派生クラスで実装されている純粋仮想関数を呼びたいのですが、不可能でしょうか?
これが出来ると基底クラスのコンストラクタを再利用出来るし、違う処理(初期化)が必要な部分は
仮想関数の実装を変えるだけでいいので便利だと思ったのですが。

16 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 21:52:47 ]
>>15
できません
基底クラスのコンストラクタ実行中は派生クラスは未構築だからです

17 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 22:10:34 ]
>>16
やはりダメですか・・・
うーん。自分の設計が悪いせいか、基底クラスのコンストラクタ今一役立たずだな・・・

18 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 22:18:57 ]
>>7
>warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。
英文のままですね。英文の意味が判らないのなら鼬害でしょう。
まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが。

19 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 22:22:21 ]
>>17
簡略化した例を示せば賢い人が答えてくれるかも

多分C++ではそういうときにはテンプレートの出番になると思うけど

20 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 23:36:19 ]
>>14
>何も書かれてないということは
いや、書かれていることになる

上の例で出ている関数などでバッファポインタとバッファサイズを取るものは、
[buf, buf+size) の範囲内がアクセス可能ということを要件としているので、
size==0のときはbufのアドレスが何であれ要件を満たすことになる

>>15
似たようなことをする方法はいくつかある

・仮想関数をvfuncとして、基底クラスにinit()などを用意して、
 派生クラスのコンストラクタから呼ぶ
  ※ 基底ctor -> 派生ctor -> 基底init() -> 派生vfunc()

・基底コンストラクタに関数ポインタ類を渡す

・templateクラスにして継承関係を逆にする
  ※ template<class T> class base : T {};



21 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 23:40:30 ]
ostringstreamクラスに、
ostringstreamオブジェクトの先頭に任意の文字列を追加できる関数ってありますでしょうか??
探しても見つからなかったのですが。


22 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 00:02:36 ]
>>21
こんなことならできる

int main()
{
using namespace std;
string t("abc");
ostringstream s;
s << "xyz";
s.seekp(0);
s << t + s.str();

cout << s.str() << endl;

return 0;
}


23 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 00:07:18 ]
>>21
一応ストリームなんだから、そういう操作は仮に出来ても勧められないな・・・

前後だけで良いならfront側とback側にstringstreamを持ってstr()時に
結合するラッパーを作るという手はある
超手抜きで書くと
struct {
  ostringstream front;
  ostringstream back;
  string str(){return front.str() + back.str();}
};

またはstd::list<std::string>で構築して、必要になった際に全結合するなど

24 名前:23 mailto:sage [2008/05/15(木) 00:10:53 ]
リロードしてなかった
>>22が手軽で良いかもな

それと>>23のfront云々のところは素でボケてたので無かったことに・・・

25 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 02:38:37 ]
>>19-20
レスありがとうございます。
なるほど、テンプレートや関数ポインタですか。
しかしC++は奥が深そうですね・・・

26 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 07:14:40 ]
Yo Yo俺ニート!

27 名前:7 [2008/05/15(木) 12:11:02 ]
>>9
質問するのに肝心な部分を書いてませんでした。
warning C4251 がエラー番号に該当すると思います。
>>11
規約としてデフォルトコンストラクタ、デストラクタは定義
しなければならないのでその点は問題ありません。
>>18
>まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが
cppファイル内で実体化させているのか、という意味ならば実体化させているので
その点は問題ないように思います。
試しにstaticをはずしてみたのですが、同様のエラーでした。

NULLチェックやdelete処理などが面倒なので実体を持つようにし、かつ、1つのシステム内で
唯一1つのインスタンスしか使用しないのでstaticで良いじゃないか?
staticにするとわざわざどこかのクラスから参照やポインタで辿っていかなくても Foo::hogehoge
とアクセスできるから楽じゃないか?
と安易に思ったのが失敗だったんでしょう。

28 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 12:14:39 ]
C4251 だけ書いて内容書かないのは、こっちで調べろってこと?

29 名前:7 [2008/05/15(木) 12:30:25 ]
>>28
言っている意味がわからないのですが、こちらでどう調査しても
warning C4251: 'hogehoge : 'class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo'
しかわからない
上記warningが発生した原因は特定インスタンスメンバをポインタではなく、static かつ 実体として持つようにした
というのは 7 で書いたつもりです。
言葉足らずのところはこちらのミスですので謝りますが。
エラー番号ではなく警告番号でしたが、どう調査してもC4251しかわかりません。


30 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 12:40:36 ]
>>29
Hohehogeの宣言を晒してくれなきゃワカンネ。
エラーが起こる最小のコードをup



31 名前:デフォルトの名無しさん [2008/05/15(木) 12:46:16 ]
平均点の高い順に並べ替えて表示するプログラムを作りたいのですが、結果が表示されません;
どこをどのように直したらいいか教えてください。お願いします。

kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6554.c

32 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 12:55:41 ]
>>31
sort()とやらはgccの拡張機能である、関数内関数定義を行っているだけで呼び出していないから。
他にもいろいろ突っ込みどころだらけだが……

33 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 12:57:32 ]
なんか、ロジックをいろいろ寄せ集めただけっぽいな。
ソートを自分で書くのが目的なら、渡すデータ型に注意だ。

34 名前:7 [2008/05/15(木) 13:00:59 ]
>>30
そういうことですか!!
確かに質問するにあたって情報が足りなかったですね。

warningが発生するHogehoge最小ソースは

class Hogehoge
{
public:
Hogehoge(){};
virtual ~Hogehoge(){};
};

です。


35 名前:31 [2008/05/15(木) 13:05:37 ]
>>32
main関数の前に
void sort(int *p,int n);
を付け加えました。

他に間違ってるところってどこですか?

36 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 13:08:23 ]
>他に間違ってるところってどこですか?
たくさん。あり過ぎて指摘する気にもならん。
まぁ、作った関数は呼ばなきゃ意味がないことくらいは判るだろうから、
後はコンパイラのエラーメッセージをよく読んで順に潰せ。
そうそう、gccを使っているだろうから、gcc file.c -ansi -Wall -pedanticすることをお勧め。

37 名前:32 mailto:sage [2008/05/15(木) 13:10:43 ]
>>35
私の指摘をちゃんと読んでますか? 「関数呼び出し」って、理解できますか?

38 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 13:11:36 ]
class HogeHoge
{
public:
HogeHoge(){};
virtual ~HogeHoge(){};
};

class Foo
{
public:
static HogeHoge hogehoge;
};

int main ()
{
Foo myClass;

return 0;
}
問題なく通るけど…

39 名前:38 mailto:sage [2008/05/15(木) 13:14:35 ]
VC++2005EE

40 名前:32 mailto:sage [2008/05/15(木) 13:15:08 ]
>>34
>38だとhogehogeの実体を参照しないからエラーにならないかと。
Hogehogeだけ抜き出さずに、実際にそのエラーが出るソースを作って貼ってみては?



41 名前:7 [2008/05/15(木) 14:08:53 ]
さらに色々調査してみたところ、ソースコードというよりも環境が怪しい気が
してきました。
もう少し調べてみます。

42 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 14:10:17 ]
もうこなくていいよ

43 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 15:58:58 ]
>>7
C4251でググったりはしたよね?

44 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 16:09:49 ]
> HogeHoge(){};
> virtual ~HogeHoge(){};
セミコロン要らないだろ

45 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 17:54:36 ]
struct point{
double x;
double y;
};


struct point q[200];

memcpy(q,p,(n+1)*sizeof(struct point));

これってどういう事をやってるんですか?

46 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:02:55 ]
pが指す所から(n+1)*sizeof(struct point)バイトqの所にコピーしてる

47 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:08:27 ]
>>45
恐らくはstruct point * pがあるとして、
先ずはpoint構造体の要素数200の配列qを宣言している。
続いてその配列qに、point構造体(n+1)個分のデータを配列pからコピーしている。
この部分は、for (int ic = 0; ic < n + 1; ++ic) q[ic] = p[ic];とほぼ同等。

48 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:19:35 ]
すいません。

int func(int n,struct point p[],double d){
struct point q[200];

;
memcpy(q,p,(n+1)*sizeof(struct point));


}

みたいに構造体が引数で渡されています。

49 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:21:52 ]
>>48
「構造体」ではなく、「構造体へのポインタ」ね。つまりは、>47。

50 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:24:31 ]
なるほどわかりました。

実際のpの大きさがソースを書くときには不定なので、
for文での代入をしていないってことでしょうか?



51 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:27:58 ]
>>50
いや違う。pの大きさは、常に一定だ。何故ならpはポインタ変数だからだ。
pが指す領域のサイズについてはnに依存するわけだが、forループでも勿論巧くコピーできる。

では何故memcpy()を使うかというと、保守性よりも(見かけ上の)効率を優先したか、単に習慣か、
書いた人間にでも聞かないと判らないだろう。

52 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:29:13 ]
for文で1個ずつでもいいけど、丸ごと全部いっぺんにやったほうが早いべ

53 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:42:40 ]
いいえ、一概には言えません。まともなコンパイラにまともに最適化させてやれば恐らくは、目に見える速度差はないでしょう。

54 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 18:46:59 ]
書く量だって少ないし、コーディングも早いだろ。

55 名前:45 mailto:sage [2008/05/15(木) 18:49:17 ]
いろいろ教えていただきありがとうございました。



56 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 19:00:21 ]
>>54
>memcpy(q,p,(n+1)*sizeof(struct point));
39文字
>for(int i=0;i<n+1;++i)q[i]=p[i];
32文字

57 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 20:30:03 ]
VC++でインラインアセンブリを使うとき、
疑似命令によくある、生データを直接コードに埋め込む事って、どのようにすればいいのですか?
テーブル参照のようなことを仕様と思ったのですが、やり方がよくわからなくて…

58 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 20:34:29 ]
>>53
逆に言えば
memcpyみたいな動作をする命令があるから、
まともでない(古い)コンパイラだとfor使うより遙かに速く動作する

そういう意味では書く人の習慣の影響が強いが

59 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 22:04:53 ]
だんだんコンパイル速度が遅くなってきたので、参照箇所の
多いクラスにPimplを導入しようかと思ってるのですが、Pimplに
すると問題のあるケースなんてのもあるんでしょうか?

60 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 22:11:37 ]
>>56
>memcpy(q,p,(n+1)*sizeof(*p));
29文字



61 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 22:27:54 ]
std::copy(p,p+n+1,q);
21文字

62 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 22:45:30 ]
>>59
pimplを経由することによる性能上のオーバーヘッド

63 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 23:02:23 ]
>>59
メモリ確保のオーバーヘッドと、メモリ確保に失敗する可能性の増加。

64 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 23:23:16 ]
>>62,63
なるほど。速度が重要な物や大量に生成される物には
避けた方が良さそうなんですね。

65 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 23:24:01 ]
>>59
仮にPimplによる問題が出ても、
大した手間無く対処出来るから気にする必要無いよ。

66 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 23:36:11 ]
>>59
相互参照の必要な場合が多いとソースが汚く見えるようになる。

67 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 02:57:03 ]
すいません、質問お願いします。
独習Cで勉強しているのですが、月での実効体重だす問題で関数を作ったのですが
float moon(void)
{
float weight;

printf("体重を入力してください:");
scanf("%f",&weight);
return weight*(17/100);
}

という関数を作った時に
「return weight*17/100」や「return weight*0.17」時は正しい値を返してくれるのですが、
自分が分かりやすいように式を()で囲うと正しい値を返してくれずに0.00000という値が返ってきます。
理由がわからないのですが、どなたか分かる方教えて下さい。

68 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 02:59:30 ]
すいません、>>67ですが、環境はDev−C++です。

69 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 03:01:40 ]
intをintで割ったときでも値はint。つまり(17/100)は小数点以下が切り捨てられて0になる。
(17.0/100)とかならOK

70 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 03:04:13 ]
>>67
17と100が整数だから、17 / 100の結果も整数(切り捨てで0)になってしまう。

weight * 17 / 100と書いたときには、(weight * 17) / 100と扱われ、
weight * 17がfloat型で結果を返し、それに整数100を掛けても
やっぱりfloat型になるのでうまくいくという具合。

逆にいえば、17などをfloat型にすればいいわけで、
return weight * (17.0f / 100.0f);とすればうまくいく。



71 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 03:09:58 ]
>>69
>>70
なるほど、型が大きいほうに合わせられるっていうのは数値だけの計算にも当てはまるんですね。
変数だけしかそういう風にならないと勘違いしていました。
非常に分かりやすい説明ありがとうございました。勉強になりました。


72 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 11:46:56 ]
直書きの数値にも型はあるんだぞ

73 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 11:58:44 ]
リテラルと言いましょう

74 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 13:09:38 ]
すまん、用語には疎いもんで・・・

75 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 20:39:22 ]
>>20

>・templateクラスにして継承関係を逆にする
>  ※ template<class T> class base : T {};

これ、よく分からないので具体例あげてくれるとありがたい。

76 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 03:21:50 ]
struct A {
A() { f(); }
virtual void f() = 0;
};

struct B {
virtual void f(){}
};





template<class T>
struct X : T {
X() { f(); }
};

struct Y {
void f() {}
};

typedef X<Y> Z;


77 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 03:22:49 ]
修正
> X() { f(); }
X() { T::f(); }

78 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 09:58:03 ]
質問です
先日基底クラスのデストラクタを仮想にし忘れ、メモリーリークというお約束のミスをやってしまいました。
この手のミスを無くしたいのですが、warningを出させる方法や、チェックツールなどはないでしょうか?
環境はVS6.0です。

仮想関数テーブルへのアクセスによるオーバーヘッドは現状気にしていないので、全てのクラス関数を仮想にしたいのですが、たまにつけわすれてしまうのです。

79 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 10:04:15 ]
初心者です。
C++を学ぼうと思ってるんですが良い参考書orWebページはありますか?


80 名前:75 mailto:sage [2008/05/17(土) 10:09:49 ]
>>76-77

ありがとう。
ただこの方法だと元々の継承関係が失われないかい?
(76はミスタイプと思うが、元々はstruct A : B)

質問者は継承関係は維持したいと思うけど。



81 名前:75 mailto:sage [2008/05/17(土) 10:13:13 ]
>>80

というか継承と同じことをテンプレートで実現するってことかな。あってる?

82 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 13:28:04 ]
>>78
「メモリリーク 検出」とかでググれば解説してるサイトがいっぱいでてくる

83 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 13:55:08 ]
>>78
デストラクタを仮想にした基底クラスを作って、クラスを作るときに必ずそれを派生して使うようにすれば忘れることはない。

84 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 13:57:15 ]
>>83
それを忘れないようにするためって話じゃないのか?w

85 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 13:58:33 ]
>>83
デストラクタの話ね。


86 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 14:43:18 ]
>>83はルート基底クラス(C#とかのObject)を用意することで、
個別にvirtualを書かなくて済むようにした方が良い、って意味なのでは?

でもそしたら今度は、それ継承するのを忘れない方法は?
って話になりそうだけど。

87 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 14:46:51 ]
クラスを定義するときに専用のマクロを使うことにするとか

88 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 14:57:06 ]
>>87
それを忘れないようにするためって話じゃないのか?w

89 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 15:02:42 ]
>>88
忘れにくさという点で、
>>78より>83
それより>>87
と良くなっているように見えるけど。

90 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 15:10:27 ]
コピペ煽りに律儀に答えなくても



91 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 15:42:28 ]
class NewClass : public Object
の : public Objectを書かなかったらやっぱりバグるわけだしなー
それじゃ意味ないだろう

継承しなければコンパイルエラーになるようにできるなら、別だが。

92 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:13:22 ]
なんでループしてんの?

93 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:19:14 ]
struct Object{virtual ~Object(){};};
#define STD_STRUCT(NAME) struct NAME : public virtual Object
#define STD_CLASS(NAME) class NAME : public virtual Object

STD_CLASS(ClassA) {
public:
  ~ClassA(){std::cout << "~ClassA" << std::endl;}
};

STD_CLASS(ClassB), public ClassA {
public:
  ~ClassB(){std::cout << "~ClassB" << std::endl;}
};

void f()
{
  ClassA* p = new ClassB();
  delete p;
}

94 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:27:10 ]
そしてそのマクロを使うのをつい忘れるわけですね、わかります

95 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:30:03 ]
>>94

>>89

5レス前すら読めない人はこのスレに必要ありませんよ

96 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:31:46 ]
いや、お前ら質問者の意図無視しすぎだろw

97 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:33:46 ]
ツールでなんとかしたいと言ってる人間に、忘れないようにマクロを使いましょうってどんな返事なんだ
俺は必要としたことないから知らんが、書式チェックツールくらいないのか?

98 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:36:19 ]
virtual忘れをチェックしてくれるツールくらい自分作ればいいんじゃね
デストラクタは先頭に ~ が付いててわかりやすいから、
その前にvirtualが付いてるかどうかくらい簡単に判定できそう
そもそもデストラクタを書いてない場合は役に立たないが・・・

99 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 16:38:42 ]
>>96
>>78を読む限り、まずミスを無くしたい、という目的があって、
その方法として警告、チェックツール「など」、
と手段の例を挙げているので、
同じく、ミスを無くす/減らす方法を書いてるレスが
意図を無視してるようには見えないけど?

100 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 17:06:19 ]
とりあえず、抽象型へのアップキャストは極力控えて、
総称型プログラミングを覚えた方がいいと思った。



101 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 17:08:30 ]
>>100
実行時ポリモーフィズムが必要な場合はどうするの。

102 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 17:10:55 ]
だから極力控えて、って・・・。

103 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 17:31:36 ]
静的な方が安全というのは分かるが、
export のない C++ でジェネリックばっかやってると
コンパイルが重くて現実的じゃない事も。

104 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 21:16:08 ]
>>98
そしてそのツールでチェックするのをつい忘れるわけですね、わかります。

105 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 22:34:11 ]
>>104
make使うならMakefileに組み込めばおk。
総合環境なら・・・ カスタムビルドステップ?

106 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 22:42:35 ]
>>104
最悪、考え方としてはおかしくなったときにチェックすればいいわけだし。

107 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 23:08:54 ]
あれ?ちょっとずれるが
なんかの統合環境で、virtualな関数をオーバーライドする時にvirtualつけておかないとワーニング出すって設定できたよな?
これはvirtualですよー、わかってますかー?って意味合いで


108 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 00:36:52 ]
微妙に宣言間違えて、いつの間にか別の仮想関数が作られちゃうのを防ぐ方法ってないかな。
delphiならviryualで新しく作って、overrideでオーバーライドするから間違えたらエラーになるんだがなぁ


109 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 00:37:37 ]
virtualだな


110 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 00:41:27 ]
override は最近の言語によく取り入れられているね。
あれはいい仕様だと思う。



111 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 01:18:54 ]
>>107
それは余計なお世話な気もするな。コーディング規約レベルだと思う。

112 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 01:25:16 ]
いんや。
仮想関数じゃないつもりで関数追加して泣きを見るのを防止できる。

113 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 09:07:18 ]
なんにしろON/OFFできりゃいいんだよな
overrideはいい仕様だ

114 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 11:38:49 ]
Java みたいに問答無用で仮想関数にする言語は
typo で泣くことになる。

115 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 11:52:39 ]
そうした事もあって、C#では明示的にoverrideする必要になりましたとさ

116 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 12:19:28 ]
それにならって、javaもoverrideをチェックする
アノテーションが用意されました。

117 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 13:19:39 ]
そしてC++はほったらかしと。

118 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 13:30:36 ]
C++ は互換性を異常に気にするからな。

119 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 13:40:20 ]
override付きのときだけチェックしてくれれば良いんだけどなぁ。その他(virtual付き/何もなし)の時は今まで通りで。

120 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 13:42:08 ]
それはあんまり override の価値がない気が



121 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 13:42:41 ]
override が無い時に警告出してくれるならいいけど






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](*・∀・)<30KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef