[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 06/03 14:53 / Filesize : 254 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


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

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



1 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 16:10:55 ]
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

【前スレ】
【初心者歓迎】C/C++室 Ver.68【環境依存OK】
pc12.2ch.net/test/read.cgi/tech/1253193779/

【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め)

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か   に置換すると見栄えだけはよくなります。

2 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 16:39:55 ]
>>1
お疲れさまです。

3 名前:前スレ964 [2009/10/20(火) 16:45:59 ]
pc12.2ch.net/test/read.cgi/tech/1253193779/
atexit()で終了関数呼び出して
その中で
delete this;
なんてやったらだめなんでしょうかね?

4 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 16:56:21 ]
pc12.2ch.net/test/read.cgi/tech/1253193779/764かな?
そこまでして自己破壊する理由は?
単にexit()を使わなければいいだけなのに敢えてそうしない理由が判らん。

5 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 17:11:15 ]
> exit関数をつかったらデストラクタを呼び出せずにプログラムが終了してしまうので
exit関数を使わなければよいことは分かってるんでしょう。
その上で、どうしてもexit関数を使いたいってことだろうから
余程の事情があるんだと思うよ。
好奇心からという可能性も。

6 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 17:46:34 ]
>>3
exitを使わない方法を検討した方がいいよ

7 名前:前スレ964 [2009/10/20(火) 18:18:10 ]
まちがえた>>764です

8 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 19:37:58 ]
>>3
exitすれば自動変数のデストラクタが呼ばれないから無理です。

9 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 23:00:43 ]
だがちょっと待ってほしい。atexitで自動変数のクラスオブジェクトのデストラクタを呼ぶ
というのはどうか。

hoge.~hoge();


10 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 23:14:07 ]
>>9
スタックが全部破棄された後なんだからダメだろうよ。



11 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:07:30 ]
ウィンドウズモバイルとか携帯用OSでC/C++ってできるの?


12 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:09:50 ]
できるよ。

13 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:24:50 ]
まじポン?

14 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:27:28 ]
「できる」の意味がわからんが、使えないわけがないだろう。

15 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:29:59 ]
visual c++とかも使えるのか

16 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 00:33:09 ]
eMbedded Visual C++ 4.0

17 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 05:47:46 ]
BREWとかもC++環境は一応あるな
制約が相当ひどいけど、少しずつマシにはなっている模様(例外が使えなかったのが
使えるようになったり)

18 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 11:01:08 ]
どうすればいいんでしょうか?

19 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 11:03:22 ]
何をどうしたいんでしょうか?

20 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 13:11:16 ]
GetWindowRectがうまくつかえません、教えてください
左上100,100の座標にあるウインドウのサイズを取得したいのですが
GetWindowRect関数でエラーが出てしまいます
#include <iostream>
#include <string>
#include <windows.h>
#include <WCHAR.H>
using namespace std;
int main(){

HWND bbb ;
POINT aaa = {100,100};
bbb = WindowFromPoint(aaa);//左上のウィンドウを取得

LPRECT x ; //ウィンドウの座標値用変数
GetWindowRect(
bbb, // ウィンドウのハンドル
x // ウィンドウの座標値
);
cout<<x->top<<"\n"<<x->bottom<<"\n"<<x->left<<"\n"<<x->right<<"\n";
}



21 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 13:13:10 ]
>>20
危ないから、xはポインタにしないで〜。

22 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 13:35:16 ]
#include <iostream> 
#include <string> 
#include <windows.h> 
#include <WCHAR.H> 
using namespace std; 
int main(){ 
HDC hdc=NULL;
HWND bbb=NULL ; 
POINT aaa = {100,100}; 
bbb = WindowFromPoint(aaa);//左上のウィンドウを取得 

RECT x ; //ウィンドウの座標値用変数 
GetWindowRect( 
bbb, // ウィンドウのハンドル 
&x // ウィンドウの座標値 
); 
/*omake*/
hdc = GetDC(NULL);
MoveToEx(hdc,x.left,x.top,NULL);
LineTo(hdc,x.left,x.bottom);
LineTo(hdc,x.right,x.bottom);
LineTo(hdc,x.right,x.top);
LineTo(hdc,x.left,x.top);
ReleaseDC(NULL,hdc);
/**/
cout<<x.top<<"\n"<<x.bottom<<"\n"<<x.left<<"\n"<<x.right<<"\n"; 
return 0;


23 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 13:41:06 ]
>>21-22
ありがとうございます!

24 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 14:41:16 ]
C言語始めたばかりのものです。
ファイルを開いて、1レコードづつ読みこんでから各項目ごとに決められた
バイト数で分けるのって、どうゆう関数を使えばいいんでしょうか


25 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 14:47:24 ]
fopen(), fclose()
fgets()
sprintf()

26 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 14:53:02 ]
ほかのプログラムの出力をメモリに読み込むにはどうすればいいの?

たとえば適当な数列を並べて出力するプログラムがあったとして
それを文字列としてstringに入れるといった感じで

27 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 15:00:42 ]
>>26
大抵の環境なら、リダイレクトを使えばいい。
例えばWindowsなら
some.exe | other.exe
unix系なら
some | other
といった要領。
これなら前者は標準出力でいいし、後者は標準入力でいい。
必要なら、片方がもう片方をpopen()で起動してもいい。
双方向であったりパフォーマンスが要求されるなら事が足りないが、
先ずはこの辺りから始めては如何か。

28 名前:デフォルトの名無しさん [2009/10/21(水) 15:08:32 ]
>>25
ありがとうございます。
やってみます

29 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 15:59:14 ]
ポップアップメニューを表示させたくて、下のコードを書いたんですが、セパレータが一つあるだけのポップアップメニューが表示されてしまいます。
本当は「v メニュー」というのが表示されて欲しいのですが。どこを直せばいいでしょう。
環境はVC++2008EEです。

HMENU menu = CreatePopupMenu();
MENUITEMINFO mii;
memset(&mii, 0, sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
mii.fType = MFT_STRING;
mii.wID = 1;
mii.fState = MFS_CHECKED;
mii.dwItemData = (DWORD)"メニュー";
InsertMenuItem(menu, 0, true, &mii);

POINT pt;
GetCursorPos(&pt);
TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, hwndView, NULL);
DestroyMenu(menu);

30 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 16:06:35 ]
メソッドの返り値を.演算子呼び出しのときと->演算子呼び出しのときで分岐することはできますか?

struct widget
{
    xxx method();
};

widget w, *p = new widget;

w.method(); // 参照を返したい
p->method(); // ポインタを返したい

// ↓のように使いたい

w.method().method().method();
p->method()->method()->method();

// ↓のような形は統一感がないから避けたい

p->method().method().method();



31 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 16:07:44 ]
>>10
実験してみたら、スタックが全部破棄される前にatexitで登録した関数で
デストラクタを走らせることができたよ。

32 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 16:10:29 ]
>>30
> w.method().method().method();
> p->method()->method()->method();

こっちのほうがよっぽど統一感がない。

そもそも.演算子はオーバーロードできない。

33 名前:29 mailto:sage [2009/10/21(水) 16:15:48 ]
mii.dwItemData = (DWORD)"メニュー";
のところを
mii.dwTypeData = _T("メニュー");
mii.cch = wcslen(mii.dwTypeData);

にしたら一応出るようになりました。失礼しました〜。

34 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 16:54:41 ]
最近気がついたんだけど、メンバ変数を下のほうに書くスタイルだとclassよりstructのほうが楽だね


35 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 17:31:57 ]
>>34
何がどう楽?

36 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 17:34:53 ]
デフォルトプロテクションじゃね? しらんけど

37 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:31:40 ]
総和を求めるプログラムです、いつも思うのですが、この
template <typename T, class Iterator>
という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できないでしょうか?
具体的に説明しますと
std::vector<int> vec;
std::vector<int>::iterator = vec.begin();
このvec.begin() からint 型を推論できないでしょうか?

template <typename T, class Iterator>
T Sum(Iterator& first, Iterator& last)
{
T sum = 0;
while ( first != last ) {
sum+=*first;
++first;
}
return sum;
}

38 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:40:38 ]
>>37
std::accumulateに何の不満があるのか

39 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:46:33 ]
>>37
std::iterator_traits<Iterator>::value_type

40 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:50:08 ]
>>38
ありがとうございます。
たしかに、acumulate で総和は求まるのですが、総和を求めるということは
今回、例えであって、疑問の本質はIterator からT 型が推論できるテクニックが知りたいのです、
言葉足らずですみません。




41 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:51:20 ]
>>39
ありがとうございます
やっと、std::iterator_traits の意味が理解できました。

42 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:52:03 ]
C++0xならもっと気楽になるね

43 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 19:53:42 ]
質問の本質をちゃんと読めないコミュ力不足の回答者って困るよね


〜はどう実装してるの? つミboost::hogehoge ←こいつマジアホ


44 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:03:02 ]
この質問内容だとaccumulateを提示されるのは当然じゃね

45 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:04:26 ]
言葉足らずというか余計なこと言うからじゃね?

46 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:04:27 ]
Boostならともかく標準だしなぁ

47 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:06:42 ]
template <typename T, class Iterator>
という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できないでしょうか?
総和を求めるプログラムを例として説明しますと

という書き始めであればよかったと

48 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:08:26 ]
つーか>>43が要らないだけじゃね?

49 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 20:24:41 ]
>>47
これがベストかな。一応質問では推論できないか?というところが疑問文だから、
それに答えればいいのだろうけど。まあ、でも、誤解はしなかった。

50 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 22:36:30 ]
>>31
スタックが破棄される前なのか後なのか、どうやって確認したんだ?



51 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 22:37:13 ]
>>30
(*p).method().method().method() ですべて解決だ。

52 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:01:21 ]
>>41です。おかげさまで、
template <typename T, class Iterator>
という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できるようになりました。ありがとうございました。
さて、教えて頂いた知識をベースに標準偏差を求めるプログラムを作り、コードをここに貼りました
codepad.org/H2ZC4RSO(掲示しているcodepad のコンパイラではエラーが出ていますが、VS2005 ではコンパイル、実行できます)
StandardDeviation クラスに、下記の関数を組み入れたいのですが、上手くいきません、方法を教えて頂けないでしょうか。
/**
* @brief 平均値
* @param[in] Iterator first 配列の先頭
* @param[in] Iterator last 配列の末尾
* @return sum / cou 平均値
*/
template<class ResultType>
typename std::iterator_traits<ResultType>::value_type average(ResultType first, ResultType last)
{
typedef std::iterator_traits<ResultType>::value_type value_type;
value_type cou = last - first;
value_type sum = std::accumulate(first, last, value_type(0.0));
return sum / cou;
}

53 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:16:42 ]
template<class ResultType>
typename std::iterator_traits<ForwardIter>::value_type average(ForwardIter first, ForwardIter last)
{
typedef std::iterator_traits<ForwardIter>::value_type value_type;
value_type cou = *last - *first;
value_type sum = std::accumulate(first, last, value_type(0.0));
return sum / cou;
}

54 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:17:13 ]
>>52
std::iterator_traits<ResultType>::difference_type

55 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:17:24 ]
あ、1行目もForwardIterね

56 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:20:19 ]
>>52
イテレータの距離を求めるにはstd::distanceを使う。

57 名前:53 mailto:sage [2009/10/21(水) 23:24:39 ]
なんか俺意味わからないことやってるね。死のう


58 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:31:10 ]
>>41 です
皆さんありがとうございます。これでいいのかな?そして、この平均値を求める関数を、クラスに組み入れるにはどうしたらいいのでしょうか?
わざわざ、クラスに組み入れなくてもいいじゃんという、意見も聞こえてきそうなのですが、教えて頂けないでしょうか。
template<class ForwardIter>
typename std::iterator_traits<ForwardIter>::value_type average(ForwardIter first, ForwardIter last)
{
typedef std::iterator_traits<ForwardIter>::value_type value_type;
value_type cou = std::distance(first, last);
value_type sum = std::accumulate(first, last, value_type(0.0));
return sum / cou;
}

59 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:35:00 ]
class Hoge { template <・・・> ave(I f, I l) {・・・ } };

Hoge h; res = h.ave(f, l);

60 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:44:11 ]
>>58
couの型はvalue_typeじゃないだろ。




61 名前:デフォルトの名無しさん mailto:sage [2009/10/21(水) 23:53:42 ]
>>58 です、下記の通りにしますと、こうなってしまうのですが?
error C2955: 'StandardDeviation' : クラス テンプレート を使用するには テンプレート 引数リストが必要です
error C2133: 'sd' : サイズが不明です。
error C2512: 'StandardDeviation' : クラス、構造体、共用体に既定のコンストラクタがありません。
error C2662: 'double StandardDeviation<ForwardIter>::average<std::_Vector_iterator<_Ty,_Alloc>>(ForwardIter,ForwardIter)' : 'StandardDeviation' から 'StandardDeviation<ForwardIter> &' へ 'this' ポインタを変換できません。
template <typename ForwardIter>
class StandardDeviation
{
ForwardIter val_;
public:
template<class ForwardIter>
typename std::iterator_traits<ForwardIter>::value_type average(ForwardIter first, ForwardIter last)
{
typedef std::iterator_traits<ForwardIter>::value_type value_type;
int cou = std::distance(first, last);
value_type sum = std::accumulate(first, last, value_type(0.0));
return sum / cou;
}
StandardDeviation( const ForwardIter& val ) : val_( val ){}
void operator()( ForwardIter& elem ) const
{
elem -= val_;
elem *= elem;
}
};
StandardDeviation sd;
AVE = sd.average(vec.begin(), vec.end());


62 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 00:07:29 ]
なんでそこに入れるんだよ。アホか

63 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 00:52:26 ]
codepad.org/J9oJ1Pbm

64 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 00:56:04 ]
あ、関係ないけど、>>63のfor_eachは移植性ないよ。

65 名前:41 mailto:sage [2009/10/22(木) 01:48:56 ]
>>63
標準偏差の答えが、合っています?


66 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 01:56:33 ]
size_t cou = abs( distance( first, last ) );

こう修正しないとだめだな。

67 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 02:00:56 ]
>>66
std::accumulate使ってるんだからfirst<lastを仮定していいだろ

68 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 02:17:08 ]
ふむ。確かに。では単純に

size_t cou = distance( first, last ); // first と last の順番が逆

と修正。

69 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 06:52:00 ]
>>50
別のクラスオブジェクトをmainの自動変数で作って、exit呼び出し時にデストラクタが走ってない
ことを確認した。

70 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 08:12:32 ]
>>69
デストラクタが走らないとまずいね




71 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 10:10:50 ]
>>70
だからatexit()で走らせたんだろ。

72 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 10:28:26 ]
このStandardDeviationって名前は気持ち悪いなぁ。
operator()()が返すのは単に(内部で持っている)平均値との差の平方じゃないか。
どうせなら、StandarDeviation(vec.begin(), vec.end())って関数にしてくれ(ぉぃ
# まぁ、既に手元には平均やら標準偏差やらを返すメンバ関数を持つ、クラスがあるから要らないけど。

73 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 12:35:16 ]
>>69
それがスタック破棄の前後と関係すると思ってるのなら勘違い。

74 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 12:51:35 ]
>>73
なぜ? スタックの破棄はオブジェクトの破棄を終えてから行うのでは?

75 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:15:55 ]
>>74
通常の関数脱出時の動作ではそうだけど、 exit() したときにはそもそも関数脱出の
動作は行われないのだから、関係ないでしょ。


規格を確認すると 3.6.1 p4 に exit() 呼び出し時の動作が書いてあった。
> Calling the function
> void exit(int);
> declared in <cstdlib> terminates the program without leaving the current block and hence without
> destroying any objects with automatic storage duration.

これに加えて 3.7.2 Automatic storage duration p1 から
> The storage for these objects lasts until the block in which they are created
> exits.
ということで、スタックは保持されたままなので atexit() で自動変数のデストラクタを
呼びだしても問題ないみたい。


ただし、 atexit() にその処理を正しく登録することがほとんど不可能なんじゃないかと思う。

76 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:25:50 ]
>>75
なるほど。exit呼び出し時にはオブジェクトの破棄を行わないのだから、>>69では
確認になってないということね。だが、それでは、>>10の突っ込みがよく分からないが。
>>75=>>10という意味ではない)

ただ、実験したのは>>9なので、君の言うとおり結局は問題ないでしょ。atexitに登録した
関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。
ほぼ無意味で、実用性のない手法だが、可能は可能ということで。

77 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:29:55 ]
と言うか、スタック上のオブジェクトが破棄されないのであれば、>>73の指摘の
意味がよく分からない。スタック上のオブジェクトが破棄されないのだから、
mainでの自動変数のデストラクタより、atexitに登録した関数でmainでの自動変数の
デストラクタのほうが先に走るのは当たり前だから。

78 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:42:35 ]
「よく分からない」
の使い方が変じゃないか?
>>10はそれを勘違いしてたのだろうか
>>73はスタックが保持されることを知らなかったのだろうか
とかでよくね


79 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:43:51 ]
×>>73の指摘の意味がよく分からない
>>73は俺と同じく、スタックが保持されることが確実であることを知らない人だったのかな

80 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:45:11 ]
exitを呼び出した時点で自動変数のデストラクタを呼び出さないまま、その記憶域だけが
解放されてしまう可能性があると考えていたんだろう。で、実はその心配はないという話。



81 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:45:37 ]
>>75の最終行の通りだと思う。

82 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 13:49:36 ]
>>78
変ではないと思うよ。

>>79
まあ、そういうことだね。

>>81
不可能ではないよ。実際やったので。

83 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:01:07 ]
つーかそんな怪しいことするくらいなら例外投げればいいのに

84 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:03:27 ]
>>83
>>76の最終行だね。

で、この話は前スレから続いてて、>>3>>8が突っ込んで、>>9で冗談めかして書いた
という流れ。

85 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:04:53 ]
>>82
だから、間違いなくatexit()で呼び出されるように登録することは難しいといいたいのだろ。
少なくとも、exit()を使わないと言う同程度で済むもっとスマートな方法があるのだから。

86 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:07:33 ]
>>85
>>76
> atexitに登録した関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。

これでは駄目か?

> 少なくとも、exit()を使わないと言う同程度で済むもっとスマートな方法があるのだから。

例えば? 例外は話題にあったけど、それはパフォーマンスコストが高くなる可能性があると
いう意見があった。だが、例外でってこと?


87 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:09:39 ]
分かりづらいかな。

つまり、main内で自動変数のオブジェクトのアドレスをグローバル変数のポインタに
代入し、atexitに登録した関数内でそのグローバル変数のポインタから逆参照して
デストラクタを実行する処理を書いたということ。

88 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:17:27 ]
ぶっちゃけatexitでどうにかしようとする方が遙かにコストは高いだろ
つーか例外コストを異常に高く考えすぎ

89 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:23:31 ]
>>86
正常系なら main まで return してくるのが望ましい。
異常系なら例外でおk。

90 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 14:24:55 ]
>>87
そんな方法、ふつうにいくつか関数呼び出してそれぞれに自動変数があるってだけで破綻するだろ。



91 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 15:39:42 ]
>>88 >>90
atexitで何とかするってのは元々ネタで、それが駄目とか言われたからやってみたって
流れなんじゃないの。

>>89
mainまでreturnしてくるってのは正しい手法ではあるが、普通であって、スマートではないな。
実際面倒だし。

92 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 16:38:36 ]
cデータを1件ずつ読んで、商品番号をキーに金額を集計し商品番号が変わったらブレイクして
集計した金額を出力させたいのですがif文での作り方がわかりません。
誰か教えてください。

93 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 18:33:03 ]
>>92
前の商品番号を記録しておく

94 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 19:00:24 ]
メインスレッドをサブスレッドから一時休止するためにHANDLEがほしいのですが、
メインスレッドのハンドルを取得する関数ってありますか?

95 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 19:05:22 ]
>>94
環境依存。まぁ、サブスレッド起動時に渡しておけば?

96 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 19:59:46 ]
>>91
> それが駄目とか言われたからやってみた
そんで、ほんとに出来たのかなあと思って突っ込んだらだんまりになっちゃったという流れ

97 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 20:00:58 ]
できるかできないか以前の問題だと思うがな
やれたところで糞設計すぎて全く話にならないのは確定なんだし

98 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 20:04:41 ]
struct iface
{
virtual void method() = 0;
};

class widget : public iface
{
virtual void method() { ・・・ }
};

int main(void)
{
iface *p = new widget; p->method(); return 0;
}

こういう風に継承の過程で可視性を変えるのはありなんでしょうか?

99 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:03:15 ]
>>96
できたのは事実だし、だんまりでもない。スレを読み返せ。

>>97
やりもしないでやった気でいるよりもましだと思うぜ。

100 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:06:16 ]
環境依存のことを実験しても意味ないだろ



101 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:10:01 ]
>>99
>>90とかは?

102 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:13:43 ]
>>100がどこらへんが環境依存なのか説明してくれるらしい。

>>101
実用的でないことは重々承知してやってるんだろ。何を勘違いしてんだ。

103 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:14:39 ]
>>99
> やりもしないでやった気でいるよりもましだと思うぜ。

こんなのは、やらない方がマシの部類。

104 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:14:47 ]
いい加減鬱陶しいのでチラシの裏にでも書いといてくれ

105 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:17:57 ]
そんなバカコードは試す価値そのものが無いことにとっとと気付いて欲しい

106 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:17:59 ]
>>103
それぐらいしか言えないか……。まあ、仕方ないよね。

107 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:18:57 ]
>>105
突っ込んでる側でも勘違いしてるのがいたんだから、それなりに役に立ってるとは思う。

108 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:20:29 ]
明らかに絶対やるべきじゃないに限りなく近いやり方を無駄に実験して
「やらない奴よりまし」は無い。やる奴がおかしいだけ。悪い意味で。

109 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:21:58 ]
>>107
別に勘違いしたままでもいいんじゃね、真人間は一生こんなクソコード書かないだろうし

110 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:23:01 ]
>>108
突っこみが間違ってると思ったからやったんじゃないか。実際間違っていたし。
スレをよく読めよ。思いこみだけで書かないでさ。



111 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:23:53 ]
>>109
exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。

112 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:25:21 ]
>>111
スタックは破棄されるだろ、デストラクタは走らないが

113 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:26:47 ]
>>112
>>75を読めよ。

> これに加えて 3.7.2 Automatic storage duration p1 から
> > The storage for these objects lasts until the block in which they are created
> > exits.
> ということで、スタックは保持されたままなので atexit() で自動変数のデストラクタを
> 呼びだしても問題ないみたい。

114 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:27:29 ]
>>113
直後じゃなくて最終的な話な

115 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:28:29 ]
__cxa_atexit

116 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:28:36 ]
全く役に立たない話をいつまで続けるの?

117 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:30:10 ]
>>114
プログラム終了時にスタックが破棄されるのは当然だろ。atexitで登録した関数が
呼び出される前にスタックが破棄されるわけではないってことだろ。認識大丈夫?

118 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:32:44 ]
つーか話の流れ的に、atexitでどうにかしようとするのはアホだろ、って話に対して
>>86みたいなアホが粘るから、いい加減にしろ使い物にならねぇから、って話だろ

119 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:37:52 ]
>>102
話が逸れてるな。
実用的じゃないことぐらいみんな理解してる。

出来た出来たと言っているが、関数内からのexit時についても出来たのか、それとも出来なかったのか。

120 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:40:51 ]
>>118
何かずれてるぞ。>>86はatexitを使用するのは無意味だと認識してるだろ。



121 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:42:02 ]
>>117
認識大丈夫?の前に日本語大丈夫?と問いたい。
話の流れで、
> exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。
exit呼び出し後にはもちろんスタックが破棄されるよ。

>atexitのタイミングでは、必ずしもスタックが保持されないと勘違いしてた奴にとっては別だろうな。

122 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:45:01 ]
めんどくさい人だな全く。

>>75を読んでも、exitしてからatexitに入るまでの間にスタックも静的記憶も
ヒープも決して破壊されない、という保証には見えない上に、そんな細かい
実用的にどうでもいい仕様は、仮に規格で規定されていたとしても処理系が
正しく準拠してくれることはほとんど期待できない。
あくまで仕様のテストとして(程度の低い曲芸だが)割り切るならまだしも、
実用にならないんだろうか、というような話を続けている奴が>>86のように
実際にいるから、いいかげんにしてくれ、って話になる。

123 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:46:08 ]
>>119
できたから書いてるんだろう。そう読めるが。

今自分でもやったらできたよ。

124 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:48:17 ]
・できても無意味だからやるな
・やるべきじゃないからもう実験も要らない

125 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:52:23 ]
>>122
少なくとも自動変数が保持されるのは書いてるように見える。

実用上どうでもいいとまで言いきっちゃうのはどうかと思うが。

自分には>>86が実用にならないんだろうかなどという話をしてるようには読めない。

126 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:53:45 ]
>>124
atexitに登録された関数の実行のタイミングぐらいは知っとけよ。

127 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:54:36 ]
>>125
実用にならないんだろうか
→実用に耐えうる場面もあるのではないだろうか

128 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:56:12 ]
>>122
つまり、ポインタは有効であることが保証されるが、free可能な領域を指していない可能性は大いにあると

129 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:58:46 ]
茶々を入れるようだけどC++でatexit()のタイミング知らなくても何も困らない希ガス

130 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 21:59:44 ]
Cでも困らな(ry



131 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:06:17 ]
>>127
そんなふうには書いてないだろ。

132 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:11:33 ]
まぁ>>86は、スタックインスタンスへのポインタ?をいちいち全部静的記憶に
登録するというかっこいい超設計より、例外一発でmainまで脱出して終了する
方がコスト高いかもしれないと思ってることになるから、exitの実装より例外の
実装を勉強した方がいいとは思う

133 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:12:03 ]
自分はデキると思ってる人たちの痛いレスだらけになってるよ
いや、実際デキるのかもしれないけど状況はスルー力検定開催中だよ

134 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:15:33 ]
>>132
そこまで誤読できるのもすごいわ。勝手にやってな。

135 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:16:22 ]
勝手にやってなというわりに、
勝手に書き込みをしている人にいちいち噛み付くのはなぜなのかしら〜♪

136 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:17:29 ]
誤読も何もそのまんまじゃん

137 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:18:43 ]
訳:かまってほしいな

138 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:19:35 ]
>>135
>>134の時点でもう相手しても無駄かなと思えたってことだろ。アホですか。

139 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:21:04 ]
>>131
書いてるだろ

140 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:23:38 ]
×相手しても無駄かな
○まともに反論できなくなってきちゃったから降りたいな



141 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:25:00 ]
東方厨はホント低能だな。

142 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:25:38 ]
煽りに完全に転じた人が現れたようです

143 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:28:46 ]
訳:話題を逸らしてごまかしたいな

144 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:29:48 ]
>>86はatexitに登録する手法は無意味だと分かった上で、

>>85
> だから、間違いなくatexit()で呼び出されるように登録することは難しいといいたいのだろ。

間違いなくatexitに登録した関数が実行されるように登録するのは難しくないということを
言ってるんだろ。

145 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:31:17 ]
atexit 厨が東方厨ってことじゃないの?

146 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:32:04 ]
「atexitで実行する関数に破棄すべきスタックインスタンスを登録するのが」難しい
って話だろ

147 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:32:50 ]
例外の件は、正常系は例外を返すべきでないってことでしょ。

148 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:32:58 ]
難しい、という言い方だと揚げ足を取られる可能性あり。
無駄に面倒、という言い方にすべき。

149 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:33:45 ]
>>146
それは、勧められる話ではないが、グローバル変数を使えば難しくないだろ。

150 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:33:51 ]
exitでいきなり終わらせる正常系とか無いだろ



151 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:34:35 ]
うわ、本当に揚げ足取られたw

152 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:34:48 ]
>>148
バトルしてるつもりなの?w

153 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:35:32 ]
>>152
別に。
しかも実際に懸念通りの展開になってしまったようで。

154 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:37:18 ]
>>150
exitは基本的に正常終了のときに使うんだが。

ttp://www.linux.or.jp/JM/html/LDP_man-pages/man3/exit.3.html

> exit() 関数は、プロセスを正常に終了させ、 status & 0377 という値を親プロセスへ返す (wait(2) を参照)。

155 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:38:36 ]
>>153
揚げ足かどうかは認識の違いだな。元々ネタなんだし。

156 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:38:40 ]
>>154
正常系≠正常終了

157 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:39:32 ]
>>156
正常系でもプログラムをさっさと終わらせたいことだってある。

158 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:40:09 ]
>>157
それならば例外を使っても問題は無い

159 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:41:00 ]
正常系じゃなきゃ例外使っちゃいけないという前提がおかしい。
変に乱用しなきゃいいだけ。

160 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:41:41 ]
間違えた。正常系では例外を、だ。



161 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:41:48 ]
>>158
自分もそう思うが、前スレで強く否定する人や正常系で例外を使うべきでないという
正論を言う人がいたりして、今は揺れているというのが実状。

162 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:46:30 ]
>>161
atexitを駆使してまで例外での脱出を避けるのは、goto絶対禁止とかそういう部類を
思い出すが。まぁ例外はコストがわずかに掛かるが。
とは言っても、例外を完全に排除して例外非対応コンパイルでもしない限り、例外
をthrowかcatchしなきゃ(例外仕様は当然書かない)効率は変わらない訳で、実際
のところはやっぱり宗教論争としか。

163 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:52:49 ]
>>162
いい加減何度も書くのもアレなんだが、元々ネタなんだよ。自分が担当者だったら、
C++でatexitなんて絶対使わない。(Cならデストラクタがない分、使えば便利なときも
あるかもしれない)

自分は元々さっさと終わりたいときは正常系で例外投げていたクチなんで、例外時に
予期しない重い処理が走る可能性があるとか、正常系で例外は投げるべきでないとか
言われると、ちょっとな。正論は強い。

自分が書いたコードで、「例外使っていて便利でしょ?」とか見せたとき、そんなことを
言われると、返す言葉もない。

164 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:53:51 ]
そしてスルーされてる質問が

165 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:55:01 ]
>>163
最初はともかく、いつの間にかネタじゃなくなってるようにしか見えない奴がいる
って話だろ

166 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:56:41 ]
グローバル変数に設定されたスタックが有効なままexitされたかどうかの判断って面倒じゃない?
関数を抜けるときに必要分POPしたりすんの?

167 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:57:01 ]
どうせ破棄が気になる時にexitなんか呼ばないんだからどうでもいいじゃんよ・・・

168 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 22:59:43 ]
どうせやらないからどうでもいいんでそろそろやめろ

何もやらないで文句言う奴よりまし

どうせやらないことをだらだら無駄に実験垂れ流す奴よりまし

取っ組み合い

169 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:01:07 ]
>>167
元々atexitを使ってるプログラムのデバッグをさせられるなんて可能性は十分に
考えられるよ。規格、仕様なら隅々まで知っていて損はない。

170 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:02:41 ]
>>169
そういう範疇の話から逸脱してきてるじゃん>>86は明らかに



171 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:03:45 ]
>>170
そういうふうにしか捉えられなかったとしたらすまなかった。

172 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:09:17 ]
徹底的に粘る人なんだなぁ
こういう人は絶対に「お前の方が馬鹿だ」って態度を曲げないと思うけど、
まだ取っ組み合うの?

173 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:11:44 ]
そのタイプが二人揃うとこうなる訳ですよ

174 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:13:21 ]
>>172
馬鹿にはしてないよ。ちょっと深読みしすぎじゃないか。


175 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:15:48 ]
自分の文章がどう見えるかが分からないタイプでもあるようだ

176 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:17:07 ]
人格攻撃始まりました

177 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:17:32 ]
そんなの受け取りかた次第でしょ。被害妄想かもしれないし。

178 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:20:07 ]
まさに>>172

179 名前:デフォルトの名無しさん mailto:sage [2009/10/22(木) 23:33:34 ]
◎◎◎
◎◎◎
◎◎◎

180 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:15:40 ]
windowsでもunixでも、確実にテンポラリファイル作る方法ありますか
DVDから起動したり、読み取りアクセスしかない場合はカレントディレクトリには出来ないのですが。



181 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:22:24 ]
>>180
tmpfile()
が使えるかも知れない

182 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:22:43 ]
>>180
環境変数で設定されているテンポラリフォルダに作る

183 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:39:16 ]
サンクス tmpfile調べてみます
環境変数は、どの環境でも同じやり方で、確実にとれるんですか。

184 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:42:02 ]
tmpfileはファイルのパスが特定できないみたいですね。
そのファイルをリネームしたりしたいんです。

185 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 00:52:06 ]
思いっきり環境依存の問題を環境に依存せず、とな
ファイルのリネームだって環境依存だろうに
ディレクトリデリミタの問題だってある
せめてgccとかビルド環境を限定しないと答えられんのでは

素直にその手の事を吸収するライブラリを使うか
個別に書いて切り分ける方がいいと思うけど

186 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 02:03:04 ]
>>183->>184
まさかこんなレスが来るとは予想できなかった
対象とするunixは何?

187 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 02:34:28 ]
codepad ttp://codepad.org/xmwNfoSh

Hogeクラスのデータメンバdataの型を
Hogeのコンストラクタの引数で決定したいと思っているのですが、
そうるすとdataの宣言の< >内が書けません。

どのようにすれば良いでしょうか?


188 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 03:08:22 ]
>>187
継承を使うべきところをテンプレートにしてるのが間違いに見える

Dataクラスは不要でHogeではD*を持つように
そしてHogeのコンストラクタでD0/D1をnewするのが普通のやり方かと思う
newの失敗とデストラクタに注意しないといけないとは思うが

class Hoge
{
private:
D* pdata;
public:
Hoge(int flag){
//以下は例外を投げる可能性があるので注意
if(flag==0){
pdata = new D0();
}else{
pdata = new D1;
}
(以下略)

189 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 04:25:32 ]
>>188
それだと Hoge() を2回呼び出しただけで死ねる。 auto_ptr ぐらい使おうぜ。

190 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 08:50:58 ]
Hogeはコンストラクタだし
質問にはそこまで含まれてないんだからいいんじゃね



191 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 14:12:31 ]
入力ファイルをプログラム引数として受け取るってどうゆう事ですか?

192 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 14:20:38 ]
>>191
FILEポインタを食う関数か、
ファイルネームを食って関数内で展開する関数か、
または実行ファイルの引数で指定するか。

193 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 15:54:06 ]
変数Aに1を代入
これをwhile(1)などでずっと繰り返しているとメモリがモリモリたまるのですが、
なぜでしょう?
どこかでログを取っているんでしょうか
またこれを防ぐ方法はありますか?

194 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 15:56:09 ]
そんなことはない
貼り付けてみろ

195 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 17:23:47 ]
>>194
すいません、なりませんでした。気のせいでした

196 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 20:26:42 ]
>>192
上二つもプログラム引数って言ったりするもんなの?

197 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 21:20:38 ]
プログラム引数なんて用語はない

198 名前:デフォルトの名無しさん mailto:sage [2009/10/23(金) 22:25:27 ]
ガチスレかと思った。

199 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:12:09 ]
すみません。これらの文字列が
一つでも出現するか調べたいのですが速い方法ありますか。
調べる文字列がおおくなるほど、その個数分時間が増える方法しかわかりません。 = 一つ一つ調べる。

"HTML"
"html"
"?xml"
"?XML"
"<body"
"<BODY"

200 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:15:58 ]
>>199
正規表現(となるべく高速な正規表現エンジン)を使う。



201 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:24:09 ]
正規表現は多機能な分だけ遅い気がしてます。あと、orで繋いだ文字列が長くなりすぎるとバグる、不安定になります、

202 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:27:41 ]
>>199
互いの単語の相関からマップを作って無駄な検索をしないで済むアルゴリズムは存在するけど
名前を思い出せない

203 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:36:40 ]
まともな正規表現エンジンは単純なORだとかなり最適化できるから自分で適当に組むよりは早くなるとおもうよ。

204 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:39:11 ]
>>201
長くなりすぎるとバグる正規表現エンジンってどれ?

205 名前:199 mailto:sage [2009/10/24(土) 02:39:58 ]
ローリングハッシュ+ブルームフィルタと、鬼車で速度比較してみます。前者を今から作ってみます。
ここで複数同時検索見つけました。 ラビン-カープ文字列検索アルゴリズム - Wikipedia

206 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:41:22 ]
>>204
秀丸と、Regrepに入ってる正規表現dllです。秀丸の場合、最大文字数制限があるんですが。

207 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 02:59:25 ]
TR1の正規表現でいいだろ。

208 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 03:25:14 ]
>>199
検索文字列がそれだけなら
適当に作ってみようか?

209 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 03:35:06 ]
おねがいします

210 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 04:21:34 ]
>>199 検索文字列が短いのでハッシュに用いる文字数を先頭4文字だけにした。 うーん我ながら酷いコードだ
#include<map>
#include<string>
#include<cstdio>
unsigned long get_hash(const unsigned char *p){
unsigned long hash=0;
for(int i=0;i<4;i++) hash=(hash<<8)|p[i];
return hash;
}
int main(void){
char *wordlist[]={"HTML","html","?XML","?xml","<BODY","<body",NULL};
unsigned long hash=0;
std::map<unsigned long, std::string> wordmap;
std::map<unsigned long, std::string>::iterator it;
FILE *fp;
if((fp=fopen("hoge.txt", "rb"))==NULL) return 1;
for(int i=0;wordlist[i];i++) wordmap[get_hash((unsigned char*)wordlist[i])]=wordlist[i];
fseek(fp, 0, SEEK_END);
size_t filesize=ftell(fp), pos=0;
fseek(fp, 0, SEEK_SET);
char buf[filesize+1];
fread(buf, 1, filesize, fp);
buf[filesize]='\0';
for(int i=0;i<filesize;i++){
hash=(hash<<8)|(unsigned char)(buf[i]);
if((it=wordmap.find(hash))!=wordmap.end()){
if(strncmp(buf+i-(4-1), it->second.c_str(), it->second.length())==0)
printf("%s found at pos %d.\n", it->second.c_str(), i-(4-1));
}
}
fclose(fp);
return 0;}



211 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 04:59:56 ]
>>199 C言語で書き直してみた
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
unsigned long get_hash(const unsigned char *p){
unsigned long hash=0, i;
for(i=0;i<4;i++) hash=(hash<<8)|p[i];
return hash;
}
#define HASH_TABLE_SIZE 1031
int main(void){
unsigned char *buf, *p, *wordlist[]={"HTML","html","?XML","?xml","<BODY","<body",NULL};
unsigned char *hash_table[HASH_TABLE_SIZE]={NULL};
unsigned long filesize, i, j, flag, hash=0;
FILE *fp;
if((fp=fopen("hoge.txt", "rb"))==NULL) return 1;
for(i=0;wordlist[i];i++) hash_table[get_hash(wordlist[i])%HASH_TABLE_SIZE]=wordlist[i];
fseek(fp, 0, SEEK_END);
filesize=ftell(fp);
fseek(fp, 0, SEEK_SET);
buf=calloc(filesize+1, sizeof(*buf));
fread(buf, sizeof(*buf), filesize, fp);
for(i=0;i<filesize;i++){
hash=(hash<<8)|(buf[i]);
if((p=hash_table[hash%HASH_TABLE_SIZE])){
flag=(strncmp(buf+i-(4-1), p, strlen(p))==0); // 毎回 strlen するのは無駄なので工夫してね
for(j=0;!flag && (p=wordlist[j]);j++) flag|=(strncmp(buf+i-(4-1), p, strlen(p))==0); // 毎回 strlen するのは無駄なので工夫してね
if(flag) printf("%s found at pos %lu.\n", p, i-(4-1));
}
}
free(buf); fclose(fp); return 0;
}

212 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 05:18:52 ]
サンクス。 自分でラビン-カープ文字列検索を作ってるけど、
文字列長が一定だといいけど
一文字や二文字程度が入ってくると、パフォーマンスが落ちるね。

213 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 05:20:57 ]
>>212
>>210,211 は検索文字列が4文字未満だと動かないよw

214 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 14:15:53 ]
先頭2バイト一致するか調べたら簡単で速い気がしてきた。
ヒットしたら完全一致調べる。
ラビン-カープ文字列検索は一回ごとのハッシュ計算に手間かかる。

215 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 14:45:55 ]
先頭2バイトが登録されていたら完全一致調べる方法。

#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define str2int(x) *(unsigned short int*)x

int main(){
unsigned int n, k;
vector<unsigned char> chk(1<<16, 0);
vector<string> findstr;
findstr.push_back("HTML");findstr.push_back("html");findstr.push_back("?xml");findstr.push_back("?XML");findstr.push_back("<body");findstr.push_back("<BODY");
for(n=0; n<findstr.size(); n++) chk[ str2int( &findstr[n][0] ) ]=1;
string s = "nbtgfhsdfmrjgijmhimhtmljdtiohbjfguhndug" ;
char findflg=0;
for(k=0; k < s.size()-1; k++)
if (chk[ str2int( &s[k] ) ] ==1 )
for(n=0; n < findstr.size(); n++ )
if( memcmp( &s[k], &findstr[n][0], findstr[n].size() )==0 ) { findflg=1; goto end; }
end:
if(findflg) cout<<k+1<<" moji me de hit\n"; else cout<< "not found\n"; }

216 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 16:54:08 ]
>>215
それは実測で速くなったの?

217 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 17:12:41 ]
いまからテキスト(html)で実測してみる

218 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 17:39:08 ]
複数箇所にまたがって使う可能性のあるクラス(Factoryやその生成物、利用クラス)はポインタの形式を統一したほうがいいですよね?
それとも早いのと賢いので細かく使い分けるべきですか?


219 名前:199 mailto:sage [2009/10/24(土) 18:24:09 ]
実測したよ。
tr1::regexは結果が間違えてるんだが。
211さんのはテストケースに書き換えるのが面倒で入れなかった。


215の方法 178秒
一つ一つstring::findで調べる方法 280秒
正規表現 鬼車  590秒
vc++2008 tr1::regex 868秒

220 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:35:17 ]
ここまでboost::xpressive無し



221 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:40:05 ]
strstrもなし。

222 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:42:22 ]
正規表現なら鬼車がいいだろ
Ruby(オリジナル版には入ってないかも)、桜エディタ、
Bregexp.dllの後継bregonig.dllに使われている。

223 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:46:30 ]
インラインアセンブラもなし

224 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:49:35 ]
215より速くできる方法あるの

225 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:51:29 ]
vector<string>に複数の文字列を定義時に登録する方法ありますか?

226 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 18:52:25 ]
C++0x対応コンパイラに乗り換える

227 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 19:01:01 ]
static int fnc(); と int fnc();は何が変わるんですか。

228 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 19:03:15 ]
自己解決
ひとつのファイル内のみで使用できるって事ですか。

229 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 22:06:29 ]
仮想関数ってポインタアクセスしてるらしいし、つまりinlineしても無駄無駄ですよね?


230 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 22:09:06 ]
インライン化できるならコンパイラが勝手にやるよ



231 名前:デフォルトの名無しさん mailto:sage [2009/10/24(土) 22:24:29 ]
これらって同じかと思ってミスりました。

memcmp( buf, "\x20\x45\x4D\x46", 4);
memcmp( buf, "0x200x450x4D0x46", 4);
memcmp( buf, "0x20454D46", 4);

232 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 00:04:57 ]
KMP とか AC とかあるよ


233 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 00:06:11 ]
KMP じゃなくて CW だった。

234 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 09:36:21 ]
反復子の正しい初期化方法を教えてください。
演算子のオーバーロードで初期化できる反復子は問題ないのですが
そうでない、反復子はどのように初期かするのがベストなのでしょうか?
template<class Iterator>
class Foo {
private:
Iterator lite_; //ok
Iterator rite_; //ok
Iterator it_; //?
Iterator p_; //?
public:
Foo() : it_(0), p_(0){} //これがベストなのでしょうか?
Foo( Iterator lite, Iterator rite ) : lite_(lite), rite_(rite){}
};

235 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 09:46:31 ]
>>234
一般的にコンテナのインスタンスに依存せずに要素を指さない有効なイテレータを作る方法はないし、
nullや0から変換できるとも限らない。

236 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 09:52:13 ]
>>235 thxです
>nullや0から変換できるとも限らない。
なるほど、やはりそうですか自分もそんな気がしていました
なので、nullや0から変換する方法というのは、他に方法が無い場合仕方無しにやってます。

237 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 11:06:39 ]
boost::optionalとかどう?

238 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 11:40:01 ]
boost は何でもあるんですね、また驚きました、参考にさせてもらいます。

239 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 13:28:38 ]
クラステンプレートでoperator() はオーバーライドすることが可能でしょうか?
もしできるならば、簡単な雛形を教えてください
それからSFINAE の使い方で、関数テンプレートの事例は検索すれば
いくつか出てきますし、「C++テンプレートテクニック」という本を読んでやり方は分かるのですが
クラステンプレートの事例が検索できません、もしかしてSFINAE はクラステンプレートには適用できないのでしょうか?
ここで言うクラステンプレートとは
template<class T>
class Foo {};
このような形式のことを意図します。
コンパイラはvs2005です。

240 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 13:29:34 ]
基底クラスがないのにオーバーライド?



241 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 14:54:02 ]
>>239
ファクトリー関数を挟めば適用できるよ

242 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 16:54:33 ]
>>239 です
>>241 さんありがとうございます、ファクトリー関数を検索したのですが、具体的にイメージができません
下記のFooクラスおHogeクラスの間で継承関係を持たせ、operator() を自在に呼び出せないでしょうか。
#include <algorithm>
#include <iostream>
#include <vector>
template<class T>
class Foo {
typedef typename std::iterator_traits<T>::value_type value_type;
public:
void operator()( const value_type& val )
{ std::cout << val << "\n"; }
};
template<class T>
class Hoge {
public:
typedef typename std::iterator_traits<T>::value_type value_type;
int operator()(const value_type& val)
{ return val; }
};
int main()
{
std::vector<int> lhs, rhs; lhs.push_back(1); lhs.push_back(2); lhs.push_back(3);
std::for_each(lhs.begin(), lhs.end(), Foo<std::vector<int>::iterator>());
std::transform(lhs.begin(), lhs.end(), std::back_inserter(rhs), Hoge<std::vector<int>::iterator>());
copy(rhs.begin(), rhs.end(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}

243 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 17:17:55 ]
どういう動作をしてほしいのかわかりません

244 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 17:29:41 ]
>>243
継承により基底クラスのメンバー関数を使いたいのですが、今回の場合はどちらが基底クラスになってもかまいませんが
仮にFoo クラスに
int Widget();
というような関数が定義されて、基底クラスとした場合、Hoge クラスでそれを使えることはもとより
operator() も呼び出せるようにしたいのですが。

245 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 17:33:49 ]
using Foo<T>::operator ();

246 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 17:39:10 ]
>>245
それは何処に記述して、main() からどのように呼び出したらいいのでしょうか?

247 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 18:24:01 ]
>>242
無理。その二つのoperatorはそもそも継承可能な同一性を持たないから。

248 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 18:56:58 ]
そうですか、ありがとうございます
int operator() とvoid operator () と違うから継承不可能なのでしょうか?

249 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 21:30:24 ]
インターフェースにコピーコンストラクタや代入ってつけないほうがいいですか?
ぜんぜん違う実装同士だとすごい困るんですけど・・・

250 名前:デフォルトの名無しさん mailto:sage [2009/10/25(日) 21:35:12 ]
>>249
付けて困るんなら付けなきゃいいじゃん。



251 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 07:53:47 ]
コンストラクタから、オーバーロードされたコンストラクタを呼び出すってアリなんですか?
class CHoge {
public:
 CHoge(int x) { CHoge((float)x); }
 CHoge(float x) { ... }
};

252 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 08:11:51 ]
0xではアリ

253 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 09:54:15 ]
>>251 今のところナシ

254 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 13:21:40 ]
もしかして、コンストラクタからオーバーロードされた普通のメソッドもダメ??
class CHoge {
 public: virtual void func() {...}
};

class CHogeEx: public CHoge {
 public: CHogeEx() { func(); /* CHogeEx::func を呼びたい */ }
 public: virtual void func() {...}
};


255 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 13:25:11 ]
>>254
× オーバーロード
○ オーバーライド

「ダメ」の意味がよくわからんが、 CHogeEx をさらに派生して func() をオーバーライドしていても
CHogeEx のコンストラクタで呼び出されるのは CHogeEx::func() になる。
つまり C++ のコンストラクタ(とデストラクタ)の中では仮想関数による動的多態は効かない。

256 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 13:25:17 ]
それオーバーロードされてなくね

257 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 13:25:53 ]
>>254 試せよ。

258 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 16:03:48 ]
クラスのstaticなメンバの初期化は

class Hoge{
 public:
  static int foo;
};
Hoge::foo = 1;

のように、fooをクラス宣言の外で初期化してあげるのが
教科書や多くのサイトで書かれていますが、

std::basic_string::npos は、
static const size_type npos = static_cast<size_type>(-1);

とクラス宣言内で定義されています。
同じようなことをstd::stringで行ってもできません。
これは単純に、staticなメンバ変数でもプリミティブ型であればクラス宣言内で定義しても良い、ということでしょうか?

259 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 16:12:51 ]
関数を抜けるころにはもう参照を使わないとわかってる→参照か生ポインタを引数にしてもよい
メンバ変数にほかのインスタンスへの参照として持たせたい→寿命がよくわからない→スマートポインタ
動的に確保して返す関数→値捨てられたら困る→スマートポインタ
メンバ変数を返す関数→外で参照を保存されたらバグる可能性がある→値返し

引数と返り値の参照について↑みたいにやってるんですが、もっと明確で安全な基準みたいなのってありませんか?

260 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 16:23:40 ]
>>258
さらにconstでなければならない



261 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 20:05:23 ]
>>259
オブジェクトの寿命で考えてみよう

262 名前:デフォルトの名無しさん mailto:sage [2009/10/26(月) 20:42:06 ]
>>260
さらに int 型、じゃなかったっけ?

263 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 00:15:22 ]
>>258,260,262
staticでconstで整数型じゃなかったっけ。 超うろ覚えだが。
ちなみにVCの6か7ぐらいまではそれすらもできないので、enumハックという手法があったがそれはもう昔の話。

264 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 00:33:46 ]
enumはOKで整数はダメとか、実に理不尽だったよな。

265 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 00:58:22 ]
ゆとりは知らない残念なVC++の歴史シリーズ

・#pragma warning( disable : 4786 )
・#define for if(0) ; else for
・#include <c****>してもstd名前空間に入っていない
・クラススコープでstatic const intの初期化ができないので代わりにenumを使う
・std::wcout << L'A' << std::endl
・<algorithm>にmin/maxがない
・typenameがなくても大体なんとかなってしまう(今でも)
・newが失敗すると0を返す(標準策定前なので仕方ないと言えば仕方ない)
・テンプレートクラスにテンプレートメンバ関数を作成できない(当時ほとんどのコンパイラは未対応だったのでまぁ仕方ない)

それが今ではexportと例外仕様以外はだいたい標準準拠の立派な子に成長しました。

266 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 01:08:37 ]
__finally節が実行されない場合があると知ったときの落胆ときたら。
なんのためのfinallyなんだよw
今ならBOOST_SCOPE_EXIT使うけど。

267 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 01:25:55 ]
今でも、ダイアモンド継承が正しく機能しないとか
ADLが標準に合致しないとか
Cライブラリがstd名前空間に含まれてないとか

問題山積みだけどね。

268 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 01:30:03 ]
まぁ問題山積みじゃないコンパイラは珍しいし
C++以外ですら

269 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 02:05:17 ]
VisualStudio6の時代が長すぎたのもあるね。
2002/2003は見送ったところが多かった。
2005からかな、みんな使い出したのは。

270 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 06:53:04 ]
CInputState& s=State[0];
s.Up|=KEYDOWN(DIK_UP);

このソースの2行目の |= は何を表しているのでしょうか?
+=や-=ならちょくちょく目にしますが、|=というのは・・・?



271 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:02:26 ]
>>270
a += b は a = a + b といっしょ。
a -= b は a = a - b といっしょ。
a |= b は a = a | b といっしょ。

272 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:13:35 ]
>>271
ありがとうございます。
助かりました。

273 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:03:39 ]
C言語から入ってアセンブラに行くと
a += b
の方が
a = a + b
よりも機械語の形式に近いと知って軽いカルチャーショックを受けるよな?
俺だけか?

274 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:11:33 ]
>>273
考えた事もなかった。

ADD A, B
こうゆう事?

275 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:27:14 ]
>>274
そうそう

CPUによっては3オペランドの四則演算もあるんだろうけど
ほとんどのCPUでは2オペランドが基本なんだよな
考えてみれば当たり前なんだが
昔々アセンブラを初めて触ったころ、へぇ〜と思った

BASICに代入付き四則演算子がなかったもんだから
なおさら、ほぉ〜と思ったな

276 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:35:33 ]
先にアセンブリ言語を知っていたから、Cは簡単だった。

277 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 09:02:29 ]
>>275
このスレで答える側の人たちは昔からプログラムやってる人が多いのかな?
BASICなんて見たことも触ったこともないな。

>>276
Cが簡単って人は俺にとって神に見える。
俺はJavaからC/C++に入ったからCがかなり難しく感じる。
涙でディスプレイが霞むほどに難しい。

278 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 09:06:01 ]
人によるとしか言いようがないんじゃね?

279 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 09:47:37 ]
最近Fortranやったんだがa+=bが使えなくてがっかりした
でもa(1:n)=a(1:n)+b(1:n)とか配列周りに関しては感動した

280 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 09:55:15 ]
少なくともCは、データがどのようにメモリに格納されているかを常に念頭に置いておけば
難しいところはないんじゃないか。
C++は全然違うけど。



281 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 10:10:47 ]
>>277
VisualBasicも基本的にはBASICだということを忘れてないかい?

C++は言語仕様が大きすぎて
ソフトを作るためにC++使ってるのか
C++の深淵を知るためにC++を使ってるのか
分からなくなる

282 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 10:14:43 ]
>>281
なんか作ろうとして、その途中でつまずいたりアイデアを思いつくと言語の勉強が始まって、気づいたら半日過ぎてたとか良くある

283 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 10:41:15 ]
>>281
そういえばVBなら少し触ったな。
基本的にはVBもBasicか。あまりにイメージが違いすg・・・


今までJavaでWeb系の開発やってていっぱしのプログラマ気取ってたんだが
C++の難しさになみだ目。C++の何が難しいって、そもそも実現しようとする事柄が難しい。

プログラミングの第一線から退いた先輩方から「オブジェクト指向ができるなんてすごいね」
なんて言われて「いや、そんな事ないですよ(フフ」なんて言ってたんだが
C++を勉強し始めた今になって猛烈に恥ずかしくなってきた。

あんたらがやってきたことに比べれば、俺がやってるWebのプロジェクトなんか屁みたいなもんですよと。
あんたらがもっと若かったら純粋なオブジェクト指向の言語においても俺より優秀な技術者になってんだろと。
今度先輩に現役時代の話を聞いてみよう。

チラ裏ごめん。

284 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 11:22:38 ]
どっちが凄いなんてないけどな
たまたま時代のニーズによって勉強した物が違うだけじゃん

でも確かにC++の深淵を〜は確かにそういう嫌いがあるよね……

285 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 11:30:48 ]
1byteを削るのに必死な時代は想像できないよな
ドラクエ1を64KiBに収めるとかどんな拷問かと…

memcpyさえないレベルから作るわけで
そもそもC言語とか一切使ってないんだろうなぁ

286 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 12:23:39 ]
バイト単位で削る世界だとアセンブラ以外は論外だな。

ところで、C++は巨大と言われるけど、一つ一つの機能をどうコンパイルされるか
把握しながら理解すれば、そこまでバカみたいな巨大さは感じないなぁ。
とは言っても、応用が色々と奥深いけど。

287 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:04:29 ]
C++が巨大っていうのはどこらへんを言ってるのだろう。皮肉じゃなくて、純粋に。
他の言語はLLぐらいしかあまり使ってないので。

たしかに大きいなとは思うけど、必要だから大きいのであって、無駄なものは
そんなにないと思うんだが。

288 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:50:29 ]
Cとの互換性を保ちつつ必要そうなものを足していったから
複雑怪奇に感じてそれを巨大だと表現したりするんだろう
無駄だとかじゃないんだ

289 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 14:11:26 ]
巨大とまでは言ってないでしょ

C++は直接見えない部分の注意点が多すぎると思う
コンストラクタでの例外とか>>251みたいなのとか
多重継承とか
デストラクタの動作タイミングとか
STLの諸々とか

無駄ではないけど複雑すぎるんだよね
メモリイメージさえできてれば使えるCに比べると
間違いなく問題ないコードを書いていると確信できるまでに
必要な知識量があまりに多すぎる

だからといってJavaでは中途半端すぎて満足できないw

290 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 14:20:09 ]
>>289
もう――――――――
もう何時間―――― こうしているのか――――

蹴っても――――
いくら蹴っても――――――――
不安がなくならない!!!

ってことだよな。CとC++の最大の違いはw



291 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 14:27:44 ]
それはちゃんと理解してないまま使ってるからだな
ちゃんと理解してないと安心して使えない言語なのが悪い、というのも一理あるし、
理解してればCより遙かに安全で気楽になったりもするし

292 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:00:59 ]
Cでは異常系の処理がパンクしちゃうから、C++のほうが結局は楽で安全だと思うけどな。

C++とCの最大の違いは、仕様変更の荒波にどれほど楽をして対応できるかどうかではないかな。

293 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:04:46 ]
C++で気を付けなければならないリストみたいなのを作って、新たにC++を学ぼうと
する者が全員それを読めばいいんじゃないか。

294 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:06:51 ]
>>293
Effective C++はじめ、そこらじゅうに名著がありますよ。
もちろん、業務としてC++を使う人たちは全員読んでいますが。

295 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:40:29 ]
C++ の方が基本的にはCより使うの安全で楽だとは思う。
流儀はある程度決めておかないと収集つかないけど。

気分的には「巨大」というのはわからないでもない。CとC++と両方
のやり方がかぶってる部分がかなりあるから、機能面だけから考えれば
不要な部分が多い。互換性は重要だから無駄ではないのだけど。

296 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:54:28 ]
入力ファイルからデータを読み込みロジック部分を関数化し、
qsort関数以外を使用して番号順にソートしたいのですが何かいい方法があれば教えてください。

例)
F016    C002
C002    C015
H001    F016
C015    H001
H009    H009


左のデータをソートし、右のように並び替えたいです。



297 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:55:32 ]
関数オブジェクトは値で渡せって言われたんだけど、実行時ポリモーフィズム的に使いたい場合はどうするの?

struct func_obj { virtual void operator () (hoge &h) = 0; };

struct func_obj_1 : public func_obj { void operator () (hoge &h) { h.method_1(); } };
struct func_obj_2 : public func_obj { void operator () (hoge &h) { h.method_2(); } };

void execute(hoge &h, func_obj &f) { f(h); }

int main(void) {
hoge h;

execute(h, func_obj_1());
execute(h, func_obj_2());

return 0;
}

この場合はconst参照にすればいいけど内部に乱数を持ってたりするとconstじゃ困る

298 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:57:36 ]
>>296
宿題スレへどうぞ。

299 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 16:03:18 ]
>>296
読み込みが終わったらソートできてる状態にすればいいと思う

300 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 16:16:01 ]
>>294
それは当然だが、それらを読まない人が多いから巨大だとか言われるわけで、それらを
簡単にまとめた物を言っている。原理を詳しく知りたかったら原著を読めばいいし。

C++には新規参入など要らないということであれば話は別だけど。



301 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 20:32:58 ]
>>281
でもその「深淵を覗いている感じ」は、なかなか他の言語では得難いものがあるよねw
なにか、つきあいの長い人に意外な一面を発見する喜び、みたいな。

302 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 20:38:17 ]
整数のゼロ除算はif(div==0)でチェックできますけど実数のゼロ除算はどうやって調べるのが妥当でしょうか?


303 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 20:56:09 ]
実数の内部表現は処理系依存。

304 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:59:45 ]
エラーで停止したくないんだったら、
z = x/y を

if ( y < 十分小) z=十分大 else z=x/y
にしとけ

305 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:22:03 ]
>>302
std::numeric_limits<double>::epsilonとか使うといいんじゃないか。

306 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:34:04 ]
>>304 y<0 かも知れないよ〜


307 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:20:43 ]
if ( y ニアリーイコール0) z=十分大 else z=x/y

308 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 04:24:21 ]
>>297
struct func_obj_wrapper {
  func_obj_wrapper(func_obj& f) : f_(f) {}
  void operator()(hoge &h) { f_(h); }
  func_obj&  f_;
};


309 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 12:02:15 ]
>>303
> 実数の内部表現は処理系依存。

…なんだけど、IEEE-754 な環境だと普通に

x / 0
= ±∞ (x != 0)
= ±NaN (x = 0)

じゃなかったっけ?

310 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 15:39:16 ]
C++ の ostream について質問なんですが、数値を大文字の 16 進数に変換するのに
簡単な方法は無いでしょうか?
std::hex だと小文字になってしまうし・・・。



311 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 15:55:47 ]
>>310
std::ios::uppercase

312 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 16:05:06 ]
>>311
速答ありがとうございました。
うまく大文字に変換できました。

313 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 18:48:07 ]
std::vector<int> lhs;
for (p = lhs.begin(); p < lhs.end()-6; ++p) {
}

lhs.end()-6 の表記が間違っていると思うのですが、どのように書いたらいいでしょうか?

314 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 19:08:14 ]
間違ってはいないと思うけど、constじゃないコンテナのend()はちょっと重いかもね。
それと、size()が6以下だとまずいね。

315 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 19:11:06 ]
実現したいことがいまひとつ分かりにくいけど
lhsの先頭から終わりの6つ前まで走査したいってこと?
それなら
for(size_t i = 0; i < lhs.size() - 6; ++i){
 // lhs[i]でアクセス出来る
}
でいいと思うが

316 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 20:50:02 ]
素直に書けばいいのに不自然なことして悩んでる質問が多くね?

317 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 20:55:02 ]
パフォーマンスがそれほど気になる状況なら

if (lhs.size() <= 6)
; // エラー処理なりreturnなり

std::vector<int>::const_iterator last(lhs.end() - 6);

for (std::vector<int>::const_iterator p(lhs.begin()); p != last; ++p){

}

でおkでは。

318 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 20:57:50 ]
C++ではfor文の比較は!=にしようね。<などは、あるイテレータの種類やカウンタで
フォールトトレランス性はあるけど、コンテナの種類が変わると使えなくなる可能性がある。

319 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:02:02 ]
2ずつカウントアップしたらスルーされる可能性ある。
n++だとしても、ループ内でnの値が変わったら停止しなくなる。

320 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:04:53 ]
>>319
ちゃんと読め



321 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:08:58 ]
>>319
ステップが1でないループやカウンタが任意の値に変わるようなループは
普通じゃないんで、使う側がそれを想定したコードを書くべきではあるが、
普通はそんなことを想定しなくてもいいと思うよ。

322 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:27:00 ]
基本的にintなど大小が付いてる場合では、条件はなるべくきつめにつけて置くべき。

!=   →   <=

値が小さいとき、どちらもループするが、!=では飛びこえても停止しない。


同じ事を説明しているだけだがな。

323 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:35:12 ]
バグが見つかる可能性を減らす事になるんでしない



324 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:43:18 ]
漏れも。たとえば5周でぴったりとまってほしいのに、
6周や7周して何事もなかったかのように続行されてはあとで大変なことに。
だから「5周で終わらなきゃだめ!」って言う条件を
「まぁ、5周以上になったら適当なところで終わってね」なんて緩めたりしない。

325 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:47:45 ]
!=とアサート併用が常識だと思ってた

326 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:51:52 ]
>>324
それは「5周以上」じゃなくて「5周以下」じゃね?
1→7とかなって2周で終わる。
あと、i!=5 と i<5 は事後条件に違いがあるから
どちらが適切かは事後条件次第じゃないかと。

で、forにおいて日常的に!=を使うか<を使うか、++iを使うかi++を使うかは
効率の問題とかもあるんだけど、結局は宗教論争なんだよね。
cout と printfに並ぶくらい。

327 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:54:31 ]
>>318の、コンテナの種類が変わると使えなくなる可能性があるというのは宗教的な話で片づけられることなのか?

328 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 21:57:15 ]
そりゃあ書き換えると不適切な場合は言わずもがな。
いちいち言及しないと気になる?

329 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:06:47 ]
気になって夜も眠れないでごわす!

・・・うそw
for文の宗教論争はGoogle Coding Standardsにも出てくるけど
「まぁ、好きにしろよ」っていうオチだったと思う。

330 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:07:49 ]
codepad.org/fR8BNHWy
C++を学び初めて四日目です (VC++2008です)
ドラクエ風戦闘プログラムの勇者の攻撃だけの部分を作ってみたんですが、
クラスのオブジェクトが生成できてないとかメンバ関数が何故か使えないとかで困ってます
オーバーロードが多重定義だというのはググったんですが、関数は一つしか定義してないはずなので多重定義といわれても分かりません……
どうにか問題を解決してもらえないでしょうか
ちなみにオーバーロードやらポインタやら継承やらはまだ勉強してません


あと他の部分のコードでこうしたらいいよ、とかあれば教えてください



331 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:08:28 ]
!=のほうが<よりも効率はいいことが多いがな。

332 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:09:20 ]
vectorからlistに変えたいとき、for文がたくさんあれば!=になってないと
修正が大変だわな。

333 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:13:30 ]
>>331
それがまた宗教論争の種なわけだ。
サッターは時期尚早の再不適化はやめようと書いているけれども
果たしてコンパイラの最適化能力をどこまで信じないかという問題もある。

>>332
こちらの問題にはメイヤーズが答えている。
どのコンテナにも使えるコードを書けると思ってはいけない。

・・・一般論では宗教論争にしかならないのはこのため。^^

334 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:14:44 ]
だいたい、std::vector<T>::iteratorが
< や <= で比較可能なことは保証されてるのかよ。

== と != は確実に保証されてるけどな。

335 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:15:25 ]
仕様は!=なんで、<にするのはフォールトトレランス性は確保できるが、上にもあった
けど、バグは潰せないんで、やっぱ自分は!=かな。

336 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:17:00 ]
あとでSTLを使うかもしれないという理由で
 != に統一すると、停止しないバグに遭遇する危険。
整数型なら< >にしとけ

337 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:18:25 ]
>>333
宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。

時期尚早の最適化は止めよう。

最適化と仕様の実装とは別の話。仕様は!=。

どのコンテナにも使えるコードを書けるとは思ってはいけない。

だが、多くのコンテナに変更可能なコードを書くことは悪ではない。

338 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:18:59 ]
for(n=0; n!=10; n++) { n+=rand()%3; }
とか中で追加してたら、バグ発生するだろ。
バグでないのに。

339 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:19:18 ]
>>330
見てるところがちがんじゃない?
どうも「endl」でエラーが出てるよ。
endlってそういう使い方しないと思うんだけど。

340 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:19:34 ]
>>336
バグはassert等で対応するべきであって、仕様を曲げるのはおかしい。



341 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:21:40 ]
>>334
保証されている。ランダムアクセスイテレータは<や<=が使用可能。

342 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:23:09 ]
>>336
停止しないバグがあるならバグを直すべき


343 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:23:31 ]
>>338
そういうのは>>321で議論から除外されてる。

344 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:23:47 ]
>>337
>宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。

そう、あなたのおっしゃるとおり。
あなたにはピントが合ってないように見えるけど
そう主張している側からはピントぴったりにしか見えてない。

for文の宗教論争史(あるかどうかしらないけど)を調べると
今まさにあなたの反論がそのまま出てくるよ。

345 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:26:06 ]
>>344
いやいや、それは逃げてるだろう。

仕様と最適化の問題は答えが明らかだろう。

346 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:27:26 ]
>>339 ありがとうございます! endl;を抜いたらうまくいきました。 cout<<endl;とすべきでしたね



347 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:29:36 ]
>>345
まぁまぁ。^^
いちどそのあたりの宗教論争を調べてみるとおもしろいよ。
まったくかみ合わない論争だから。w

ちなみに、自分はさっきの引用が「正しい」とか「的を射ている」とは思ってないよ。
かみ合わないのを承知で引用している。

348 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:33:57 ]
>>321の条件ならfor文じゃなくてfor_each使うべきじゃね?
まぁ使いにくいんだけど

349 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:57:08 ]
>>346
あと、各case節の終わりでbreakしなくていいのかい?

350 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 22:58:18 ]
>>347
そんな雰囲気だったが、そんなことしてどうすんのとは思う。

自分は!=を使う。理由はそれが仕様だから。バグはassert等で補足するべき。

ちなみに「的を得ている」についての議論。
ttp://mojix.org/2009/06/17/matowo_eta
ttp://www.mainichikoaki.com/2008/04/post-100.html
ttp://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1410695749



351 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 23:24:16 ]
>>349 変なループが直りました! ありがとうございます

352 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 23:36:43 ]
まぁ普通はポインタやインデックスじゃなくイテレータを比較するなら!=が無難だろ
実装の中身が生ポインタならば、というような仮定はしたくないからな

353 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 00:24:43 ]
別の話になるけど
ちょっとイテレータを弄ろうとするとend()に++したり、begin()に--出来ないから
一々チェックを入れる必要が出てきて非常に面倒。でも普通のポインタも保証無いんだっけ?

354 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 00:40:51 ]
最初の前は見れないけど、最後の次は見れるんだっけか。

355 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 00:43:41 ]
>>353
3行目以降の意味が全くわからんけどとりあえずboost::nextとboost::priorでぐぐれ

356 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 00:51:28 ]
参照とポインタってどっちが速いんだろう

357 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 01:07:16 ]
バイナリになっちゃえば同じ。
そうでない処理系もあるかもしれないけど。

358 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 01:11:34 ]
参照だな。
参照とインライン展開だと、ひとつもメモリの生成しないですむが
ポインタは32bit か64bitの変数を生成するからな。
でも計測可能なほどかは微妙だが

359 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 01:30:24 ]
別に vector 使うなら iterator 明示的に使わないで v[j] みたいに
使ったっていいんだけどな。そっちの方がわかりやすいなら。

360 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 02:22:07 ]
>>350
リンク先を見ずに言うが、「的を射ている」と書いてるよ。
当を得ているとすべき、的を得るもあながち間違いとは言い切れない
という意見もあるけど、何で「的を得ている」についてのアンカーを?



361 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 03:31:22 ]
「ちなみに」と書いてあるから、ちなんだんだろう。

362 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 05:02:17 ]
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10026.txt

10、19行目のInt型の引数に0を代入する処理はどういった効果があるのでしょうか?
引数の値はコンストラクタ呼び出し時に上書きされるので、無意味に見えるのですが・・・

19行目のClsA(n1)は初期化子の書き方だと思うのですが、ClsAという変数はありません。
何をしているのでしょうか?

363 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 05:14:35 ]
NULLが入っていた場合対策では

364 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 05:24:05 ]
よくわからないので試してみましたが、エラーにはなりませんでした。

int main(){
int iii = NULL;
iii = 1;
}

365 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 05:39:08 ]
f (NULL, NULL)という呼び出しの場合。

366 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 05:52:38 ]
私の実行環境のビジュアルスタジオではヌルで呼び出しても問題ありませんでしたが
>>1のアップローダーでコンパイルしたところ、エラーになったため、理解できました。
ヌルの扱いはコンパイラ依存なんですね。
ありがとうございます。

初期化子の方がまだわからないのですが、教えて下さる方いませんか?

367 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 06:11:25 ]
>>362
引数リストでの代入式はデフォルト引数の指定。
ClsA(n1) は基底クラスの初期化。

368 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 06:45:57 ]
理解できました

変数だけでなく、コンストラクタも初期化子で初期化できるんですね。
というと、基底クラスの関数も初期化できそうですね。
ありがとうございました。

369 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:03:45 ]
なんでNULLとかいってんだ?
>>362は納得できたからいいけど。

370 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 13:04:11 ]
ソース1の2行目に出てくるi(list)はどうゆう構文なのでしょうか?
iがそもそもなんだかわからないのでVisualStudioの「定義へ移動」を使用したところ、WinCrypt.hに飛ばされ
その中の記述がソース2のようになっていました。
不思議な事に、「定義へ移動」を使用してもWinCrypt.hに飛ばされずに何も起こらない事もありました。

//ソース1
1:void CShtGame::DrawTask(CTaskList* list) {
2: for (CTaskIter i(list); i.HasNext(); ) {
3:  ((CMover*)i.Next())->Draw();
4: }
5:}

//ソース2
1:typedef struct _CRYPT_RC4_KEY_STATE {
2: unsigned char Key[16];
3: unsigned char SBox[256];
4: unsigned char i;
5: unsigned char j;
6:} CRYPT_RC4_KEY_STATE, *PCRYPT_RC4_KEY_STATE;



371 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 13:11:21 ]
>>370
iはCTaskIterクラスのインスタンス。名前から察するに、CTaskListのイテレータなのだろう。
i.HasNext()はiが指しているlistに次の要素があるかどうかを返す関数だと推測する。
いずれにしろ、この際WinCrypt.hは関係なさそうだな。

372 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 13:13:27 ]
CTaskIter 型の変数 i を1個の引数 list で初期化している
for 文の最初で for (int i = 0; ..... ) のように変数宣言できることをご存じない?
それとも int i(0); のような書き方で変数が初期化できることをご存じない?

373 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 13:24:02 ]
>>371
VisualStudioの誤動作だったんですね。

>>371>>372
CTaskIter i(list)は、CTaskIterクラスの引数がCTaskListになっているコンストラクタを呼び出してたんですね。
いろいろ勘違いしていました。ありがとうございます。


374 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:27:18 ]
違う。コンストラクタの呼び出しじゃなくて、インスタンスの生成。
インスタンスを生成する途中でコンストラクタも呼び出すけど。

375 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:28:57 ]
誤動作って言うよりは誤操作って感じだな。

376 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:31:58 ]
>>374
そんなこと言うと、変数の初期化だとか変数の定義だとか、もっと言い換えできるぜ。

377 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:32:54 ]
コンストラクタの呼び出しとインスタンスの生成の違いは、言い換えってレベルじゃねーだろ

378 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:35:38 ]
>>377
「コンストラクタの呼び出し」と「インスタンスの生成」って、そんなに違うか?例えばどこが?
その違いは「インスタンスの生成」と「変数の定義」よりも大きいんだよね?

379 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:36:02 ]
CTaskIter(foo); // A
CTaskIter i(foo); // B

Aがコンストラクタ呼び出しの構文だろ?
Bが変数定義。

380 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:37:38 ]
>>378
この場合は自動インスタンスの生成だから、スタックからメモリを確保する作業が
含まれるな。
自動インスタンス生成と変数定義は変わらん。インスタンス生成と自動インスタンス
生成は違う。



381 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:39:36 ]
CTaskIter i(); // C
では、これは何でしょう?

382 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:40:14 ]
コンスラクタの呼び出しはplacement newを使う。
void* p; に対して、 CTaskIter* q = new(p) CTaskIter(foo);

383 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:43:43 ]
>>380
「自動」ってつければそうなるね。
後だしジャンケンっぽいけど、言いたかったことはわかったからまぁいいや。

384 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:46:36 ]
俺が>>381だが、誰か俺の引っ掛けクイズに反応してやってくれ

385 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:00:11 ]
正しくは、CTaskIter i(list)はCtaskIterクラスの引数CTaskListのコンストラクタを呼び出してインスタンス化し、
そのインスタンスの位置情報(使用しているアドレスの先頭)をCtaskIter型のiという名前で定義した変数に割り当てている。
ということでしょうか?
書いてて自分でよくわからなくなってきたんですが、おそらく間違っていないでしょう。
間違っていないで下さい。
>>384
CTaskIterクラスのデフォルトコンストラクタを呼び出してインスタンス化し、
そのインスタンスの位置情報(略)をCtaskIter型のiという名前で定義した変数に割り当てている。
ひっかけ・・・?

386 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:03:30 ]
有名な本のネタをそのままやってもな。

387 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:03:40 ]
>>385
ありがとう。救われた気持ちです。

iという名前で、CTaskIter型の戻り値を持ち、引数が無い関数のプロトタイプ宣言です。

388 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:04:17 ]
関数の宣言に見えるものは関数の宣言。

389 名前:これで満足した?w mailto:sage [2009/10/29(木) 15:04:45 ]
>>381
関数宣言。

390 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:08:05 ]
T t = param;
じゃなくて
T t(param);
を使いたい時ってどんな時だろう。何かあった気もするけど。



391 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:08:51 ]
すまん、焦りすぎてて豪快に間違えた、忘れてくれ

392 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:28:22 ]
>>387
正解しちゃってすみませんと思いながら書き込んだのにこのざまですよ。

393 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:42:52 ]
Cみたいにvoidがないとプロトタイプ宣言と見做さない仕様ならこんなこともなかったのに……
とは言え、CTaskIter i(void);と書くのも気持ち悪いなw

394 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:00:13 ]
まぁ、Cのその仕様も単にANSI以前への互換性の為に一応、って感じみたいだしな

395 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:21:56 ]
C++を独学で覚えたくて本を買って勉強しはじめたばかりなんですが、質問があります。
BCCDeveloperを使ってDXライブラリを使う設定したはずなんですが、DXLib_lnitとDXLi_Endで未定議の関数とエラーがでます。
ググッて調べてみてもわからず...
どなたかアドバイスいただけないでしょうか。

396 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:30:52 ]
関数名が間違ってるだけじゃね?

397 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:43:32 ]
エラーメッセージはコピペしてくれないと質問時のタイプミスなのかもとから違ってるのかわからん

398 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:46:32 ]
>>395です。
みなさんありがとうございます。
今はコピペできないので帰宅したらエラーメッセージをコピペします。

399 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:46:44 ]
まあまあ、要領を得た質問ができるようなら、そりゃ既に初心者じゃないよ。

400 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:05:56 ]
初期化はこれが安全ってことでOK?
explicit widget(type);

widget w = widget(t);





401 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:06:14 ]
>>399
核心を突いてるなぁ

402 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:07:24 ]
>>400
explicit使うと下の書き方は出来なくなるだろ

widget w(widget(t)); でも関数とみなされるかもしれないから

widget w((widget(t))); が一番安全だな

403 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:09:58 ]
最近C++も勉強しはじめたのですが、new演算子がよくわかりません。

下記の二つのソースは、出力を行う関数の内部的な動作を除き
まったく同じ意味になるのでしょうか?
あまり要領を得た質問とは言えず、心苦しいばかりですが
もしもJavaもわかるという方がいらっしゃればお願いします。

//Javaの場合
Test t1 = new Test();
Test t2;
t2 = t1;
System.out.println(t1 + "\n" + t2); //t1とt2は同じ値(アドレス値)が表示される。

//C++の場合
Test t1;
Test *t2 = new Test();
t2 = &t1;
cout << &t1 << "\n" << t2 << endl; //t1とt2は同じ値(アドレス値)が表示される。

404 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:12:27 ]
>>403
//C++の場合
Test t1;
Test *t2;
t2 = &t1;

こう。
じゃないとメモリリークする

405 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:15:55 ]
>>402
VCとCODEPADでコンパイル通ったよ
最適化されてないとコピーコンストラクタ挟まれるっぽいけど・・・

406 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 19:58:49 ]
>>404
なぜnewした方だけがメモリリークするのでしょうか?
ポインタはnewしたしないにかかわらず、deleteしないとメモリリークしてしまうものだと思っているのですが・・・
今回の場合、Test *t2 = new Test();でもTest *t2;でもdeleteをすると実行値エラーが出てしまいます。
結局newしない書き方でもメモリリークするように見えるのですが、違うのでしょうか?

407 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:08:20 ]
javaのTest t1はc++のTest* t1。javaのTest t1 = new Test()はc++のTest t1* = new Test()に等しい。言語仕様の違い。考えることではなく覚えておくこと。

408 名前:お約束 mailto:sage [2009/10/29(木) 20:12:51 ]
これだからJava厨は……

409 名前:Java厨 mailto:sage [2009/10/29(木) 20:20:11 ]
ガベコレあるからメモリリークしても問題ないもんね

410 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:21:26 ]
>>409
何も考えずに shared_ptr 使えばいいよ



411 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:31:34 ]
>>395
とりあえず、こだわりが無いなら素直にVC++2008EEにした方がいいと思うが。
昔はWindowsで比較的素直に使えるフリーコンパイラがBCCくらいしか無かったが、
今はVC++EEがあって、ぶっちゃけBCCより遙かにまともに動くし、Windowsだと
VC++以外全く考えられてないのも普通だし。

412 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:48:56 ]
イテレータでvectorをfor文でbeginからendまで読んでいる途中でそのvectorにpush_backしても問題ないですか

413 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:55:11 ]
>>403はむしろ、C++のTest t1;の意味を誤解してそうな気がする。
C++の場合、これで作られるのは参照じゃなくて値(インスタンス)。つまり、
そのソースではインスタンスが二個作られてる。
Test *t2 = new Test();の方は、new Test()がヒープ上にインスタンスを生成して、
それを指すポインタを返す。で、t2というポインタ変数に代入する。
C++では、ヒープ上に生成したインスタンスは必ずdeleteしなきゃ駄目なので、
delete t2;をしないとリークする。これが忘れやすくて危険だから、専用のクラスを
作って、コンストラクタでポインタを記憶してデストラクタでdelete、という手法が
ある。いわゆるスマートポインタで、有名なのはshared_ptr。既に標準ライブラリに
入ってる処理系も多数あり。無くてもBoostライブラリを入れればおk。
これをポインタ以外に広げて、例えばファイルハンドルをコンストラクタで生成や
記憶などして、デストラクタでクローズ、というように、資源の確保と開放を専用の
クラスに包んでしまうのがRAIIという概念で、資源リーク回避の基本技。

414 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:56:19 ]
>>412
push_backでイテレータは無効化される
push_backの後でイテレータを拾い直すならおk

415 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:12:21 ]
shared_ptrのコピーってポインタの十倍以上時間かかるのね
これからは生ポインタ引き数でいいところは生にしよう

416 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:15:47 ]
すいません。下記のようにやるとセグりました。どうやればいいんでしょう。
vector<Objects*>::iterator it;
for(it=v_obj.begin(); it != v_obj.end(); it++){
  if(ある条件){
    push_back(new Objects());
   }
}

417 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:16:31 ]
v_obj.push_back(new Objects())のミス

418 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:17:30 ]
>>416
>>412 なの?

419 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:10:51 ]
とりあえず、下記のようにして回避したんですが、もっとスマートな方法ないですかね。
vector<Objects*>::iterator it;
for(it=v_obj.begin(); it != v_obj.end(); it++){
  if(ある条件){
    flag = true;
   }
}
if(flag){
  flag = false;
  v_obj.push_back(new Objects());
}

420 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:12:32 ]
>>416
別にテンポラリのvectorを作って、ループの中ではテンポラリの方に追加しておいて、
ループを抜けてから連結。
あと、激しくメモリリークの予感。



421 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:21:38 ]
>>407
把握しました。

>>410>>413
Test t1;の動作は理解していましたが、newはメモリ領域を確保するだけで、インスタンスは生成しないものだと思い込んでいました。
つまり、>>404さんが示してくれた方法の場合、ヒープ領域を使用していないからdeleteはできないし不要なわけですね。
下記のように書くと、1行目と2行目で計2回インスタンスを生成していて、2行目でnewしたインスタンスが完全に無意味になる上に
Testクラスにポインタを使用しているメンバ変数があった場合、そのメンバ変数に割り当てられたヒープ領域が開放されない(リーク)というおまけが付いてくると。
1:Test t1;
2:Test *t2 = new Test();
3:t2 = &t1;

shared_ptrはおもしろいですね。
メンバ変数に関してはデストラクタにdeleteを書けば良さそうですが
ローカル変数に関してはこれを使っておけば安心できそうです。
ためしに近々使ってみます。

ありがとうございます。

422 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:23:54 ]
>>416
生ポインタをコンテナに突っ込むのはやめれ、どうしてもというならshared_ptr を使うと幸せになれる

423 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:28:10 ]
STLは糞。全部自分で管理するしくみを作った方が早い。

424 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:37:25 ]
>>419
やりたがってることがイマイチわからないけど、そのコードから受け取れるものだけで言うなら、
ループ内でこうすればいいんじゃないの?
if (ある条件) {
  v_obj.push_back(new Objects());
  break;
}
今回の君のコードからは、一つでも「ある条件」を満たすものを見つけたら
もうその時点でループは用済み、という状況がうかがえるので。

そういうこと(何をやりたいか、何をやらなくていいか)をちゃんと書いて欲しいんだけどな、
質問する時は。

425 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:52:52 ]
プログラムを簡略化してるからちょっと分かりずらいかもしれません。
ループは最初から最期まで全てのイテレータである処理をしてます。
(*it)->do_something();
途中でbreakするわけにはいかないです。
この方法だとif(ある条件)が複数回満たされた場合に1回しかpush_backしませんが、
今回はこの方法で私の問題は解決しました。複数回できればなお嬉しいですが。

426 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:59:06 ]
譲れない条件を「簡略化」したら、「分かりづらい」じゃなくて、わからなくなるよ。

もう他に新事実が無いというのなら、for文の前にint count = 0;でも置いて、ループ内で
if (ある条件) {
  ++count;
}
として、あとからcount個の要素を追加すればいい。

427 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:09:07 ]
粘着うぜ

428 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:15:53 ]
>>415
shared_ptrのconst参照という手もあるよ。

>>421
メンバ変数もshared_ptr使っておくほうがいい。デストラクタでdeleteだと抜けがある。

429 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 01:02:22 ]
>>421
リークする、と断言したのは、
1:Test t1;
2:Test *t2 = new Test();
3:t2 = &t1;

としたときに2でヒープに確保した領域をdeleteできなくなるから。

430 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 02:53:47 ]
>>421
まだ何か誤解があるぽ。

> Testクラスにポインタを使用しているメンバ変数があった場合、そのメンバ変数に
> 割り当てられたヒープ領域が開放されない(リーク)というおまけが付いてくると。

そうではなく、Testクラスのインスタンスがnew Test()によってヒープ領域に生成
されるが、CやC++では、ヒープに確保したメモリ領域は自分で解放する必要がある。
newで確保したならdeleteで。mallocならfreeで。new[]ならdelete[]で。
だが、そのコードでは、newでヒープに確保したメモリ領域を指すポインタはt2に
まず代入されるが、t2 = &t1;の時点で上書きされるので、newした領域がどこに
あるか分からなくなる。つまりdeleteできないので、普通に考えればリーク確定と
いうこと。Testクラスのインスタンスそのもののメモリ領域がリークする。



431 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 07:32:21 ]
純粋仮想関数を持つ抽象クラスはインスタンス化できませんが
デフォルトコンストラクタをprotectedとして宣言、定義して、インスタンス化拒否を明示するのか
コンパイラが自動的に生成するのを用いるのか、どちらが妥当なんでしょうか。

432 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 07:40:35 ]
>>431
なんでそんな余計なコードを書こうかなんて思うの?

433 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:04:21 ]
>>428
shared_ptrは一般的なんですね。
レスポンスが少し気になるところですが、使っておきます。

>>429
new Test();がdelete不可なんですね。把握しました。
※newして生成したインスタンスを格納した変数は、deleteせずに他の値を格納すると
 デストラクタ内で処理されているか、スマートポインタを使用していない限り必ずリークする。

>>430
昨日は少し混乱していました。
Testクラス内にメンバ変数がなくても、newした段階で最低1byteは使用するため、結局deleteできなくてリークすると。
今度こそ完全に理解しました。

434 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:10:52 ]
>>433
大丈夫、未だ勘違いしている。
生成したインスタンスのポインタを格納しているポインタ変数に、他の値を格納してしまうと
単純に、最初のインスタンスのポインタが失われるのであってデストラクタも何も走らない。
まさに、>408だな。

435 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:37:19 ]
なんと!
デストラクタ内で適切に処理しておけば問題ないと考えていましたが、書き方によってはリークするんですね。
ヒープに確保した領域が行方不明になるような書き方してたら
コンパイルエラーにしてくれればいいのにというのは甘えですか?

436 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:54:29 ]
1:Test t1;
2:Test *t2 = new Test();
3:foo->bar(t2);
4:t2 = &t1;

この場合leakするかどうかは 3 の内容に依る。不完全
な警告をコンパイラに実装して「警告が出てないから
leakしてない」なんていう阿呆を産み出すよりは出さな
い方がマシ。

437 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 11:02:31 ]
書き方によってはリークするのではない。
適切に書くことによってリークしないのだ。
--
Test * func() {return new Test();}
--
void someOtherFunc()
{
func();
}
--
これでもリークするわけだが、例えばfunc()が別のコンパイル単位にあるとしたらどうやって検出しろと?

438 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:07:17 ]
3行目はいったい何をしているのでしょうか?
関数のプロトタイプ宣言のように見えますが
そうすると戻り値がvoidで関数の名前がInitで引数は無し?*の意味は・・・?
.h.cppのどちらにもInitを実装しているような箇所は見当たらないし
3行目はどうゆう意味なのでしょうか?


439 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:10:32 ]
失礼しましたソースです。
//Common.h
1: struct STAGE {
2:  const wchar_t* Name;
3:  void (*Init)();
4:  int TopTime;
5: };


440 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:13:27 ]
関数ポインタです。




441 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:14:16 ]
>>438-439
引数も戻り値もない関数へのポインタ。
わからない単語はぐぐればいいと思うよ

442 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:14:21 ]
>>439
型がよく判らないときは、括弧に注目。この場合、Initに*がついていてそれが括弧で拘束されている。
つまり、Initはポインタ変数であることが判る。
それが指しているものは、void ()()となるので、戻り値のない、引き数もない関数となる。
要は、void func()という関数と同じ型の関数ポインタであるInitの宣言。

443 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:36:04 ]
少し調べてみました。
メモリ領域はコード、データ、ヒープ、スタックの4種類にわかれている。

//関数ポインタ。コード領域へのポインタ。
void (*Init)();
//普通のポインタ。データ領域へのポインタ。
int *a;
//deleteしないとリークするポインタ。ヒープ領域へのポインタ。
int *a = new int();
//スタックは今のところ使い方がよくわからないので割愛。

構造体の中に関数ポインタを入れておくと、より汎用的なコーディングができる事がある。
助かりました。

444 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:39:29 ]
>>443
ヒープに確保されないオブジェクト、つまり自動変数とかはスタックに確保されて、
スコープアウトしたらデストラクトされる。

445 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 13:58:05 ]
>>444
補足ありがとうございます。
//普通の変数。スタック領域に実態がある。
int main(){
int a;
Cls b;
}
//普通の変数。データ領域へのポインタ。
class Cls{
public:
int a;
TestCls b;
}
//これはスタック違いかな?メモリ領域のスタックの事ではなく、スタックという機能?
#include <stack>
template<Class T, class Container = deque<T> > class stack{};


446 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:01:46 ]
>>445
*が付いてなければおよそポインタではない
まだ何か勘違いしてない?

447 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:21:55 ]
>>445
スタックってデータ構造もあるけど、それに近い機能をもったメモリ領域がある。
関数とかの中で、

 /*DoSomething...*/
} 
のように記述するとブロックとして認識されてそのブロックの中で宣言された自動変数はブロックを抜けると破棄される。
これをスコープという。ブロックは入れ子にしたりして何個でも作れる。
ポインタなどはポインタ変数は破棄されるが、指してる先をdeleteするような器用さはない。

ちなみに、以下は
class Cls{
public:
int a;
TestCls b;
};
どっちの宣言も自動変数。
sizeofで見てみるとわかると思うけど、sizeof(int)+sizeof(TestCls)の領域が確保されることになる。
C++の参照型は、
Cls& <- 一度しか初期化できない参照。
Cls* <- 何度でも初期化できる参照。名前はポインタと呼ばれる。
javaだとクラスを宣言すると無条件でC++でいうCls&の形をしたポインタが使われるみたいだ。ちなみに俺はJAVAは初心者以下だ。

448 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 14:37:27 ]
仮想関数テーブルとか考えると危険な…いや、なんでもない

よく分かってないことは書かないことにしましょうか

449 名前:447 mailto:sage [2009/10/30(金) 14:47:30 ]
>>448
vtableは使ってないから説明してない。

仮想関数のオーバーライドの説明だけど、
C++の上書きオーバーライド(virtual function)は、大雑把に言って関数ポインタを上書きすることで実現している。
そのためにはクラスのメモリのどこかに関数ポインタのリストを持つためのポインタを持つことになる。
基本的にこれはメモリを操作してかきかえる類ではないのであることを知っていればいい。
で、仮想関数を持ったクラスをsizeofをすると関数ポインタのリストのポインタ変数のサイズ分増分して返ってくる。


450 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:06:07 ]
>>446
×//普通の変数。データ領域へのポインタ。
○//普通の変数。スタック領域に実態がある。
なんかもう滅茶苦茶ですね。
書き間違いと勘違いといろいろまざtt・・・

>>447
#include なんちゃら
int gInt; //データ領域に実態が格納されているグローバル変数(非自動変数)
TestCls gCls; //同上
class Cls{
public:
 int a; //スタック領域に格納されている自動変数
 TestCls b; //同上
};
int main(){
int a; TestCls t; //スタック領域に格納されている自動変数
}
今度こそOKでしょうか?

>>448
>>449
初めて目にした単語なので、wiki見てみましたがイミフ。
基底クラスAを継承したサブクラスB,Cがあり
Aで仮想関数speakを宣言し、B,Cクラスでそれぞれ実装した場合、次の関数の呼び出しはどうなるか?
ClsB b;
ClsA *a = &b;
a->speak();
どう考えてもBで実装したspeakが呼ばれます。vtableの入る余地がありません。

ちょっと試行錯誤してきます。



451 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:29:09 ]
1.ClsA *aはポインタ型なんだから、ClsAの継承クラスのインスタンスならどれでも受け入れられる。
2.受け入れるオブジェクトの型は、ユーザーの入力などにより動的(実行時)に変化する。
以上より仮想関数テーブルが必要になる。

450のように、静的(コンパイル時)に型が限定できる場合ばかりではないということ。

452 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:29:31 ]
>>450
基本的にグローバル変数も自動変数というルールに違いはない。
それは、グローバルスコープに宣言されているという前提になる。
あと、ちょっと妙な書き方をしてしまったので訂正するが、
class Cls{
public:
 int a; //スタック領域に格納されている自動変数
 TestCls b; //同上
};
上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。でも動作は自動変数と変わらない。
deleteした瞬間がスコープ終了の瞬間。

あと、オーバーライドの話。
C++のオーバーライドはvirtualをつけなかったら、上書きされない。よって、vtableも生成されない。
つまり、基本的には、そのクラスで宣言されたそのメンバ関数が呼ばれる。
virtualをつけてオーバーライドされる前提のメンバ関数は継承先で上書きすることができる。
virtualの上書きされた関数は、基底でも上書きされた関数を呼ぶ。
もちろんインスタンスは実装したクラスのインスタンスじゃないといけないけども。

453 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:43:11 ]
ちょっとした違和感を感じたんだが、
>>450 の言うデータ領域って、たとえばimmutableな文字列定数とかを格納するところかな??
static constの変数とか。

454 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 15:59:33 ]
何かもう、ネイティブコードでどう実装されてるかから説明した方が早い気がしてきた

455 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 16:25:02 ]
>>451
ttp://codepad.org/Pldw34mI
1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。
何も問題ありません。頭が爆破寸前です。

>>452
>上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。
おkです。

>でも動作は自動変数と変わらない。
>deleteした瞬間がスコープ終了の瞬間。
自動変数の定義は、「関数内で宣言された記憶クラス指定子の付かない変数」ですよね?
deleteさえしっかりやれば、newしたものも自動変数と同じ振る舞いをすると。

>>453
>>450のソースのコメントは間違い・・・?
下記2種「以外」の変数が格納される領域がデータ領域?
・グローバル変数
・自動変数

456 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 17:10:43 ]
>>455
C++におけるメジャーなメモリ領域は2つ。
一つはスタックと呼ばれる領域。一つは、ヒープと呼ばれる領域。
スタックは宣言したときに確保されてスコープが終了したら破棄されることを約束された領域。
ヒープはメモリのプールで必要なときに確保して不要になったらユーザの責任で開放する。資源は有効に。

で、コード領域やデータ領域というのはコンパイラやOSの最適化によって発生した領域。
たぶん、データ領域は何度も参照されるような定数データを効率よく回すための機構で基本的に書き込み禁止。
で、たぶん、コード領域はプログラムコード自身をOSがロードした領域。
なので、後の2つはC++の仕様外だと思う。

457 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 18:40:54 ]
>>456
静的記憶期間(static付きやグローバル変数など)のオブジェクトの置き場なのだから、
データ領域はスタック・ヒープと同列に扱おうよ。
規格書でも(言葉は違うけど)その3つの概念は出てくることだし。

458 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 19:24:41 ]
コンパイル時には、ClsSub1になるのかClsSub2になるのかわかっていない。
→このままでは、ClsSuper::test(), ClsSub1::test(), ClsSub2::test()のどれとしてコンパイルすればいいのかわからない。
  このコードで言うと、sub1, sub2 superのどれを表示していいかわからない。

ここまでは大丈夫?

次に、ClsSuperの隠しメンバ変数にpTestFunctionという関数ポインタを追加して、
実行時、インスタンスが生成時にその関数ポインタへ使用すべきメンバ関数を代入するようにする。

ClsSuper *s; には使用すべき関数ポインタが含まれているので、
コンパイル時に s->test(); という文を、関数ポインタからの呼び出しに翻訳する。

実行時に、sがどの型をさしていようと適切な関数ポインタが指定されるので、問題なく実行できる。



> 1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。
というのは、仮想関数テーブル(=関数ポインタのようなもの)が仕事をしてるから。
とりあえずコメントにも補足書いたけど、以上が仮想関数テーブルが必要な理由。
codepad.org/uuPlC3eO

459 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 20:26:13 ]
>>456
>>457も言ってるけど、スタックとヒープと静的の三つとした方が。
静的記憶は普通に読み書き可能なことが多いんじゃないかな、x86では。dsセレクタで
アクセスされるようなセグメントに配置するのが一般的な気がする。
リードオンリーの定数はむしろ、コンパイル時点で埋め込んじゃう気がするし。

460 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 20:47:25 ]
スタックもヒープも物理的には同じだぞ。
コンパイル時に固定サイズの領域を割り当てるのがスタック。
スタック不足になるのは、メモリが足らないからではなく
予測以上に初期の固定メモリを使い切ったため。
物理的には、スタックもヒープも違いはないので、
多くメモリ確保するなら動的=ヒープがいい。



461 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:00:19 ]
>>456>>457>>459>>460
今の私の認識と、説明していただいたメモリ領域の説明がだいたい一致するので
メモリ領域に関しては大丈夫そうです。

>>460
>多くメモリ確保するなら動的=ヒープがいい。
私がはじめに学んだ言語ではそのあたりを気にしながらコーディングしていましたが
c++においてはまったく意識してませんでした。
メモリをいっぱい使うような処理をする場合には気をつけてみます。

>>458
40行目で正しく関数が呼べてるのは仮想関数テーブルがあるからなんですね。
コーディングしている分には見えないものですが、内部的には説明してくださったような動作になっていると。

今日1日でc++に対する理解度がだいぶ深まった気がします。

462 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:05:38 ]
aa

463 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:08:23 ]
でもヒープ確保には、OSとのやりとりがあって、生成に時間食うがな。
スタックは、はじめに確保した領域を使い回すだけだからOSとのやりとりはなく
高速。

464 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 21:11:40 ]
動作速度に関しては、
スタック ヒープに違いはないが
生成と破棄に関しては違いが出るってこと。
長いこと(10秒以上とか)保持するなら、
生成コストは無視できるから
安定性のためヒープを使う方が良いな。

465 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:07:18 ]
待て待て、スタックとヒープは実装原理が全く違うがな。適当言うんじゃない。
一般的なスタックは、pushするかスタックポインタを移動させることで積み上げて、
破棄する時はスタックポインタの移動だけで終わるから、ヒープに比べたら圧倒的に
確保も解放も高速だぞ。

466 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:08:28 ]
確保と解放は速度差があるが、確保されたメモリを使う分には同じ速度だな。

467 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 22:26:53 ]
>>465
確保方法に違いはあっても、どちらも同一の(実)メモリつかうんだよ。
OSに問い合わせるか、C言語が管理している領域に問い合わせるかだけ。
スタックでさえ仮想メモリに移動することもある。
OSや他のアプリからみれば特殊な物ではない。

468 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 23:41:54 ]
とりあえず確保解放の速度が圧倒的に違うのは確実だけどな、スタックとヒープじゃ。
>>466がほとんどの環境で正解。

469 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 23:44:38 ]
圧倒的に違うといっても総実行時間の何%だよ

以下ループ

470 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 01:50:36 ]
ボトルネックに突っ込んだら恐ろしく違うだろうな



471 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:11:39 ]
まぁ環境によっていろいろあるってことでFA

472 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:48:03 ]
dllを作っているのですが
デバッグでは作成できて、リリースしてビルドすると
ライブラリ ***testdll.exp を作成中
LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。
ビルドログは "***" に保存されました。
testdll - エラー 1、警告 0

と表示されてできません
どうすればできるのでしょうか・・・・・

473 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 03:52:30 ]
>>472
「エントリーポイントを定義しなければなりません」

エントリーポイントを定義すればできる

これぐらいの推測ができないようじゃ、前途多難だな。

474 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 11:53:20 ]
enumとかstatic constの定数は外のクラスに見せないならクラススコープでprivateで定義するのが良いんですよね?

475 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:31:50 ]
コンテナのイテレータから、渡されたコンテナの要素数を求めることはできますか?
template<class Iterator>
size_t Size(Iterator it)
{
return ?;
}

int main()
{
std::vector<int> lhs;
lhs.push_back(1); lhs.push_back(2);
std::vector<int>::iterator ite;
ite = lhs.begin();
int n = Size(ite); // こんな感じでコンテナの要素数を求めたいのですが
}

476 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:34:41 ]
vector::size()では何か不都合でもあるの?

477 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:42:59 ]
>>475 です
vector::size() をこのように使っているのですが
これでは、イテレータを渡しても、当然のことですがエラーになってしまいます、
なんとかイテレータを渡して、そのコンテナのサイズがわからないものかと思案しています。
template <class Container> inline
size_t Size(const Container& c)
{ return c.size(); }

478 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 12:55:04 ]
要素へのポインタを所有しているコンテナを特定する手段があるなら可能


479 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:02:22 ]
>>470
ボトルネックの個所で
スタックだろうがヒープだろうがメモリの確保解放するコード書くのは論外だろう


480 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:09:48 ]
>>479
秒間一万回程度の半端なボトルネックだと、スタックかヒープかで致命的な事態に
なるだろうな。

まぁ、違いを知った上で、大差無いと判断したところで使うのは最初から問題無い。
「違わない」と断言するのは激しく問題があるってだけ。カーネルに落ちる場合は
スタックの数万倍も重いことがある訳で。



481 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:10:09 ]
>>478 thx です
関数オブジェクトを作っていて、引数が多くなってしまい
なんとか、減らせないものだろうかと思い質問したしだいでした
要素へのポインタを所持しているコンテナを引き渡すのなら、
要素数を引き渡すだけのことなので、同じくらいのコストがかかりそうで
あききらめますが、要素へのポインタを所持しているコンテナを引き渡して
要素数を求める方法へ関心があります、単純な実装例をご教示願えませんか。

482 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:29:21 ]
c.size()

483 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 13:45:50 ]
>>477
イテレータのペア(開始と終端)を取る関数オブジェクトなら
std::distance(it1, it2) で [it1-it2)間の要素数が求められるよ。

484 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 14:20:44 ]
>>475,477,481
ひとつのイテレータからコンテナの要素数を求める一般的な方法はないよ。
実装依存の機能でそういうのがあるか、自分で実装すれば可能。
beginとendがあるなら>>483のでいける。

485 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 18:59:20 ]
>>484ありがとう
>実装依存の機能でそういうのがあるか、自分で実装すれば可能。
もし仮に実装するなら、どんな感じになるのでしょうか?
まずは、イテレータのアドレスを取得しなければならないのはわかるのですが
それ以降の展開が想像できません、向学のために概略だけでも教えてもらえないでしょうか。

486 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 19:11:13 ]
>>485
MinGW だとイテレータはコンテナのアドレスを持ってるようだ

487 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 20:54:21 ]
そもそもイテレータ渡ししてるのに本当に要素数が必要なのかから考えるべきな気がする。

488 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 21:51:29 ]
>>485
元のイテレータの派生クラスかラッパークラスを作って、そいつに要素数か親コンテナのポインタを持たせる。
しかし、親コンテナの要素数が必要な処理ってどんなだ?
コードをさらしてみる気はないか?

489 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 21:56:41 ]
技巧する必要なし
元のをを渡せよ。

490 名前:デフォルトの名無しさん mailto:sage [2009/10/31(土) 22:09:55 ]
引き数へらしたいならレンジイテレータでもつかってコンテナまるごと渡せよ



491 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:07:20 ]
演算子のオーバーライドって一般企業でも使ってますか?
パッと見どうゆう動作をするのかわからないから、危険な香りがするのですが。
例えば、タスクシステムを使っていて、とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
一見メモリリークするコードに見えます。

492 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:13:44 ]
>>491
基本的にそういうことはドキュメントに書いておくべきことじゃないかなぁ。
読まない人もいるみたいだけどね。読みやすいドキュメントって言うのもむずかしいけど。

493 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:13:49 ]
>>491
何を使っても酷いことになる人はどこにでもいるよ

494 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:28:12 ]
>>491
そんな事言ったらoperator+をオーバーロードしてマイナスの動作を
させるへそ曲がりな事だって出来るぞ

仕様書でちゃんと最初に決めとけ

495 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 21:46:43 ]
>>491
危険だよ。だから是非使うべきだと感じないなら使うものではない。ただ、例えば、
class に + or - があればすごく楽な場合があるでしょ。operator
overloading して a+b+c と書くのと a.plus(b).plus(c) とか書いたり
してわかりにくくなる(そしてミスしやすくなる)のとのどちらが良いか。
どう使うかによる。グループで仕事してるなら合意が必要。たとえば、一応

ttp://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Operator_Overloading#Operator_Overloading

496 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:15:04 ]
>>491
基本的には使わないだろう。企業に限らず。
でも、例えば多倍長整数クラスとか、有理数クラスとか、ベクトルクラスとかを
作るなら、operator+を定義しても恐らく誰も間違わない。そういう場合は使う
方が楽という判断も十分有力だし、それでも使わないという判断もやはり有力。

497 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:17:08 ]
まぁ、暗黙の変換なんかと同じだな。
無闇やたらと使うのは糞設計だが、完全排除すれば良設計というものでもない。

498 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 22:28:05 ]
微妙なら()つけろよ。簡単のために公開しない関数内部で使うなら別に良いだろ。

499 名前:デフォルトの名無しさん mailto:sage [2009/11/02(月) 23:31:40 ]
>>497
俺は argument 一つの constructor はやっぱり explicit 付けてる。
operator overloading の方はたまに使う時がある。

500 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 03:04:26 ]
スマポなんかは暗黙の変換に対応しないと微妙



501 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 06:28:54 ]
>>491
× オーバーライド
○ オーバーロード

あと、タスクシステム死ね。

> とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
> 一見メモリリークするコードに見えます。
具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?

502 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:46:36 ]
すいません。下記のようなことがやりたいのですが、
”\debug.cpp(13) : error C2059: 構文エラー : ')'”
と表示されコンパイルが通りません。どうしたらいいですか。
void Debug::create_debug_message(...)
{
  char tmp_str[100];
  sprintf(tmp_str, __VA_ARGS__);   // line: 13
}

503 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:50:37 ]
>>502
void Debug::create_debug_message(const char *format, ...)
{
  char tmp_str[100];
  va_list ap;
  va_start(ap, format);
  vsprintf(tmp_str, format, ap);
}


504 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 14:58:30 ]
できました。ありがとうございました。

505 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 15:54:29 ]
そういや可変長引数長い事使ってないなあ
リハビリしとかなきゃ

506 名前:491 mailto:sage [2009/11/03(火) 18:00:50 ]
>>492-497
多倍長整数クラスの+のように、直感的にわかるような動作をするものなら演算子のオーバーロードをしても良いが
基本的に多用するものではないということですね。


>>501
>×オーバーライド
間違いを確認しました。

>具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?
デメリットがあっても、それを打ち消すようなコーディングの仕方や
デメリットを凌駕するメリットがあれば、演算子のオーバーロードを積極的に使っていこうと考えていたからです。
私はC++を勉強しはじめてまだ日が浅いので、私の知らない何かがあるのかもしれないと思い、質問させてもらいました。


一般的な演算子のオーバーロードに対する考えが聞けて、とてもためになりました。
ありがとうございます。

507 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 12:21:15 ]
>>506
業種によっても違うんじゃないかな。
私のところは画像処理や数値計算関係なので座標の足し算とかベクタの掛け算なんかが
頻発するので演算子オーバーロードはあるとないとじゃ大違いだから。

508 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 16:41:27 ]
ベクトルの掛け算も演算子オーバーロードしちゃうのか…
内積にすんのかな

509 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 16:48:04 ]
スカラ倍のことじゃないの

510 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:07:21 ]
内積、スカラ倍両方オーバーロードするのもありだな。
いずれにせよ、ベクトルや行列使った数値計算とかは
オーバーロードしないとコードが読めなくなるからリスクとの
トレードオフとして悪くないと思う。



511 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:18:02 ]
インラインアセンブラと組み合わせれば演算子でSIMDも可能
って考えるとなんか夢が広がるような気がするよね
実際には関数呼び出しだって同じなんだが、表記的に
高水準(抽象的)・低水準(具体的)の混在具合が脳汁出そう

512 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 17:59:50 ]
ベクタ×ベクタは演算ライブラリによっては内積だけど、
演算ライブラリによっては敢えて用意していないね。
それでもスカラ積があるだけでも随分違うけど。

513 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:19:06 ]
「絶対に内積だろ」とは言い切れないし、スカラ積だけ対応するのが個人的には好み
だけど、内積でも別に文句言うほどじゃないかな

514 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:55:01 ]
スカラ積って内積じゃないの

515 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:59:47 ]
iostreamやBoostに見られるような「Cの文脈からかけ離れた演算子オーバーロード」
は、実際使ってみると割と平気だったりするんだよな。
ただ、見慣れない問題に直面する可能性も高いから、やっぱりお仕事だと微妙かな。
boost::formatとか激しく便利ではあるんだけど。

516 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 22:57:49 ]
>>514
数Bやり直せw

517 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 23:06:14 ]
>>516
おまえこそやり直せ

518 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 23:14:19 ]
小学生ktkr

519 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 03:19:55 ]
スカラー積=内積
ベクトル積=外積

520 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 08:51:58 ]
>>503
va_endわすれてるぞ



521 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:18:30 ]
スカラー積ってスカラ倍のことじゃないの?


522 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:24:31 ]
もうその話題は終わり

523 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 09:48:19 ]
namespace Hello
{
class A;
};

namespace World
{
class B;
};

ヘッダーファイルに上記のように書いたところ、
class Bの所属がなぜかHello::World::Bとして扱われてしまい、
コンパイルエラーになります。これはコンパイラのバグでしょうか?


環境はwinXP x86 VC++ 2008Expressを使ってます。

524 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 10:01:37 ]
どうせ打ち間違い
523自体は正しい

525 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 10:03:15 ]
ていうかエラーメッセージ書けって

526 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:07:06 ]
もう少し状況を詳しく書いてみます

"helloworld.h"
namespace Hello
{
--class A;
}

namespace World
{
--class Hoge;
--namespace Button
--{
----enum Value { A, B, C };
--}
};

"hoge.h"
#include "helloworld.h"

namespace World
{
--class Hoge
--{
--public:
----Button::Value m_value;
--}
};

"error messeage"
C3083: 'World': '::' の左側のシンボルには、型を指定しなければなりません
C2460: 'Hello::World::Value::m_value' : 宣言されている 'Hello::World::Value' を使用しています。

527 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:10:32 ]
>>526
namespace Helloが閉じていない。
# まぁ、想定の範囲内だな。

528 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:11:50 ]
Hello::
まで書くとvisual studio のインテリセンスがWorldや
ヘッダーに書いた他のnamespaceを全部含んでしまっているように表示します。
World::やその他のネームスペースからはHelloを参照することはありません。

529 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:14:22 ]
;が抜けているのに気づけない間抜けであったか。

530 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:14:30 ]
本当だ。すいません小さなミスでした。



531 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:32:52 ]
VCなんですけど
floatとdoubleはどっちが速いですか?

532 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:39:13 ]
>>531
一概には言えませんが、doubleで組んで速度に不満があったら両方実測して比較すればよいでしょう。

533 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:43:23 ]
floatが速いよ
昔は、doubleに変換されるという説もあったが、いまは直に計算する。

534 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:45:13 ]
特に配列に格納すると、メモリ呼び出しが半分のサイズですむから
計算だけではなく、メモリサイズと呼び出し時間が短縮できる。

535 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 11:52:00 ]
フロートがSSEで二倍速い

536 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 12:10:08 ]
namespaceって;必要だっけ?

537 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 13:15:38 ]
必要じゃないことはないですよ

538 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:20:32 ]
floatにしてみます。

539 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:43:18 ]
floatは有効桁数がIEEE754では6桁しかないよ
だから用途が限られる
画面座標とか

540 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 17:46:27 ]
配列のインデックスは符号無しですか?



541 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 18:05:17 ]
厳密に言えば、いいえ

542 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 18:58:15 ]
ポインタの計算だからマイナスもある

543 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 19:14:31 ]
まず配列のインデックスの定義をだな


544 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:29:16 ]
namespace は ; いらないよね??
class は ; いるけどさ。

ていうか namespace {} に ; つけないで普通に使っているんだが…

545 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:35:52 ]
クラス定義は文だから;が必要で名前空間はスコープだからいらない。たぶん


546 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:46:17 ]
確かポインタ間の距離はptrdiff_t型で符号あり整数じゃね?

547 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 21:08:49 ]
struct foo { int bar; } buzz;
class foo { int bar; } buzz;
namespace foo { int bar; } buzz; // ← これだけ明らかにおかしく見えれば大丈夫

548 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 10:11:30 ]
>526がセミコロンが抜けているのは事実だが、>527は間違い。

>534、>535は正しいが、速度よりも>539の問題の方が通常は問題になるので、doubleを使っておくのが無難。

ポインタ演算については>542、>546の通りだが、>543の言うように「インデックス」が何を指しているかが問題。

549 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:20:14 ]
C/C++でZipファイルの追記したいのですがいいライブラリありますか。
DLL使うと、中間ファイルを生成してから追記するので遅いです。
100Mのzipファイルならそれをopenして追記したいです。

550 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:31:39 ]
tarならできるだろうけどzipはむりじゃね



551 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:33:27 ]
zlibは圧縮は出来るけど、書庫のフォーマットには対応してないですよね?

552 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:36:35 ]
>>550
このwebサイト収集するやつは、zip追記してます。
でもC言語でやってないです。
www.unixuser.org/~euske/python/webstemmer/index-j.html

553 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 14:01:44 ]
>>550
外人がいいやつ作ってくれました。
これで追記出来ました。

www.wischik.com/lu/programmer/zip_utils.html

554 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 18:19:57 ]
>>548
> doubleを使っておくのが無難。

それは微妙。どっちが向いてるのか考えるべき。ちょっと考えれば大体正解が選べるし。
例えば、APIがfloatを要求してるような場合はfloatが無難。
floatは精度に注意、floatとdoubleを無駄に混在させるのはアホ、SSEでは圧倒的に速度
が違う、SSE使わないならほんの僅かにfloatが速い、くらいであとは自己判断かな。

555 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:10:20 ]
混在を避けるのは鉄則。doubleの演算速度よりも、float⇔doubleの変換の方がよっぽど遅い。

556 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:12:50 ]
>>555
え?

557 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:14:14 ]
下のようにvectorの入った構造体があります。
typedef struct
{
  std::vector<int> foo;
  std::vector<float> bar;
}
HOGE;

これを値渡しすると、各vectorのコピーコンストラクタはちゃんと呼ばれるんでしょうか。

558 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:17:36 ]
>>556
それも環境次第だとは思うけど、少なくとも整数の符号拡張みたいに単純にはいかない。
フォーマットの変換が必要だから。
x86のFPUだと相当なコストがかかるけど、SSEなんかだとどうかは知らない。

559 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 20:24:57 ]
>>557
ヒント : C++では基本的にclass と struct は同等の扱い
デフォルトのprivateとpublicが違うだけ

560 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 21:13:15 ]
>557
ヒントより短い答え:呼ばれます。



561 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:03:45 ]
そんな巨大になりそうなもの値渡しして欲しくないな

562 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:24:42 ]
大丈夫
俺のちんこよりは小さいから

563 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 22:50:31 ]
>>553
よく読めてないけど、オンメモリで展開、追加、圧縮をやってるんじゃないの?

564 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 23:55:53 ]
>>561
新人「大丈夫ですよ先輩。sizeofで見たらたった80バイトです」

565 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:00:20 ]
ああそうだ、俺のコンパイラは構造体に巨大な配列を入れて
値渡しすると馬鹿みたいにpushの荒らしになる

rep movsが使えないのはpushが逆順になるからだろうな
それなら簡単なループ組んで転送すればいいと思うのに
pushを配列数分吐くもんだからexeが巨大になって馬鹿みたい

566 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:00:29 ]
>>563
追記は新規に作ったファイルだけだった
既存ファイルには追記できなかった
追加しようとしたらデータ初期化されたよ

567 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:09:08 ]
zipフォーマットここに書いてあるから追記自分でやってみるか

www.tnksoft.com/reading/zipfile/arczip.php
www.tnksoft.com/reading/zipfile/nonarc2.php

568 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:17:40 ]
もう一度いうけど、tarならできるだろうけどzipは無理だと思う。
無圧縮zipならできるかな

569 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:20:34 ]
100個のファイルを圧縮したzipを用意して、それを展開して、一つファイルを増やして、
圧縮して、バイナリ比較して、「追記」が実現可能かどうか見てみたら。
無圧縮でもそれやってみたら。

570 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 00:30:05 ]
駄目な理由はなんだ>
絶対出来るはず



571 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 01:25:11 ]
rep movsとか最近のコンパイラは間違っても使わないような

572 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 01:39:47 ]
サイズ重視のコードなら使う

573 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:11:52 ]
俺のコンパイラは断りもなくmemcpy呼んでるな。構造体の初期化には勝手にmemset使うし。

574 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:18:32 ]
>>573
それで何か問題でも?

575 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:23:41 ]
>>571
変数の初期化に使われているよ
特に配列だと間違いなく出てくる

576 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:34:11 ]
そもそも構造体の値渡しが必要な状況ってどんなの?
ポインタや参照が使えない状況ってのが思い浮かばない。

577 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 02:55:20 ]
逆に考えるんだ。ポインタでは困る場面なんだよ。
それが必要な状況?それは↓

578 名前:デフォルトの名無しさん [2009/11/07(土) 03:36:48 ]
ぬるぽ

579 名前:デフォルトの名無しさん [2009/11/07(土) 06:46:06 ]
再帰させるときなんかたまに使うけどね。

580 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 07:46:51 ]
RECT rc = { 0 };
とかってありなの?

VCだと中の変数ゼロになるんだけど



581 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:04:27 ]
そうだよ

582 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:11:19 ]
zip64の追記つくってくれ

583 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 08:15:20 ]
後半の情報フォーマット部分を追記データで
書き換えれば理論的には可能なはずなんだ。
でも正しいセットの仕方が判らない。

584 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 11:04:21 ]
zipの仕様は公開されてるからそれに従って書けばいいと思うよ
www.pkware.com/documents/casestudies/APPNOTE.TXT

585 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 11:15:53 ]
ファイルを個別に zip 圧縮してから tar でまとめるとか…

586 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:03:04 ]
つか
追記くらいライブラリないのかよ

587 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:18:34 ]
zipの構造はおおまかに

 ファイルヘッダ
 圧縮データ
 ファイルヘッダ
 圧縮データ
 ....
 ファイルヘッダ
 圧縮データ
 アーカイブインデックス(>>583のいう情報フォーマット部分)

てなってるから最後の圧縮データとアーカイブインデックスの間に
追記のファイルヘッダと圧縮データを入れて
アーカイブインデックスにも追加できればいける

7zとかcabなんかのソリッド圧縮形式だと
LZ77の辞書とエントロピー圧縮のコンテキストが必要だから
オンメモリでもいいから一度展開作業をしないと追記できない

ちなみにJavaScriptで無圧縮zip作るひとがいるくらいだから
圧縮をzlibですればzipのフォーマット自体はそれほど難しくない

588 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 13:39:27 ]
作ってクレオ

589 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 14:08:45 ]
パイロンだと、直書き出来る。
でも巨大ファイル(個数が100万とか)に追記すると解析に時間かかる。
パイロンのzip64の追記のソースをC++に書き換えられる人いますか。

パイロンの例
import zipfile
z = zipfile.ZipFile("test.zip", "a", zipfile.ZIP_DEFLATED, True )
z.write("log_data.txt")
z.close()

590 名前:589 mailto:sage [2009/11/07(土) 14:13:08 ]
実際に400M、50万ファイルのZIPファイルで実験したから間違いない。
コピーしたり展開したら時間かかるが、追記はコピーより速くできた。



591 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 14:49:15 ]
c言語の話題かぁ?

592 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 16:25:07 ]
struct Bar {
  Bar(): x(m_x), m_x() { }
  Foo &x;
private:
  Foo m_x;
};
初期化子の実行順序は、初期化子の順序ではなくて変数宣言の順序だと記憶していますが、
(例のコードではどちらにせよxが先だと思います。)上のようなコードを書くと、xの初期化から
始まって何物でもないm_xを参照してしまうはずなのにVisual C++のコンパイラは警告すら発し
ません。
このようなコードは避けるべきということは言うまでもないですが、コンパイラがまったく順序に
関知しないというのはいかがなものでしょうか、と。


593 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 16:32:20 ]
>>591
Zipは追記できないという説に対して
ZipもZip64も追記できたと言うこと

594 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:13:59 ]
>>592
嫌だったらC++使うなカス

595 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:14:59 ]
VCで複数のソースファイルがある場合、プリプロセッサの処理順てどこで定義されているの?
例えば aaa.h, bbb.h, ccc.h
の3つが互いにインクルードしている場合、
全体で使用できるためにはどのファイルで定義すればいいのかわからん

596 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:21:08 ]
#includeした順に決まってるだろ

597 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:21:08 ]
何を言いたいのかわからないけど、
#includeはそこにテキストがそのまま展開される。

#include "aaa.h"
#include "bbb.h"
#include "ccc.h"

なら aaa.h が真っ先に展開される。
しかし、非ローカルなスタティック変数の初期化順とかいう話になるのなら
それはそれは難しいことに。

違ったかな。ほほほ。

598 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:30:31 ]
結局、「暗黙の初期化順に依存するな」ってことね。

599 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:04:33 ]
#define #undef みたいにusing namespaceを無かったことにできないもんでしょうか

600 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:08:02 ]
逆に、using namespace を使うところだけスコープを切ればいい。

{
using namespace boost::lambda;

// ここでbindとか_1とか使う
}
// ここでは using namespace は無効



601 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:10:36 ]
みんなはusing namespace std;ってグローバルにおいちゃう派?おいちゃだめ派?

602 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:11:45 ]
Google Coding Standardsではらめってなってた。

603 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:12:27 ]
チーム全員がstd名前空間の全内容を把握しているなら
グローバルでもいいんじゃないですかね。

604 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:34:43 ]
同一プロジェクトでstd::stringとhoge::stringが混在したらそっちのほうがいやじゃない?
だからまとめて共通ヘッダに入れてグローバルusingしてる

605 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:37:12 ]
いちいちstd::stringとかhoge::stringと書けばいいじゃない。

606 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 18:43:32 ]
>>605
結構めんどくさくね?

607 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:01:18 ]
WinAPI使ってるともっと長くてどうしようもない名前がわらわら出てくるから
あんまり気にしたことないなぁ。って言うか末尾にSEXついてるの多すぎ。
マイクロソフトの技術者はどんだけ欲求不満なのか、と。

608 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:01:19 ]
入力補完で切るエディタなら
std::と打ったほうが楽

609 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:06:03 ]
>>607
sexわろたw
気にしたことなかったけど確かにそうだな

610 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:16:11 ]
>>576
インライン展開を期待するときなんか、あえて構造体の値戻しを使ったりする。



611 名前:デフォルトの名無しさん [2009/11/07(土) 19:41:39 ]
WIN32APIのSendMessageを使用する時、引数のwparamを文字列で渡す方法ってある?WinXPが環境です

612 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:43:12 ]
とりあえず、グローバル変数の初期化順序に関しては、チューリングマシンの停止問題
みたいに定義不可能な面があるから、依存するな、とかEffectiveC++に書いてあった
ような気がしなくもない

613 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 19:52:02 ]
そこでシングルトンの登場ですよ。

614 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:01:16 ]
シングルトンは俺的にはもうアンチパターンだな
Google的に、コンストラクタでは単純な初期化にとどめて、複雑な初期化はInit()で
やれ、というコーディングを採用してれば、初期化順序で悩むことも無い気がする

615 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:17:49 ]
単豚

616 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 21:00:39 ]
>>614
コンストラクタから初期化を追い出す必要は無いよ。
Init() 呼ぶくらいならグローバルなポインタに new すればいいじゃん。

617 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 22:58:31 ]
ゼロオーバーヘッド的にはグローバルなポインタにnewするくらいならInit()呼ぶなぁ

618 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:26:56 ]
operator newのオーバーロード(配置ではなくて)なんですけどグローバルにするのかstaticメンバにするのはどっちがいいんでしょうか?

619 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:31:20 ]
一緒。staticメンバは単にクラスのスコープの中に入っちゃうだけ。

620 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 23:36:58 ]
>>618
追加の引数が無い奴はグローバルにすると全体に影響が出るから気をつけてな。



621 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 00:09:48 ]
ありがとうございます
グローバルだと目的のクラス以外でもオーバーロードされてしまう
staticメンバだと目的のクラスだけオーバーロードされる
ということでしょうか。基本的にはstaticメンバにしたほうがよさそうですね


622 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 00:12:34 ]
>>621
影響範囲については、だいたいそういうこと。

細かい話をすると、クラスの奴は派生クラスでも使われる。
あと、追加の引数が無い奴をグローバルに置くのはオーバーロードじゃなくて置き換え、な。

623 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 15:27:46 ]
基底クラスのポインタから派生クラスのポインタへのキャストって
dynamic_castは遅いけど変換不能な場合NULLを返す
static_castは早いけど変換不能でも知らせてくれない
これ以外の違いってなんかある?

624 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 15:34:01 ]
その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない
その派生クラスがその基底クラスを仮想継承している場合、static_castは使用できない
(両方に当てはまる場合、どちらも使用できない)

625 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 19:45:51 ]
>その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない
マジすか初めて知った
確かにできてもあんまり意味はないけど


626 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 20:18:33 ]
キャストしない暗黙変換が一番使いやすい。とか本末転倒なこと言ってみる。

HogeBase* hoge;
Hoge2 *p = new Hoge2;
hoge = p;//基底があってなかったらコンパイルエラー吐く。 

627 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 01:46:58 ]
dynamic_castが必要になるのは糞設計に仕方なく対応する時だけ

628 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 01:56:39 ]
クロスキャストには必須だろ

629 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 02:49:46 ]
クロスキャストしたい時点で糞設計になってるんじゃ?

630 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:04:02 ]
>>629
違う
クラスが複雑になるとクロスキャストしたい局面はよく現れる



631 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:04:46 ]
×クラスが複雑になると
○継承関係が複雑になると

あ、継承関係が糞設計なんだろって突っ込みは無しな
そういう事を言い出すとキリがなくなってしまうんで

632 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:24:18 ]
そうは言っても、継承関係が糞設計なんだろ?w

633 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:49:06 ]
>>632
ほうら来た
だからそういう突っ込みは無し
人間そこまで完全な奴はいない
特にある程度プロジェクトが進んでしまっていると
今更設計を変えられない事も多い

634 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 03:55:13 ]
配られたカードがどんな悲惨でも
それで何とか勝負するしかないって事はあるだろう、仕事なら。

635 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:06:19 ]
結局>>627で全て終結していたわけか

636 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:06:54 ]
最初から「仕方なく対応する時」って書かれてるんだから、それは分かった上でだろう

637 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:14:02 ]
少なくともC++では、dynamic_castを使う必要が出てきた時点でほぼ糞設計。

糞設計をしてしまうことはあるし、気付いた時には引き返せないこともあるから、
使う時は使うべき。設計は変えられないが他の方法でどうにかしよう、というのは
最悪だから。
でも、そういう事態になったなら設計が糞だったんだ、という認識はすべき。

638 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:50:41 ]
>>637
それは当たり前だろう
そんな事はわざわざ言わなくても誰でもわかっている

639 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:58:39 ]
つーかそれ以上の話をする必要を感じない

640 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 04:59:42 ]
つーか>>628が要らんこと言ったのが悪い



641 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 23:38:14 ]
シェア的にC/C++のコンパイラあげると上二つはVCとgccかなって思ってるんだが、
ベスト5ぐらいには他にどんなのがあるの?

642 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 23:54:09 ]
>>641
ボーランドとかTurboとか

643 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 01:28:56 ]
当然 icc は入ると思う。

644 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 10:52:51 ]
Code Warrierも入るな。間違いない。

645 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 12:31:11 ]
じゃあ俺はLSI-C

646 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:03:07 ]
codepad.org/kd2xzcnB

コードパッドのほうだと期待通りに動くんですけど
僕の使ってるコンパイラ(VC++EE2008)ではdelete[]が確保したサイズじゃなくてクラスのサイズを引き数に渡してしまいます
これは規格で定まっていないんじゃなくて僕が使ってるのがただのクソッタレコンパイラということですか?

647 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:47:50 ]
>>641-645
「シェア」の意味によって違ってくるだろうな。
使ってる人数か?コンパイルされたコードの走っている台数か?
商用に限るのか?学生の講義とかも含めるのか?日本なのか世界なのか?

コンパイルされたコードの走ってる台数だとOSなんかも入って
ちょっとナンセンスになるから、結局人数なんだろうけど。
そうすると組み込み系とかはそんなに多くないと思う。

648 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 17:56:12 ]
>>646
size_tを引数にとるoperator delete[]なんて規格にあったっけ?

649 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 18:00:26 ]
ああ、そうか。メンバ関数のほうはsize_tを引数にとるのか。

650 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 21:53:50 ]
関数を作っています。
int型の引数nに応じて、配列の大きさを決めたいのですが、コンパイルすると
「定数式が必要です」とのエラーメッセージが出て失敗します。
どうすれば私の意図する動作が可能になるでしょうか?

int* getTest(int n, int o[], float r) {

int p[n][2];// = new int[n][2];

//省略

return *p;
}



651 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 22:17:15 ]
mallocもしくはnewで調べれ
配列の大きさはコンパイル時に決定されなければならない。

652 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 22:38:07 ]
>>650
配列の大きさを指定できるのは一番右側のoperator[]内だけ

653 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:39:18 ]
int (*p)[2] = new int[n][2];

654 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:42:36 ]
>>650
関数内でnewやmallocしてそのポインタを返すのは危険きわまる。
C++なんだから、vector<vector<int>>を参照渡しするのがいいと思う。

655 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:44:32 ]
すまぽが早く実用化されれば、こんな問題どうってことないんだけどなぁ。。。

656 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 23:55:55 ]
これがJavaやC#なら、どんなオブジェクトでも平然と返せるんだけどねえ。
shared_ptrを使えばいいんだけどね。std::tr1::shared_ptr<std::string>とか
長くなりがちなのがちょっと。

657 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 00:13:10 ]
どこでもshared_ptrに頼るのってどうなのよ
コピーと代入のコスト結構馬鹿にならんし
寿命と例外安全考えて使わなくていいところは使わないほうがいいと思うんだし

658 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 00:41:54 ]
>>653
おいデタラメ書くな

659 名前:650 mailto:sage [2009/11/11(水) 02:52:29 ]
関数を呼ぶ側が自分でvectorを宣言しなければならないのでかなり面倒ですが
こんな感じでしょうか?
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10091.txt

できれば関数名をsetPolygonPointsでなくgetPolygonPointsとしてvector<vector<float>>型のポインタを戻り値としたいのですが
やり方がよくわかりません。

こんな感じで関数内にて、戻り値とするvを宣言すると
vector<vector<float>> *v = new vector<vector<float>>;
16行目のv[c][0] = の部分をどう書いてもエラーになってしまいます。


660 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 04:08:45 ]
スマートポインタ使わずに平気で関数内new&returnしてますが何か



661 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 09:13:01 ]
もらったほうがきちんとすてればなんのもんだいもない

662 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 10:01:28 ]
>>659
そこで new はおかしいし、それじゃインスタンス作りようないでしょ。
(vector の大きさも指定していない)単に、

vector<vector<float> > v = vector<vector<float> >(n,vector<float>(2,0));

return v;

とかいう話?(次元 nx2 で良いのか知らんが)

それにしても cast をたくさん使ってるね。


663 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 10:04:12 ]
毎回floatにキャストしても
CPUの中の人は結局doubleで計算するわけ?

664 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 12:14:43 ]
>>663
x86系CPU+Visual C++では、そう(doubleじゃなくてlong doubleだけど)。
x64だとちょっと違ってて、多分floatで計算してると思う。

詳しくはx87FPUとSSE演算を調べてみてくれ。
重要なのはx64+WindowsだとFPUレジスタがDisableされていること。

665 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:50:25 ]
>>660
プロジェクトに悪意あるメンバーがいたらメモリリークさせられるぞ

666 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 13:59:53 ]
悪気は無かったんです・・・

667 名前:デフォルトの名無しさん [2009/11/11(水) 14:25:35 ]
VC++のMFCアプリで、あるjavaアプレットの画面イメージを取得するため
対象ウィンドウを検索して存在すればCWnd::SetWindowPos()で最前面にもってきて
CWnd::RedrawWindow()で再描画、ということを行っています。
対象ウィンドウが他のウィンドウに隠れている場合はこれでいいんですが
もともと最前面にある場合は、再描画の処理は不要だと思うのでスキップしたいのですが
最前面であるかどうかはどう判断すれば良いのでしょうか?
CWnd::GetWindow()でいろいろやってみているんですがうまくいきません。

668 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 15:41:34 ]
>>664
>x64+WindowsだとFPUレジスタがDisableされていること。

されてねえよ
タスクスイッチの時もスレッド切り替えの時もちゃんとFPUはsaveするように
仕様が変わった

669 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:06:54 ]
>>667
::EnumWindows()とかでどうか
不安ならそれに::GetWindow()を組み合わせる

670 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:24:15 ]
独学でCを学んでいます。
2進数から10進数への変換方法がわかったので
入力した2進数を10進数で表示する関数を作ったのですが
32桁あるときだけ答えが空白になってしまいます。
問題がある箇所を教えてください、お願いします。
環境はxp homeのvisual studio 2005です。

kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10099.txt



671 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 16:58:16 ]
ソース1とソース2のコストは同じでしょうか?
CPUのコストはわかりませんが、少なくともメモリの使用量は同じに見えますが、どうでしょうか?
1: //ソース1
2: for(int i=0; i<10; i++){
3:  for(int j=0; j<10; j++){
4:   static const float x = 10;
5:   //処理省略
6:  }
7: }
8: //ソース2
9: static const float x = 10;
10: for(int i=0; i<10; i++){
11:  for(int j=0; j<10; j++){
12:   //処理省略
13:  }
14: }

672 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:21:01 ]
>>671
コンパイラと環境によって違いますとしか言えない

最適化が優れたコンパイラなら float x そのものを消去してしまうと思う

673 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:31:12 ]
使用していない変数は消去ってやつですね。
処理省略の部分でxは使っている事とします。
変数は静的な領域に確保するわけですから、どのコンパイラでもメモリの使用量はかわらないように見えるんですが、違うのでしょうか?

674 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:00 ]
>>673
そうとも言えない
とにかくコンパイラの吐いたコードを見るしか確かめる手はない

675 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:52 ]
>>671
横から、付け加えるなら、省略された部分の処理内容も影響する。
場合によっちゃあ処理フローまでガラッと変わる。

676 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:33:57 ]
あ、xは使ってるのか
それなら変わらないだろうという予測が立つ
しかしあくまでも予測だという事を忘れないように

677 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:36:51 ]
>>673
言語仕様では、静的変数の振舞は定義されていても、実装方法までは定義されていないので、
本当に静的な領域に確保されるかどうかは、コンパイラの出力したコードを見ないとわからない。
もっとも、一度確認したからといって、次にコンパイルしたときは違う結果になっているかもしれない。

678 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 17:39:07 ]
x86/x64のVCやgccなら、たぶん即値として命令コードに埋め込まれちゃう。
あくまで予測ですがね。

679 名前:671 mailto:sage [2009/11/11(水) 18:25:50 ]
私のレベルからしてコンパイラが吐いたコードを解析するのは無理です。
コストに関しては曖昧な感じですし
for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。

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

680 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 18:46:12 ]
for(int i = 0, const float x = 10; i < 10; ++i)

つーか80:20の(ry



681 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:02:03 ]
>>679
>for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。
そりゃ逆だ。
「スコープはなるべく小さく」といわれている。


682 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:03:20 ]
L2キャッシュが良く効くからな

683 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 19:04:03 ]
じゃなかった、バグが減るからか
C++はスマポがあるからいいんだが

684 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 20:45:41 ]
嘘みたいな話だが、昔の gcc だとスコープ狭い方が良
いコードが出た(龍本レベルでもあり得ないと思うんだ
が…)。

しかしまぁ、人間にとってもスコープ狭い方が読むとき
に気にすべき情報が減るので読み易い。

685 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 21:48:52 ]
{
const int c = 10;

for(int j = 0; ・・・

}

でもこれってちょっとダサくない?
インデント深くなるし

686 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:05:04 ]
慣れればスコープ無視したコードの方がダサイと思うようになるさ

687 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:34:36 ]
コピーコンストラクタとoperator=()の内容って同じことが多いのですが、
コピーコンストラクタには「*this = コピー元;」とだけ書いて
operator=()のほうに処理を集約してしまうことって、なにかまずいことはありますか?

688 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:08 ]
俺もよく使うな、自動変数の生存範囲を限定するためだけのスコープ。

689 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 22:40:42 ]
場合によってはバグの元になる
ならなくてもメンバ変数が全部初期化された後
すぐに代入することになるから無駄な処理が発生する


690 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 02:14:40 ]
>>687
コピーコンストラクタと代入演算子で2つも似たような処理を書きたくないのなら、
逆にコピーコンストラクタ(とswap)を使ってoperator =を実装するほうがおすすめ。こんな感じ。
class Hoge
{
Hoge(const Hoge&); //コピーコンストラクタ
void swap(Hoge& other); // *thisとotherの全メンバをswapする

Hoge& operator =(const Hoge& y)
{
Hoge(y).swap(*this);
return *this;
}

};
めちゃくちゃ新しい処理系ならswapの代わりにstd::moveを
(ムーブ代入演算子を定義して)使う方法も使えるけど、ここでは取り上げない。あしからず。



691 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 03:17:23 ]
>>690
これ未定義の動作にならない?

class Hoge
{
int i;
public:
Hoge(int ii = 0) : i(ii) {}
Hoge(const Hoge& j) : i(j.i) {} //コピーコンストラクタ
void swap(Hoge& other) { // *thisとotherの全メンバをswapする
Hoge* tmp = new Hoge;
std::memcpy(tmp, this, sizeof(*this)); // undefined behavior
std::memcpy(this, &other, sizeof(*this));
std::memcpy(&other, tmp, sizeof(*this));
}
Hoge& operator=(const Hoge& y) {
Hoge(y).swap(*this);
return *this;
}
void print() const {
std::cout << i << std::endl;
}
};

int main()
{
Hoge a(1);
Hoge b(2);
a = b;
a.print();
b.print();
}

692 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:00:58 ]
質問です
C++において、関数ポインタを使う意義は何があるでしょうか?
言い換えれば、具体的にどのような事をするときに便利なのでしょうか
どなたかお願いします・・・

693 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 04:48:35 ]
コールバックとか。・・・でもC++だとその多くは仮想関数に取って代わるかな?

C++でも使う例というと、関数テーブルかなぁ。
たとえば、ユーザーの入力したコマンドに応じた動作をしたい場合(以下コードは適当)、
typedef int(*Cmd)(T* args);
Cmd command = { &CommandA, &CommandB ... }; // 関数テーブル(関数ポインタのリスト)
みたいなのを用意した上で、それをこんな風に実行する。
int Execute(int cmd, T* args) { return (command[cmd])(args); } // cmdの値はユーザーの入力次第

もちろん、switch (cmd) { ... } で分岐させてもいいけど、それだと各コマンドに対応する関数を
色々切り替えたい時とかには少々不便だし、コマンドの総数が3桁だったりするとswitch文が長すぎちゃう。
まぁその辺は結局作りたい物次第なわけだけど。
世の中に無数にあるはずの、オリジナルのスクリプト言語(ゲームエンジン用でも何でも)のコードには、
関数テーブルが山ほど出てきそうだなぁ。

694 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:09:50 ]
最近の OO 学習から入った C++ な人は基底クラスのポ
インタ使ってれば無理に関数ポインタ使わなくてもいい
気がする。

695 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 09:36:52 ]
クラスのインスタンスのメソッドへのポインタって使えますか?

696 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 10:10:15 ]
はい

697 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 12:27:45 ]
>>692
Win32を使うと嫌でもコールバックを使う場面に出くわすよ

698 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 16:09:11 ]
>>695
使えるけど使わないほうが無難だな。 ->* とか .* とか見たくないよ。
C++的には operator()()がいいかも。

699 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 20:26:12 ]
->*は拡張メソッドで使ってしまう


700 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:49:51 ]
Cです
構造体の初期化でmemsetを使うと問題があると聞きました.
ループ文でまわしている場合,毎回初期化する必要があるんですが
どうすればいいんでしょうか?

ポインタ配列です.

typedef struct{




701 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 21:52:43 ]
struct Hoge hoge = {0};

702 名前:700 mailto:sage [2009/11/12(木) 21:52:57 ]
すいません.途中で送信してしまいました.
どうやって初期化すればよろしいのでしょうか?

703 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:24:39 ]
>>701
ありがとうございます.
実際にはポインタで宣言しているのですが,

Hoge *hoge

hoge = malloc(sizeof(Hoge) * 100);

for(i = 0; i < 100; i++){
hoge[i] = {0};
}

でいいんですかね?

704 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:32:05 ]
zeromemory使えや

705 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:53:04 ]
std::fill()使えや

706 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:57:05 ]
>>705
それはC++。

707 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 22:59:33 ]
>>703だけ見てCかC++か区別付くかヴォケ

708 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:04 ]
Hoge foo = {0};

for(i = 0; i < 100; i++)
hoge[i] = foo;

709 名前:デフォルトの名無しさん mailto:sage [2009/11/12(木) 23:00:35 ]
C++ならmalloc()の戻り値をキャストしないのはエラーなのでは

710 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 00:44:58 ]
Hoge の中に微妙なモノが union で詰まってる時は必要
に応じて何種類か用意しておいてコピーすればいいと思
うんだけど、この場合何も考えずに {0} で初期化する
と未定義動作だっけ?



711 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:01:58 ]
HogeがPODじゃない場合はそもそもそういう初期化は出来ない

712 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 01:55:16 ]
>>707
この質問は>>700だぞ? 一行目でちゃんと「Cです」って言ってるじゃん。
>>703だけ見て」ってお前、>>703だけ見ること自体がヴォケなんだよw

713 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 07:12:50 ]
>>646
規格の 12.5 p5 で、解放されるメモリブロックのサイズが渡されると
定められている。
> When a delete-expression is executed, the selected deallocation function
> shall be called with the address of the block of storage to be reclaimed
> as its first argument and (if the two-parameter style is used) the size
> of the block as its second argument.

かなり古い VC についてはバグとして見つかっていたみたいだけど、
新しいのでも直ってないのかな?
ml.tietew.jp/cppll/cppll/thread_articles/5126

714 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:25:48 ]
結論、そのコードがCで、今後C++に転用する可能性を排除できるのならmemset()でもいいんでない?
そうでないなら、>708で。間違っても、一部のロートルの世迷言に釣られてmemcpy(hoge + i, & foo, sizeof(foo))なんてしないように。

715 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:53:37 ]
>>711
こういうことなんだが。

struct {
  union {
    void *p;
    void (*func)(void);
    float f;
    double d;
  } u;
} s = {0};


716 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 10:56:01 ]
>>715
今規格見た。最初のメンバが初期化されるんだな。

717 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 11:59:14 ]
unionを{0}で初期化してもいいけど
最初のメンバと違う型で参照したら処理系依存ってことか

718 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:47:56 ]
EUCで「。」の区切りを見つけるにはどうすればいいですか
文字コードは0xa1 0xa3です。
偶然にaaaa 0xa1、0xa3 bbbb となった場合が判断できないですが。

719 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 12:59:15 ]
>>718
探したい対象が文字列のように、EUCエンコードされていることが保証されているなら、
0xa1から遡って0x80以上のコードが偶数個連続していたらその0xa1が1バイト目。
遡るのが嫌なら、先頭から監視するしか。

720 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:02:24 ]
実行ファイルやDLLに画像など任意のバイナリデータを埋め込むにはどうするればいいんでしょうか?
今考えてるのは、unsigned char配列にデータを読み込んで0xXX, 0xYY, 0xZZ, ・・・のような形式で出力するプログラムを作り
コンパイル前に一度実行してdata.datに保存。利用者側は
unsigned char data[] =
{
#include "data.dat"
};
と書いて使う。という感じなんですが・・・



721 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:07:32 ]
>>719
トンクス

722 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:09:09 ]
>>720
windows限定なら、標準のリソースとして埋め込めばいいのでは。アイコンなど。

723 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 13:53:35 ]
>>719
文字化けや不要コードの埋め込みなどが原因と思うけど
いい具合に出来なかった。

724 名前:718 mailto:sage [2009/11/13(金) 14:05:36 ]
変換ツール任せでやってみる。wstring型に変換できれば比較は簡単だから。

725 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 14:21:20 ]
wchar_tに変換して出来ました。
手間かかるけど、文字化け多発するよりかは良いか。

726 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 15:47:40 ]
vs2008なのですがboostのshared_ptrでインテリセンスって使えますか?
試したところ効かなかったのですが

using boost::shared_ptr;
shared_ptr<Hoge> pHoge = shared_ptr<Hoge>( new Hoge( 3 ) );
pHoge->
↑で出したい

727 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:18:31 ]
std::tr1::shared_ptrなら出るよ。

728 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:45:12 ]
C++の識別子長すぎていらつく
スコープ付きの識別子の別名定義ができれば便利なのに


729 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:51:33 ]
つスコープ内でtypedef

730 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 16:52:48 ]
725だけど、「。」の発見は出来たけど、こんどは文字種の特定が困難になったよ。
かな、カナ、漢字など。UTF16らしいが文字コードがよくわからん。
EUC -> UTF16 -> SJIS OR EUCと何度も変換するしかないのか。



731 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:11:00 ]
>>727
試したけどダメっぽいです。コンパイルは通るんですが
何か根本的な間違いをしてるのかも・・・。
ひとまず諦めます

732 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:13:00 ]
>>729
それじゃ型限定じゃん
変数や関数の別名を参照や関数ポインタ使わずに楽に短くしたいんだよ


733 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:16:05 ]
>>731
インテリセンスするための情報収集が狂っちゃうと、そういうことがおきるねー

リビルドや
中間ファイル(.obj や .res .scc .pdb .pch .ilk .idb .ncb .plg .bsc まだあるかも)を完全に消してのビルドで
復活したりするよ。

734 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 17:40:31 ]
>>732
C#のusing的なやつ(しかもスコープ限定)が欲しいってことか。

735 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:07:55 ]
>>730
混ぜるな危険

736 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 18:18:15 ]
>>714
まぁ俺も sockaddr_in 辺りは memset でクリアしちゃ
うけどさ。

> そのコードがCで、今後C++に転用する可能性を排除で
> きるのならmemset()でもいいんでない?

厳しく言うと >>715 みたいなのは union を struct に
しても memset はアウトだよな?

737 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 19:05:49 ]
[迷信] とりあえず memset で初期化
www.kijineko.co.jp/tech/superstitions/initialization-by-memset.html

738 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:29:57 ]
>>737
リンク先あっているのか?
A a[10] = {0} で a[0]〜a[9] のすべてが0クリアされるのか?
static なら保障されているが、auto な配列ではダメなのでは?

739 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:30:49 ]
されるよ
ダメくない

740 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 20:44:04 ]
>>739
確認しました。
明示的に初期化される、ただし、一部しか明示されていない場合は、残りは 0 で初期化される、これは
auto でも static でも同じとのことですね。
thanks a lot.



741 名前:デフォルトの名無しさん mailto:sage [2009/11/13(金) 23:45:42 ]
>>733
もしやと思ってSP1にアップデートしたらstd::tr1::shared_ptで出来ました!
今までアップデートしてなかったんだなぁ…

742 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:37:57 ]
sscanfでは、第一引数の文字列の
半角スペースのある領域を""で囲っても、
ひとつの区切りとしてくれないみたいですが、
それができる方法がありましたら教えてください。

sscanf("\"abc de\" 5", "%s%s", s1, s2);

743 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:39:42 ]
>>742
面倒でもstrtok()使え

744 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 03:46:13 ]
*scanf は糞

745 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:23:51 ]
>>743>>744
ありがとうございます。
やはり、自前で実装ですか・・
やってみます。

746 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:31:30 ]
parserつかえ

747 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 04:51:18 ]
>>746
ありがとうございます。
試してみます。

748 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 05:52:57 ]
>>742
"%s"ではなく、"\"[^\"]"を使えばOK!

749 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:21:31 ]
構造体の配列について質問です
構造体Aを
A **a
で定義し a[x][y] でメモリを確保して他の関数に引数として渡します
その際
test_func(**a)
test_func(*a[y])
test_func(a[][y])
で全て同じ定義だと思うのですが全て関数の中で
a[i][j]でアクセスできますよね
(ただし i <= x && j <= y)
二つ目と三つ目では[y]で定義しているのでアクセス可能かと思いますが
一つ目はどうやって認識しているのですか?

750 名前:デフォルトの名無しさん [2009/11/14(土) 07:23:15 ]
unsigned long からfloatに変換した場合、起こりうる問題を教えてください



751 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:38:56 ]
>>750
有効桁数が減ります

752 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 07:55:40 ]
>>749
アクセスの仕方は一緒でも
渡されるものの内容が違います

753 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 08:49:47 ]
>test_func(**a)
>test_func(*a[y])
>test_func(a[][y])
>で全て同じ定義だと思うのですが

ちがいます

754 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:51:11 ]
>>753
一つ目と二つ目は違いますが二つ目と三つ目はおなじですよね?
ポインタのポインタとして渡された先頭のアドレスが渡された関数で
アドレスしか渡してないのにその内部構造が定義したように認識されているのはなぜなのでしょうか?

755 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:54:11 ]
>>754
二番目と三番目で渡している型は
配列を指すポインタであって、ポインタのポインタではありません

756 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 09:58:06 ]
>>754
少なくとも2と3はまったく違う
1と2は一緒とみなしてよいときとそうではない場合がある

757 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 11:56:11 ]
>>748
ありがとうございます。
試してみます。

758 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 15:26:21 ]
CLASS x=y; は
xは初期化されず
コピーコンストラクタへいくね。
これってたまたま不定値によっては動作がおかしくなりそうだが。
メモリ確保してあるかどうかのフラグの部分でおかしな動作したよ。

759 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:03:10 ]
>>758
コピーコンストラクタは初期化処理の一種なわけだが。
CLASS の定義がバグってるんじゃね?

760 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:10:49 ]
CLASS () { flg=0; }やCLASS (int n) { flg=0; }だとflgは確定してるけど
コピーコンストラクタは、xが初めて生成されたのか不明で
初期化して良いのかわからないと思ったんです。
コピーコンストラクタは初期化時にしか使われないんですか。
代入と一緒の気がしてました。どちらの場合も対応しないといけない気がしてました。



761 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:13:36 ]
>>760
コンストラクタはぜんぶ初期化処理。
初期化後のコピーは代入演算子で定義する。

762 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 16:15:04 ]
トンクス!

763 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:12:15 ]
>749

>test_func(**a)
>test_func(*a[y])
>test_func(a[][y])

これはプロトタイプ宣言の話?
それとも呼び側?
それによって話が変わる。

プロトタイプ宣言ならNを正の整数定数として
1)void func(char **a);
2)void func(char *a[]);
3)void func(char a[][N]);
4)void func(char (*a)[N]);

1と2は全く同じ意味。3と4は全く同じ意味。

764 名前:763 mailto:sage [2009/11/14(土) 19:15:55 ]
>749

よく読むと A a[x][y];
を渡したいみたいだね。
それならば、>763の3か4を使う。
1,2ではダメ。


765 名前:763 mailto:sage [2009/11/14(土) 19:23:23 ]
>749

何度もすまん。

>A **a
>で定義し a[x][y] でメモリを確保して他の関数に引数として渡します

aの定義がA **aなら1か2で渡す必要があるが、
それと
>a[x][y] でメモリを確保して
という部分がつながらない。

やりたいことはこれ?
A hoge[x][y];
A (*a)[y] = hoge;

それともこれ?
A **a;
int i;
a = malloc(sizeof(A*)*x);
for (i = 0; i < x; i++) {
a[i] = malloc(sizeof(A) * y);
}


766 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:45:18 ]
Visual C++ 2005 の環境でファイルを出力するプログラムを作成していますが、
期待通りに出力が行えません。

fprintf_s関数の第2引数の中で、%sを指定していますが、
文字列ではなく、文字として、「C」だけが出力されているようです。
どのようにすれば、文字列「C:\test」が出力されるのか、お分かりの方がおりましたらご教授いただけませんか?

-----プログラム-----
CString csvFile = _T("C:\\test");
FILE *fileStream;
if(_tfopen_s(&fileStream, (LPCTSTR)csvFile, _T("w")) != 0)
{
return -1;
}

fprintf_s(fileStream, "あいうえおABC123\r\n"); // あいうえおABC123
fprintf_s(fileStream, "FILE %s\r\n", csvFile); // FILE C:\test → FILE C

-----出力結果-----
あいうえおABC123
FILE C

-----期待している出力結果-----
あいうえおABC123
FILE C:\test

※ファイル名を格納してる変数の型は、他の処理でも使用している都合上、変更できません。


767 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:03 ]
>>766
試してないけど、こうじゃない?
_ftprintf_s(fileStream, _T("FILE %s\r\n"), static_cast<LPCTSTR>(csvFile));

可変長引数に渡す場合にクラスからの暗黙の変換は効かない。
CString 使うなら TCHAR を扱うように統一しないと。
Cスタイルキャストは無しで。

768 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:52:15 ]
fprintf_sの引数を(LPCSTR)csvFileにしたらどうだろうか

769 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:54:38 ]
>>766
_T マクロ無しにしたら?

770 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 19:59:58 ]
>>767-768
大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、
この場合問題なのはfprintf_sの"%s"にLPTSTRを渡してることだと思う。
つまりtprintf系の関数を使うのが正しい

>>769
それは間違ってる。むしろ至る所に_Tマクロを使うべき



771 名前:766 mailto:sage [2009/11/14(土) 20:09:45 ]
記載いただいた内容で出力することができました。
ありがとうございます。

>>767-770
C言語と比べると全然違うんですね。
Cを少しかじったことがあるので、書けると思っていたら全然でした…。


772 名前:766 mailto:sage [2009/11/14(土) 20:14:34 ]
>>770
770さんの書き込みをよくよく読むと出力はできるけど、
これだと正しくないということですか?

773 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:19:02 ]
ジェネリックテキスト(_Tマクロとか使うやつ)は使わないほうがいいだろ。
95/98対応する必要があるとかかわいそうな人なんてもう、そうそういない
だろうし、ワイド文字列きめうちのほうがトラブルがなくて楽だよ。

それにジェネリックテキスト使っていたって、本当にワイド文字列と
マルチバイト文字列の両方に対応できてるコード書けてるかってのもあるし。

両方で動くように意識して書いてるやつなんて少数派だし、_UNICODEありと
なしでコンパイルが通るかとか、テストを両方でやってるところとかまで
いくと壊滅状態だろうし、事実上ジェネリックテキストなんて機能してないよな。


774 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:21:28 ]
>>770
> 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、

へー。いまの可変長引数の ... 部分に渡したときも LPCTSTR への暗黙変換が入るのかー。
いったいどういう仕組みで?
クラスに operator LPCTSTR () を持ってるだけじゃ、そうはいかないよね?

775 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:03 ]
>>773
一般的な話ならそれでもいいんだけど、ここでは CString を使ってて、
その型は変えられないと質問者が言ってるんだから _T() が要るだろ。

776 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:25:58 ]
>>774
>>770じゃないけどCSimpleStringT<>のソースは大分前に見たよ

データメンバがポインタ1個でvtblもないから
メモリレイアウトがTCHAR*と同じになってるんだよ確か

777 名前:768 mailto:sage [2009/11/14(土) 20:29:40 ]
よく考えたらLPCSTRへ変換はできなかったかも
CStringへ代入はできるけど

778 名前:766 mailto:sage [2009/11/14(土) 20:31:31 ]
ごめんなさい。
出力はできるようにはなったのですが、日本語が含んでいるとクエスチョンマークの
文字列が並んでしまいます。
これはやっぱり、上で説明されている変換がうまくいっていないからですか?

779 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:44 ]
>>778
setlocale(LC_CTYPE, "");
とかやろう!

780 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:32:49 ]
>>770,776
msdn.microsoft.com/ja-jp/library/awkwbzyc.aspx#_core_using_cstring_objects_with_variable_argument_functions
> ... 可変個の引数リストを取る関数に CString オブジェクトを渡すときは、明示的に
> 型キャストによる変換を行う必要があります。

やっぱりダメじゃねーか。

www.trickpalace.net/cppll/reference/printf.htm#argument
こいつのデマに騙されたんじゃね?



781 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:37:51 ]
>>780
#include <cstdio>
#include <atlstr.h>

int main()
{
    CStringA s = "world";
    std::printf("hello, %s\n", s);
}
うちではこのコードはVC7.1でもVC9でも動くよ
まあ推奨はしないってか誰もしてないと思うけど

782 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 20:41:17 ]
>>780
古いATLの利用を考えているならキャストするのが安全だろうけど、
最近のはreinterpret_cast相当の操作でも安全に使えるようにできているから必要はない。

というのはATLの解説書のどれかに書いてあったはず

783 名前:766 mailto:sage [2009/11/14(土) 20:44:59 ]
>>779
無事に出力できました。ありがとうございます。
第2引数に何か入れた方が良いのかと思いましたら、そのままでも平気なんですね。

784 名前:781 mailto:sage [2009/11/14(土) 20:52:17 ]
どーでもいいけど例が良くなかったね

#include <cstdio>
#include <atlstr.h>

int main()
{
    CStringA s = "world";
    std::printf("hello, %s %d\n", s, 123);
}

これがちゃんと動きます。

785 名前:774 mailto:sage [2009/11/14(土) 21:08:10 ]
groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/028f80f03d7e253d#msg_7fb2a35dbe1e6ff1
把握した。なるほど。

開発者はがんばって大丈夫なようにしたけど、外向けの仕様としてはキャストが必要と
書かれたままになってるってことだね。ちょっと不憫だな。まぁ古い実装を使ってる場合や
可変長引数の実装方法の違うコンパイラを使う場合にはやっぱり問題になるんで、
しょうがないところかとは思う。

>>780
デマじゃなかったみたいね。

786 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:12:38 ]
C++でポインタを *で参照はがしした時って、*pointerは参照ということになるの?
codepad.org/A8sFOqoG
こんな感じで仮想関数使いたい場合、とりあえず思った通りに動くんだけど、
*baseとした時点でBase型に補足されるということはないんですか。

787 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:14:29 ]
>>786 参照だよ。

788 名前:デフォルトの名無しさん mailto:sage [2009/11/14(土) 21:17:35 ]
わかりました。ありがとうございます。

789 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:40:57 ]
char 配列が300個連続で0であることを高速で見つけるにはどうすればいいですか。

790 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:48:00 ]
どういう意味で高速なんだ



791 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 14:56:55 ]
CPUの性能を上げれば高速になるよ

792 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:11:29 ]
ひとつひとつ探すより、memcmp使うとかです。
これは実際に速くなるのですが、500個になると困ります。

793 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:12:39 ]
0に限定すれば、memcmpより高速に出来る可能性があると思いますが
アセンブラなどわかりません。

794 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:15:32 ]
O(n)よりは速くならないんだから、あとはCPUのデータシート眺めながらチューンしていくしかないよ

795 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 15:18:52 ]
いい方法わかりました。300個目だけ1だったら途中は調べなくて良かったです。

796 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 16:54:40 ]
ああもうそれでいいよ、もう来ないでね

797 名前:デフォルトの名無しさん mailto:sage [2009/11/15(日) 23:16:34 ]
>>795
もう少しマシにしようか
300個が0なら150個目を調べる
それも0なら75個目と225個目を調べる
それも0なら・・・・

非0である確率が高いならともかく、そうでないなら最初から順々に調べたほうがマシだな

798 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:13:52 ]
>>797
えっ

799 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:20:58 ]
データに偏りがあるなら、そういう最適化もあるが、ないなら最初から配列舐めるなぁ。。。

800 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 00:22:43 ]
つまらないこと言ってないで、死の行進しとけよ
学生はIT土方になるために必死に勉強しとけ



801 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:54:58 ]
> これは実際に速くなるのですが、500個になると困ります
なんで?

そもそも memcmp() 呼び出しが 単純なループ処理より速いってどんな環境?
(つーか、まさか毎回if判定してないよな?)

802 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 01:56:41 ]
>801
いや普通、ループは毎回判定してるぞw

803 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 02:05:47 ]
例えば
・charではなく、もっと大きな(intとか)のサイズでアクセスし
・毎回判定するのではなく、数十個単位とかを|してから判定することにして
・さらに、場合によってはプリフェッチ的なアクセスの仕方も行う
というようなことをすれば、

・もしかしたら
・あなたの使っているCPUやOS、及びコンパイラと使用ライブラリ限定で
・データによっては
・気休め程度には
速くなる可能性はあるかもね。

804 名前:デフォルトの名無しさん [2009/11/16(月) 11:02:47 ]
バーチャルで関数をオーバーライドするときって型を変えたりできないんですか?
virtual ってvoidばっかりなのですが


805 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 13:34:53 ]
>>804
基本的にはできない。
例外として共変戻り値がある。

806 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:46:54 ]
グローバル変数はどこから書き換えられるか解らないといった弊害があるから推奨されないかと思うのですが
グローバルな定数であれば別にガツガツ使用しても問題ないのでしょうか?

807 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:57:15 ]
一番大事なことはそれではないとおもう。
変数がかぶることと思う。
ネームスペースやオブジェクト指向も
変数名、関数名がかぶらなくなることが大事思う。

808 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 16:59:04 ]
変数や関数の生存範囲が小さいほどよい。
公開する部分はのぞく。
グローバル定数も変数も公開するで無ければなるべく範囲を縮める。

809 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:19 ]
変数を生成するコストを減らすためとかいう理由で
グローバル使うのはあほですよ。
大して時間食わないし、変数生成がボトルネックなることはまれ。
時間食ってることが確認できてから変えれば良いんです。
なるべく生存範囲が短くなるようにするのが吉

810 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:02:27 ]
じゃネームスペースの中にグローバル変数入れときゃいいじゃん



811 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:07:16 ]
>>805
ありがとうごじあました

812 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 17:08:01 ]
名前の競合なんて屁でもないだろ。
モジュール間でのカプセル化という意味合いの方が大きい。

813 名前:806 mailto:sage [2009/11/16(月) 17:29:33 ]
グローバル定数も出来る限り控える方が良いんですね。
ありがとうございます。

814 名前:デフォルトの名無しさん [2009/11/16(月) 18:25:46 ]
error C2276: '&' : 仮想関数のアドレスを取ろうとしました。
とか、書き方を変えると、
error C2440: '<function-style-cast>' : 'overloaded-function' から 'float' に変換できません。
とか出ます、仮想関数をはじめていじくっているのでどうすれば良いかわかりません
仮想関数のオーバーライド中では引数のメンバの型を変えてはいけないのですか?

815 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:24:18 ]
>>814
スレ違い。↓こっち行け。
pc12.2ch.net/test/read.cgi/tech/1187922645/

816 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 21:59:01 ]
グローバルスコープがふさわしい物までグローバルから追い出そうとするのも問題だと
個人的には思う

つーか、初心者が一番やらかしやすいのは、関数スコープがふさわしい物をファイル
スコープに出してしまうことじゃないかと

817 名前:デフォルトの名無しさん [2009/11/16(月) 22:23:03 ]
vc++でトランプゲームとか作ろうと思っています。そこで質問が二つあります。
@画像データをPROJECT内に保管しておいて必要な部分を切り取って表示する方法ってありますか?
AWIN32とmfcとで方法が違うかもしれませんが、ゲームを作成するのに向いているのはどっちでしょうか?

※開発環境(といえるほどのレベルではないのですが・・・)VISUALSTUDIO2005でvista32bitです。
入門書とかも何冊か読んでみたのですが、自分が求めている情報がズバリ載っているわけではいないので、
質問させていただきました。詳しい方がいらしたらぜひアドバイス願います。


818 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 22:29:58 ]
>>817
1、ビットマップの管理方法で違う。APIに任せるなら、loadImageしてBitBltなどのAPIを使う。
  自前で管理するなら、配列いじるのと変わらない。が、約束事はある。
2、どっちでも作れるから、作りやすいほう選べ。CかC++か位の違いしかない。どっちにもお約束事はある。

819 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:09:48 ]
環境変数はグローバル変数だから使用禁止
外部からファイル読み込むのもグローバル変数だから使用禁止

820 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:17:27 ]
#define HOGE 1
#define HOGE 1
#define HOGE 1
#define HOGE 2
#define HOGE 1
#define HOGE 1

同じ名前の定数を何度も宣言した場合、値が同じうちは何も言われず、
上の場合は1→2と2→1のところでのみ警告が発生するのですが、
これはCやC++の標準の仕様として頼ってしまってもよいものですか?

Win32のDLLからエクスポートするクラス群が複数のヘッダに分散していて、
各ヘッダにそれぞれ
#ifdef HOGE_EXPORTS
#define HOGE_API __declspec(dllexport)
#else
#define HOGE_API __declspec(dllimport)
#endif
を入れてしまいたいのです。

それとも、上のものだけが書かれた二重インクルード対策付きヘッダも別に用意して、
各クラスのヘッダからちゃんとインクルードするべきですか?



821 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:19:43 ]
>>820
#ifndef HOGE_API
#ifdef HOGE_EXPORTS
#define HOGE_API __declspec(dllexport)
#else
#define HOGE_API __declspec(dllimport)
#endif
#endif

822 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:22:58 ]
>>820
同じ名前で内容の全く同じマクロなら何度定義してもいいことになってる。
(厳密にはもう少し複雑な規定があるけど)

823 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:46:26 ]
>>821-822
何度定義してもよいということが仕様として存在するのですね。
安心しました。ありがとうございます。

824 名前:デフォルトの名無しさん [2009/11/16(月) 23:49:24 ]
名前: デフォルトの名無しさん
E-mail:
内容:
818さんアドバイスありがとうございます。さっそく、プログラムに入力しビルドしてみました。私の力量不足でエラーになってしまいましたが、 loadImage()をいかに使いこなせるかというところが質問の答えのようですね。
A:秀和システムの本:「VisualC++.net逆引き大全」
B:秀和システムの本:「C言語逆引き大全」をぱらぱらとめくってみました。
AのほうにはMFCのところにLoadBitmapを使った方法が載っており、BのほうにはLoadImage()を使う方法が載っていました。

Aのほう
CBitmap m_hBitmap;
if (m_hBitmap.LoadBitmap(CARD)){
}
pDC->DrawState( CPoint(0,0),
CSize(100,100),
&m_hBitmap;
DST_BITMAP);

Bのほう
HANDLE LoadImage(
HINSTANCE hinst,//インスタンスのハンドル
LPCTSTR CARD,//イメージの名前または識別子
IMAGE_BITMAP,//イメージのタイプ
100,//希望する幅
100,//希望する高さ
LR_DEFAULT //ロードのオプション
);
という風なことが書いてあるのですが、Aのほうは、構文エラー )や;があるとかないとか。
Bのほうは、LR_DEFAULTが認識されない識別子だとか、 )や;があるとかないとか。
のエラーが出でしまいます。 これはなぜエラーになってしまうのでしょうか?
理由が分かる方、ぜひアドバイスをお願いいたします。※CARD.bmpという画像ファイルを扱おうとしています。

825 名前:デフォルトの名無しさん [2009/11/16(月) 23:54:46 ]
デバッグしてるときに変数に何が入ってるか知りたいのですが_CrtSetBreakAlloc(1162);これしかないですか?

826 名前:デフォルトの名無しさん mailto:sage [2009/11/16(月) 23:55:49 ]
>>825 VC ならデバッガ使えよ。

827 名前:デフォルトの名無しさん [2009/11/16(月) 23:59:30 ]
>>826
効果的な使い方がわからん
_CrtSetBreakAlloc(1162);で止めて下に出てるツリーを開いていくやり方以外やったことない
教えて

828 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 00:07:56 ]
>>827
_CrtSetBreakAlloc()って知らんからググってみたら、メモリリークの箇所を
調べるみたいなことが書いてあった。
勉強になるなぁ。

変数の中身をみるって、適当にブレイクポイントでとめて、ウオッチで見るとかじゃなくて?

829 名前:デフォルトの名無しさん [2009/11/17(火) 00:10:22 ]
おkサンクス、やってみる

830 名前:デフォルトの名無しさん [2009/11/17(火) 00:13:03 ]
ああ、普通こうやってやるのか
すげえな、サンクス



831 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 05:38:13 ]
VCならウォッチ式の設定とか言わず、変数をポイントするだけでもおk。

832 名前:デフォルトの名無しさん [2009/11/17(火) 06:05:27 ]
ちょwwVC便利すぎワロタw
プログラム暦2年だけど何やってたんだ俺wめっちゃ簡単に割り出せるやんw

833 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:32:32 ]
vectorの内部で確保されているメモリってclear()でも解放されるの?

834 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 06:36:33 ]
解放されない

swapですれよ

835 名前:833 mailto:sage [2009/11/17(火) 06:47:54 ]
なるほど、どうも

836 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:26:26 ]
std::vector<T> v のバッファサイズをバイト単位で取得したい時は、
v.size() * sizeof(T)
でいいんでしょうか?
実装によっては何か詰め物でも入っているのではないかと不安なんですが。

837 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:40:57 ]
vectorのバッファは配列と同じメモリ配置であることが保証されてるから、それでいいよ

838 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 07:54:16 ]
>>836
そのサイズを使った操作が何であるかによっては危険な予感がする。

839 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 08:22:29 ]
>>837
ありがとうございます。
>>838
内容をファイルに書き出したいんです。

840 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 15:26:13 ]
普通に書き込めばいいじゃん



841 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:07:07 ]
>>839
ostreamのシフト演算子を定義すればいいと思うよ。
v.size() * sizeof(T) だと、vtableがあったら色々まずい。

842 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:21:33 ]
バッファサイズに仮想関数テーブルは関係ないだろ

843 名前:デフォルトの名無しさん mailto:sage [2009/11/17(火) 17:42:42 ]
copy(v.begin(), v.end(), ostream_iterator<T>(cout, "\t");

これってさ、Tによっては<<定義しても動作しなくね?

844 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 00:58:34 ]
>>843 Tによらずコンパイルエラーになるね。

845 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:16:44 ]
>>844
いやそういう下らん揚げ足取りはいいから

846 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 01:20:59 ]
>>843
動作しそうで動作しない T の例をひとつでも挙げてみてくれ。
そうじゃないと、当たり前のことを聞かれてるだけにしか見えん。

847 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 17:25:58 ]
メモリイメージをメモリマップトファイルにmemcpyすれば楽ちん。
ていう考えは古いですか。

848 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 19:48:32 ]
質問させてください。
静的メンバはクラスが存在する前からあるはずなのに、なんでクラスの外で再宣言しなくてはならないんですか?

849 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 20:19:01 ]
ヘッダファイルにクラス定義を書いた場合ということでいいのかな?

その場合、各翻訳単位の間で重複してクラスの静的変数を定義しない為。
ヘッダファイルにグローバル変数を書いて共有するときも、externで宣言しといてどこかで一度だけ実体の宣言をするよね。

850 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:00:32 ]
codepad.org/auJS2ura

ngの部分でコンパイルエラーが出てしまいます
VC++2008EEのエラーメッセージによると引数があいまいだから、ということなんですが
どうすれば曖昧さをなくせるのかちょっとわかりません
うまいことstd::endlを渡す方法はありませんか?



851 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:40:11 ]
>>850
endlの型を調べよう

852 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:48:59 ]
CParent ◇- CChild

というように親クラスが子クラスを保持しているとします。

子クラスはプログラム動作中、たくさんnewでメモリを確保します。

プログラム終了時、CChild内でdeleteせず、CParentでだけdeleteすれば、
CChildがそれまで確保してきた領域も伴ってdeleteされるのでしょうか?


というのも、ある書籍についてたサンプルコードを見ると、newしまくりなのに、
それらがdeleteされる記述がぜんぜんないんです・・・
最も最上位のクラス(他の下位クラスを保持している)を最後にdeleteしてるところ
くらいしか考えられない・・・


よろしくお願いします。 m(_ _)m

853 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:51:28 ]
メモリリークしちゃうね
とりあえずその書籍の名前を


854 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 21:56:05 ]
スマートポインタ使ってたらそう見えるかもしれない

855 名前:852 mailto:sage [2009/11/18(水) 22:01:00 ]
>>853
「3D格闘ゲームプログラミング」という本です。
不思議なことに、サンプルのVC++プログクトでビルド実行してプログラムを終了させたとき、
リークがある場合にVC++のログ出力に出てくるメモリリークバイト数が出て来ず、
正常終了できたかに見えます・・・

>>854
スマートポインタを使っているようにも見えません・・・

一例として

ヘッダファイル内
char* xxx

C++ファイル内
 xxx = new char[ strlen( yyy ) + 1 ];

で、xxxはどこでもdeleteされていません。
VC++上でソリューション内を検索もしましたが見つかりませんでした・・・

856 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:09:26 ]
別の変数に代入されてどっかで解放されてるんじゃないの

857 名前:852 mailto:sage [2009/11/18(水) 22:21:50 ]
>>856
追跡してみましたが、見当たらず・・・

そういえば、newされたやつの多くはSTLのvectorにpush_back()されています。


ヘッダーファイル内
 #include <vector>
 using namespace std;

 vector<CChild*> Child;

C++ファイル内
 Child.push_back( new CChild() );


何か関係があるのでしょうか?
このvectorはポインタのコンテナになっていて、やはりどこかでそれらのポインタの先にある
実体領域を解放してやる必要がありますよね?

858 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:24:30 ]
そういわれても実際にコードを見られないんじゃ何とも答えられん。

859 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 22:26:10 ]
Childが死ぬときに開放してるんだろ。
とりあえずステップ実行して、本当に開放されないのか一行ずつ確認してください。

860 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:01:08 ]
>>848
クラスの外に書くのは、宣言ではなく定義。



861 名前:852 mailto:sage [2009/11/18(水) 23:01:49 ]
作者さんのページで、どうも関係のありそうな記述を発見しました。

ttp://cgi32.plala.or.jp/higpen/book/shtPro/qa.shtml#program10

違う書籍の違うプログラム部のところの話ですが、
たぶん、これと同じことだと思います。

なんと、解放はOSに任せられるとのこと。
あまり行儀は良くないですよね^^;
よほどプログラムの動きやOSのメモリ管理に精通してないととてもできないw

でも勉強になりました。

みなさん、ありがとうございました。 m(_ _)m

862 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:19:45 ]
なんか苦しい言い訳に見えるな。百歩譲ってそれが「正しい」方法だとして、
プログラミングを勉強する本にそういう書き方をするのはいかがなものだろうか…

863 名前:デフォルトの名無しさん mailto:sage [2009/11/18(水) 23:26:33 ]
質問を勝手に自分の理解できる範囲の問題に解釈し直すのはいくない

864 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:25:35 ]
>>861
そんなこと言ってると、ごちゃごちゃ言ってないで std::vector 使えカス、ってバカにされちゃうよ。

865 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 00:29:15 ]
VC6 時代の古い本ならしょうがないか、と思ったけどそのリンク先 Q&A の
日付見たらごく最近なのな。著者が不勉強なんだろうと思う。

866 名前:852 mailto:sage [2009/11/19(木) 00:57:36 ]
>>864
多態を使わなければ、クラスのインスタンスのvectorを使ってもOKみたいですね。


vector<CXXX> xxx;

CXXX x;

xxx.push_back( x ); // xxxコンテナへのコピーになる


これだったら、領域確保はvectorがしてくれるので楽ちんですね。

これでいきます。
ありがとうございました。

867 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:51:30 ]
コンストラクタ初期化子を使わないと駄目だっていうけど、初期化の順番を明示したい場合はコンストラクタ関数内で初期化してもいいよね?俺悪くないよね?



868 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 01:53:45 ]
どうでもいい。

869 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:41:35 ]
>>867
IDE のインテリジェンス機能が動かなくてもいいならそれでもいいよ

870 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 02:57:34 ]
コンパイル時にクラスや構造体のメンバのオフセットアドレスを得る方法ってあります?



871 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:00:38 ]
offsetof

872 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 03:30:02 ]
>>871
それだったか、感謝。

873 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:16:43 ]
>>861
それはメモリリークそのものだろw
そんなレベルで本書くなよ…

874 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:47:42 ]
よく読んでないけど

説明は下手糞だけど、最初に確保したメモリをプールしておいて使いまわす手法じゃないの?
だとしたら、そういうのはリークとは呼ばないよ。
MoreEffectiveC++にもちゃんと書いてあるし。

違ったらごめんな。

875 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:48:47 ]
×使いまわす手法
○使いまわして、最後まで(プログラムのコード内では)解放しない手法

876 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 08:57:25 ]
メモリなら最悪リークしてても、プロセス終了時に解放されますよって話だろ?
まぁメモリ以外のリソースだと解放してくれなかったりすることもあるけど。

877 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:29:20 ]
だから、たとえ解放処理(free/delete)をしていないとしても
ちゃんと管理できているものは「リーク」とは呼ばないって話だよ。

878 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:34:03 ]
>>867
初期化の順番はメンバの宣言順と決まっている。
コンストラクタの記述方法で明示などできない。

無知なオマエ悪い。

879 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:38:59 ]
>>874-875
よく読んでみなよ。 >>861 のやつは使いまわしてすらいない。

880 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 09:39:33 ]
最後にOS任せで消滅させて、途中どんなに肥大してもシラネ、ってのは管理ではなく
リークと呼ぶだろw



881 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:06:29 ]
>>879
だから、
>タスク用メモリはプログラムの終了時まで解放しない
が、「deleteを呼ばない」という意味ではなく
「プログラム終了まで使用している領域である」という意味ではないか、と言っている。
使用している(管理している)領域なんだから、deleteするコードが無くても問題ない。

もちろん、その「タスク」が、プログラムの中で際限なく増えていく
(あるいそのタスクを指す領域を見失っている)ようなら問題だが
俺はコードを読んでないので、どういう構造なのかは明言できない。


だから、「よく読んでないが」「説明は下手糞」と書いた。
そして、(明示的にdeleteを呼んで無くても)管理下にあるものはリークとは呼ばない。これは確実。

882 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:07:54 ]
で、使いまわしているかどうかは問題の本質じゃない。
管理下にあるかどうかが本質。

883 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:23:05 ]
>>881-882
よく読んでみなよ。 >>861 のやつは管理下にすらない。

「タスク」じゃなくて char 配列のほうな。ローカルな生ポインタ変数に入れて、
そのままスコープアウトしちゃってるみたい。

当たり前の主張を長文で繰り返す前に、「よく読んでない」と自分でわかってる
なら元記事をよく読めと。

884 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:36:43 ]

このサンプルでは以下の理由から、new char[]で確保した領域を明示的に解放する処理を省略しています。同様の理由で、他にもメモリの破棄を省略している部分があります。

* サンプルプログラムをなるべくシンプルにしたい
* タスク用メモリはプログラムの終了時まで解放しない
* プログラム終了時にはOSがプログラムに関連するメモリを解放してくれる
* 一般にdeleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、タスクリストの場合は実行中に解放する意味が薄い

上記の理由から、メモリを解放しなくても動作に問題はなく、他のプログラムへの影響もありません。推奨される方法としては、例えばタスクリストのデストラクタ
~CTaskList() を記述して、その中で上記のバッファを、
delete [] buf; のように解放します。この場合、bufをメンバ変数にしておく必要もあります。

885 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 10:49:18 ]
「禁無断転載」と明記された記事を意味もなく転載するのはおすすめしない。
せめて引用の形にとどめておけ。

886 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:04:53 ]
っていうか、いかなる場合でも
確保したメモリちゃんと解放すればいいんだよ。

メモリを解放するデメリットなんてないだろ?
もし、終了時に遅くなるとかいう話なら
「終了処理を速くするテクニック」として使えばいいだけの話。
それが必要になるときがくれば使え

887 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:08:20 ]
>deleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、
再利用されるとか考えないのかね?

888 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 12:13:50 ]
その機構部分は仮に良い という立場だったとして
new と delete がペアになっていない構造だから

別コードで本当にリークさせてる部分の追跡をするのに面倒じゃね?

889 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:33:47 ]
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?

890 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 13:34:17 ]
どうもしない



891 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:50:59 ]
なんで、サンプルで手抜きをするのかねぇ?
deleteなんて一行増えるだけじゃん。

いちいち言い訳を書くよりも
deleteを書けばいいじゃんか。

892 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 14:52:56 ]
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?

893 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:02:56 ]
>>892
マジレスはしてあげないよw

894 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:03:31 ]
どうもしない

newしたときに再利用されるだろうな

895 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 15:34:47 ]
サンプルをシンプルにしたいからって理由で無茶すんなよなぁw
リーク検出とか使えなくなりそうだしなぁ

896 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 16:12:06 ]
>>893
無知は黙ってろハゲ

897 名前:852 mailto:sage [2009/11/19(木) 19:05:22 ]
物議を醸していますね^^;
作者の方は東大を出ておられますが、地頭が良いとこういう考え方になるのでしょうか・・・
ともあれ、今はnew、deleteはセットで書くよう心がけたいですね。

898 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:44:29 ]
deleteするしないはコードの本質でないと判断したんだろう。
まぁ論文ならそれでいいんだろうが、一般向け、しかも初心者が食いつきやすいゲームプログラミングの書籍で
それをやると何も考えずに模倣する馬鹿が出てきてしまうから、やめた方がいいと思うがな。

899 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:46:38 ]
メモリリークしてたらだめだ
実測しむ

900 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 19:49:53 ]
1Mのメモリーリークが100回起これば100M消費する
プログラムが終了すればOSが回収するが、
動いている間はそのまま。



901 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:10:32 ]
東大出てても糞コード書く奴はどうしようもないよ
しかも学歴が高いせいで自信だけはあるから逆にめんどい

902 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 21:34:57 ]
Cなら終了時まで解放しないメモリをfreeしないっていう層は結構いるから
その亜流なんだろう

903 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 22:48:47 ]
>>897
もちろんnew/deleteをセットで書いてもいいが
それよりスマートポインタを使うんだ

904 名前:852 mailto:sage [2009/11/19(木) 23:01:20 ]
>>903
COMでCComPtrを使ったことがあって、めちゃくちゃ便利でした。
自前のを作るとなると・・・うまく組めるかちょっと心配です(汗)
でも便利なのはたしかなので、勉強してみます。
ありがとうございます。

905 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:04:08 ]
shared_ptr < ・・・

906 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:36:09 ]
BCB5+Win環境です
char配列などを頻繁にnew・deleatする際、どっかのサイトで
win環境では固定サイズでnewしたほうが断片化しにくいと
書いてあったような気がするのですか
本当でしょうか?
あまりnewをいじりたくないので気になります

907 名前:852 mailto:sage [2009/11/19(木) 23:45:36 ]
>>905
おおお!
こんな便利なものがあったのですか!
VC++2008ならstd::で使えるそうですが、自分は2005ですね・・・
しかし、boostを導入すれば使えますね。
CComPtrと同じように使えるのであれば、慣れていますし、導入もし易そうです。

教えてくださって、ありがとうございました!

908 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:54:42 ]
std::multimap<int, int> test;
test[0] = 1
test[0] = 2
test[0] = 3
...いろいろ代入...

としたときに、
std::multimap<int, int>::iteartor begin = test.lower_bound(0);
std::multimap<int, int>::iteartor end = test.lower_bound(0);
std::multimap<int, int>::iteartor it;
for (it=begin; it!=end; ++it) printf("%d", it->second);

で得られる結果は必ず 1, 2, 3 の順番になると保障されていますか?


909 名前:デフォルトの名無しさん mailto:sage [2009/11/19(木) 23:56:21 ]
std::multimap<int, int>::iteartor end = test.upper_bound(0);
でしたすみません

910 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 00:10:27 ]
されてません。



911 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 01:05:18 ]
>>906
new の回数を減らせば断片が減る(断片化しにくい)のはあたりまえ。

それ以前に、ほんとうに断片化による悪影響で困ってるのか?
Windows 上では、特にギガバイト単位のメモリ空間(アドレス空間)があたりまえな
最近の一般的な環境ではかなり稀なケースになると思うんだが。

912 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:12:17 ]
>>901
実際に動作させるコードでdeleteするしないの問題と、解説書でdeleteを省略するしないの問題を
区別できていないお前は多分低学歴なんだろうな

913 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:13:44 ]
実際に動作させるコードからかけ離れたコードを提示する解説書がそもそも問題
削っていい部分とそうでない部分があるが、こういうのを削っていいと思うようなら
糞コードと言われても仕方ない

914 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:15:13 ]
ま、万人向けの本でやっちゃだめだよな。

915 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:17:50 ]
ぶっちゃけこんなアホなコードを本気で擁護する奴なんて本人以外いるの?w

916 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:28:12 ]
>>912
省略したほうがシンプルでいいと思ったけど結局は言い訳がましい Q&A を書くハメに
なったってことで、解説書のための判断としても失敗だろ。

紙面の問題を考えても、 std::vector 使っとけば #include が1行増えるかもしれないって
程度だし。

917 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 02:38:29 ]
まぁ、全てを綺麗に書くことが正義という言語でもないし、本当に必要ならば手を汚す
こともあるけどな。>>884は手を染める理由としては全く不足だと思うが。
とりあえず買っちゃいけない類の本ではあるな。良い初心者は混乱し、悪い初心者は
汚れる。中級者以上なら他に投資すべき本があるだろう。

918 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:10:28 ]
確保したハンドルやリソースを開放しないままプログラムが終了しても
言語やOSの仕様でプログラム終了時に確実に回収することがわかっていて
かつ、リークしないこともわかっているなら、別に開放しないまま終わってもいいじゃないか。^^
たとえば、

int main() {
int* i = new int;
}

上のプログラムはメモリリークしていない。
なぜなら、ポインタが消失して削除不能になるのはプログラムが終了する瞬間であり
その直後にはすべてのリソースが回収されることが仕様で決まっているからだ^−^
美学とかいうなら別だが。


919 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:28:08 ]
classのお作法を守ってないからでしょ。後で書いた方?は直してるみたいだし

920 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 03:37:02 ]
あえてdeleteしない、なんて初心者向け解説本でやるべきじゃないよな。

「3D格闘ゲーム」ってことだから、おそらくキャラクタ2体分のオブジェクトを作って
プログラム終了まで開放しない、みたいなコードだと思うんだけど、
読者がそこから拡張していこうとした途端にメモリリークを起こす気がする。



921 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 06:08:35 ]
繰り返しのnewがでたらやばいんだって。

922 名前:852 mailto:sage [2009/11/20(金) 08:12:39 ]
この本はdelete問題の他にも、ちょっと「?」というか、もっと効率的な方法があるのでは?と
思ってしまうようなところもあるのですが、
アニメーション付Xファイルの読み込み、およびそれをゲーム中でアニメーションさせるところの
解説はものすごく参考になっています。
今までいくつかのWebサイトでそれを解説しているところも見てきましたが、
この本の内容が一番分かり易かったです。

アニメーションのための本質的なところ(動作、仕様レベル)だけ抽出して、
実装に向けたクラス設計や仕様は自分で改めて考えてからコーディングしていったら良いと思いました。

923 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:00:43 ]
分かりやすいように見えても、どこに罠が仕込まれてるか分からんのではなぁ

924 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:06:43 ]
糞コードを本にして売るほうも、本に書いてあるコードを吟味せずにそのまま使うほうもアホ

925 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 09:12:37 ]
Amazonレビューを見たら、そのアニメーションの解説も参考にするとまずそうな
雰囲気に見えるが…
まぁ、買っちまったら何とか活用したいんだろうけどなぁ…

つーかサンプルプログラムの作り方もひどそうだ
ゲームがコマンドライン引数でviewerに変わるらしいが、やってみたくてやっちゃった
のかな、使い勝手とか全然考えずにw
もちろん「コマンドラインの処理サンプルを入れたかったので」とか言い訳はいくら
でも思いつくが

926 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 10:25:39 ]
DLLとEXEでは使ってるアドレス空間が違うとのことなんですがポインタがどっちのアドレス空間に属しているかしらべる方法はありますか?

927 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:15:06 ]
>>918
そういう特殊な事例でしか当てはまらないものは
特殊な例としてあげればいいんだよ。

int foo() {
int* i = new int;
}
関数名を変えただけで、この処理はリークしているかもしれない。

int main() {
MyClass* i = new MyClass;
}
クラス名を変えただけだが、delete時にファイル削除とかしているかもしれない。

な? コードは修正されるもの。
そういうときに自分で罠を仕掛けてどうする。

928 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:33:29 ]
>>926
できるでしょうね

929 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:44:16 ]
連続稼働させるものや、多くメモリ確保する物では
メモリリークは致命的。
512K確保する関数を200回呼び出せば、合計で1ギガ消費する。
deleteしないでこれを放置するやつは超初心者

930 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 11:45:57 ]
ブラウザはよくリークする



931 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:23:01 ]
>>918
それはメモリリークだよ。
もう使わないからdeleteしていいのにdeleteしないままプロセス終了を迎えたら、それはメモリリーク。

「プロセス終了時に把握できているメモリリークがあっても特に問題無い」には反論しないけど、
「リークじゃない」はおかしい。

そのプログラムがメモリリークしてないなら、メモリリークしてるプログラムなんてこの世に無いよ。

932 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 13:44:20 ]
目立ってメモリリークしなければ無視でも良いけどね。
たとえば、4バイトのメモリリークで128M=2^24バイトたまるには、
400万回やらないといけない。
10秒に一回起こったとしても、400万回するには一年半ほどかかる。、

933 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:14:47 ]
まぁ、習慣的にリーク対策しないと、大事なとき忘れるし、コードの再利用したときも不具合を生みやすい。
俺は基本的にnewしないでスタックに確保するから、そういう問題はほとんどないな。
はやくスマートポインタが使いたいぜ。

934 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:18:40 ]
vcでメモリリーク検出できるからそれでいいよ。
わずかに残ったとしても致命的にはなりにくい。
なったら変更すればいいし。

935 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 14:25:54 ]
シングルトンな奴は基本 delete しねぇなぁ、俺は。

936 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:10:46 ]
new deleteはコンパイラ依存していますか?
別のコンパイラで確保したメモリを、VCでdeleteは出来ませんか?

937 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:27:03 ]
>>936
別のコンパイラどころか、同じコンパイラでも異なるDLLでnewしたオブジェクトをdeleteすることは
原則としてできません。(MFCの拡張DLLは別)


938 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:34:39 ]
new deleteはオーバーロードだってできるからな。
あえてやるひとはいないだろうけど、
自分以外誰にも使えないnewの実装だってありえる。

939 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:37:30 ]
そうだったんですか。
そうだとすると、DLLがメモリ確保してリターンしたら解放不可能になるんですか。

940 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:40:48 ]
んなこたーない
メモリを確保する関数 と 確保したメモリを開放する関数 を用意しときゃよい

fopen() と fclose() の関係



941 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:49:42 ]
DLL が提供しているのが newしたポインタを戻すだけで
その後始末の delete は呼び出し側がやってね  という造りはマズイ ってこと

DLL は 自前newしたものを戻すつもりなら それを受けて delete する部分も提供すべき

# で、後者を記述するのに安全を見て >>926 で保険かけたいんだけど… どうすれば良い?
# という流れになるのかな?

942 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:50:14 ]
Windows APIだとCreateなんたらでハンドル作ったら、
CloseHandleよびだしたりするね。

943 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 15:55:17 ]
----DLL----
typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t);

__declspec(dllexport) void *dll_alloc(void *(*)(size_t), size_t);

void *dll_alloc(void *(*alloc)(size_t), size_t s)
{
     return alloc(s);
}

----EXE----
dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddres(hDLL, "dll_alloc");

void *p = dll_alloc(malloc, size);


こうした場合メモリはどっちに確保されるの?


944 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:03:32 ]
内部実装に詳しいわけじゃないから適当にいうけど、
EXEから呼ばれるDLLがリンクしているalloc関数を実装しているライブラリ・・・が
OSにメモリ割り当てを要求して、OSが返してくれる適当なメモリ領域・・・・の
一部分をallocが適当に調節して返すんだから、
どっかOSが適当に決めた場所なんじゃないの?

945 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 16:37:27 ]
VC++だとこうなったが・・・

//DLL.c
#include <stddef.h>

__declspec(dllexport) void *dll_alloc(void *(*alloc)(size_t), size_t size) { return alloc(size); }

//Main.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef void *(*dll_alloc_t)(void *(*)(size_t), size_t);

int main(void)
{
HINSTANCE hDLL = LoadLibrary("DLL");
dll_alloc_t dll_alloc = (dll_alloc_t)GetProcAddress(hDLL, "dll_alloc");
char *p = (char *)dll_alloc(malloc, 10);

strcpy(p, "hello!"); puts(p); FreeLibrary(hDLL); puts(p); free(p); puts(p);

return 0;
}

//OUT
hello!
hello!
ンンンンンンンンンンンンンンンン-


946 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:01:03 ]
これで良いみたいだな。winapi使った

// DLL

#include <windows.h>
#include <stdio.h>

extern "C" WINAPI void memo( HANDLE hd, char *&p ) {
p = (char*) HeapAlloc(hd, HEAP_ZERO_MEMORY, 1<<20);
strcpy(p,"hgujyguyguyguyguby");
printf("%s\n",p); }


// EXE

#include <windows.h>
#include <stdio.h>

typedef void (WINAPI *FNC)(HANDLE , char*& );
int main(){
HINSTANCE hd= LoadLibrary("dll.dll");
FNC memo = (FNC)GetProcAddress(hd, "memo");
HANDLE hHeap = HeapCreate(NULL, 0, 0);
char *p;
memo(hHeap, p);
printf("%s\n",p);
HeapFree(hHeap, NULL, p);
HeapDestroy(hHeap);
getchar(); }

947 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:48:12 ]
C言語でWin32APIをさわっています。winbase.hに
WINBASEAPI VOID WINAPI OutputDebugStringA(__in LPCSTR lpOutputString);

と書いてあったんですが__inって何ですか?

948 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 17:53:49 ]
msdn.microsoft.com/en-us/library/aa383701(VS.85).aspx
まずは自分で調べてほしい。

949 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:38:48 ]
DLLとメモリのやりとりを確実にするには、(HANDLE, char*)のペアで
扱うのが良いと思いますが、
一方ではペアとして、一方ではchar*と自動的にキャストさせる方法はありますか。

950 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:43:12 ]
>>948
縛りの弱いconstのようなものでしょうか?
SAL解釈と言うんですね
ググったんですがなかなかそこまでたどり着けませんでした



951 名前:949 mailto:sage [2009/11/20(金) 18:43:43 ]
自作関数だと、ペアでもchar*でも受け入れるように出来ますけど
自作ではない関数に対しても、自動でキャストして通るように出来れば便利なんですが。

952 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:46:22 ]
何でもかんでも暗黙キャストしてると後ですごい不安になる


953 名前:950 mailto:sage [2009/11/20(金) 18:46:57 ]
>SAL解釈と言うんですね
SAL注釈ですね、間違えました

954 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 18:47:31 ]
double - int みたいな暗黙キャストを実現する方法はないですか?

955 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:00:34 ]
>>949
ごめん、なんでハンドルが出て来るのか分からない。

956 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:05:55 ]
>>946

HANDLE hHeap = HeapCreate(NULL, 0, 0); と char *p; のペアを 
char*型のように扱いたいって事なんです。
無理でしょうか?

957 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:33:10 ]
std::vector< boost::shared_ptr< T > > と boost::ptr_vector< T > はどちらを使っても同じでしょうか?
「一方ではこれができないから注意!」とかあったら教えてください m(_ _)m

958 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:45:50 ]
猿介錯

959 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 19:52:27 ]
よくわからないならvector<shared_ptr<T>>のほう使っとけ

960 名前:957 mailto:sage [2009/11/20(金) 20:33:38 ]
>>959
分かりました!
ありがとうございます!



961 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 20:43:50 ]
shared_ptrって余分に一回メモリ確保してない?あれは何なの?


962 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:30 ]
参照回数を共有するため、その変数を確保してる。

963 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:00:34 ]
関数の戻り値は、通常 値渡しですが
100Mほどのデータをもつクラスでも値渡しになりますか。
(値渡しのコストを下げるために) もし100Mがポインタに入っていて、
auto変数でリターンするとデストラクタが働いてメモリは解放されてしまいますが
newで確保した物をリターンすると、それは解放できなくなりますか。

964 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:03:27 ]
戻り値にクラスを持ってこずに引数を参照渡しにすればいいのですが
変数を用意する事無しに、リターンがクラスになっていると便利なことがあるんです。

965 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:27:13 ]
戻り値がクラスというのは意味不明。

オブジェクトを返すとして、たとえば、
 LARGE func() { return * new LARGE; }
というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。

LARGE & func( LARGE & inout ) {
 //LARGEを使った処理。
 return inout;
}
として、外で大きなデータを用意してやるか、
funcで全く新しいオブジェクトを作成したいと言うなら、newしてポインタを返せばよい。

966 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 21:38:14 ]
>>965
Qtでこんな関数をオーバーロードしろって言われてるんだけど、
何を返せばいいの?

QSize sizeHint(引数略)
{
  return ?
}

967 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:05:09 ]
QSizeオブジェクトでいいと思うよ。

968 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:16:32 ]
え? でも>>965・・・

969 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:18:16 ]
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

あとこんなのもあるんですが・・・


970 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:20:50 ]
QSizeオブジェクトを返すことが、ライブラリによって強制されてるんだから、従えよ。



971 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:21:12 ]
お前が何を聞きたいのかわからない

972 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:15 ]
> というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。
ってかいてるじゃないですか


973 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:23:59 ]
QSizeって大きくないでしょ。(というか100Mというサイズはどこから)
値で返しても何も問題ないじゃん。

974 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:40:44 ]
それ以前に

QSize sizeHint(引数略)

をオーバーロードするのに、
戻り値を参照やポインタにはできんだろ。
オーバーロードのルールを思い出すのだ。

975 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:42:16 ]
いや、戻り値を変えられないのはオーバーライドじゃろ。

976 名前:デフォルトの名無しさん mailto:sage [2009/11/20(金) 22:47:28 ]
たまにいるよね(値|参照)(返し|渡し)の違いがわからない人って
まあわからないようなレベルでできることなんて高が知れてるから分かるまで値返しでいいんじゃないかな

977 名前:デフォルトの名無しさん [2009/11/21(土) 05:12:37 ]
インテルコンパイラでコンパイルしている場合に#ifdef分岐させたい場合、
#ifdefの後何を書けばよいのでしょうか?

978 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:16:39 ]
defined (__ICC)

979 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 05:35:04 ]
archives.postgresql.org/pgsql-committers/2007-08/msg00120.php

Apparently icc doesn't always define __ICC, and it's more correct to
check for __INTEL_COMPILER.  Per report from Dirk Tilger.
Not back-patched since I don't fully trust it yet ...


980 名前:デフォルトの名無しさん [2009/11/21(土) 05:37:04 ]
オンラインで見られて、プログラム未経験者向けのC++の講座って、ロベール以外に何がありますか?



981 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 09:58:59 ]
>>980
こことか見てた
Programing Place
ttp://www.geocities.jp/ky_webid/index_old.html


982 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 12:57:09 ]
ロベールの翻訳は分かりやすい

983 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 13:17:19 ]
>>982
どこが翻訳なんですか?

984 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:38:20 ]
自作クラスをcoutで出力するにはどうすれば良いですか?

985 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 16:41:43 ]
ここみたら無理そうなことがわかりました
諦めました
www.jah.ne.jp/~naoyuki/Writings/ExtIos.html

986 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:00:01 ]
そのページに書いてあるのは標準ストリームクラスの拡張であって、
君がやりたいのは標準ストリームクラスで自作クラスを出力することでしょ?
まったくの別件だと思うよ。

君が勉強すべきなのは、演算子オーバーロード。

987 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:06:21 ]
サンクス!です

988 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 17:27:13 ]
これで出来ることはわかりましたが、char*からsize分だけ渡すにはどうすればいいですか。


std::ostream& operator<<(std::ostream& os, const ustring& x) {
return (os<<*****): }

989 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:15:23 ]
>>983
多くのプログラミング書籍が洋書からの翻訳であることを揶揄したジョークだろう
よく書かれるコピペみたいなものだ

990 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:22:42 ]
>>988
C/C++言語の仕様で\0まで出力だと思うので、任意の場所に\0を突っ込んでやればいいと思うよ。
バッファのオーバーランやアンダーランに気をつけて。



991 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:30:02 ]
\0があっても標準出力へ渡したいんです… ustringはchar*とintのペアです。
STLは使えません。
あと、別の質問があるのですが。

クラスのメンバ関数で、
char* & operator [] ( int n ) { return &(ch[n]); } だとエラーになります。
char* & operator [] ( int n ) { static char*p=&(ch[n]); return p; } だと通るのですが
同時にアクセス来た場合に困ります。
衝突しない参照渡しはどうやればいいですか。STL stringみてもよくわかりません。

992 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:11 ]
>>991
変数でもないものの参照を返したいとか訳分からん
値を返すんだと不都合なの?

993 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:39:28 ]
>991
やりたい事は本当に operator[] で char* & を返す事なのか?
ch って char* なんだよな?
string と名のつく型で operator[] だったら普通 char& が返ると思うんだが。

994 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:43:27 ]
値で返すと
memcpy(buf, &str[0], size);
が実行できないんです。

error メモリ上に配置されなければならない

がでます。
static char*の参照返しだと出ません。

995 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 18:44:35 ]
わかりました。間違えてました。>>993さんのご指摘通り間違えしてました。

996 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:05:39 ]
>>988 たのみます 
char* , intが与えられたときに標準出力( << )に\0を含む文字列を出力したいです。

997 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:31:43 ]
>>996
その前に、どういうインタフェースにしたいのか考えれ。
operator<< をオーバーロードすると
cout << yourclass << endl;
のような書き方ができるわけだが、
char*とintの二つのパラメータを与えるなら
そういう書き方はできなくなる。
それとも const char * operator()( int ) みたいなメンバを持たせて
cout << yourclass( 文字数 ) << endl;
とかけるようにでもするかい^^

998 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:37:28 ]
stringは、string(ch, size)で、\0を含む文字列を
cout<<に渡せるじゃないですか。
この実装はどうやってるのかわかりたいです。

999 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 19:45:50 ]
templateクラスのメソッドってnewしたら使われてなくても全部実体化しちゃう?

1000 名前:デフォルトの名無しさん mailto:sage [2009/11/21(土) 20:03:01 ]
>>998
コンストラクタの話とoperator<<の話がごっちゃになってるじゃないか^^



1001 名前:1001 [Over 1000 Thread]
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。






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

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

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