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

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

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

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

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か   に置換すると見栄えだけはよくなります。
2デフォルトの名無しさん:2009/10/20(火) 16:39:55
>>1
お疲れさまです。
3前スレ964:2009/10/20(火) 16:45:59
http://pc12.2ch.net/test/read.cgi/tech/1253193779/
atexit()で終了関数呼び出して
その中で
delete this;
なんてやったらだめなんでしょうかね?
4デフォルトの名無しさん:2009/10/20(火) 16:56:21
http://pc12.2ch.net/test/read.cgi/tech/1253193779/764かな?
そこまでして自己破壊する理由は?
単にexit()を使わなければいいだけなのに敢えてそうしない理由が判らん。
5デフォルトの名無しさん:2009/10/20(火) 17:11:15
> exit関数をつかったらデストラクタを呼び出せずにプログラムが終了してしまうので
exit関数を使わなければよいことは分かってるんでしょう。
その上で、どうしてもexit関数を使いたいってことだろうから
余程の事情があるんだと思うよ。
好奇心からという可能性も。
6デフォルトの名無しさん:2009/10/20(火) 17:46:34
>>3
exitを使わない方法を検討した方がいいよ
7前スレ964:2009/10/20(火) 18:18:10
まちがえた>>764です
8デフォルトの名無しさん:2009/10/20(火) 19:37:58
>>3
exitすれば自動変数のデストラクタが呼ばれないから無理です。
9デフォルトの名無しさん:2009/10/20(火) 23:00:43
だがちょっと待ってほしい。atexitで自動変数のクラスオブジェクトのデストラクタを呼ぶ
というのはどうか。

hoge.~hoge();
10デフォルトの名無しさん:2009/10/20(火) 23:14:07
>>9
スタックが全部破棄された後なんだからダメだろうよ。
11デフォルトの名無しさん:2009/10/21(水) 00:07:30
ウィンドウズモバイルとか携帯用OSでC/C++ってできるの?
12デフォルトの名無しさん:2009/10/21(水) 00:09:50
できるよ。
13デフォルトの名無しさん:2009/10/21(水) 00:24:50
まじポン?
14デフォルトの名無しさん:2009/10/21(水) 00:27:28
「できる」の意味がわからんが、使えないわけがないだろう。
15デフォルトの名無しさん:2009/10/21(水) 00:29:59
visual c++とかも使えるのか
16デフォルトの名無しさん:2009/10/21(水) 00:33:09
eMbedded Visual C++ 4.0
17デフォルトの名無しさん:2009/10/21(水) 05:47:46
BREWとかもC++環境は一応あるな
制約が相当ひどいけど、少しずつマシにはなっている模様(例外が使えなかったのが
使えるようになったり)
18デフォルトの名無しさん:2009/10/21(水) 11:01:08
どうすればいいんでしょうか?
19デフォルトの名無しさん:2009/10/21(水) 11:03:22
何をどうしたいんでしょうか?
20デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 13:13:10
>>20
危ないから、xはポインタにしないで〜。
22デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 13:41:06
>>21-22
ありがとうございます!
24デフォルトの名無しさん:2009/10/21(水) 14:41:16
C言語始めたばかりのものです。
ファイルを開いて、1レコードづつ読みこんでから各項目ごとに決められた
バイト数で分けるのって、どうゆう関数を使えばいいんでしょうか
25デフォルトの名無しさん:2009/10/21(水) 14:47:24
fopen(), fclose()
fgets()
sprintf()
26デフォルトの名無しさん:2009/10/21(水) 14:53:02
ほかのプログラムの出力をメモリに読み込むにはどうすればいいの?

たとえば適当な数列を並べて出力するプログラムがあったとして
それを文字列としてstringに入れるといった感じで
27デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 16:07:44
>>10
実験してみたら、スタックが全部破棄される前にatexitで登録した関数で
デストラクタを走らせることができたよ。
32デフォルトの名無しさん:2009/10/21(水) 16:10:29
>>30
> w.method().method().method();
> p->method()->method()->method();

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

そもそも.演算子はオーバーロードできない。
3329:2009/10/21(水) 16:15:48
mii.dwItemData = (DWORD)"メニュー";
のところを
mii.dwTypeData = _T("メニュー");
mii.cch = wcslen(mii.dwTypeData);

にしたら一応出るようになりました。失礼しました〜。
34デフォルトの名無しさん:2009/10/21(水) 16:54:41
最近気がついたんだけど、メンバ変数を下のほうに書くスタイルだとclassよりstructのほうが楽だね
35デフォルトの名無しさん:2009/10/21(水) 17:31:57
>>34
何がどう楽?
36デフォルトの名無しさん:2009/10/21(水) 17:34:53
デフォルトプロテクションじゃね? しらんけど
37デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 19:40:38
>>37
std::accumulateに何の不満があるのか
39デフォルトの名無しさん:2009/10/21(水) 19:46:33
>>37
std::iterator_traits<Iterator>::value_type
40デフォルトの名無しさん:2009/10/21(水) 19:50:08
>>38
ありがとうございます。
たしかに、acumulate で総和は求まるのですが、総和を求めるということは
今回、例えであって、疑問の本質はIterator からT 型が推論できるテクニックが知りたいのです、
言葉足らずですみません。
41デフォルトの名無しさん:2009/10/21(水) 19:51:20
>>39
ありがとうございます
やっと、std::iterator_traits の意味が理解できました。
42デフォルトの名無しさん:2009/10/21(水) 19:52:03
C++0xならもっと気楽になるね
43デフォルトの名無しさん:2009/10/21(水) 19:53:42
質問の本質をちゃんと読めないコミュ力不足の回答者って困るよね


〜はどう実装してるの? つミboost::hogehoge ←こいつマジアホ
44デフォルトの名無しさん:2009/10/21(水) 20:03:02
この質問内容だとaccumulateを提示されるのは当然じゃね
45デフォルトの名無しさん:2009/10/21(水) 20:04:26
言葉足らずというか余計なこと言うからじゃね?
46デフォルトの名無しさん:2009/10/21(水) 20:04:27
Boostならともかく標準だしなぁ
47デフォルトの名無しさん:2009/10/21(水) 20:06:42
template <typename T, class Iterator>
という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できないでしょうか?
総和を求めるプログラムを例として説明しますと

という書き始めであればよかったと
48デフォルトの名無しさん:2009/10/21(水) 20:08:26
つーか>>43が要らないだけじゃね?
49デフォルトの名無しさん:2009/10/21(水) 20:24:41
>>47
これがベストかな。一応質問では推論できないか?というところが疑問文だから、
それに答えればいいのだろうけど。まあ、でも、誤解はしなかった。
50デフォルトの名無しさん:2009/10/21(水) 22:36:30
>>31
スタックが破棄される前なのか後なのか、どうやって確認したんだ?
51デフォルトの名無しさん:2009/10/21(水) 22:37:13
>>30
(*p).method().method().method() ですべて解決だ。
52デフォルトの名無しさん:2009/10/21(水) 23:01:21
>>41です。おかげさまで、
template <typename T, class Iterator>
という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できるようになりました。ありがとうございました。
さて、教えて頂いた知識をベースに標準偏差を求めるプログラムを作り、コードをここに貼りました
http://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デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 23:17:13
>>52
std::iterator_traits<ResultType>::difference_type
55デフォルトの名無しさん:2009/10/21(水) 23:17:24
あ、1行目もForwardIterね
56デフォルトの名無しさん:2009/10/21(水) 23:20:19
>>52
イテレータの距離を求めるにはstd::distanceを使う。
5753:2009/10/21(水) 23:24:39
なんか俺意味わからないことやってるね。死のう
58デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/21(水) 23:35:00
class Hoge { template <・・・> ave(I f, I l) {・・・ } };

Hoge h; res = h.ave(f, l);
60デフォルトの名無しさん:2009/10/21(水) 23:44:11
>>58
couの型はvalue_typeじゃないだろ。
61デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/22(木) 00:07:29
なんでそこに入れるんだよ。アホか
63デフォルトの名無しさん:2009/10/22(木) 00:52:26
64デフォルトの名無しさん:2009/10/22(木) 00:56:04
あ、関係ないけど、>>63のfor_eachは移植性ないよ。
6541:2009/10/22(木) 01:48:56
>>63
標準偏差の答えが、合っています?
66デフォルトの名無しさん:2009/10/22(木) 01:56:33
size_t cou = abs( distance( first, last ) );

こう修正しないとだめだな。
67デフォルトの名無しさん:2009/10/22(木) 02:00:56
>>66
std::accumulate使ってるんだからfirst<lastを仮定していいだろ
68デフォルトの名無しさん:2009/10/22(木) 02:17:08
ふむ。確かに。では単純に

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

と修正。
69デフォルトの名無しさん:2009/10/22(木) 06:52:00
>>50
別のクラスオブジェクトをmainの自動変数で作って、exit呼び出し時にデストラクタが走ってない
ことを確認した。
70デフォルトの名無しさん:2009/10/22(木) 08:12:32
>>69
デストラクタが走らないとまずいね
71デフォルトの名無しさん:2009/10/22(木) 10:10:50
>>70
だからatexit()で走らせたんだろ。
72デフォルトの名無しさん:2009/10/22(木) 10:28:26
このStandardDeviationって名前は気持ち悪いなぁ。
operator()()が返すのは単に(内部で持っている)平均値との差の平方じゃないか。
どうせなら、StandarDeviation(vec.begin(), vec.end())って関数にしてくれ(ぉぃ
# まぁ、既に手元には平均やら標準偏差やらを返すメンバ関数を持つ、クラスがあるから要らないけど。
73デフォルトの名無しさん:2009/10/22(木) 12:35:16
>>69
それがスタック破棄の前後と関係すると思ってるのなら勘違い。
74デフォルトの名無しさん:2009/10/22(木) 12:51:35
>>73
なぜ? スタックの破棄はオブジェクトの破棄を終えてから行うのでは?
75デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/22(木) 13:25:50
>>75
なるほど。exit呼び出し時にはオブジェクトの破棄を行わないのだから、>>69では
確認になってないということね。だが、それでは、>>10の突っ込みがよく分からないが。
>>75=>>10という意味ではない)

ただ、実験したのは>>9なので、君の言うとおり結局は問題ないでしょ。atexitに登録した
関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。
ほぼ無意味で、実用性のない手法だが、可能は可能ということで。
77デフォルトの名無しさん:2009/10/22(木) 13:29:55
と言うか、スタック上のオブジェクトが破棄されないのであれば、>>73の指摘の
意味がよく分からない。スタック上のオブジェクトが破棄されないのだから、
mainでの自動変数のデストラクタより、atexitに登録した関数でmainでの自動変数の
デストラクタのほうが先に走るのは当たり前だから。
78デフォルトの名無しさん:2009/10/22(木) 13:42:35
「よく分からない」
の使い方が変じゃないか?
>>10はそれを勘違いしてたのだろうか
>>73はスタックが保持されることを知らなかったのだろうか
とかでよくね
79デフォルトの名無しさん:2009/10/22(木) 13:43:51
×>>73の指摘の意味がよく分からない
>>73は俺と同じく、スタックが保持されることが確実であることを知らない人だったのかな
80デフォルトの名無しさん:2009/10/22(木) 13:45:11
exitを呼び出した時点で自動変数のデストラクタを呼び出さないまま、その記憶域だけが
解放されてしまう可能性があると考えていたんだろう。で、実はその心配はないという話。
81デフォルトの名無しさん:2009/10/22(木) 13:45:37
>>75の最終行の通りだと思う。
82デフォルトの名無しさん:2009/10/22(木) 13:49:36
>>78
変ではないと思うよ。

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

>>81
不可能ではないよ。実際やったので。
83デフォルトの名無しさん:2009/10/22(木) 14:01:07
つーかそんな怪しいことするくらいなら例外投げればいいのに
84デフォルトの名無しさん:2009/10/22(木) 14:03:27
>>83
>>76の最終行だね。

で、この話は前スレから続いてて、>>3>>8が突っ込んで、>>9で冗談めかして書いた
という流れ。
85デフォルトの名無しさん:2009/10/22(木) 14:04:53
>>82
だから、間違いなくatexit()で呼び出されるように登録することは難しいといいたいのだろ。
少なくとも、exit()を使わないと言う同程度で済むもっとスマートな方法があるのだから。
86デフォルトの名無しさん:2009/10/22(木) 14:07:33
>>85
>>76
> atexitに登録した関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。

これでは駄目か?

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

例えば? 例外は話題にあったけど、それはパフォーマンスコストが高くなる可能性があると
いう意見があった。だが、例外でってこと?
87デフォルトの名無しさん:2009/10/22(木) 14:09:39
分かりづらいかな。

つまり、main内で自動変数のオブジェクトのアドレスをグローバル変数のポインタに
代入し、atexitに登録した関数内でそのグローバル変数のポインタから逆参照して
デストラクタを実行する処理を書いたということ。
88デフォルトの名無しさん:2009/10/22(木) 14:17:27
ぶっちゃけatexitでどうにかしようとする方が遙かにコストは高いだろ
つーか例外コストを異常に高く考えすぎ
89デフォルトの名無しさん:2009/10/22(木) 14:23:31
>>86
正常系なら main まで return してくるのが望ましい。
異常系なら例外でおk。
90デフォルトの名無しさん:2009/10/22(木) 14:24:55
>>87
そんな方法、ふつうにいくつか関数呼び出してそれぞれに自動変数があるってだけで破綻するだろ。
91デフォルトの名無しさん:2009/10/22(木) 15:39:42
>>88 >>90
atexitで何とかするってのは元々ネタで、それが駄目とか言われたからやってみたって
流れなんじゃないの。

>>89
mainまでreturnしてくるってのは正しい手法ではあるが、普通であって、スマートではないな。
実際面倒だし。
92デフォルトの名無しさん:2009/10/22(木) 16:38:36
cデータを1件ずつ読んで、商品番号をキーに金額を集計し商品番号が変わったらブレイクして
集計した金額を出力させたいのですがif文での作り方がわかりません。
誰か教えてください。
93デフォルトの名無しさん:2009/10/22(木) 18:33:03
>>92
前の商品番号を記録しておく
94デフォルトの名無しさん:2009/10/22(木) 19:00:24
メインスレッドをサブスレッドから一時休止するためにHANDLEがほしいのですが、
メインスレッドのハンドルを取得する関数ってありますか?
95デフォルトの名無しさん:2009/10/22(木) 19:05:22
>>94
環境依存。まぁ、サブスレッド起動時に渡しておけば?
96デフォルトの名無しさん:2009/10/22(木) 19:59:46
>>91
> それが駄目とか言われたからやってみた
そんで、ほんとに出来たのかなあと思って突っ込んだらだんまりになっちゃったという流れ
97デフォルトの名無しさん:2009/10/22(木) 20:00:58
できるかできないか以前の問題だと思うがな
やれたところで糞設計すぎて全く話にならないのは確定なんだし
98デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/22(木) 21:03:15
>>96
できたのは事実だし、だんまりでもない。スレを読み返せ。

>>97
やりもしないでやった気でいるよりもましだと思うぜ。
100デフォルトの名無しさん:2009/10/22(木) 21:06:16
環境依存のことを実験しても意味ないだろ
101デフォルトの名無しさん:2009/10/22(木) 21:10:01
>>99
>>90とかは?
102デフォルトの名無しさん:2009/10/22(木) 21:13:43
>>100がどこらへんが環境依存なのか説明してくれるらしい。

>>101
実用的でないことは重々承知してやってるんだろ。何を勘違いしてんだ。
103デフォルトの名無しさん:2009/10/22(木) 21:14:39
>>99
> やりもしないでやった気でいるよりもましだと思うぜ。

こんなのは、やらない方がマシの部類。
104デフォルトの名無しさん:2009/10/22(木) 21:14:47
いい加減鬱陶しいのでチラシの裏にでも書いといてくれ
105デフォルトの名無しさん:2009/10/22(木) 21:17:57
そんなバカコードは試す価値そのものが無いことにとっとと気付いて欲しい
106デフォルトの名無しさん:2009/10/22(木) 21:17:59
>>103
それぐらいしか言えないか……。まあ、仕方ないよね。
107デフォルトの名無しさん:2009/10/22(木) 21:18:57
>>105
突っ込んでる側でも勘違いしてるのがいたんだから、それなりに役に立ってるとは思う。
108デフォルトの名無しさん:2009/10/22(木) 21:20:29
明らかに絶対やるべきじゃないに限りなく近いやり方を無駄に実験して
「やらない奴よりまし」は無い。やる奴がおかしいだけ。悪い意味で。
109デフォルトの名無しさん:2009/10/22(木) 21:21:58
>>107
別に勘違いしたままでもいいんじゃね、真人間は一生こんなクソコード書かないだろうし
110デフォルトの名無しさん:2009/10/22(木) 21:23:01
>>108
突っこみが間違ってると思ったからやったんじゃないか。実際間違っていたし。
スレをよく読めよ。思いこみだけで書かないでさ。
111デフォルトの名無しさん:2009/10/22(木) 21:23:53
>>109
exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。
112デフォルトの名無しさん:2009/10/22(木) 21:25:21
>>111
スタックは破棄されるだろ、デストラクタは走らないが
113デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/22(木) 21:27:29
>>113
直後じゃなくて最終的な話な
115デフォルトの名無しさん:2009/10/22(木) 21:28:29
__cxa_atexit
116デフォルトの名無しさん:2009/10/22(木) 21:28:36
全く役に立たない話をいつまで続けるの?
117デフォルトの名無しさん:2009/10/22(木) 21:30:10
>>114
プログラム終了時にスタックが破棄されるのは当然だろ。atexitで登録した関数が
呼び出される前にスタックが破棄されるわけではないってことだろ。認識大丈夫?
118デフォルトの名無しさん:2009/10/22(木) 21:32:44
つーか話の流れ的に、atexitでどうにかしようとするのはアホだろ、って話に対して
>>86みたいなアホが粘るから、いい加減にしろ使い物にならねぇから、って話だろ
119デフォルトの名無しさん:2009/10/22(木) 21:37:52
>>102
話が逸れてるな。
実用的じゃないことぐらいみんな理解してる。

出来た出来たと言っているが、関数内からのexit時についても出来たのか、それとも出来なかったのか。
120デフォルトの名無しさん:2009/10/22(木) 21:40:51
>>118
何かずれてるぞ。>>86はatexitを使用するのは無意味だと認識してるだろ。
121デフォルトの名無しさん:2009/10/22(木) 21:42:02
>>117
認識大丈夫?の前に日本語大丈夫?と問いたい。
話の流れで、
> exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。
exit呼び出し後にはもちろんスタックが破棄されるよ。

>atexitのタイミングでは、必ずしもスタックが保持されないと勘違いしてた奴にとっては別だろうな。
122デフォルトの名無しさん:2009/10/22(木) 21:45:01
めんどくさい人だな全く。

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

今自分でもやったらできたよ。
124デフォルトの名無しさん:2009/10/22(木) 21:48:17
・できても無意味だからやるな
・やるべきじゃないからもう実験も要らない
125デフォルトの名無しさん:2009/10/22(木) 21:52:23
>>122
少なくとも自動変数が保持されるのは書いてるように見える。

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

自分には>>86が実用にならないんだろうかなどという話をしてるようには読めない。
126デフォルトの名無しさん:2009/10/22(木) 21:53:45
>>124
atexitに登録された関数の実行のタイミングぐらいは知っとけよ。
127デフォルトの名無しさん:2009/10/22(木) 21:54:36
>>125
実用にならないんだろうか
→実用に耐えうる場面もあるのではないだろうか
128デフォルトの名無しさん:2009/10/22(木) 21:56:12
>>122
つまり、ポインタは有効であることが保証されるが、free可能な領域を指していない可能性は大いにあると
129デフォルトの名無しさん:2009/10/22(木) 21:58:46
茶々を入れるようだけどC++でatexit()のタイミング知らなくても何も困らない希ガス
130デフォルトの名無しさん:2009/10/22(木) 21:59:44
Cでも困らな(ry
131デフォルトの名無しさん:2009/10/22(木) 22:06:17
>>127
そんなふうには書いてないだろ。
132デフォルトの名無しさん:2009/10/22(木) 22:11:33
まぁ>>86は、スタックインスタンスへのポインタ?をいちいち全部静的記憶に
登録するというかっこいい超設計より、例外一発でmainまで脱出して終了する
方がコスト高いかもしれないと思ってることになるから、exitの実装より例外の
実装を勉強した方がいいとは思う
133デフォルトの名無しさん:2009/10/22(木) 22:12:03
自分はデキると思ってる人たちの痛いレスだらけになってるよ
いや、実際デキるのかもしれないけど状況はスルー力検定開催中だよ
134デフォルトの名無しさん:2009/10/22(木) 22:15:33
>>132
そこまで誤読できるのもすごいわ。勝手にやってな。
135デフォルトの名無しさん:2009/10/22(木) 22:16:22
勝手にやってなというわりに、
勝手に書き込みをしている人にいちいち噛み付くのはなぜなのかしら〜♪
136デフォルトの名無しさん:2009/10/22(木) 22:17:29
誤読も何もそのまんまじゃん
137デフォルトの名無しさん:2009/10/22(木) 22:18:43
訳:かまってほしいな
138デフォルトの名無しさん:2009/10/22(木) 22:19:35
>>135
>>134の時点でもう相手しても無駄かなと思えたってことだろ。アホですか。
139デフォルトの名無しさん:2009/10/22(木) 22:21:04
>>131
書いてるだろ
140デフォルトの名無しさん:2009/10/22(木) 22:23:38
×相手しても無駄かな
○まともに反論できなくなってきちゃったから降りたいな
141デフォルトの名無しさん:2009/10/22(木) 22:25:00
東方厨はホント低能だな。
142デフォルトの名無しさん:2009/10/22(木) 22:25:38
煽りに完全に転じた人が現れたようです
143デフォルトの名無しさん:2009/10/22(木) 22:28:46
訳:話題を逸らしてごまかしたいな
144デフォルトの名無しさん:2009/10/22(木) 22:29:48
>>86はatexitに登録する手法は無意味だと分かった上で、

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

間違いなくatexitに登録した関数が実行されるように登録するのは難しくないということを
言ってるんだろ。
145デフォルトの名無しさん:2009/10/22(木) 22:31:17
atexit 厨が東方厨ってことじゃないの?
146デフォルトの名無しさん:2009/10/22(木) 22:32:04
「atexitで実行する関数に破棄すべきスタックインスタンスを登録するのが」難しい
って話だろ
147デフォルトの名無しさん:2009/10/22(木) 22:32:50
例外の件は、正常系は例外を返すべきでないってことでしょ。
148デフォルトの名無しさん:2009/10/22(木) 22:32:58
難しい、という言い方だと揚げ足を取られる可能性あり。
無駄に面倒、という言い方にすべき。
149デフォルトの名無しさん:2009/10/22(木) 22:33:45
>>146
それは、勧められる話ではないが、グローバル変数を使えば難しくないだろ。
150デフォルトの名無しさん:2009/10/22(木) 22:33:51
exitでいきなり終わらせる正常系とか無いだろ
151デフォルトの名無しさん:2009/10/22(木) 22:34:35
うわ、本当に揚げ足取られたw
152デフォルトの名無しさん:2009/10/22(木) 22:34:48
>>148
バトルしてるつもりなの?w
153デフォルトの名無しさん:2009/10/22(木) 22:35:32
>>152
別に。
しかも実際に懸念通りの展開になってしまったようで。
154デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/22(木) 22:38:36
>>153
揚げ足かどうかは認識の違いだな。元々ネタなんだし。
156デフォルトの名無しさん:2009/10/22(木) 22:38:40
>>154
正常系≠正常終了
157デフォルトの名無しさん:2009/10/22(木) 22:39:32
>>156
正常系でもプログラムをさっさと終わらせたいことだってある。
158デフォルトの名無しさん:2009/10/22(木) 22:40:09
>>157
それならば例外を使っても問題は無い
159デフォルトの名無しさん:2009/10/22(木) 22:41:00
正常系じゃなきゃ例外使っちゃいけないという前提がおかしい。
変に乱用しなきゃいいだけ。
160デフォルトの名無しさん:2009/10/22(木) 22:41:41
間違えた。正常系では例外を、だ。
161デフォルトの名無しさん:2009/10/22(木) 22:41:48
>>158
自分もそう思うが、前スレで強く否定する人や正常系で例外を使うべきでないという
正論を言う人がいたりして、今は揺れているというのが実状。
162デフォルトの名無しさん:2009/10/22(木) 22:46:30
>>161
atexitを駆使してまで例外での脱出を避けるのは、goto絶対禁止とかそういう部類を
思い出すが。まぁ例外はコストがわずかに掛かるが。
とは言っても、例外を完全に排除して例外非対応コンパイルでもしない限り、例外
をthrowかcatchしなきゃ(例外仕様は当然書かない)効率は変わらない訳で、実際
のところはやっぱり宗教論争としか。
163デフォルトの名無しさん:2009/10/22(木) 22:52:49
>>162
いい加減何度も書くのもアレなんだが、元々ネタなんだよ。自分が担当者だったら、
C++でatexitなんて絶対使わない。(Cならデストラクタがない分、使えば便利なときも
あるかもしれない)

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

自分が書いたコードで、「例外使っていて便利でしょ?」とか見せたとき、そんなことを
言われると、返す言葉もない。
164デフォルトの名無しさん:2009/10/22(木) 22:53:51
そしてスルーされてる質問が
165デフォルトの名無しさん:2009/10/22(木) 22:55:01
>>163
最初はともかく、いつの間にかネタじゃなくなってるようにしか見えない奴がいる
って話だろ
166デフォルトの名無しさん:2009/10/22(木) 22:56:41
グローバル変数に設定されたスタックが有効なままexitされたかどうかの判断って面倒じゃない?
関数を抜けるときに必要分POPしたりすんの?
167デフォルトの名無しさん:2009/10/22(木) 22:57:01
どうせ破棄が気になる時にexitなんか呼ばないんだからどうでもいいじゃんよ・・・
168デフォルトの名無しさん:2009/10/22(木) 22:59:43
どうせやらないからどうでもいいんでそろそろやめろ

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

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

取っ組み合い
169デフォルトの名無しさん:2009/10/22(木) 23:01:07
>>167
元々atexitを使ってるプログラムのデバッグをさせられるなんて可能性は十分に
考えられるよ。規格、仕様なら隅々まで知っていて損はない。
170デフォルトの名無しさん:2009/10/22(木) 23:02:41
>>169
そういう範疇の話から逸脱してきてるじゃん>>86は明らかに
171デフォルトの名無しさん:2009/10/22(木) 23:03:45
>>170
そういうふうにしか捉えられなかったとしたらすまなかった。
172デフォルトの名無しさん:2009/10/22(木) 23:09:17
徹底的に粘る人なんだなぁ
こういう人は絶対に「お前の方が馬鹿だ」って態度を曲げないと思うけど、
まだ取っ組み合うの?
173デフォルトの名無しさん:2009/10/22(木) 23:11:44
そのタイプが二人揃うとこうなる訳ですよ
174デフォルトの名無しさん:2009/10/22(木) 23:13:21
>>172
馬鹿にはしてないよ。ちょっと深読みしすぎじゃないか。
175デフォルトの名無しさん:2009/10/22(木) 23:15:48
自分の文章がどう見えるかが分からないタイプでもあるようだ
176デフォルトの名無しさん:2009/10/22(木) 23:17:07
人格攻撃始まりました
177デフォルトの名無しさん:2009/10/22(木) 23:17:32
そんなの受け取りかた次第でしょ。被害妄想かもしれないし。
178デフォルトの名無しさん:2009/10/22(木) 23:20:07
まさに>>172
179デフォルトの名無しさん:2009/10/22(木) 23:33:34
◎◎◎
◎◎◎
◎◎◎
180デフォルトの名無しさん:2009/10/23(金) 00:15:40
windowsでもunixでも、確実にテンポラリファイル作る方法ありますか
DVDから起動したり、読み取りアクセスしかない場合はカレントディレクトリには出来ないのですが。
181デフォルトの名無しさん:2009/10/23(金) 00:22:24
>>180
tmpfile()
が使えるかも知れない
182デフォルトの名無しさん:2009/10/23(金) 00:22:43
>>180
環境変数で設定されているテンポラリフォルダに作る
183デフォルトの名無しさん:2009/10/23(金) 00:39:16
サンクス tmpfile調べてみます
環境変数は、どの環境でも同じやり方で、確実にとれるんですか。
184デフォルトの名無しさん:2009/10/23(金) 00:42:02
tmpfileはファイルのパスが特定できないみたいですね。
そのファイルをリネームしたりしたいんです。
185デフォルトの名無しさん:2009/10/23(金) 00:52:06
思いっきり環境依存の問題を環境に依存せず、とな
ファイルのリネームだって環境依存だろうに
ディレクトリデリミタの問題だってある
せめてgccとかビルド環境を限定しないと答えられんのでは

素直にその手の事を吸収するライブラリを使うか
個別に書いて切り分ける方がいいと思うけど
186デフォルトの名無しさん:2009/10/23(金) 02:03:04
>>183->>184
まさかこんなレスが来るとは予想できなかった
対象とするunixは何?
187デフォルトの名無しさん:2009/10/23(金) 02:34:28
codepad ttp://codepad.org/xmwNfoSh

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

どのようにすれば良いでしょうか?
188デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/23(金) 04:25:32
>>188
それだと Hoge() を2回呼び出しただけで死ねる。 auto_ptr ぐらい使おうぜ。
190デフォルトの名無しさん:2009/10/23(金) 08:50:58
Hogeはコンストラクタだし
質問にはそこまで含まれてないんだからいいんじゃね
191デフォルトの名無しさん:2009/10/23(金) 14:12:31
入力ファイルをプログラム引数として受け取るってどうゆう事ですか?
192デフォルトの名無しさん:2009/10/23(金) 14:20:38
>>191
FILEポインタを食う関数か、
ファイルネームを食って関数内で展開する関数か、
または実行ファイルの引数で指定するか。
193デフォルトの名無しさん:2009/10/23(金) 15:54:06
変数Aに1を代入
これをwhile(1)などでずっと繰り返しているとメモリがモリモリたまるのですが、
なぜでしょう?
どこかでログを取っているんでしょうか
またこれを防ぐ方法はありますか?
194デフォルトの名無しさん:2009/10/23(金) 15:56:09
そんなことはない
貼り付けてみろ
195デフォルトの名無しさん:2009/10/23(金) 17:23:47
>>194
すいません、なりませんでした。気のせいでした
196デフォルトの名無しさん:2009/10/23(金) 20:26:42
>>192
上二つもプログラム引数って言ったりするもんなの?
197デフォルトの名無しさん:2009/10/23(金) 21:20:38
プログラム引数なんて用語はない
198デフォルトの名無しさん:2009/10/23(金) 22:25:27
ガチスレかと思った。
199デフォルトの名無しさん:2009/10/24(土) 02:12:09
すみません。これらの文字列が
一つでも出現するか調べたいのですが速い方法ありますか。
調べる文字列がおおくなるほど、その個数分時間が増える方法しかわかりません。 = 一つ一つ調べる。

"HTML"
"html"
"?xml"
"?XML"
"<body"
"<BODY"
200デフォルトの名無しさん:2009/10/24(土) 02:15:58
>>199
正規表現(となるべく高速な正規表現エンジン)を使う。
201デフォルトの名無しさん:2009/10/24(土) 02:24:09
正規表現は多機能な分だけ遅い気がしてます。あと、orで繋いだ文字列が長くなりすぎるとバグる、不安定になります、
202デフォルトの名無しさん:2009/10/24(土) 02:27:41
>>199
互いの単語の相関からマップを作って無駄な検索をしないで済むアルゴリズムは存在するけど
名前を思い出せない
203デフォルトの名無しさん:2009/10/24(土) 02:36:40
まともな正規表現エンジンは単純なORだとかなり最適化できるから自分で適当に組むよりは早くなるとおもうよ。
204デフォルトの名無しさん:2009/10/24(土) 02:39:11
>>201
長くなりすぎるとバグる正規表現エンジンってどれ?
205199:2009/10/24(土) 02:39:58
ローリングハッシュ+ブルームフィルタと、鬼車で速度比較してみます。前者を今から作ってみます。
ここで複数同時検索見つけました。 ラビン-カープ文字列検索アルゴリズム - Wikipedia
206デフォルトの名無しさん:2009/10/24(土) 02:41:22
>>204
秀丸と、Regrepに入ってる正規表現dllです。秀丸の場合、最大文字数制限があるんですが。
207デフォルトの名無しさん:2009/10/24(土) 02:59:25
TR1の正規表現でいいだろ。
208デフォルトの名無しさん:2009/10/24(土) 03:25:14
>>199
検索文字列がそれだけなら
適当に作ってみようか?
209デフォルトの名無しさん:2009/10/24(土) 03:35:06
おねがいします
210デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/24(土) 05:18:52
サンクス。 自分でラビン-カープ文字列検索を作ってるけど、
文字列長が一定だといいけど
一文字や二文字程度が入ってくると、パフォーマンスが落ちるね。
213デフォルトの名無しさん:2009/10/24(土) 05:20:57
>>212
>>210,211 は検索文字列が4文字未満だと動かないよw
214デフォルトの名無しさん:2009/10/24(土) 14:15:53
先頭2バイト一致するか調べたら簡単で速い気がしてきた。
ヒットしたら完全一致調べる。
ラビン-カープ文字列検索は一回ごとのハッシュ計算に手間かかる。
215デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/24(土) 16:54:08
>>215
それは実測で速くなったの?
217デフォルトの名無しさん:2009/10/24(土) 17:12:41
いまからテキスト(html)で実測してみる
218デフォルトの名無しさん:2009/10/24(土) 17:39:08
複数箇所にまたがって使う可能性のあるクラス(Factoryやその生成物、利用クラス)はポインタの形式を統一したほうがいいですよね?
それとも早いのと賢いので細かく使い分けるべきですか?
219199:2009/10/24(土) 18:24:09
実測したよ。
tr1::regexは結果が間違えてるんだが。
211さんのはテストケースに書き換えるのが面倒で入れなかった。


215の方法 178秒
一つ一つstring::findで調べる方法 280秒
正規表現 鬼車  590秒
vc++2008 tr1::regex 868秒
220デフォルトの名無しさん:2009/10/24(土) 18:35:17
ここまでboost::xpressive無し
221デフォルトの名無しさん:2009/10/24(土) 18:40:05
strstrもなし。
222デフォルトの名無しさん:2009/10/24(土) 18:42:22
正規表現なら鬼車がいいだろ
Ruby(オリジナル版には入ってないかも)、桜エディタ、
Bregexp.dllの後継bregonig.dllに使われている。
223デフォルトの名無しさん:2009/10/24(土) 18:46:30
インラインアセンブラもなし
224デフォルトの名無しさん:2009/10/24(土) 18:49:35
215より速くできる方法あるの
225デフォルトの名無しさん:2009/10/24(土) 18:51:29
vector<string>に複数の文字列を定義時に登録する方法ありますか?
226デフォルトの名無しさん:2009/10/24(土) 18:52:25
C++0x対応コンパイラに乗り換える
227デフォルトの名無しさん:2009/10/24(土) 19:01:01
static int fnc(); と int fnc();は何が変わるんですか。
228デフォルトの名無しさん:2009/10/24(土) 19:03:15
自己解決
ひとつのファイル内のみで使用できるって事ですか。
229デフォルトの名無しさん:2009/10/24(土) 22:06:29
仮想関数ってポインタアクセスしてるらしいし、つまりinlineしても無駄無駄ですよね?
230デフォルトの名無しさん:2009/10/24(土) 22:09:06
インライン化できるならコンパイラが勝手にやるよ
231デフォルトの名無しさん:2009/10/24(土) 22:24:29
これらって同じかと思ってミスりました。

memcmp( buf, "\x20\x45\x4D\x46", 4);
memcmp( buf, "0x200x450x4D0x46", 4);
memcmp( buf, "0x20454D46", 4);
232デフォルトの名無しさん:2009/10/25(日) 00:04:57
KMP とか AC とかあるよ
233デフォルトの名無しさん:2009/10/25(日) 00:06:11
KMP じゃなくて CW だった。
234デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/25(日) 09:46:31
>>234
一般的にコンテナのインスタンスに依存せずに要素を指さない有効なイテレータを作る方法はないし、
nullや0から変換できるとも限らない。
236デフォルトの名無しさん:2009/10/25(日) 09:52:13
>>235 thxです
>nullや0から変換できるとも限らない。
なるほど、やはりそうですか自分もそんな気がしていました
なので、nullや0から変換する方法というのは、他に方法が無い場合仕方無しにやってます。
237デフォルトの名無しさん:2009/10/25(日) 11:06:39
boost::optionalとかどう?
238デフォルトの名無しさん:2009/10/25(日) 11:40:01
boost は何でもあるんですね、また驚きました、参考にさせてもらいます。
239デフォルトの名無しさん:2009/10/25(日) 13:28:38
クラステンプレートでoperator() はオーバーライドすることが可能でしょうか?
もしできるならば、簡単な雛形を教えてください
それからSFINAE の使い方で、関数テンプレートの事例は検索すれば
いくつか出てきますし、「C++テンプレートテクニック」という本を読んでやり方は分かるのですが
クラステンプレートの事例が検索できません、もしかしてSFINAE はクラステンプレートには適用できないのでしょうか?
ここで言うクラステンプレートとは
template<class T>
class Foo {};
このような形式のことを意図します。
コンパイラはvs2005です。
240デフォルトの名無しさん:2009/10/25(日) 13:29:34
基底クラスがないのにオーバーライド?
241デフォルトの名無しさん:2009/10/25(日) 14:54:02
>>239
ファクトリー関数を挟めば適用できるよ
242デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/25(日) 17:17:55
どういう動作をしてほしいのかわかりません
244デフォルトの名無しさん:2009/10/25(日) 17:29:41
>>243
継承により基底クラスのメンバー関数を使いたいのですが、今回の場合はどちらが基底クラスになってもかまいませんが
仮にFoo クラスに
int Widget();
というような関数が定義されて、基底クラスとした場合、Hoge クラスでそれを使えることはもとより
operator() も呼び出せるようにしたいのですが。
245デフォルトの名無しさん:2009/10/25(日) 17:33:49
using Foo<T>::operator ();
246デフォルトの名無しさん:2009/10/25(日) 17:39:10
>>245
それは何処に記述して、main() からどのように呼び出したらいいのでしょうか?
247デフォルトの名無しさん:2009/10/25(日) 18:24:01
>>242
無理。その二つのoperatorはそもそも継承可能な同一性を持たないから。
248デフォルトの名無しさん:2009/10/25(日) 18:56:58
そうですか、ありがとうございます
int operator() とvoid operator () と違うから継承不可能なのでしょうか?
249デフォルトの名無しさん:2009/10/25(日) 21:30:24
インターフェースにコピーコンストラクタや代入ってつけないほうがいいですか?
ぜんぜん違う実装同士だとすごい困るんですけど・・・
250デフォルトの名無しさん:2009/10/25(日) 21:35:12
>>249
付けて困るんなら付けなきゃいいじゃん。
251デフォルトの名無しさん:2009/10/26(月) 07:53:47
コンストラクタから、オーバーロードされたコンストラクタを呼び出すってアリなんですか?
class CHoge {
public:
 CHoge(int x) { CHoge((float)x); }
 CHoge(float x) { ... }
};
252デフォルトの名無しさん:2009/10/26(月) 08:11:51
0xではアリ
253デフォルトの名無しさん:2009/10/26(月) 09:54:15
>>251 今のところナシ
254デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/26(月) 13:25:11
>>254
× オーバーロード
○ オーバーライド

「ダメ」の意味がよくわからんが、 CHogeEx をさらに派生して func() をオーバーライドしていても
CHogeEx のコンストラクタで呼び出されるのは CHogeEx::func() になる。
つまり C++ のコンストラクタ(とデストラクタ)の中では仮想関数による動的多態は効かない。
256デフォルトの名無しさん:2009/10/26(月) 13:25:17
それオーバーロードされてなくね
257デフォルトの名無しさん:2009/10/26(月) 13:25:53
>>254 試せよ。
258デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/26(月) 16:12:51
関数を抜けるころにはもう参照を使わないとわかってる→参照か生ポインタを引数にしてもよい
メンバ変数にほかのインスタンスへの参照として持たせたい→寿命がよくわからない→スマートポインタ
動的に確保して返す関数→値捨てられたら困る→スマートポインタ
メンバ変数を返す関数→外で参照を保存されたらバグる可能性がある→値返し

引数と返り値の参照について↑みたいにやってるんですが、もっと明確で安全な基準みたいなのってありませんか?
260デフォルトの名無しさん:2009/10/26(月) 16:23:40
>>258
さらにconstでなければならない
261デフォルトの名無しさん:2009/10/26(月) 20:05:23
>>259
オブジェクトの寿命で考えてみよう
262デフォルトの名無しさん:2009/10/26(月) 20:42:06
>>260
さらに int 型、じゃなかったっけ?
263デフォルトの名無しさん:2009/10/27(火) 00:15:22
>>258,260,262
staticでconstで整数型じゃなかったっけ。 超うろ覚えだが。
ちなみにVCの6か7ぐらいまではそれすらもできないので、enumハックという手法があったがそれはもう昔の話。
264デフォルトの名無しさん:2009/10/27(火) 00:33:46
enumはOKで整数はダメとか、実に理不尽だったよな。
265デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/27(火) 01:08:37
__finally節が実行されない場合があると知ったときの落胆ときたら。
なんのためのfinallyなんだよw
今ならBOOST_SCOPE_EXIT使うけど。
267デフォルトの名無しさん:2009/10/27(火) 01:25:55
今でも、ダイアモンド継承が正しく機能しないとか
ADLが標準に合致しないとか
Cライブラリがstd名前空間に含まれてないとか

問題山積みだけどね。
268デフォルトの名無しさん:2009/10/27(火) 01:30:03
まぁ問題山積みじゃないコンパイラは珍しいし
C++以外ですら
269デフォルトの名無しさん:2009/10/27(火) 02:05:17
VisualStudio6の時代が長すぎたのもあるね。
2002/2003は見送ったところが多かった。
2005からかな、みんな使い出したのは。
270デフォルトの名無しさん:2009/10/27(火) 06:53:04
CInputState& s=State[0];
s.Up|=KEYDOWN(DIK_UP);

このソースの2行目の |= は何を表しているのでしょうか?
+=や-=ならちょくちょく目にしますが、|=というのは・・・?
271デフォルトの名無しさん:2009/10/27(火) 07:02:26
>>270
a += b は a = a + b といっしょ。
a -= b は a = a - b といっしょ。
a |= b は a = a | b といっしょ。
272デフォルトの名無しさん:2009/10/27(火) 07:13:35
>>271
ありがとうございます。
助かりました。
273デフォルトの名無しさん:2009/10/27(火) 08:03:39
C言語から入ってアセンブラに行くと
a += b
の方が
a = a + b
よりも機械語の形式に近いと知って軽いカルチャーショックを受けるよな?
俺だけか?
274デフォルトの名無しさん:2009/10/27(火) 08:11:33
>>273
考えた事もなかった。

ADD A, B
こうゆう事?
275デフォルトの名無しさん:2009/10/27(火) 08:27:14
>>274
そうそう

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

BASICに代入付き四則演算子がなかったもんだから
なおさら、ほぉ〜と思ったな
276デフォルトの名無しさん:2009/10/27(火) 08:35:33
先にアセンブリ言語を知っていたから、Cは簡単だった。
277デフォルトの名無しさん:2009/10/27(火) 09:02:29
>>275
このスレで答える側の人たちは昔からプログラムやってる人が多いのかな?
BASICなんて見たことも触ったこともないな。

>>276
Cが簡単って人は俺にとって神に見える。
俺はJavaからC/C++に入ったからCがかなり難しく感じる。
涙でディスプレイが霞むほどに難しい。
278デフォルトの名無しさん:2009/10/27(火) 09:06:01
人によるとしか言いようがないんじゃね?
279デフォルトの名無しさん:2009/10/27(火) 09:47:37
最近Fortranやったんだがa+=bが使えなくてがっかりした
でもa(1:n)=a(1:n)+b(1:n)とか配列周りに関しては感動した
280デフォルトの名無しさん:2009/10/27(火) 09:55:15
少なくともCは、データがどのようにメモリに格納されているかを常に念頭に置いておけば
難しいところはないんじゃないか。
C++は全然違うけど。
281デフォルトの名無しさん:2009/10/27(火) 10:10:47
>>277
VisualBasicも基本的にはBASICだということを忘れてないかい?

C++は言語仕様が大きすぎて
ソフトを作るためにC++使ってるのか
C++の深淵を知るためにC++を使ってるのか
分からなくなる
282デフォルトの名無しさん:2009/10/27(火) 10:14:43
>>281
なんか作ろうとして、その途中でつまずいたりアイデアを思いつくと言語の勉強が始まって、気づいたら半日過ぎてたとか良くある
283デフォルトの名無しさん:2009/10/27(火) 10:41:15
>>281
そういえばVBなら少し触ったな。
基本的にはVBもBasicか。あまりにイメージが違いすg・・・


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

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

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

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

でも確かにC++の深淵を〜は確かにそういう嫌いがあるよね……
285デフォルトの名無しさん:2009/10/27(火) 11:30:48
1byteを削るのに必死な時代は想像できないよな
ドラクエ1を64KiBに収めるとかどんな拷問かと…

memcpyさえないレベルから作るわけで
そもそもC言語とか一切使ってないんだろうなぁ
286デフォルトの名無しさん:2009/10/27(火) 12:23:39
バイト単位で削る世界だとアセンブラ以外は論外だな。

ところで、C++は巨大と言われるけど、一つ一つの機能をどうコンパイルされるか
把握しながら理解すれば、そこまでバカみたいな巨大さは感じないなぁ。
とは言っても、応用が色々と奥深いけど。
287デフォルトの名無しさん:2009/10/27(火) 13:04:29
C++が巨大っていうのはどこらへんを言ってるのだろう。皮肉じゃなくて、純粋に。
他の言語はLLぐらいしかあまり使ってないので。

たしかに大きいなとは思うけど、必要だから大きいのであって、無駄なものは
そんなにないと思うんだが。
288デフォルトの名無しさん:2009/10/27(火) 13:50:29
Cとの互換性を保ちつつ必要そうなものを足していったから
複雑怪奇に感じてそれを巨大だと表現したりするんだろう
無駄だとかじゃないんだ
289デフォルトの名無しさん:2009/10/27(火) 14:11:26
巨大とまでは言ってないでしょ

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

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

だからといってJavaでは中途半端すぎて満足できないw
290デフォルトの名無しさん:2009/10/27(火) 14:20:09
>>289
もう――――――――
もう何時間―――― こうしているのか――――

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

ってことだよな。CとC++の最大の違いはw
291デフォルトの名無しさん:2009/10/27(火) 14:27:44
それはちゃんと理解してないまま使ってるからだな
ちゃんと理解してないと安心して使えない言語なのが悪い、というのも一理あるし、
理解してればCより遙かに安全で気楽になったりもするし
292デフォルトの名無しさん:2009/10/27(火) 15:00:59
Cでは異常系の処理がパンクしちゃうから、C++のほうが結局は楽で安全だと思うけどな。

C++とCの最大の違いは、仕様変更の荒波にどれほど楽をして対応できるかどうかではないかな。
293デフォルトの名無しさん:2009/10/27(火) 15:04:46
C++で気を付けなければならないリストみたいなのを作って、新たにC++を学ぼうと
する者が全員それを読めばいいんじゃないか。
294デフォルトの名無しさん:2009/10/27(火) 15:06:51
>>293
Effective C++はじめ、そこらじゅうに名著がありますよ。
もちろん、業務としてC++を使う人たちは全員読んでいますが。
295デフォルトの名無しさん:2009/10/27(火) 15:40:29
C++ の方が基本的にはCより使うの安全で楽だとは思う。
流儀はある程度決めておかないと収集つかないけど。

気分的には「巨大」というのはわからないでもない。CとC++と両方
のやり方がかぶってる部分がかなりあるから、機能面だけから考えれば
不要な部分が多い。互換性は重要だから無駄ではないのだけど。
296デフォルトの名無しさん:2009/10/27(火) 15:54:28
入力ファイルからデータを読み込みロジック部分を関数化し、
qsort関数以外を使用して番号順にソートしたいのですが何かいい方法があれば教えてください。

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


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

297デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/27(火) 15:57:36
>>296
宿題スレへどうぞ。
299デフォルトの名無しさん:2009/10/27(火) 16:03:18
>>296
読み込みが終わったらソートできてる状態にすればいいと思う
300デフォルトの名無しさん:2009/10/27(火) 16:16:01
>>294
それは当然だが、それらを読まない人が多いから巨大だとか言われるわけで、それらを
簡単にまとめた物を言っている。原理を詳しく知りたかったら原著を読めばいいし。

C++には新規参入など要らないということであれば話は別だけど。
301デフォルトの名無しさん:2009/10/27(火) 20:32:58
>>281
でもその「深淵を覗いている感じ」は、なかなか他の言語では得難いものがあるよねw
なにか、つきあいの長い人に意外な一面を発見する喜び、みたいな。
302デフォルトの名無しさん:2009/10/27(火) 20:38:17
整数のゼロ除算はif(div==0)でチェックできますけど実数のゼロ除算はどうやって調べるのが妥当でしょうか?
303デフォルトの名無しさん:2009/10/27(火) 20:56:09
実数の内部表現は処理系依存。
304デフォルトの名無しさん:2009/10/27(火) 22:59:45
エラーで停止したくないんだったら、
z = x/y を

if ( y < 十分小) z=十分大 else z=x/y
にしとけ
305デフォルトの名無しさん:2009/10/27(火) 23:22:03
>>302
std::numeric_limits<double>::epsilonとか使うといいんじゃないか。
306デフォルトの名無しさん:2009/10/27(火) 23:34:04
>>304 y<0 かも知れないよ〜
307デフォルトの名無しさん:2009/10/28(水) 01:20:43
if ( y ニアリーイコール0) z=十分大 else z=x/y
308デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/28(水) 12:02:15
>>303
> 実数の内部表現は処理系依存。

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

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

じゃなかったっけ?
310デフォルトの名無しさん:2009/10/28(水) 15:39:16
C++ の ostream について質問なんですが、数値を大文字の 16 進数に変換するのに
簡単な方法は無いでしょうか?
std::hex だと小文字になってしまうし・・・。
311デフォルトの名無しさん:2009/10/28(水) 15:55:47
>>310
std::ios::uppercase
312デフォルトの名無しさん:2009/10/28(水) 16:05:06
>>311
速答ありがとうございました。
うまく大文字に変換できました。
313デフォルトの名無しさん:2009/10/28(水) 18:48:07
std::vector<int> lhs;
for (p = lhs.begin(); p < lhs.end()-6; ++p) {
}

lhs.end()-6 の表記が間違っていると思うのですが、どのように書いたらいいでしょうか?
314デフォルトの名無しさん:2009/10/28(水) 19:08:14
間違ってはいないと思うけど、constじゃないコンテナのend()はちょっと重いかもね。
それと、size()が6以下だとまずいね。
315デフォルトの名無しさん:2009/10/28(水) 19:11:06
実現したいことがいまひとつ分かりにくいけど
lhsの先頭から終わりの6つ前まで走査したいってこと?
それなら
for(size_t i = 0; i < lhs.size() - 6; ++i){
 // lhs[i]でアクセス出来る
}
でいいと思うが
316デフォルトの名無しさん:2009/10/28(水) 20:50:02
素直に書けばいいのに不自然なことして悩んでる質問が多くね?
317デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/28(水) 20:57:50
C++ではfor文の比較は!=にしようね。<などは、あるイテレータの種類やカウンタで
フォールトトレランス性はあるけど、コンテナの種類が変わると使えなくなる可能性がある。
319デフォルトの名無しさん:2009/10/28(水) 21:02:02
2ずつカウントアップしたらスルーされる可能性ある。
n++だとしても、ループ内でnの値が変わったら停止しなくなる。
320デフォルトの名無しさん:2009/10/28(水) 21:04:53
>>319
ちゃんと読め
321デフォルトの名無しさん:2009/10/28(水) 21:08:58
>>319
ステップが1でないループやカウンタが任意の値に変わるようなループは
普通じゃないんで、使う側がそれを想定したコードを書くべきではあるが、
普通はそんなことを想定しなくてもいいと思うよ。
322デフォルトの名無しさん:2009/10/28(水) 21:27:00
基本的にintなど大小が付いてる場合では、条件はなるべくきつめにつけて置くべき。

!=   →   <=

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


同じ事を説明しているだけだがな。
323デフォルトの名無しさん:2009/10/28(水) 21:35:12
バグが見つかる可能性を減らす事になるんでしない

324デフォルトの名無しさん:2009/10/28(水) 21:43:18
漏れも。たとえば5周でぴったりとまってほしいのに、
6周や7周して何事もなかったかのように続行されてはあとで大変なことに。
だから「5周で終わらなきゃだめ!」って言う条件を
「まぁ、5周以上になったら適当なところで終わってね」なんて緩めたりしない。
325デフォルトの名無しさん:2009/10/28(水) 21:47:45
!=とアサート併用が常識だと思ってた
326デフォルトの名無しさん:2009/10/28(水) 21:51:52
>>324
それは「5周以上」じゃなくて「5周以下」じゃね?
1→7とかなって2周で終わる。
あと、i!=5 と i<5 は事後条件に違いがあるから
どちらが適切かは事後条件次第じゃないかと。

で、forにおいて日常的に!=を使うか<を使うか、++iを使うかi++を使うかは
効率の問題とかもあるんだけど、結局は宗教論争なんだよね。
cout と printfに並ぶくらい。
327デフォルトの名無しさん:2009/10/28(水) 21:54:31
>>318の、コンテナの種類が変わると使えなくなる可能性があるというのは宗教的な話で片づけられることなのか?
328デフォルトの名無しさん:2009/10/28(水) 21:57:15
そりゃあ書き換えると不適切な場合は言わずもがな。
いちいち言及しないと気になる?
329デフォルトの名無しさん:2009/10/28(水) 22:06:47
気になって夜も眠れないでごわす!

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


あと他の部分のコードでこうしたらいいよ、とかあれば教えてください
331デフォルトの名無しさん:2009/10/28(水) 22:08:28
!=のほうが<よりも効率はいいことが多いがな。
332デフォルトの名無しさん:2009/10/28(水) 22:09:20
vectorからlistに変えたいとき、for文がたくさんあれば!=になってないと
修正が大変だわな。
333デフォルトの名無しさん:2009/10/28(水) 22:13:30
>>331
それがまた宗教論争の種なわけだ。
サッターは時期尚早の再不適化はやめようと書いているけれども
果たしてコンパイラの最適化能力をどこまで信じないかという問題もある。

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

・・・一般論では宗教論争にしかならないのはこのため。^^
334デフォルトの名無しさん:2009/10/28(水) 22:14:44
だいたい、std::vector<T>::iteratorが
< や <= で比較可能なことは保証されてるのかよ。

== と != は確実に保証されてるけどな。
335デフォルトの名無しさん:2009/10/28(水) 22:15:25
仕様は!=なんで、<にするのはフォールトトレランス性は確保できるが、上にもあった
けど、バグは潰せないんで、やっぱ自分は!=かな。
336デフォルトの名無しさん:2009/10/28(水) 22:17:00
あとでSTLを使うかもしれないという理由で
 != に統一すると、停止しないバグに遭遇する危険。
整数型なら< >にしとけ
337デフォルトの名無しさん:2009/10/28(水) 22:18:25
>>333
宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。

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

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

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

だが、多くのコンテナに変更可能なコードを書くことは悪ではない。
338デフォルトの名無しさん:2009/10/28(水) 22:18:59
for(n=0; n!=10; n++) { n+=rand()%3; }
とか中で追加してたら、バグ発生するだろ。
バグでないのに。
339デフォルトの名無しさん:2009/10/28(水) 22:19:18
>>330
見てるところがちがんじゃない?
どうも「endl」でエラーが出てるよ。
endlってそういう使い方しないと思うんだけど。
340デフォルトの名無しさん:2009/10/28(水) 22:19:34
>>336
バグはassert等で対応するべきであって、仕様を曲げるのはおかしい。
341デフォルトの名無しさん:2009/10/28(水) 22:21:40
>>334
保証されている。ランダムアクセスイテレータは<や<=が使用可能。
342デフォルトの名無しさん:2009/10/28(水) 22:23:09
>>336
停止しないバグがあるならバグを直すべき
343デフォルトの名無しさん:2009/10/28(水) 22:23:31
>>338
そういうのは>>321で議論から除外されてる。
344デフォルトの名無しさん:2009/10/28(水) 22:23:47
>>337
>宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。

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

for文の宗教論争史(あるかどうかしらないけど)を調べると
今まさにあなたの反論がそのまま出てくるよ。
345デフォルトの名無しさん:2009/10/28(水) 22:26:06
>>344
いやいや、それは逃げてるだろう。

仕様と最適化の問題は答えが明らかだろう。
346デフォルトの名無しさん:2009/10/28(水) 22:27:26
>>339 ありがとうございます! endl;を抜いたらうまくいきました。 cout<<endl;とすべきでしたね

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

ちなみに、自分はさっきの引用が「正しい」とか「的を射ている」とは思ってないよ。
かみ合わないのを承知で引用している。
348デフォルトの名無しさん:2009/10/28(水) 22:33:57
>>321の条件ならfor文じゃなくてfor_each使うべきじゃね?
まぁ使いにくいんだけど
349デフォルトの名無しさん:2009/10/28(水) 22:57:08
>>346
あと、各case節の終わりでbreakしなくていいのかい?
350デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/28(水) 23:24:16
>>349 変なループが直りました! ありがとうございます
352デフォルトの名無しさん:2009/10/28(水) 23:36:43
まぁ普通はポインタやインデックスじゃなくイテレータを比較するなら!=が無難だろ
実装の中身が生ポインタならば、というような仮定はしたくないからな
353デフォルトの名無しさん:2009/10/29(木) 00:24:43
別の話になるけど
ちょっとイテレータを弄ろうとするとend()に++したり、begin()に--出来ないから
一々チェックを入れる必要が出てきて非常に面倒。でも普通のポインタも保証無いんだっけ?
354デフォルトの名無しさん:2009/10/29(木) 00:40:51
最初の前は見れないけど、最後の次は見れるんだっけか。
355デフォルトの名無しさん:2009/10/29(木) 00:43:41
>>353
3行目以降の意味が全くわからんけどとりあえずboost::nextとboost::priorでぐぐれ
356デフォルトの名無しさん:2009/10/29(木) 00:51:28
参照とポインタってどっちが速いんだろう
357デフォルトの名無しさん:2009/10/29(木) 01:07:16
バイナリになっちゃえば同じ。
そうでない処理系もあるかもしれないけど。
358デフォルトの名無しさん:2009/10/29(木) 01:11:34
参照だな。
参照とインライン展開だと、ひとつもメモリの生成しないですむが
ポインタは32bit か64bitの変数を生成するからな。
でも計測可能なほどかは微妙だが
359デフォルトの名無しさん:2009/10/29(木) 01:30:24
別に vector 使うなら iterator 明示的に使わないで v[j] みたいに
使ったっていいんだけどな。そっちの方がわかりやすいなら。
360デフォルトの名無しさん:2009/10/29(木) 02:22:07
>>350
リンク先を見ずに言うが、「的を射ている」と書いてるよ。
当を得ているとすべき、的を得るもあながち間違いとは言い切れない
という意見もあるけど、何で「的を得ている」についてのアンカーを?
361デフォルトの名無しさん:2009/10/29(木) 03:31:22
「ちなみに」と書いてあるから、ちなんだんだろう。
362デフォルトの名無しさん:2009/10/29(木) 05:02:17
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10026.txt

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

19行目のClsA(n1)は初期化子の書き方だと思うのですが、ClsAという変数はありません。
何をしているのでしょうか?
363デフォルトの名無しさん:2009/10/29(木) 05:14:35
NULLが入っていた場合対策では
364デフォルトの名無しさん:2009/10/29(木) 05:24:05
よくわからないので試してみましたが、エラーにはなりませんでした。

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

初期化子の方がまだわからないのですが、教えて下さる方いませんか?
367デフォルトの名無しさん:2009/10/29(木) 06:11:25
>>362
引数リストでの代入式はデフォルト引数の指定。
ClsA(n1) は基底クラスの初期化。
368デフォルトの名無しさん:2009/10/29(木) 06:45:57
理解できました

変数だけでなく、コンストラクタも初期化子で初期化できるんですね。
というと、基底クラスの関数も初期化できそうですね。
ありがとうございました。
369デフォルトの名無しさん:2009/10/29(木) 11:03:45
なんでNULLとかいってんだ?
>>362は納得できたからいいけど。
370デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 13:11:21
>>370
iはCTaskIterクラスのインスタンス。名前から察するに、CTaskListのイテレータなのだろう。
i.HasNext()はiが指しているlistに次の要素があるかどうかを返す関数だと推測する。
いずれにしろ、この際WinCrypt.hは関係なさそうだな。
372デフォルトの名無しさん:2009/10/29(木) 13:13:27
CTaskIter 型の変数 i を1個の引数 list で初期化している
for 文の最初で for (int i = 0; ..... ) のように変数宣言できることをご存じない?
それとも int i(0); のような書き方で変数が初期化できることをご存じない?
373デフォルトの名無しさん:2009/10/29(木) 13:24:02
>>371
VisualStudioの誤動作だったんですね。

>>371>>372
CTaskIter i(list)は、CTaskIterクラスの引数がCTaskListになっているコンストラクタを呼び出してたんですね。
いろいろ勘違いしていました。ありがとうございます。
374デフォルトの名無しさん:2009/10/29(木) 14:27:18
違う。コンストラクタの呼び出しじゃなくて、インスタンスの生成。
インスタンスを生成する途中でコンストラクタも呼び出すけど。
375デフォルトの名無しさん:2009/10/29(木) 14:28:57
誤動作って言うよりは誤操作って感じだな。
376デフォルトの名無しさん:2009/10/29(木) 14:31:58
>>374
そんなこと言うと、変数の初期化だとか変数の定義だとか、もっと言い換えできるぜ。
377デフォルトの名無しさん:2009/10/29(木) 14:32:54
コンストラクタの呼び出しとインスタンスの生成の違いは、言い換えってレベルじゃねーだろ
378デフォルトの名無しさん:2009/10/29(木) 14:35:38
>>377
「コンストラクタの呼び出し」と「インスタンスの生成」って、そんなに違うか?例えばどこが?
その違いは「インスタンスの生成」と「変数の定義」よりも大きいんだよね?
379デフォルトの名無しさん:2009/10/29(木) 14:36:02
CTaskIter(foo); // A
CTaskIter i(foo); // B

Aがコンストラクタ呼び出しの構文だろ?
Bが変数定義。
380デフォルトの名無しさん:2009/10/29(木) 14:37:38
>>378
この場合は自動インスタンスの生成だから、スタックからメモリを確保する作業が
含まれるな。
自動インスタンス生成と変数定義は変わらん。インスタンス生成と自動インスタンス
生成は違う。
381デフォルトの名無しさん:2009/10/29(木) 14:39:36
CTaskIter i(); // C
では、これは何でしょう?
382デフォルトの名無しさん:2009/10/29(木) 14:40:14
コンスラクタの呼び出しはplacement newを使う。
void* p; に対して、 CTaskIter* q = new(p) CTaskIter(foo);
383デフォルトの名無しさん:2009/10/29(木) 14:43:43
>>380
「自動」ってつければそうなるね。
後だしジャンケンっぽいけど、言いたかったことはわかったからまぁいいや。
384デフォルトの名無しさん:2009/10/29(木) 14:46:36
俺が>>381だが、誰か俺の引っ掛けクイズに反応してやってくれ
385デフォルトの名無しさん:2009/10/29(木) 15:00:11
正しくは、CTaskIter i(list)はCtaskIterクラスの引数CTaskListのコンストラクタを呼び出してインスタンス化し、
そのインスタンスの位置情報(使用しているアドレスの先頭)をCtaskIter型のiという名前で定義した変数に割り当てている。
ということでしょうか?
書いてて自分でよくわからなくなってきたんですが、おそらく間違っていないでしょう。
間違っていないで下さい。
>>384
CTaskIterクラスのデフォルトコンストラクタを呼び出してインスタンス化し、
そのインスタンスの位置情報(略)をCtaskIter型のiという名前で定義した変数に割り当てている。
ひっかけ・・・?
386デフォルトの名無しさん:2009/10/29(木) 15:03:30
有名な本のネタをそのままやってもな。
387デフォルトの名無しさん:2009/10/29(木) 15:03:40
>>385
ありがとう。救われた気持ちです。

iという名前で、CTaskIter型の戻り値を持ち、引数が無い関数のプロトタイプ宣言です。
388デフォルトの名無しさん:2009/10/29(木) 15:04:17
関数の宣言に見えるものは関数の宣言。
389これで満足した?w:2009/10/29(木) 15:04:45
>>381
関数宣言。
390デフォルトの名無しさん:2009/10/29(木) 15:08:05
T t = param;
じゃなくて
T t(param);
を使いたい時ってどんな時だろう。何かあった気もするけど。
391デフォルトの名無しさん:2009/10/29(木) 15:08:51
すまん、焦りすぎてて豪快に間違えた、忘れてくれ
392デフォルトの名無しさん:2009/10/29(木) 15:28:22
>>387
正解しちゃってすみませんと思いながら書き込んだのにこのざまですよ。
393デフォルトの名無しさん:2009/10/29(木) 15:42:52
Cみたいにvoidがないとプロトタイプ宣言と見做さない仕様ならこんなこともなかったのに……
とは言え、CTaskIter i(void);と書くのも気持ち悪いなw
394デフォルトの名無しさん:2009/10/29(木) 16:00:13
まぁ、Cのその仕様も単にANSI以前への互換性の為に一応、って感じみたいだしな
395デフォルトの名無しさん:2009/10/29(木) 18:21:56
C++を独学で覚えたくて本を買って勉強しはじめたばかりなんですが、質問があります。
BCCDeveloperを使ってDXライブラリを使う設定したはずなんですが、DXLib_lnitとDXLi_Endで未定議の関数とエラーがでます。
ググッて調べてみてもわからず...
どなたかアドバイスいただけないでしょうか。
396デフォルトの名無しさん:2009/10/29(木) 18:30:52
関数名が間違ってるだけじゃね?
397デフォルトの名無しさん:2009/10/29(木) 18:43:32
エラーメッセージはコピペしてくれないと質問時のタイプミスなのかもとから違ってるのかわからん
398デフォルトの名無しさん:2009/10/29(木) 18:46:32
>>395です。
みなさんありがとうございます。
今はコピペできないので帰宅したらエラーメッセージをコピペします。
399デフォルトの名無しさん:2009/10/29(木) 18:46:44
まあまあ、要領を得た質問ができるようなら、そりゃ既に初心者じゃないよ。
400デフォルトの名無しさん:2009/10/29(木) 19:05:56
初期化はこれが安全ってことでOK?
explicit widget(type);

widget w = widget(t);

401デフォルトの名無しさん:2009/10/29(木) 19:06:14
>>399
核心を突いてるなぁ
402デフォルトの名無しさん:2009/10/29(木) 19:07:24
>>400
explicit使うと下の書き方は出来なくなるだろ

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

widget w((widget(t))); が一番安全だな
403デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 19:12:27
>>403
//C++の場合
Test t1;
Test *t2;
t2 = &t1;

こう。
じゃないとメモリリークする
405デフォルトの名無しさん:2009/10/29(木) 19:15:55
>>402
VCとCODEPADでコンパイル通ったよ
最適化されてないとコピーコンストラクタ挟まれるっぽいけど・・・
406デフォルトの名無しさん:2009/10/29(木) 19:58:49
>>404
なぜnewした方だけがメモリリークするのでしょうか?
ポインタはnewしたしないにかかわらず、deleteしないとメモリリークしてしまうものだと思っているのですが・・・
今回の場合、Test *t2 = new Test();でもTest *t2;でもdeleteをすると実行値エラーが出てしまいます。
結局newしない書き方でもメモリリークするように見えるのですが、違うのでしょうか?
407デフォルトの名無しさん:2009/10/29(木) 20:08:20
javaのTest t1はc++のTest* t1。javaのTest t1 = new Test()はc++のTest t1* = new Test()に等しい。言語仕様の違い。考えることではなく覚えておくこと。
408お約束:2009/10/29(木) 20:12:51
これだからJava厨は……
409Java厨:2009/10/29(木) 20:20:11
ガベコレあるからメモリリークしても問題ないもんね
410デフォルトの名無しさん:2009/10/29(木) 20:21:26
>>409
何も考えずに shared_ptr 使えばいいよ
411デフォルトの名無しさん:2009/10/29(木) 20:31:34
>>395
とりあえず、こだわりが無いなら素直にVC++2008EEにした方がいいと思うが。
昔はWindowsで比較的素直に使えるフリーコンパイラがBCCくらいしか無かったが、
今はVC++EEがあって、ぶっちゃけBCCより遙かにまともに動くし、Windowsだと
VC++以外全く考えられてないのも普通だし。
412デフォルトの名無しさん:2009/10/29(木) 20:48:56
イテレータでvectorをfor文でbeginからendまで読んでいる途中でそのvectorにpush_backしても問題ないですか
413デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 20:56:19
>>412
push_backでイテレータは無効化される
push_backの後でイテレータを拾い直すならおk
415デフォルトの名無しさん:2009/10/29(木) 21:12:21
shared_ptrのコピーってポインタの十倍以上時間かかるのね
これからは生ポインタ引き数でいいところは生にしよう
416デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 21:16:31
v_obj.push_back(new Objects())のミス
418デフォルトの名無しさん:2009/10/29(木) 21:17:30
>>416
>>412 なの?
419デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 22:12:32
>>416
別にテンポラリのvectorを作って、ループの中ではテンポラリの方に追加しておいて、
ループを抜けてから連結。
あと、激しくメモリリークの予感。
421デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/29(木) 22:23:54
>>416
生ポインタをコンテナに突っ込むのはやめれ、どうしてもというならshared_ptr を使うと幸せになれる
423デフォルトの名無しさん:2009/10/29(木) 23:28:10
STLは糞。全部自分で管理するしくみを作った方が早い。
424デフォルトの名無しさん:2009/10/29(木) 23:37:25
>>419
やりたがってることがイマイチわからないけど、そのコードから受け取れるものだけで言うなら、
ループ内でこうすればいいんじゃないの?
if (ある条件) {
  v_obj.push_back(new Objects());
  break;
}
今回の君のコードからは、一つでも「ある条件」を満たすものを見つけたら
もうその時点でループは用済み、という状況がうかがえるので。

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

もう他に新事実が無いというのなら、for文の前にint count = 0;でも置いて、ループ内で
if (ある条件) {
  ++count;
}
として、あとからcount個の要素を追加すればいい。
427デフォルトの名無しさん:2009/10/30(金) 00:09:07
粘着うぜ
428デフォルトの名無しさん:2009/10/30(金) 00:15:53
>>415
shared_ptrのconst参照という手もあるよ。

>>421
メンバ変数もshared_ptr使っておくほうがいい。デストラクタでdeleteだと抜けがある。
429デフォルトの名無しさん:2009/10/30(金) 01:02:22
>>421
リークする、と断言したのは、
1:Test t1;
2:Test *t2 = new Test();
3:t2 = &t1;

としたときに2でヒープに確保した領域をdeleteできなくなるから。
430デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 07:32:21
純粋仮想関数を持つ抽象クラスはインスタンス化できませんが
デフォルトコンストラクタをprotectedとして宣言、定義して、インスタンス化拒否を明示するのか
コンパイラが自動的に生成するのを用いるのか、どちらが妥当なんでしょうか。
432デフォルトの名無しさん:2009/10/30(金) 07:40:35
>>431
なんでそんな余計なコードを書こうかなんて思うの?
433デフォルトの名無しさん:2009/10/30(金) 10:04:21
>>428
shared_ptrは一般的なんですね。
レスポンスが少し気になるところですが、使っておきます。

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

>>430
昨日は少し混乱していました。
Testクラス内にメンバ変数がなくても、newした段階で最低1byteは使用するため、結局deleteできなくてリークすると。
今度こそ完全に理解しました。
434デフォルトの名無しさん:2009/10/30(金) 10:10:52
>>433
大丈夫、未だ勘違いしている。
生成したインスタンスのポインタを格納しているポインタ変数に、他の値を格納してしまうと
単純に、最初のインスタンスのポインタが失われるのであってデストラクタも何も走らない。
まさに、>408だな。
435デフォルトの名無しさん:2009/10/30(金) 10:37:19
なんと!
デストラクタ内で適切に処理しておけば問題ないと考えていましたが、書き方によってはリークするんですね。
ヒープに確保した領域が行方不明になるような書き方してたら
コンパイルエラーにしてくれればいいのにというのは甘えですか?
436デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 11:02:31
書き方によってはリークするのではない。
適切に書くことによってリークしないのだ。
--
Test * func() {return new Test();}
--
void someOtherFunc()
{
func();
}
--
これでもリークするわけだが、例えばfunc()が別のコンパイル単位にあるとしたらどうやって検出しろと?
438デフォルトの名無しさん:2009/10/30(金) 13:07:17
3行目はいったい何をしているのでしょうか?
関数のプロトタイプ宣言のように見えますが
そうすると戻り値がvoidで関数の名前がInitで引数は無し?*の意味は・・・?
.h.cppのどちらにもInitを実装しているような箇所は見当たらないし
3行目はどうゆう意味なのでしょうか?
439デフォルトの名無しさん:2009/10/30(金) 13:10:32
失礼しましたソースです。
//Common.h
1: struct STAGE {
2:  const wchar_t* Name;
3:  void (*Init)();
4:  int TopTime;
5: };
440デフォルトの名無しさん:2009/10/30(金) 13:13:27
関数ポインタです。
441デフォルトの名無しさん:2009/10/30(金) 13:14:16
>>438-439
引数も戻り値もない関数へのポインタ。
わからない単語はぐぐればいいと思うよ
442デフォルトの名無しさん:2009/10/30(金) 13:14:21
>>439
型がよく判らないときは、括弧に注目。この場合、Initに*がついていてそれが括弧で拘束されている。
つまり、Initはポインタ変数であることが判る。
それが指しているものは、void ()()となるので、戻り値のない、引き数もない関数となる。
要は、void func()という関数と同じ型の関数ポインタであるInitの宣言。
443デフォルトの名無しさん:2009/10/30(金) 13:36:04
少し調べてみました。
メモリ領域はコード、データ、ヒープ、スタックの4種類にわかれている。

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

構造体の中に関数ポインタを入れておくと、より汎用的なコーディングができる事がある。
助かりました。
444デフォルトの名無しさん:2009/10/30(金) 13:39:29
>>443
ヒープに確保されないオブジェクト、つまり自動変数とかはスタックに確保されて、
スコープアウトしたらデストラクトされる。
445デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 14:01:46
>>445
*が付いてなければおよそポインタではない
まだ何か勘違いしてない?
447デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 14:37:27
仮想関数テーブルとか考えると危険な…いや、なんでもない

よく分かってないことは書かないことにしましょうか
449447:2009/10/30(金) 14:47:30
>>448
vtableは使ってないから説明してない。

仮想関数のオーバーライドの説明だけど、
C++の上書きオーバーライド(virtual function)は、大雑把に言って関数ポインタを上書きすることで実現している。
そのためにはクラスのメモリのどこかに関数ポインタのリストを持つためのポインタを持つことになる。
基本的にこれはメモリを操作してかきかえる類ではないのであることを知っていればいい。
で、仮想関数を持ったクラスをsizeofをすると関数ポインタのリストのポインタ変数のサイズ分増分して返ってくる。
450デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 15:29:09
1.ClsA *aはポインタ型なんだから、ClsAの継承クラスのインスタンスならどれでも受け入れられる。
2.受け入れるオブジェクトの型は、ユーザーの入力などにより動的(実行時)に変化する。
以上より仮想関数テーブルが必要になる。

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

あと、オーバーライドの話。
C++のオーバーライドはvirtualをつけなかったら、上書きされない。よって、vtableも生成されない。
つまり、基本的には、そのクラスで宣言されたそのメンバ関数が呼ばれる。
virtualをつけてオーバーライドされる前提のメンバ関数は継承先で上書きすることができる。
virtualの上書きされた関数は、基底でも上書きされた関数を呼ぶ。
もちろんインスタンスは実装したクラスのインスタンスじゃないといけないけども。
453デフォルトの名無しさん:2009/10/30(金) 15:43:11
ちょっとした違和感を感じたんだが、
>>450 の言うデータ領域って、たとえばimmutableな文字列定数とかを格納するところかな??
static constの変数とか。
454デフォルトの名無しさん:2009/10/30(金) 15:59:33
何かもう、ネイティブコードでどう実装されてるかから説明した方が早い気がしてきた
455デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/30(金) 17:10:43
>>455
C++におけるメジャーなメモリ領域は2つ。
一つはスタックと呼ばれる領域。一つは、ヒープと呼ばれる領域。
スタックは宣言したときに確保されてスコープが終了したら破棄されることを約束された領域。
ヒープはメモリのプールで必要なときに確保して不要になったらユーザの責任で開放する。資源は有効に。

で、コード領域やデータ領域というのはコンパイラやOSの最適化によって発生した領域。
たぶん、データ領域は何度も参照されるような定数データを効率よく回すための機構で基本的に書き込み禁止。
で、たぶん、コード領域はプログラムコード自身をOSがロードした領域。
なので、後の2つはC++の仕様外だと思う。
457デフォルトの名無しさん:2009/10/30(金) 18:40:54
>>456
静的記憶期間(static付きやグローバル変数など)のオブジェクトの置き場なのだから、
データ領域はスタック・ヒープと同列に扱おうよ。
規格書でも(言葉は違うけど)その3つの概念は出てくることだし。
458デフォルトの名無しさん: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が表示されます。
というのは、仮想関数テーブル(=関数ポインタのようなもの)が仕事をしてるから。
とりあえずコメントにも補足書いたけど、以上が仮想関数テーブルが必要な理由。
http://codepad.org/uuPlC3eO
459デフォルトの名無しさん:2009/10/30(金) 20:26:13
>>456
>>457も言ってるけど、スタックとヒープと静的の三つとした方が。
静的記憶は普通に読み書き可能なことが多いんじゃないかな、x86では。dsセレクタで
アクセスされるようなセグメントに配置するのが一般的な気がする。
リードオンリーの定数はむしろ、コンパイル時点で埋め込んじゃう気がするし。
460デフォルトの名無しさん:2009/10/30(金) 20:47:25
スタックもヒープも物理的には同じだぞ。
コンパイル時に固定サイズの領域を割り当てるのがスタック。
スタック不足になるのは、メモリが足らないからではなく
予測以上に初期の固定メモリを使い切ったため。
物理的には、スタックもヒープも違いはないので、
多くメモリ確保するなら動的=ヒープがいい。
461デフォルトの名無しさん:2009/10/30(金) 21:00:19
>>456>>457>>459>>460
今の私の認識と、説明していただいたメモリ領域の説明がだいたい一致するので
メモリ領域に関しては大丈夫そうです。

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

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

今日1日でc++に対する理解度がだいぶ深まった気がします。
462デフォルトの名無しさん:2009/10/30(金) 21:05:38
aa
463デフォルトの名無しさん:2009/10/30(金) 21:08:23
でもヒープ確保には、OSとのやりとりがあって、生成に時間食うがな。
スタックは、はじめに確保した領域を使い回すだけだからOSとのやりとりはなく
高速。
464デフォルトの名無しさん:2009/10/30(金) 21:11:40
動作速度に関しては、
スタック ヒープに違いはないが
生成と破棄に関しては違いが出るってこと。
長いこと(10秒以上とか)保持するなら、
生成コストは無視できるから
安定性のためヒープを使う方が良いな。
465デフォルトの名無しさん:2009/10/30(金) 22:07:18
待て待て、スタックとヒープは実装原理が全く違うがな。適当言うんじゃない。
一般的なスタックは、pushするかスタックポインタを移動させることで積み上げて、
破棄する時はスタックポインタの移動だけで終わるから、ヒープに比べたら圧倒的に
確保も解放も高速だぞ。
466デフォルトの名無しさん:2009/10/30(金) 22:08:28
確保と解放は速度差があるが、確保されたメモリを使う分には同じ速度だな。
467デフォルトの名無しさん:2009/10/30(金) 22:26:53
>>465
確保方法に違いはあっても、どちらも同一の(実)メモリつかうんだよ。
OSに問い合わせるか、C言語が管理している領域に問い合わせるかだけ。
スタックでさえ仮想メモリに移動することもある。
OSや他のアプリからみれば特殊な物ではない。
468デフォルトの名無しさん:2009/10/30(金) 23:41:54
とりあえず確保解放の速度が圧倒的に違うのは確実だけどな、スタックとヒープじゃ。
>>466がほとんどの環境で正解。
469デフォルトの名無しさん:2009/10/30(金) 23:44:38
圧倒的に違うといっても総実行時間の何%だよ

以下ループ
470デフォルトの名無しさん:2009/10/31(土) 01:50:36
ボトルネックに突っ込んだら恐ろしく違うだろうな
471デフォルトの名無しさん:2009/10/31(土) 03:11:39
まぁ環境によっていろいろあるってことでFA
472デフォルトの名無しさん:2009/10/31(土) 03:48:03
dllを作っているのですが
デバッグでは作成できて、リリースしてビルドすると
ライブラリ ***testdll.exp を作成中
LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。
ビルドログは "***" に保存されました。
testdll - エラー 1、警告 0

と表示されてできません
どうすればできるのでしょうか・・・・・
473デフォルトの名無しさん:2009/10/31(土) 03:52:30
>>472
「エントリーポイントを定義しなければなりません」

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

これぐらいの推測ができないようじゃ、前途多難だな。
474デフォルトの名無しさん:2009/10/31(土) 11:53:20
enumとかstatic constの定数は外のクラスに見せないならクラススコープでprivateで定義するのが良いんですよね?
475デフォルトの名無しさん: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デフォルトの名無しさん:2009/10/31(土) 12:34:41
vector::size()では何か不都合でもあるの?
477デフォルトの名無しさん:2009/10/31(土) 12:42:59
>>475 です
vector::size() をこのように使っているのですが
これでは、イテレータを渡しても、当然のことですがエラーになってしまいます、
なんとかイテレータを渡して、そのコンテナのサイズがわからないものかと思案しています。
template <class Container> inline
size_t Size(const Container& c)
{ return c.size(); }
478デフォルトの名無しさん:2009/10/31(土) 12:55:04
要素へのポインタを所有しているコンテナを特定する手段があるなら可能
479デフォルトの名無しさん:2009/10/31(土) 13:02:22
>>470
ボトルネックの個所で
スタックだろうがヒープだろうがメモリの確保解放するコード書くのは論外だろう
480デフォルトの名無しさん:2009/10/31(土) 13:09:48
>>479
秒間一万回程度の半端なボトルネックだと、スタックかヒープかで致命的な事態に
なるだろうな。

まぁ、違いを知った上で、大差無いと判断したところで使うのは最初から問題無い。
「違わない」と断言するのは激しく問題があるってだけ。カーネルに落ちる場合は
スタックの数万倍も重いことがある訳で。
481デフォルトの名無しさん:2009/10/31(土) 13:10:09
>>478 thx です
関数オブジェクトを作っていて、引数が多くなってしまい
なんとか、減らせないものだろうかと思い質問したしだいでした
要素へのポインタを所持しているコンテナを引き渡すのなら、
要素数を引き渡すだけのことなので、同じくらいのコストがかかりそうで
あききらめますが、要素へのポインタを所持しているコンテナを引き渡して
要素数を求める方法へ関心があります、単純な実装例をご教示願えませんか。
482デフォルトの名無しさん:2009/10/31(土) 13:29:21
c.size()
483デフォルトの名無しさん:2009/10/31(土) 13:45:50
>>477
イテレータのペア(開始と終端)を取る関数オブジェクトなら
std::distance(it1, it2) で [it1-it2)間の要素数が求められるよ。
484デフォルトの名無しさん:2009/10/31(土) 14:20:44
>>475,477,481
ひとつのイテレータからコンテナの要素数を求める一般的な方法はないよ。
実装依存の機能でそういうのがあるか、自分で実装すれば可能。
beginとendがあるなら>>483のでいける。
485デフォルトの名無しさん:2009/10/31(土) 18:59:20
>>484ありがとう
>実装依存の機能でそういうのがあるか、自分で実装すれば可能。
もし仮に実装するなら、どんな感じになるのでしょうか?
まずは、イテレータのアドレスを取得しなければならないのはわかるのですが
それ以降の展開が想像できません、向学のために概略だけでも教えてもらえないでしょうか。
486デフォルトの名無しさん:2009/10/31(土) 19:11:13
>>485
MinGW だとイテレータはコンテナのアドレスを持ってるようだ
487デフォルトの名無しさん:2009/10/31(土) 20:54:21
そもそもイテレータ渡ししてるのに本当に要素数が必要なのかから考えるべきな気がする。
488デフォルトの名無しさん:2009/10/31(土) 21:51:29
>>485
元のイテレータの派生クラスかラッパークラスを作って、そいつに要素数か親コンテナのポインタを持たせる。
しかし、親コンテナの要素数が必要な処理ってどんなだ?
コードをさらしてみる気はないか?
489デフォルトの名無しさん:2009/10/31(土) 21:56:41
技巧する必要なし
元のをを渡せよ。
490デフォルトの名無しさん:2009/10/31(土) 22:09:55
引き数へらしたいならレンジイテレータでもつかってコンテナまるごと渡せよ
491デフォルトの名無しさん:2009/11/02(月) 21:07:20
演算子のオーバーライドって一般企業でも使ってますか?
パッと見どうゆう動作をするのかわからないから、危険な香りがするのですが。
例えば、タスクシステムを使っていて、とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
一見メモリリークするコードに見えます。
492デフォルトの名無しさん:2009/11/02(月) 21:13:44
>>491
基本的にそういうことはドキュメントに書いておくべきことじゃないかなぁ。
読まない人もいるみたいだけどね。読みやすいドキュメントって言うのもむずかしいけど。
493デフォルトの名無しさん:2009/11/02(月) 21:13:49
>>491
何を使っても酷いことになる人はどこにでもいるよ
494デフォルトの名無しさん:2009/11/02(月) 21:28:12
>>491
そんな事言ったらoperator+をオーバーロードしてマイナスの動作を
させるへそ曲がりな事だって出来るぞ

仕様書でちゃんと最初に決めとけ
495デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/02(月) 22:15:04
>>491
基本的には使わないだろう。企業に限らず。
でも、例えば多倍長整数クラスとか、有理数クラスとか、ベクトルクラスとかを
作るなら、operator+を定義しても恐らく誰も間違わない。そういう場合は使う
方が楽という判断も十分有力だし、それでも使わないという判断もやはり有力。
497デフォルトの名無しさん:2009/11/02(月) 22:17:08
まぁ、暗黙の変換なんかと同じだな。
無闇やたらと使うのは糞設計だが、完全排除すれば良設計というものでもない。
498デフォルトの名無しさん:2009/11/02(月) 22:28:05
微妙なら()つけろよ。簡単のために公開しない関数内部で使うなら別に良いだろ。
499デフォルトの名無しさん:2009/11/02(月) 23:31:40
>>497
俺は argument 一つの constructor はやっぱり explicit 付けてる。
operator overloading の方はたまに使う時がある。
500デフォルトの名無しさん:2009/11/03(火) 03:04:26
スマポなんかは暗黙の変換に対応しないと微妙
501デフォルトの名無しさん:2009/11/03(火) 06:28:54
>>491
× オーバーライド
○ オーバーロード

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

> とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
> 一見メモリリークするコードに見えます。
具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?
502デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/03(火) 14:58:30
できました。ありがとうございました。
505デフォルトの名無しさん:2009/11/03(火) 15:54:29
そういや可変長引数長い事使ってないなあ
リハビリしとかなきゃ
506491:2009/11/03(火) 18:00:50
>>492-497
多倍長整数クラスの+のように、直感的にわかるような動作をするものなら演算子のオーバーロードをしても良いが
基本的に多用するものではないということですね。


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

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


一般的な演算子のオーバーロードに対する考えが聞けて、とてもためになりました。
ありがとうございます。
507デフォルトの名無しさん:2009/11/04(水) 12:21:15
>>506
業種によっても違うんじゃないかな。
私のところは画像処理や数値計算関係なので座標の足し算とかベクタの掛け算なんかが
頻発するので演算子オーバーロードはあるとないとじゃ大違いだから。
508デフォルトの名無しさん:2009/11/04(水) 16:41:27
ベクトルの掛け算も演算子オーバーロードしちゃうのか…
内積にすんのかな
509デフォルトの名無しさん:2009/11/04(水) 16:48:04
スカラ倍のことじゃないの
510デフォルトの名無しさん:2009/11/04(水) 17:07:21
内積、スカラ倍両方オーバーロードするのもありだな。
いずれにせよ、ベクトルや行列使った数値計算とかは
オーバーロードしないとコードが読めなくなるからリスクとの
トレードオフとして悪くないと思う。
511デフォルトの名無しさん:2009/11/04(水) 17:18:02
インラインアセンブラと組み合わせれば演算子でSIMDも可能
って考えるとなんか夢が広がるような気がするよね
実際には関数呼び出しだって同じなんだが、表記的に
高水準(抽象的)・低水準(具体的)の混在具合が脳汁出そう
512デフォルトの名無しさん:2009/11/04(水) 17:59:50
ベクタ×ベクタは演算ライブラリによっては内積だけど、
演算ライブラリによっては敢えて用意していないね。
それでもスカラ積があるだけでも随分違うけど。
513デフォルトの名無しさん:2009/11/04(水) 21:19:06
「絶対に内積だろ」とは言い切れないし、スカラ積だけ対応するのが個人的には好み
だけど、内積でも別に文句言うほどじゃないかな
514デフォルトの名無しさん:2009/11/04(水) 21:55:01
スカラ積って内積じゃないの
515デフォルトの名無しさん:2009/11/04(水) 21:59:47
iostreamやBoostに見られるような「Cの文脈からかけ離れた演算子オーバーロード」
は、実際使ってみると割と平気だったりするんだよな。
ただ、見慣れない問題に直面する可能性も高いから、やっぱりお仕事だと微妙かな。
boost::formatとか激しく便利ではあるんだけど。
516デフォルトの名無しさん:2009/11/04(水) 22:57:49
>>514
数Bやり直せw
517デフォルトの名無しさん:2009/11/04(水) 23:06:14
>>516
おまえこそやり直せ
518デフォルトの名無しさん:2009/11/04(水) 23:14:19
小学生ktkr
519デフォルトの名無しさん:2009/11/05(木) 03:19:55
スカラー積=内積
ベクトル積=外積
520デフォルトの名無しさん:2009/11/05(木) 08:51:58
>>503
va_endわすれてるぞ
521デフォルトの名無しさん:2009/11/05(木) 09:18:30
スカラー積ってスカラ倍のことじゃないの?
522デフォルトの名無しさん:2009/11/05(木) 09:24:31
もうその話題は終わり
523デフォルトの名無しさん:2009/11/05(木) 09:48:19
namespace Hello
{
class A;
};

namespace World
{
class B;
};

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


環境はwinXP x86 VC++ 2008Expressを使ってます。
524デフォルトの名無しさん:2009/11/05(木) 10:01:37
どうせ打ち間違い
523自体は正しい
525デフォルトの名無しさん:2009/11/05(木) 10:03:15
ていうかエラーメッセージ書けって
526デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/05(木) 11:10:32
>>526
namespace Helloが閉じていない。
# まぁ、想定の範囲内だな。
528デフォルトの名無しさん:2009/11/05(木) 11:11:50
Hello::
まで書くとvisual studio のインテリセンスがWorldや
ヘッダーに書いた他のnamespaceを全部含んでしまっているように表示します。
World::やその他のネームスペースからはHelloを参照することはありません。
529デフォルトの名無しさん:2009/11/05(木) 11:14:22
;が抜けているのに気づけない間抜けであったか。
530デフォルトの名無しさん:2009/11/05(木) 11:14:30
本当だ。すいません小さなミスでした。
531デフォルトの名無しさん:2009/11/05(木) 11:32:52
VCなんですけど
floatとdoubleはどっちが速いですか?
532デフォルトの名無しさん:2009/11/05(木) 11:39:13
>>531
一概には言えませんが、doubleで組んで速度に不満があったら両方実測して比較すればよいでしょう。
533デフォルトの名無しさん:2009/11/05(木) 11:43:23
floatが速いよ
昔は、doubleに変換されるという説もあったが、いまは直に計算する。
534デフォルトの名無しさん:2009/11/05(木) 11:45:13
特に配列に格納すると、メモリ呼び出しが半分のサイズですむから
計算だけではなく、メモリサイズと呼び出し時間が短縮できる。
535デフォルトの名無しさん:2009/11/05(木) 11:52:00
フロートがSSEで二倍速い
536デフォルトの名無しさん:2009/11/05(木) 12:10:08
namespaceって;必要だっけ?
537デフォルトの名無しさん:2009/11/05(木) 13:15:38
必要じゃないことはないですよ
538デフォルトの名無しさん:2009/11/05(木) 16:20:32
floatにしてみます。
539デフォルトの名無しさん:2009/11/05(木) 16:43:18
floatは有効桁数がIEEE754では6桁しかないよ
だから用途が限られる
画面座標とか
540デフォルトの名無しさん:2009/11/05(木) 17:46:27
配列のインデックスは符号無しですか?
541デフォルトの名無しさん:2009/11/05(木) 18:05:17
厳密に言えば、いいえ
542デフォルトの名無しさん:2009/11/05(木) 18:58:15
ポインタの計算だからマイナスもある
543デフォルトの名無しさん:2009/11/05(木) 19:14:31
まず配列のインデックスの定義をだな
544デフォルトの名無しさん:2009/11/05(木) 20:29:16
namespace は ; いらないよね??
class は ; いるけどさ。

ていうか namespace {} に ; つけないで普通に使っているんだが…
545デフォルトの名無しさん:2009/11/05(木) 20:35:52
クラス定義は文だから;が必要で名前空間はスコープだからいらない。たぶん
546デフォルトの名無しさん:2009/11/05(木) 20:46:17
確かポインタ間の距離はptrdiff_t型で符号あり整数じゃね?
547デフォルトの名無しさん:2009/11/05(木) 21:08:49
struct foo { int bar; } buzz;
class foo { int bar; } buzz;
namespace foo { int bar; } buzz; // ← これだけ明らかにおかしく見えれば大丈夫
548デフォルトの名無しさん:2009/11/06(金) 10:11:30
>526がセミコロンが抜けているのは事実だが、>527は間違い。

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

ポインタ演算については>542、>546の通りだが、>543の言うように「インデックス」が何を指しているかが問題。
549デフォルトの名無しさん:2009/11/06(金) 13:20:14
C/C++でZipファイルの追記したいのですがいいライブラリありますか。
DLL使うと、中間ファイルを生成してから追記するので遅いです。
100Mのzipファイルならそれをopenして追記したいです。
550デフォルトの名無しさん:2009/11/06(金) 13:31:39
tarならできるだろうけどzipはむりじゃね
551デフォルトの名無しさん:2009/11/06(金) 13:33:27
zlibは圧縮は出来るけど、書庫のフォーマットには対応してないですよね?
552デフォルトの名無しさん:2009/11/06(金) 13:36:35
>>550
このwebサイト収集するやつは、zip追記してます。
でもC言語でやってないです。
http://www.unixuser.org/~euske/python/webstemmer/index-j.html
553デフォルトの名無しさん:2009/11/06(金) 14:01:44
>>550
外人がいいやつ作ってくれました。
これで追記出来ました。

http://www.wischik.com/lu/programmer/zip_utils.html
554デフォルトの名無しさん:2009/11/06(金) 18:19:57
>>548
> doubleを使っておくのが無難。

それは微妙。どっちが向いてるのか考えるべき。ちょっと考えれば大体正解が選べるし。
例えば、APIがfloatを要求してるような場合はfloatが無難。
floatは精度に注意、floatとdoubleを無駄に混在させるのはアホ、SSEでは圧倒的に速度
が違う、SSE使わないならほんの僅かにfloatが速い、くらいであとは自己判断かな。
555デフォルトの名無しさん:2009/11/06(金) 20:10:20
混在を避けるのは鉄則。doubleの演算速度よりも、float⇔doubleの変換の方がよっぽど遅い。
556デフォルトの名無しさん:2009/11/06(金) 20:12:50
>>555
え?
557デフォルトの名無しさん:2009/11/06(金) 20:14:14
下のようにvectorの入った構造体があります。
typedef struct
{
  std::vector<int> foo;
  std::vector<float> bar;
}
HOGE;

これを値渡しすると、各vectorのコピーコンストラクタはちゃんと呼ばれるんでしょうか。
558デフォルトの名無しさん:2009/11/06(金) 20:17:36
>>556
それも環境次第だとは思うけど、少なくとも整数の符号拡張みたいに単純にはいかない。
フォーマットの変換が必要だから。
x86のFPUだと相当なコストがかかるけど、SSEなんかだとどうかは知らない。
559デフォルトの名無しさん:2009/11/06(金) 20:24:57
>>557
ヒント : C++では基本的にclass と struct は同等の扱い
デフォルトのprivateとpublicが違うだけ
560デフォルトの名無しさん:2009/11/06(金) 21:13:15
>557
ヒントより短い答え:呼ばれます。
561デフォルトの名無しさん:2009/11/06(金) 22:03:45
そんな巨大になりそうなもの値渡しして欲しくないな
562デフォルトの名無しさん:2009/11/06(金) 22:24:42
大丈夫
俺のちんこよりは小さいから
563デフォルトの名無しさん:2009/11/06(金) 22:50:31
>>553
よく読めてないけど、オンメモリで展開、追加、圧縮をやってるんじゃないの?
564デフォルトの名無しさん:2009/11/06(金) 23:55:53
>>561
新人「大丈夫ですよ先輩。sizeofで見たらたった80バイトです」
565デフォルトの名無しさん:2009/11/07(土) 00:00:20
ああそうだ、俺のコンパイラは構造体に巨大な配列を入れて
値渡しすると馬鹿みたいにpushの荒らしになる

rep movsが使えないのはpushが逆順になるからだろうな
それなら簡単なループ組んで転送すればいいと思うのに
pushを配列数分吐くもんだからexeが巨大になって馬鹿みたい
566デフォルトの名無しさん:2009/11/07(土) 00:00:29
>>563
追記は新規に作ったファイルだけだった
既存ファイルには追記できなかった
追加しようとしたらデータ初期化されたよ
567デフォルトの名無しさん:2009/11/07(土) 00:09:08
zipフォーマットここに書いてあるから追記自分でやってみるか

http://www.tnksoft.com/reading/zipfile/arczip.php
http://www.tnksoft.com/reading/zipfile/nonarc2.php
568デフォルトの名無しさん:2009/11/07(土) 00:17:40
もう一度いうけど、tarならできるだろうけどzipは無理だと思う。
無圧縮zipならできるかな
569デフォルトの名無しさん:2009/11/07(土) 00:20:34
100個のファイルを圧縮したzipを用意して、それを展開して、一つファイルを増やして、
圧縮して、バイナリ比較して、「追記」が実現可能かどうか見てみたら。
無圧縮でもそれやってみたら。
570デフォルトの名無しさん:2009/11/07(土) 00:30:05
駄目な理由はなんだ>
絶対出来るはず
571デフォルトの名無しさん:2009/11/07(土) 01:25:11
rep movsとか最近のコンパイラは間違っても使わないような
572デフォルトの名無しさん:2009/11/07(土) 01:39:47
サイズ重視のコードなら使う
573デフォルトの名無しさん:2009/11/07(土) 02:11:52
俺のコンパイラは断りもなくmemcpy呼んでるな。構造体の初期化には勝手にmemset使うし。
574デフォルトの名無しさん:2009/11/07(土) 02:18:32
>>573
それで何か問題でも?
575デフォルトの名無しさん:2009/11/07(土) 02:23:41
>>571
変数の初期化に使われているよ
特に配列だと間違いなく出てくる
576デフォルトの名無しさん:2009/11/07(土) 02:34:11
そもそも構造体の値渡しが必要な状況ってどんなの?
ポインタや参照が使えない状況ってのが思い浮かばない。
577デフォルトの名無しさん:2009/11/07(土) 02:55:20
逆に考えるんだ。ポインタでは困る場面なんだよ。
それが必要な状況?それは↓
578デフォルトの名無しさん:2009/11/07(土) 03:36:48
ぬるぽ
579デフォルトの名無しさん:2009/11/07(土) 06:46:06
再帰させるときなんかたまに使うけどね。
580デフォルトの名無しさん:2009/11/07(土) 07:46:51
RECT rc = { 0 };
とかってありなの?

VCだと中の変数ゼロになるんだけど
581デフォルトの名無しさん:2009/11/07(土) 08:04:27
そうだよ
582デフォルトの名無しさん:2009/11/07(土) 08:11:19
zip64の追記つくってくれ
583デフォルトの名無しさん:2009/11/07(土) 08:15:20
後半の情報フォーマット部分を追記データで
書き換えれば理論的には可能なはずなんだ。
でも正しいセットの仕方が判らない。
584デフォルトの名無しさん:2009/11/07(土) 11:04:21
zipの仕様は公開されてるからそれに従って書けばいいと思うよ
http://www.pkware.com/documents/casestudies/APPNOTE.TXT
585デフォルトの名無しさん:2009/11/07(土) 11:15:53
ファイルを個別に zip 圧縮してから tar でまとめるとか…
586デフォルトの名無しさん:2009/11/07(土) 13:03:04
つか
追記くらいライブラリないのかよ
587デフォルトの名無しさん:2009/11/07(土) 13:18:34
zipの構造はおおまかに

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

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

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

ちなみにJavaScriptで無圧縮zip作るひとがいるくらいだから
圧縮をzlibですればzipのフォーマット自体はそれほど難しくない
588デフォルトの名無しさん:2009/11/07(土) 13:39:27
作ってクレオ
589デフォルトの名無しさん: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()
590589:2009/11/07(土) 14:13:08
実際に400M、50万ファイルのZIPファイルで実験したから間違いない。
コピーしたり展開したら時間かかるが、追記はコピーより速くできた。
591デフォルトの名無しさん:2009/11/07(土) 14:49:15
c言語の話題かぁ?
592デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/07(土) 16:32:20
>>591
Zipは追記できないという説に対して
ZipもZip64も追記できたと言うこと
594デフォルトの名無しさん:2009/11/07(土) 17:13:59
>>592
嫌だったらC++使うなカス
595デフォルトの名無しさん:2009/11/07(土) 17:14:59
VCで複数のソースファイルがある場合、プリプロセッサの処理順てどこで定義されているの?
例えば aaa.h, bbb.h, ccc.h
の3つが互いにインクルードしている場合、
全体で使用できるためにはどのファイルで定義すればいいのかわからん
596デフォルトの名無しさん:2009/11/07(土) 17:21:08
#includeした順に決まってるだろ
597デフォルトの名無しさん:2009/11/07(土) 17:21:08
何を言いたいのかわからないけど、
#includeはそこにテキストがそのまま展開される。

#include "aaa.h"
#include "bbb.h"
#include "ccc.h"

なら aaa.h が真っ先に展開される。
しかし、非ローカルなスタティック変数の初期化順とかいう話になるのなら
それはそれは難しいことに。

違ったかな。ほほほ。
598デフォルトの名無しさん:2009/11/07(土) 17:30:31
結局、「暗黙の初期化順に依存するな」ってことね。
599デフォルトの名無しさん:2009/11/07(土) 18:04:33
#define #undef みたいにusing namespaceを無かったことにできないもんでしょうか
600デフォルトの名無しさん:2009/11/07(土) 18:08:02
逆に、using namespace を使うところだけスコープを切ればいい。

{
using namespace boost::lambda;

// ここでbindとか_1とか使う
}
// ここでは using namespace は無効
601デフォルトの名無しさん:2009/11/07(土) 18:10:36
みんなはusing namespace std;ってグローバルにおいちゃう派?おいちゃだめ派?
602デフォルトの名無しさん:2009/11/07(土) 18:11:45
Google Coding Standardsではらめってなってた。
603デフォルトの名無しさん:2009/11/07(土) 18:12:27
チーム全員がstd名前空間の全内容を把握しているなら
グローバルでもいいんじゃないですかね。
604デフォルトの名無しさん:2009/11/07(土) 18:34:43
同一プロジェクトでstd::stringとhoge::stringが混在したらそっちのほうがいやじゃない?
だからまとめて共通ヘッダに入れてグローバルusingしてる
605デフォルトの名無しさん:2009/11/07(土) 18:37:12
いちいちstd::stringとかhoge::stringと書けばいいじゃない。
606デフォルトの名無しさん:2009/11/07(土) 18:43:32
>>605
結構めんどくさくね?
607デフォルトの名無しさん:2009/11/07(土) 19:01:18
WinAPI使ってるともっと長くてどうしようもない名前がわらわら出てくるから
あんまり気にしたことないなぁ。って言うか末尾にSEXついてるの多すぎ。
マイクロソフトの技術者はどんだけ欲求不満なのか、と。
608デフォルトの名無しさん:2009/11/07(土) 19:01:19
入力補完で切るエディタなら
std::と打ったほうが楽
609デフォルトの名無しさん:2009/11/07(土) 19:06:03
>>607
sexわろたw
気にしたことなかったけど確かにそうだな
610デフォルトの名無しさん:2009/11/07(土) 19:16:11
>>576
インライン展開を期待するときなんか、あえて構造体の値戻しを使ったりする。
611デフォルトの名無しさん:2009/11/07(土) 19:41:39
WIN32APIのSendMessageを使用する時、引数のwparamを文字列で渡す方法ってある?WinXPが環境です
612デフォルトの名無しさん:2009/11/07(土) 19:43:12
とりあえず、グローバル変数の初期化順序に関しては、チューリングマシンの停止問題
みたいに定義不可能な面があるから、依存するな、とかEffectiveC++に書いてあった
ような気がしなくもない
613デフォルトの名無しさん:2009/11/07(土) 19:52:02
そこでシングルトンの登場ですよ。
614デフォルトの名無しさん:2009/11/07(土) 20:01:16
シングルトンは俺的にはもうアンチパターンだな
Google的に、コンストラクタでは単純な初期化にとどめて、複雑な初期化はInit()で
やれ、というコーディングを採用してれば、初期化順序で悩むことも無い気がする
615デフォルトの名無しさん:2009/11/07(土) 20:17:49
単豚
616デフォルトの名無しさん:2009/11/07(土) 21:00:39
>>614
コンストラクタから初期化を追い出す必要は無いよ。
Init() 呼ぶくらいならグローバルなポインタに new すればいいじゃん。
617デフォルトの名無しさん:2009/11/07(土) 22:58:31
ゼロオーバーヘッド的にはグローバルなポインタにnewするくらいならInit()呼ぶなぁ
618デフォルトの名無しさん:2009/11/07(土) 23:26:56
operator newのオーバーロード(配置ではなくて)なんですけどグローバルにするのかstaticメンバにするのはどっちがいいんでしょうか?
619デフォルトの名無しさん:2009/11/07(土) 23:31:20
一緒。staticメンバは単にクラスのスコープの中に入っちゃうだけ。
620デフォルトの名無しさん:2009/11/07(土) 23:36:58
>>618
追加の引数が無い奴はグローバルにすると全体に影響が出るから気をつけてな。
621デフォルトの名無しさん:2009/11/08(日) 00:09:48
ありがとうございます
グローバルだと目的のクラス以外でもオーバーロードされてしまう
staticメンバだと目的のクラスだけオーバーロードされる
ということでしょうか。基本的にはstaticメンバにしたほうがよさそうですね
622デフォルトの名無しさん:2009/11/08(日) 00:12:34
>>621
影響範囲については、だいたいそういうこと。

細かい話をすると、クラスの奴は派生クラスでも使われる。
あと、追加の引数が無い奴をグローバルに置くのはオーバーロードじゃなくて置き換え、な。
623デフォルトの名無しさん:2009/11/08(日) 15:27:46
基底クラスのポインタから派生クラスのポインタへのキャストって
dynamic_castは遅いけど変換不能な場合NULLを返す
static_castは早いけど変換不能でも知らせてくれない
これ以外の違いってなんかある?
624デフォルトの名無しさん:2009/11/08(日) 15:34:01
その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない
その派生クラスがその基底クラスを仮想継承している場合、static_castは使用できない
(両方に当てはまる場合、どちらも使用できない)
625デフォルトの名無しさん:2009/11/08(日) 19:45:51
>その基底クラスが仮想関数を持たない場合、dynamic_castは使用できない
マジすか初めて知った
確かにできてもあんまり意味はないけど
626デフォルトの名無しさん:2009/11/08(日) 20:18:33
キャストしない暗黙変換が一番使いやすい。とか本末転倒なこと言ってみる。

HogeBase* hoge;
Hoge2 *p = new Hoge2;
hoge = p;//基底があってなかったらコンパイルエラー吐く。 
627デフォルトの名無しさん:2009/11/09(月) 01:46:58
dynamic_castが必要になるのは糞設計に仕方なく対応する時だけ
628デフォルトの名無しさん:2009/11/09(月) 01:56:39
クロスキャストには必須だろ
629デフォルトの名無しさん:2009/11/09(月) 02:49:46
クロスキャストしたい時点で糞設計になってるんじゃ?
630デフォルトの名無しさん:2009/11/09(月) 03:04:02
>>629
違う
クラスが複雑になるとクロスキャストしたい局面はよく現れる
631デフォルトの名無しさん:2009/11/09(月) 03:04:46
×クラスが複雑になると
○継承関係が複雑になると

あ、継承関係が糞設計なんだろって突っ込みは無しな
そういう事を言い出すとキリがなくなってしまうんで
632デフォルトの名無しさん:2009/11/09(月) 03:24:18
そうは言っても、継承関係が糞設計なんだろ?w
633デフォルトの名無しさん:2009/11/09(月) 03:49:06
>>632
ほうら来た
だからそういう突っ込みは無し
人間そこまで完全な奴はいない
特にある程度プロジェクトが進んでしまっていると
今更設計を変えられない事も多い
634デフォルトの名無しさん:2009/11/09(月) 03:55:13
配られたカードがどんな悲惨でも
それで何とか勝負するしかないって事はあるだろう、仕事なら。
635デフォルトの名無しさん:2009/11/09(月) 04:06:19
結局>>627で全て終結していたわけか
636デフォルトの名無しさん:2009/11/09(月) 04:06:54
最初から「仕方なく対応する時」って書かれてるんだから、それは分かった上でだろう
637デフォルトの名無しさん:2009/11/09(月) 04:14:02
少なくともC++では、dynamic_castを使う必要が出てきた時点でほぼ糞設計。

糞設計をしてしまうことはあるし、気付いた時には引き返せないこともあるから、
使う時は使うべき。設計は変えられないが他の方法でどうにかしよう、というのは
最悪だから。
でも、そういう事態になったなら設計が糞だったんだ、という認識はすべき。
638デフォルトの名無しさん:2009/11/09(月) 04:50:41
>>637
それは当たり前だろう
そんな事はわざわざ言わなくても誰でもわかっている
639デフォルトの名無しさん:2009/11/09(月) 04:58:39
つーかそれ以上の話をする必要を感じない
640デフォルトの名無しさん:2009/11/09(月) 04:59:42
つーか>>628が要らんこと言ったのが悪い
641デフォルトの名無しさん:2009/11/09(月) 23:38:14
シェア的にC/C++のコンパイラあげると上二つはVCとgccかなって思ってるんだが、
ベスト5ぐらいには他にどんなのがあるの?
642デフォルトの名無しさん:2009/11/09(月) 23:54:09
>>641
ボーランドとかTurboとか
643デフォルトの名無しさん:2009/11/10(火) 01:28:56
当然 icc は入ると思う。
644デフォルトの名無しさん:2009/11/10(火) 10:52:51
Code Warrierも入るな。間違いない。
645デフォルトの名無しさん:2009/11/10(火) 12:31:11
じゃあ俺はLSI-C
646デフォルトの名無しさん:2009/11/10(火) 17:03:07
http://codepad.org/kd2xzcnB

コードパッドのほうだと期待通りに動くんですけど
僕の使ってるコンパイラ(VC++EE2008)ではdelete[]が確保したサイズじゃなくてクラスのサイズを引き数に渡してしまいます
これは規格で定まっていないんじゃなくて僕が使ってるのがただのクソッタレコンパイラということですか?
647デフォルトの名無しさん:2009/11/10(火) 17:47:50
>>641-645
「シェア」の意味によって違ってくるだろうな。
使ってる人数か?コンパイルされたコードの走っている台数か?
商用に限るのか?学生の講義とかも含めるのか?日本なのか世界なのか?

コンパイルされたコードの走ってる台数だとOSなんかも入って
ちょっとナンセンスになるから、結局人数なんだろうけど。
そうすると組み込み系とかはそんなに多くないと思う。
648デフォルトの名無しさん:2009/11/10(火) 17:56:12
>>646
size_tを引数にとるoperator delete[]なんて規格にあったっけ?
649デフォルトの名無しさん:2009/11/10(火) 18:00:26
ああ、そうか。メンバ関数のほうはsize_tを引数にとるのか。
650デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/10(火) 22:17:15
mallocもしくはnewで調べれ
配列の大きさはコンパイル時に決定されなければならない。
652デフォルトの名無しさん:2009/11/10(火) 22:38:07
>>650
配列の大きさを指定できるのは一番右側のoperator[]内だけ
653デフォルトの名無しさん:2009/11/10(火) 23:39:18
int (*p)[2] = new int[n][2];
654デフォルトの名無しさん:2009/11/10(火) 23:42:36
>>650
関数内でnewやmallocしてそのポインタを返すのは危険きわまる。
C++なんだから、vector<vector<int>>を参照渡しするのがいいと思う。
655デフォルトの名無しさん:2009/11/10(火) 23:44:32
すまぽが早く実用化されれば、こんな問題どうってことないんだけどなぁ。。。
656デフォルトの名無しさん:2009/11/10(火) 23:55:55
これがJavaやC#なら、どんなオブジェクトでも平然と返せるんだけどねえ。
shared_ptrを使えばいいんだけどね。std::tr1::shared_ptr<std::string>とか
長くなりがちなのがちょっと。
657デフォルトの名無しさん:2009/11/11(水) 00:13:10
どこでもshared_ptrに頼るのってどうなのよ
コピーと代入のコスト結構馬鹿にならんし
寿命と例外安全考えて使わなくていいところは使わないほうがいいと思うんだし
658デフォルトの名無しさん:2009/11/11(水) 00:41:54
>>653
おいデタラメ書くな
659650: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デフォルトの名無しさん:2009/11/11(水) 04:08:45
スマートポインタ使わずに平気で関数内new&returnしてますが何か
661デフォルトの名無しさん:2009/11/11(水) 09:13:01
もらったほうがきちんとすてればなんのもんだいもない
662デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/11(水) 10:04:12
毎回floatにキャストしても
CPUの中の人は結局doubleで計算するわけ?
664デフォルトの名無しさん:2009/11/11(水) 12:14:43
>>663
x86系CPU+Visual C++では、そう(doubleじゃなくてlong doubleだけど)。
x64だとちょっと違ってて、多分floatで計算してると思う。

詳しくはx87FPUとSSE演算を調べてみてくれ。
重要なのはx64+WindowsだとFPUレジスタがDisableされていること。
665デフォルトの名無しさん:2009/11/11(水) 13:50:25
>>660
プロジェクトに悪意あるメンバーがいたらメモリリークさせられるぞ
666デフォルトの名無しさん:2009/11/11(水) 13:59:53
悪気は無かったんです・・・
667デフォルトの名無しさん:2009/11/11(水) 14:25:35
VC++のMFCアプリで、あるjavaアプレットの画面イメージを取得するため
対象ウィンドウを検索して存在すればCWnd::SetWindowPos()で最前面にもってきて
CWnd::RedrawWindow()で再描画、ということを行っています。
対象ウィンドウが他のウィンドウに隠れている場合はこれでいいんですが
もともと最前面にある場合は、再描画の処理は不要だと思うのでスキップしたいのですが
最前面であるかどうかはどう判断すれば良いのでしょうか?
CWnd::GetWindow()でいろいろやってみているんですがうまくいきません。
668デフォルトの名無しさん:2009/11/11(水) 15:41:34
>>664
>x64+WindowsだとFPUレジスタがDisableされていること。

されてねえよ
タスクスイッチの時もスレッド切り替えの時もちゃんとFPUはsaveするように
仕様が変わった
669デフォルトの名無しさん:2009/11/11(水) 16:06:54
>>667
::EnumWindows()とかでどうか
不安ならそれに::GetWindow()を組み合わせる
670デフォルトの名無しさん:2009/11/11(水) 16:24:15
独学でCを学んでいます。
2進数から10進数への変換方法がわかったので
入力した2進数を10進数で表示する関数を作ったのですが
32桁あるときだけ答えが空白になってしまいます。
問題がある箇所を教えてください、お願いします。
環境はxp homeのvisual studio 2005です。

http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10099.txt
671デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/11(水) 17:21:01
>>671
コンパイラと環境によって違いますとしか言えない

最適化が優れたコンパイラなら float x そのものを消去してしまうと思う
673デフォルトの名無しさん:2009/11/11(水) 17:31:12
使用していない変数は消去ってやつですね。
処理省略の部分でxは使っている事とします。
変数は静的な領域に確保するわけですから、どのコンパイラでもメモリの使用量はかわらないように見えるんですが、違うのでしょうか?
674デフォルトの名無しさん:2009/11/11(水) 17:33:00
>>673
そうとも言えない
とにかくコンパイラの吐いたコードを見るしか確かめる手はない
675デフォルトの名無しさん:2009/11/11(水) 17:33:52
>>671
横から、付け加えるなら、省略された部分の処理内容も影響する。
場合によっちゃあ処理フローまでガラッと変わる。
676デフォルトの名無しさん:2009/11/11(水) 17:33:57
あ、xは使ってるのか
それなら変わらないだろうという予測が立つ
しかしあくまでも予測だという事を忘れないように
677デフォルトの名無しさん:2009/11/11(水) 17:36:51
>>673
言語仕様では、静的変数の振舞は定義されていても、実装方法までは定義されていないので、
本当に静的な領域に確保されるかどうかは、コンパイラの出力したコードを見ないとわからない。
もっとも、一度確認したからといって、次にコンパイルしたときは違う結果になっているかもしれない。
678デフォルトの名無しさん:2009/11/11(水) 17:39:07
x86/x64のVCやgccなら、たぶん即値として命令コードに埋め込まれちゃう。
あくまで予測ですがね。
679671:2009/11/11(水) 18:25:50
私のレベルからしてコンパイラが吐いたコードを解析するのは無理です。
コストに関しては曖昧な感じですし
for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。

ありがとうございました。
680デフォルトの名無しさん:2009/11/11(水) 18:46:12
for(int i = 0, const float x = 10; i < 10; ++i)

つーか80:20の(ry
681デフォルトの名無しさん:2009/11/11(水) 19:02:03
>>679
>for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。
そりゃ逆だ。
「スコープはなるべく小さく」といわれている。
682デフォルトの名無しさん:2009/11/11(水) 19:03:20
L2キャッシュが良く効くからな
683デフォルトの名無しさん:2009/11/11(水) 19:04:03
じゃなかった、バグが減るからか
C++はスマポがあるからいいんだが
684デフォルトの名無しさん:2009/11/11(水) 20:45:41
嘘みたいな話だが、昔の gcc だとスコープ狭い方が良
いコードが出た(龍本レベルでもあり得ないと思うんだ
が…)。

しかしまぁ、人間にとってもスコープ狭い方が読むとき
に気にすべき情報が減るので読み易い。
685デフォルトの名無しさん:2009/11/11(水) 21:48:52
{
const int c = 10;

for(int j = 0; ・・・

}

でもこれってちょっとダサくない?
インデント深くなるし
686デフォルトの名無しさん:2009/11/11(水) 22:05:04
慣れればスコープ無視したコードの方がダサイと思うようになるさ
687デフォルトの名無しさん:2009/11/11(水) 22:34:36
コピーコンストラクタとoperator=()の内容って同じことが多いのですが、
コピーコンストラクタには「*this = コピー元;」とだけ書いて
operator=()のほうに処理を集約してしまうことって、なにかまずいことはありますか?
688デフォルトの名無しさん:2009/11/11(水) 22:40:08
俺もよく使うな、自動変数の生存範囲を限定するためだけのスコープ。
689デフォルトの名無しさん:2009/11/11(水) 22:40:42
場合によってはバグの元になる
ならなくてもメンバ変数が全部初期化された後
すぐに代入することになるから無駄な処理が発生する
690デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/12(木) 04:00:58
質問です
C++において、関数ポインタを使う意義は何があるでしょうか?
言い換えれば、具体的にどのような事をするときに便利なのでしょうか
どなたかお願いします・・・
693デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/12(木) 09:09:50
最近の OO 学習から入った C++ な人は基底クラスのポ
インタ使ってれば無理に関数ポインタ使わなくてもいい
気がする。
695デフォルトの名無しさん:2009/11/12(木) 09:36:52
クラスのインスタンスのメソッドへのポインタって使えますか?
696デフォルトの名無しさん:2009/11/12(木) 10:10:15
はい
697デフォルトの名無しさん:2009/11/12(木) 12:27:45
>>692
Win32を使うと嫌でもコールバックを使う場面に出くわすよ
698デフォルトの名無しさん:2009/11/12(木) 16:09:11
>>695
使えるけど使わないほうが無難だな。 ->* とか .* とか見たくないよ。
C++的には operator()()がいいかも。
699デフォルトの名無しさん:2009/11/12(木) 20:26:12
->*は拡張メソッドで使ってしまう
700デフォルトの名無しさん:2009/11/12(木) 21:49:51
Cです
構造体の初期化でmemsetを使うと問題があると聞きました.
ループ文でまわしている場合,毎回初期化する必要があるんですが
どうすればいいんでしょうか?

ポインタ配列です.

typedef struct{
701デフォルトの名無しさん:2009/11/12(木) 21:52:43
struct Hoge hoge = {0};
702700:2009/11/12(木) 21:52:57
すいません.途中で送信してしまいました.
どうやって初期化すればよろしいのでしょうか?
703デフォルトの名無しさん:2009/11/12(木) 22:24:39
>>701
ありがとうございます.
実際にはポインタで宣言しているのですが,

Hoge *hoge

hoge = malloc(sizeof(Hoge) * 100);

for(i = 0; i < 100; i++){
hoge[i] = {0};
}

でいいんですかね?
704デフォルトの名無しさん:2009/11/12(木) 22:32:05
zeromemory使えや
705デフォルトの名無しさん:2009/11/12(木) 22:53:04
std::fill()使えや
706デフォルトの名無しさん:2009/11/12(木) 22:57:05
>>705
それはC++。
707デフォルトの名無しさん:2009/11/12(木) 22:59:33
>>703だけ見てCかC++か区別付くかヴォケ
708デフォルトの名無しさん:2009/11/12(木) 23:00:04
Hoge foo = {0};

for(i = 0; i < 100; i++)
hoge[i] = foo;
709デフォルトの名無しさん:2009/11/12(木) 23:00:35
C++ならmalloc()の戻り値をキャストしないのはエラーなのでは
710デフォルトの名無しさん:2009/11/13(金) 00:44:58
Hoge の中に微妙なモノが union で詰まってる時は必要
に応じて何種類か用意しておいてコピーすればいいと思
うんだけど、この場合何も考えずに {0} で初期化する
と未定義動作だっけ?
711デフォルトの名無しさん:2009/11/13(金) 01:01:58
HogeがPODじゃない場合はそもそもそういう初期化は出来ない
712デフォルトの名無しさん:2009/11/13(金) 01:55:16
>>707
この質問は>>700だぞ? 一行目でちゃんと「Cです」って言ってるじゃん。
>>703だけ見て」ってお前、>>703だけ見ること自体がヴォケなんだよw
713デフォルトの名無しさん: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 についてはバグとして見つかっていたみたいだけど、
新しいのでも直ってないのかな?
http://ml.tietew.jp/cppll/cppll/thread_articles/5126
714デフォルトの名無しさん:2009/11/13(金) 10:25:48
結論、そのコードがCで、今後C++に転用する可能性を排除できるのならmemset()でもいいんでない?
そうでないなら、>708で。間違っても、一部のロートルの世迷言に釣られてmemcpy(hoge + i, & foo, sizeof(foo))なんてしないように。
715デフォルトの名無しさん:2009/11/13(金) 10:53:37
>>711
こういうことなんだが。

struct {
  union {
    void *p;
    void (*func)(void);
    float f;
    double d;
  } u;
} s = {0};
716デフォルトの名無しさん:2009/11/13(金) 10:56:01
>>715
今規格見た。最初のメンバが初期化されるんだな。
717デフォルトの名無しさん:2009/11/13(金) 11:59:14
unionを{0}で初期化してもいいけど
最初のメンバと違う型で参照したら処理系依存ってことか
718デフォルトの名無しさん:2009/11/13(金) 12:47:56
EUCで「。」の区切りを見つけるにはどうすればいいですか
文字コードは0xa1 0xa3です。
偶然にaaaa 0xa1、0xa3 bbbb となった場合が判断できないですが。
719デフォルトの名無しさん:2009/11/13(金) 12:59:15
>>718
探したい対象が文字列のように、EUCエンコードされていることが保証されているなら、
0xa1から遡って0x80以上のコードが偶数個連続していたらその0xa1が1バイト目。
遡るのが嫌なら、先頭から監視するしか。
720デフォルトの名無しさん:2009/11/13(金) 13:02:24
実行ファイルやDLLに画像など任意のバイナリデータを埋め込むにはどうするればいいんでしょうか?
今考えてるのは、unsigned char配列にデータを読み込んで0xXX, 0xYY, 0xZZ, ・・・のような形式で出力するプログラムを作り
コンパイル前に一度実行してdata.datに保存。利用者側は
unsigned char data[] =
{
#include "data.dat"
};
と書いて使う。という感じなんですが・・・
721デフォルトの名無しさん:2009/11/13(金) 13:07:32
>>719
トンクス
722デフォルトの名無しさん:2009/11/13(金) 13:09:09
>>720
windows限定なら、標準のリソースとして埋め込めばいいのでは。アイコンなど。
723デフォルトの名無しさん:2009/11/13(金) 13:53:35
>>719
文字化けや不要コードの埋め込みなどが原因と思うけど
いい具合に出来なかった。
724718:2009/11/13(金) 14:05:36
変換ツール任せでやってみる。wstring型に変換できれば比較は簡単だから。
725デフォルトの名無しさん:2009/11/13(金) 14:21:20
wchar_tに変換して出来ました。
手間かかるけど、文字化け多発するよりかは良いか。
726デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/13(金) 16:18:31
std::tr1::shared_ptrなら出るよ。
728デフォルトの名無しさん:2009/11/13(金) 16:45:12
C++の識別子長すぎていらつく
スコープ付きの識別子の別名定義ができれば便利なのに
729デフォルトの名無しさん:2009/11/13(金) 16:51:33
つスコープ内でtypedef
730デフォルトの名無しさん:2009/11/13(金) 16:52:48
725だけど、「。」の発見は出来たけど、こんどは文字種の特定が困難になったよ。
かな、カナ、漢字など。UTF16らしいが文字コードがよくわからん。
EUC -> UTF16 -> SJIS OR EUCと何度も変換するしかないのか。
731デフォルトの名無しさん:2009/11/13(金) 17:11:00
>>727
試したけどダメっぽいです。コンパイルは通るんですが
何か根本的な間違いをしてるのかも・・・。
ひとまず諦めます
732デフォルトの名無しさん:2009/11/13(金) 17:13:00
>>729
それじゃ型限定じゃん
変数や関数の別名を参照や関数ポインタ使わずに楽に短くしたいんだよ
733デフォルトの名無しさん:2009/11/13(金) 17:16:05
>>731
インテリセンスするための情報収集が狂っちゃうと、そういうことがおきるねー

リビルドや
中間ファイル(.obj や .res .scc .pdb .pch .ilk .idb .ncb .plg .bsc まだあるかも)を完全に消してのビルドで
復活したりするよ。
734デフォルトの名無しさん:2009/11/13(金) 17:40:31
>>732
C#のusing的なやつ(しかもスコープ限定)が欲しいってことか。
735デフォルトの名無しさん:2009/11/13(金) 18:07:55
>>730
混ぜるな危険
736デフォルトの名無しさん:2009/11/13(金) 18:18:15
>>714
まぁ俺も sockaddr_in 辺りは memset でクリアしちゃ
うけどさ。

> そのコードがCで、今後C++に転用する可能性を排除で
> きるのならmemset()でもいいんでない?

厳しく言うと >>715 みたいなのは union を struct に
しても memset はアウトだよな?
737デフォルトの名無しさん:2009/11/13(金) 19:05:49
738デフォルトの名無しさん:2009/11/13(金) 20:29:57
>>737
リンク先あっているのか?
A a[10] = {0} で a[0]〜a[9] のすべてが0クリアされるのか?
static なら保障されているが、auto な配列ではダメなのでは?
739デフォルトの名無しさん:2009/11/13(金) 20:30:49
されるよ
ダメくない
740デフォルトの名無しさん:2009/11/13(金) 20:44:04
>>739
確認しました。
明示的に初期化される、ただし、一部しか明示されていない場合は、残りは 0 で初期化される、これは
auto でも static でも同じとのことですね。
thanks a lot.
741デフォルトの名無しさん:2009/11/13(金) 23:45:42
>>733
もしやと思ってSP1にアップデートしたらstd::tr1::shared_ptで出来ました!
今までアップデートしてなかったんだなぁ…
742デフォルトの名無しさん:2009/11/14(土) 03:37:57
sscanfでは、第一引数の文字列の
半角スペースのある領域を""で囲っても、
ひとつの区切りとしてくれないみたいですが、
それができる方法がありましたら教えてください。

sscanf("\"abc de\" 5", "%s%s", s1, s2);
743デフォルトの名無しさん:2009/11/14(土) 03:39:42
>>742
面倒でもstrtok()使え
744デフォルトの名無しさん:2009/11/14(土) 03:46:13
*scanf は糞
745デフォルトの名無しさん:2009/11/14(土) 04:23:51
>>743>>744
ありがとうございます。
やはり、自前で実装ですか・・
やってみます。
746デフォルトの名無しさん:2009/11/14(土) 04:31:30
parserつかえ
747デフォルトの名無しさん:2009/11/14(土) 04:51:18
>>746
ありがとうございます。
試してみます。
748デフォルトの名無しさん:2009/11/14(土) 05:52:57
>>742
"%s"ではなく、"\"[^\"]"を使えばOK!
749デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/14(土) 07:38:56
>>750
有効桁数が減ります
752デフォルトの名無しさん:2009/11/14(土) 07:55:40
>>749
アクセスの仕方は一緒でも
渡されるものの内容が違います
753デフォルトの名無しさん:2009/11/14(土) 08:49:47
>test_func(**a)
>test_func(*a[y])
>test_func(a[][y])
>で全て同じ定義だと思うのですが

ちがいます
754デフォルトの名無しさん:2009/11/14(土) 09:51:11
>>753
一つ目と二つ目は違いますが二つ目と三つ目はおなじですよね?
ポインタのポインタとして渡された先頭のアドレスが渡された関数で
アドレスしか渡してないのにその内部構造が定義したように認識されているのはなぜなのでしょうか?
755デフォルトの名無しさん:2009/11/14(土) 09:54:11
>>754
二番目と三番目で渡している型は
配列を指すポインタであって、ポインタのポインタではありません
756デフォルトの名無しさん:2009/11/14(土) 09:58:06
>>754
少なくとも2と3はまったく違う
1と2は一緒とみなしてよいときとそうではない場合がある
757デフォルトの名無しさん:2009/11/14(土) 11:56:11
>>748
ありがとうございます。
試してみます。
758デフォルトの名無しさん:2009/11/14(土) 15:26:21
CLASS x=y; は
xは初期化されず
コピーコンストラクタへいくね。
これってたまたま不定値によっては動作がおかしくなりそうだが。
メモリ確保してあるかどうかのフラグの部分でおかしな動作したよ。
759デフォルトの名無しさん:2009/11/14(土) 16:03:10
>>758
コピーコンストラクタは初期化処理の一種なわけだが。
CLASS の定義がバグってるんじゃね?
760デフォルトの名無しさん:2009/11/14(土) 16:10:49
CLASS () { flg=0; }やCLASS (int n) { flg=0; }だとflgは確定してるけど
コピーコンストラクタは、xが初めて生成されたのか不明で
初期化して良いのかわからないと思ったんです。
コピーコンストラクタは初期化時にしか使われないんですか。
代入と一緒の気がしてました。どちらの場合も対応しないといけない気がしてました。
761デフォルトの名無しさん:2009/11/14(土) 16:13:36
>>760
コンストラクタはぜんぶ初期化処理。
初期化後のコピーは代入演算子で定義する。
762デフォルトの名無しさん:2009/11/14(土) 16:15:04
トンクス!
763デフォルトの名無しさん: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は全く同じ意味。
764763:2009/11/14(土) 19:15:55
>749

よく読むと A a[x][y];
を渡したいみたいだね。
それならば、>763の3か4を使う。
1,2ではダメ。
765763: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/14(土) 19:52:03
>>766
試してないけど、こうじゃない?
_ftprintf_s(fileStream, _T("FILE %s\r\n"), static_cast<LPCTSTR>(csvFile));

可変長引数に渡す場合にクラスからの暗黙の変換は効かない。
CString 使うなら TCHAR を扱うように統一しないと。
Cスタイルキャストは無しで。
768デフォルトの名無しさん:2009/11/14(土) 19:52:15
fprintf_sの引数を(LPCSTR)csvFileにしたらどうだろうか
769デフォルトの名無しさん:2009/11/14(土) 19:54:38
>>766
_T マクロ無しにしたら?
770デフォルトの名無しさん:2009/11/14(土) 19:59:58
>>767-768
大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、
この場合問題なのはfprintf_sの"%s"にLPTSTRを渡してることだと思う。
つまりtprintf系の関数を使うのが正しい

>>769
それは間違ってる。むしろ至る所に_Tマクロを使うべき
771766:2009/11/14(土) 20:09:45
記載いただいた内容で出力することができました。
ありがとうございます。

>>767-770
C言語と比べると全然違うんですね。
Cを少しかじったことがあるので、書けると思っていたら全然でした…。
772766:2009/11/14(土) 20:14:34
>>770
770さんの書き込みをよくよく読むと出力はできるけど、
これだと正しくないということですか?
773デフォルトの名無しさん:2009/11/14(土) 20:19:02
ジェネリックテキスト(_Tマクロとか使うやつ)は使わないほうがいいだろ。
95/98対応する必要があるとかかわいそうな人なんてもう、そうそういない
だろうし、ワイド文字列きめうちのほうがトラブルがなくて楽だよ。

それにジェネリックテキスト使っていたって、本当にワイド文字列と
マルチバイト文字列の両方に対応できてるコード書けてるかってのもあるし。

両方で動くように意識して書いてるやつなんて少数派だし、_UNICODEありと
なしでコンパイルが通るかとか、テストを両方でやってるところとかまで
いくと壊滅状態だろうし、事実上ジェネリックテキストなんて機能してないよな。
774デフォルトの名無しさん:2009/11/14(土) 20:21:28
>>770
> 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、

へー。いまの可変長引数の ... 部分に渡したときも LPCTSTR への暗黙変換が入るのかー。
いったいどういう仕組みで?
クラスに operator LPCTSTR () を持ってるだけじゃ、そうはいかないよね?
775デフォルトの名無しさん:2009/11/14(土) 20:25:03
>>773
一般的な話ならそれでもいいんだけど、ここでは CString を使ってて、
その型は変えられないと質問者が言ってるんだから _T() が要るだろ。
776デフォルトの名無しさん:2009/11/14(土) 20:25:58
>>774
>>770じゃないけどCSimpleStringT<>のソースは大分前に見たよ

データメンバがポインタ1個でvtblもないから
メモリレイアウトがTCHAR*と同じになってるんだよ確か
777768:2009/11/14(土) 20:29:40
よく考えたらLPCSTRへ変換はできなかったかも
CStringへ代入はできるけど
778766:2009/11/14(土) 20:31:31
ごめんなさい。
出力はできるようにはなったのですが、日本語が含んでいるとクエスチョンマークの
文字列が並んでしまいます。
これはやっぱり、上で説明されている変換がうまくいっていないからですか?
779デフォルトの名無しさん:2009/11/14(土) 20:32:44
>>778
setlocale(LC_CTYPE, "");
とかやろう!
780デフォルトの名無しさん:2009/11/14(土) 20:32:49
>>770,776
http://msdn.microsoft.com/ja-jp/library/awkwbzyc.aspx#_core_using_cstring_objects_with_variable_argument_functions
> ... 可変個の引数リストを取る関数に CString オブジェクトを渡すときは、明示的に
> 型キャストによる変換を行う必要があります。

やっぱりダメじゃねーか。

http://www.trickpalace.net/cppll/reference/printf.htm#argument
こいつのデマに騙されたんじゃね?
781デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/14(土) 20:41:17
>>780
古いATLの利用を考えているならキャストするのが安全だろうけど、
最近のはreinterpret_cast相当の操作でも安全に使えるようにできているから必要はない。

というのはATLの解説書のどれかに書いてあったはず
783766:2009/11/14(土) 20:44:59
>>779
無事に出力できました。ありがとうございます。
第2引数に何か入れた方が良いのかと思いましたら、そのままでも平気なんですね。
784781:2009/11/14(土) 20:52:17
どーでもいいけど例が良くなかったね

#include <cstdio>
#include <atlstr.h>

int main()
{
    CStringA s = "world";
    std::printf("hello, %s %d\n", s, 123);
}

これがちゃんと動きます。
785774:2009/11/14(土) 21:08:10
http://groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/028f80f03d7e253d#msg_7fb2a35dbe1e6ff1
把握した。なるほど。

開発者はがんばって大丈夫なようにしたけど、外向けの仕様としてはキャストが必要と
書かれたままになってるってことだね。ちょっと不憫だな。まぁ古い実装を使ってる場合や
可変長引数の実装方法の違うコンパイラを使う場合にはやっぱり問題になるんで、
しょうがないところかとは思う。

>>780
デマじゃなかったみたいね。
786デフォルトの名無しさん:2009/11/14(土) 21:12:38
C++でポインタを *で参照はがしした時って、*pointerは参照ということになるの?
http://codepad.org/A8sFOqoG
こんな感じで仮想関数使いたい場合、とりあえず思った通りに動くんだけど、
*baseとした時点でBase型に補足されるということはないんですか。
787デフォルトの名無しさん:2009/11/14(土) 21:14:29
>>786 参照だよ。
788デフォルトの名無しさん:2009/11/14(土) 21:17:35
わかりました。ありがとうございます。
789デフォルトの名無しさん:2009/11/15(日) 14:40:57
char 配列が300個連続で0であることを高速で見つけるにはどうすればいいですか。
790デフォルトの名無しさん:2009/11/15(日) 14:48:00
どういう意味で高速なんだ
791デフォルトの名無しさん:2009/11/15(日) 14:56:55
CPUの性能を上げれば高速になるよ
792デフォルトの名無しさん:2009/11/15(日) 15:11:29
ひとつひとつ探すより、memcmp使うとかです。
これは実際に速くなるのですが、500個になると困ります。
793デフォルトの名無しさん:2009/11/15(日) 15:12:39
0に限定すれば、memcmpより高速に出来る可能性があると思いますが
アセンブラなどわかりません。
794デフォルトの名無しさん:2009/11/15(日) 15:15:32
O(n)よりは速くならないんだから、あとはCPUのデータシート眺めながらチューンしていくしかないよ
795デフォルトの名無しさん:2009/11/15(日) 15:18:52
いい方法わかりました。300個目だけ1だったら途中は調べなくて良かったです。
796デフォルトの名無しさん:2009/11/15(日) 16:54:40
ああもうそれでいいよ、もう来ないでね
797デフォルトの名無しさん:2009/11/15(日) 23:16:34
>>795
もう少しマシにしようか
300個が0なら150個目を調べる
それも0なら75個目と225個目を調べる
それも0なら・・・・

非0である確率が高いならともかく、そうでないなら最初から順々に調べたほうがマシだな
798デフォルトの名無しさん:2009/11/16(月) 00:13:52
>>797
えっ
799デフォルトの名無しさん:2009/11/16(月) 00:20:58
データに偏りがあるなら、そういう最適化もあるが、ないなら最初から配列舐めるなぁ。。。
800デフォルトの名無しさん:2009/11/16(月) 00:22:43
つまらないこと言ってないで、死の行進しとけよ
学生はIT土方になるために必死に勉強しとけ
801デフォルトの名無しさん:2009/11/16(月) 01:54:58
> これは実際に速くなるのですが、500個になると困ります
なんで?

そもそも memcmp() 呼び出しが 単純なループ処理より速いってどんな環境?
(つーか、まさか毎回if判定してないよな?)
802デフォルトの名無しさん:2009/11/16(月) 01:56:41
>801
いや普通、ループは毎回判定してるぞw
803デフォルトの名無しさん:2009/11/16(月) 02:05:47
例えば
・charではなく、もっと大きな(intとか)のサイズでアクセスし
・毎回判定するのではなく、数十個単位とかを|してから判定することにして
・さらに、場合によってはプリフェッチ的なアクセスの仕方も行う
というようなことをすれば、

・もしかしたら
・あなたの使っているCPUやOS、及びコンパイラと使用ライブラリ限定で
・データによっては
・気休め程度には
速くなる可能性はあるかもね。
804デフォルトの名無しさん:2009/11/16(月) 11:02:47
バーチャルで関数をオーバーライドするときって型を変えたりできないんですか?
virtual ってvoidばっかりなのですが
805デフォルトの名無しさん:2009/11/16(月) 13:34:53
>>804
基本的にはできない。
例外として共変戻り値がある。
806デフォルトの名無しさん:2009/11/16(月) 16:46:54
グローバル変数はどこから書き換えられるか解らないといった弊害があるから推奨されないかと思うのですが
グローバルな定数であれば別にガツガツ使用しても問題ないのでしょうか?
807デフォルトの名無しさん:2009/11/16(月) 16:57:15
一番大事なことはそれではないとおもう。
変数がかぶることと思う。
ネームスペースやオブジェクト指向も
変数名、関数名がかぶらなくなることが大事思う。
808デフォルトの名無しさん:2009/11/16(月) 16:59:04
変数や関数の生存範囲が小さいほどよい。
公開する部分はのぞく。
グローバル定数も変数も公開するで無ければなるべく範囲を縮める。
809デフォルトの名無しさん:2009/11/16(月) 17:02:19
変数を生成するコストを減らすためとかいう理由で
グローバル使うのはあほですよ。
大して時間食わないし、変数生成がボトルネックなることはまれ。
時間食ってることが確認できてから変えれば良いんです。
なるべく生存範囲が短くなるようにするのが吉
810デフォルトの名無しさん:2009/11/16(月) 17:02:27
じゃネームスペースの中にグローバル変数入れときゃいいじゃん
811デフォルトの名無しさん:2009/11/16(月) 17:07:16
>>805
ありがとうごじあました
812デフォルトの名無しさん:2009/11/16(月) 17:08:01
名前の競合なんて屁でもないだろ。
モジュール間でのカプセル化という意味合いの方が大きい。
813806:2009/11/16(月) 17:29:33
グローバル定数も出来る限り控える方が良いんですね。
ありがとうございます。
814デフォルトの名無しさん:2009/11/16(月) 18:25:46
error C2276: '&' : 仮想関数のアドレスを取ろうとしました。
とか、書き方を変えると、
error C2440: '<function-style-cast>' : 'overloaded-function' から 'float' に変換できません。
とか出ます、仮想関数をはじめていじくっているのでどうすれば良いかわかりません
仮想関数のオーバーライド中では引数のメンバの型を変えてはいけないのですか?
815デフォルトの名無しさん:2009/11/16(月) 21:24:18
>>814
スレ違い。↓こっち行け。
http://pc12.2ch.net/test/read.cgi/tech/1187922645/
816デフォルトの名無しさん:2009/11/16(月) 21:59:01
グローバルスコープがふさわしい物までグローバルから追い出そうとするのも問題だと
個人的には思う

つーか、初心者が一番やらかしやすいのは、関数スコープがふさわしい物をファイル
スコープに出してしまうことじゃないかと
817デフォルトの名無しさん:2009/11/16(月) 22:23:03
vc++でトランプゲームとか作ろうと思っています。そこで質問が二つあります。
@画像データをPROJECT内に保管しておいて必要な部分を切り取って表示する方法ってありますか?
AWIN32とmfcとで方法が違うかもしれませんが、ゲームを作成するのに向いているのはどっちでしょうか?

※開発環境(といえるほどのレベルではないのですが・・・)VISUALSTUDIO2005でvista32bitです。
入門書とかも何冊か読んでみたのですが、自分が求めている情報がズバリ載っているわけではいないので、
質問させていただきました。詳しい方がいらしたらぜひアドバイス願います。
818デフォルトの名無しさん:2009/11/16(月) 22:29:58
>>817
1、ビットマップの管理方法で違う。APIに任せるなら、loadImageしてBitBltなどのAPIを使う。
  自前で管理するなら、配列いじるのと変わらない。が、約束事はある。
2、どっちでも作れるから、作りやすいほう選べ。CかC++か位の違いしかない。どっちにもお約束事はある。
819デフォルトの名無しさん:2009/11/16(月) 23:09:48
環境変数はグローバル変数だから使用禁止
外部からファイル読み込むのもグローバル変数だから使用禁止
820デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/16(月) 23:22:58
>>820
同じ名前で内容の全く同じマクロなら何度定義してもいいことになってる。
(厳密にはもう少し複雑な規定があるけど)
823デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/16(月) 23:55:49
>>825 VC ならデバッガ使えよ。
827デフォルトの名無しさん:2009/11/16(月) 23:59:30
>>826
効果的な使い方がわからん
_CrtSetBreakAlloc(1162);で止めて下に出てるツリーを開いていくやり方以外やったことない
教えて
828デフォルトの名無しさん:2009/11/17(火) 00:07:56
>>827
_CrtSetBreakAlloc()って知らんからググってみたら、メモリリークの箇所を
調べるみたいなことが書いてあった。
勉強になるなぁ。

変数の中身をみるって、適当にブレイクポイントでとめて、ウオッチで見るとかじゃなくて?
829デフォルトの名無しさん:2009/11/17(火) 00:10:22
おkサンクス、やってみる
830デフォルトの名無しさん:2009/11/17(火) 00:13:03
ああ、普通こうやってやるのか
すげえな、サンクス
831デフォルトの名無しさん:2009/11/17(火) 05:38:13
VCならウォッチ式の設定とか言わず、変数をポイントするだけでもおk。
832デフォルトの名無しさん:2009/11/17(火) 06:05:27
ちょwwVC便利すぎワロタw
プログラム暦2年だけど何やってたんだ俺wめっちゃ簡単に割り出せるやんw
833デフォルトの名無しさん:2009/11/17(火) 06:32:32
vectorの内部で確保されているメモリってclear()でも解放されるの?
834デフォルトの名無しさん:2009/11/17(火) 06:36:33
解放されない

swapですれよ
835833:2009/11/17(火) 06:47:54
なるほど、どうも
836デフォルトの名無しさん:2009/11/17(火) 07:26:26
std::vector<T> v のバッファサイズをバイト単位で取得したい時は、
v.size() * sizeof(T)
でいいんでしょうか?
実装によっては何か詰め物でも入っているのではないかと不安なんですが。
837デフォルトの名無しさん:2009/11/17(火) 07:40:57
vectorのバッファは配列と同じメモリ配置であることが保証されてるから、それでいいよ
838デフォルトの名無しさん:2009/11/17(火) 07:54:16
>>836
そのサイズを使った操作が何であるかによっては危険な予感がする。
839デフォルトの名無しさん:2009/11/17(火) 08:22:29
>>837
ありがとうございます。
>>838
内容をファイルに書き出したいんです。
840デフォルトの名無しさん:2009/11/17(火) 15:26:13
普通に書き込めばいいじゃん
841デフォルトの名無しさん:2009/11/17(火) 17:07:07
>>839
ostreamのシフト演算子を定義すればいいと思うよ。
v.size() * sizeof(T) だと、vtableがあったら色々まずい。
842デフォルトの名無しさん:2009/11/17(火) 17:21:33
バッファサイズに仮想関数テーブルは関係ないだろ
843デフォルトの名無しさん:2009/11/17(火) 17:42:42
copy(v.begin(), v.end(), ostream_iterator<T>(cout, "\t");

これってさ、Tによっては<<定義しても動作しなくね?
844デフォルトの名無しさん:2009/11/18(水) 00:58:34
>>843 Tによらずコンパイルエラーになるね。
845デフォルトの名無しさん:2009/11/18(水) 01:16:44
>>844
いやそういう下らん揚げ足取りはいいから
846デフォルトの名無しさん:2009/11/18(水) 01:20:59
>>843
動作しそうで動作しない T の例をひとつでも挙げてみてくれ。
そうじゃないと、当たり前のことを聞かれてるだけにしか見えん。
847デフォルトの名無しさん:2009/11/18(水) 17:25:58
メモリイメージをメモリマップトファイルにmemcpyすれば楽ちん。
ていう考えは古いですか。
848デフォルトの名無しさん:2009/11/18(水) 19:48:32
質問させてください。
静的メンバはクラスが存在する前からあるはずなのに、なんでクラスの外で再宣言しなくてはならないんですか?
849デフォルトの名無しさん:2009/11/18(水) 20:19:01
ヘッダファイルにクラス定義を書いた場合ということでいいのかな?

その場合、各翻訳単位の間で重複してクラスの静的変数を定義しない為。
ヘッダファイルにグローバル変数を書いて共有するときも、externで宣言しといてどこかで一度だけ実体の宣言をするよね。
850デフォルトの名無しさん:2009/11/18(水) 21:00:32
http://codepad.org/auJS2ura

ngの部分でコンパイルエラーが出てしまいます
VC++2008EEのエラーメッセージによると引数があいまいだから、ということなんですが
どうすれば曖昧さをなくせるのかちょっとわかりません
うまいことstd::endlを渡す方法はありませんか?
851デフォルトの名無しさん:2009/11/18(水) 21:40:11
>>850
endlの型を調べよう
852デフォルトの名無しさん:2009/11/18(水) 21:48:59
CParent ◇- CChild

というように親クラスが子クラスを保持しているとします。

子クラスはプログラム動作中、たくさんnewでメモリを確保します。

プログラム終了時、CChild内でdeleteせず、CParentでだけdeleteすれば、
CChildがそれまで確保してきた領域も伴ってdeleteされるのでしょうか?


というのも、ある書籍についてたサンプルコードを見ると、newしまくりなのに、
それらがdeleteされる記述がぜんぜんないんです・・・
最も最上位のクラス(他の下位クラスを保持している)を最後にdeleteしてるところ
くらいしか考えられない・・・


よろしくお願いします。 m(_ _)m
853デフォルトの名無しさん:2009/11/18(水) 21:51:28
メモリリークしちゃうね
とりあえずその書籍の名前を
854デフォルトの名無しさん:2009/11/18(水) 21:56:05
スマートポインタ使ってたらそう見えるかもしれない
855852:2009/11/18(水) 22:01:00
>>853
「3D格闘ゲームプログラミング」という本です。
不思議なことに、サンプルのVC++プログクトでビルド実行してプログラムを終了させたとき、
リークがある場合にVC++のログ出力に出てくるメモリリークバイト数が出て来ず、
正常終了できたかに見えます・・・

>>854
スマートポインタを使っているようにも見えません・・・

一例として

ヘッダファイル内
char* xxx

C++ファイル内
 xxx = new char[ strlen( yyy ) + 1 ];

で、xxxはどこでもdeleteされていません。
VC++上でソリューション内を検索もしましたが見つかりませんでした・・・
856デフォルトの名無しさん:2009/11/18(水) 22:09:26
別の変数に代入されてどっかで解放されてるんじゃないの
857852: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デフォルトの名無しさん:2009/11/18(水) 22:24:30
そういわれても実際にコードを見られないんじゃ何とも答えられん。
859デフォルトの名無しさん:2009/11/18(水) 22:26:10
Childが死ぬときに開放してるんだろ。
とりあえずステップ実行して、本当に開放されないのか一行ずつ確認してください。
860デフォルトの名無しさん:2009/11/18(水) 23:01:08
>>848
クラスの外に書くのは、宣言ではなく定義。
861852:2009/11/18(水) 23:01:49
作者さんのページで、どうも関係のありそうな記述を発見しました。

ttp://cgi32.plala.or.jp/higpen/book/shtPro/qa.shtml#program10

違う書籍の違うプログラム部のところの話ですが、
たぶん、これと同じことだと思います。

なんと、解放はOSに任せられるとのこと。
あまり行儀は良くないですよね^^;
よほどプログラムの動きやOSのメモリ管理に精通してないととてもできないw

でも勉強になりました。

みなさん、ありがとうございました。 m(_ _)m
862デフォルトの名無しさん:2009/11/18(水) 23:19:45
なんか苦しい言い訳に見えるな。百歩譲ってそれが「正しい」方法だとして、
プログラミングを勉強する本にそういう書き方をするのはいかがなものだろうか…
863デフォルトの名無しさん:2009/11/18(水) 23:26:33
質問を勝手に自分の理解できる範囲の問題に解釈し直すのはいくない
864デフォルトの名無しさん:2009/11/19(木) 00:25:35
>>861
そんなこと言ってると、ごちゃごちゃ言ってないで std::vector 使えカス、ってバカにされちゃうよ。
865デフォルトの名無しさん:2009/11/19(木) 00:29:15
VC6 時代の古い本ならしょうがないか、と思ったけどそのリンク先 Q&A の
日付見たらごく最近なのな。著者が不勉強なんだろうと思う。
866852:2009/11/19(木) 00:57:36
>>864
多態を使わなければ、クラスのインスタンスのvectorを使ってもOKみたいですね。


vector<CXXX> xxx;

CXXX x;

xxx.push_back( x ); // xxxコンテナへのコピーになる


これだったら、領域確保はvectorがしてくれるので楽ちんですね。

これでいきます。
ありがとうございました。
867デフォルトの名無しさん:2009/11/19(木) 01:51:30
コンストラクタ初期化子を使わないと駄目だっていうけど、初期化の順番を明示したい場合はコンストラクタ関数内で初期化してもいいよね?俺悪くないよね?

868デフォルトの名無しさん:2009/11/19(木) 01:53:45
どうでもいい。
869デフォルトの名無しさん:2009/11/19(木) 02:41:35
>>867
IDE のインテリジェンス機能が動かなくてもいいならそれでもいいよ
870デフォルトの名無しさん:2009/11/19(木) 02:57:34
コンパイル時にクラスや構造体のメンバのオフセットアドレスを得る方法ってあります?
871デフォルトの名無しさん:2009/11/19(木) 03:00:38
offsetof
872デフォルトの名無しさん:2009/11/19(木) 03:30:02
>>871
それだったか、感謝。
873デフォルトの名無しさん:2009/11/19(木) 08:16:43
>>861
それはメモリリークそのものだろw
そんなレベルで本書くなよ…
874デフォルトの名無しさん:2009/11/19(木) 08:47:42
よく読んでないけど

説明は下手糞だけど、最初に確保したメモリをプールしておいて使いまわす手法じゃないの?
だとしたら、そういうのはリークとは呼ばないよ。
MoreEffectiveC++にもちゃんと書いてあるし。

違ったらごめんな。
875デフォルトの名無しさん:2009/11/19(木) 08:48:47
×使いまわす手法
○使いまわして、最後まで(プログラムのコード内では)解放しない手法
876デフォルトの名無しさん:2009/11/19(木) 08:57:25
メモリなら最悪リークしてても、プロセス終了時に解放されますよって話だろ?
まぁメモリ以外のリソースだと解放してくれなかったりすることもあるけど。
877デフォルトの名無しさん:2009/11/19(木) 09:29:20
だから、たとえ解放処理(free/delete)をしていないとしても
ちゃんと管理できているものは「リーク」とは呼ばないって話だよ。
878デフォルトの名無しさん:2009/11/19(木) 09:34:03
>>867
初期化の順番はメンバの宣言順と決まっている。
コンストラクタの記述方法で明示などできない。

無知なオマエ悪い。
879デフォルトの名無しさん:2009/11/19(木) 09:38:59
>>874-875
よく読んでみなよ。 >>861 のやつは使いまわしてすらいない。
880デフォルトの名無しさん:2009/11/19(木) 09:39:33
最後にOS任せで消滅させて、途中どんなに肥大してもシラネ、ってのは管理ではなく
リークと呼ぶだろw
881デフォルトの名無しさん:2009/11/19(木) 10:06:29
>>879
だから、
>タスク用メモリはプログラムの終了時まで解放しない
が、「deleteを呼ばない」という意味ではなく
「プログラム終了まで使用している領域である」という意味ではないか、と言っている。
使用している(管理している)領域なんだから、deleteするコードが無くても問題ない。

もちろん、その「タスク」が、プログラムの中で際限なく増えていく
(あるいそのタスクを指す領域を見失っている)ようなら問題だが
俺はコードを読んでないので、どういう構造なのかは明言できない。


だから、「よく読んでないが」「説明は下手糞」と書いた。
そして、(明示的にdeleteを呼んで無くても)管理下にあるものはリークとは呼ばない。これは確実。
882デフォルトの名無しさん:2009/11/19(木) 10:07:54
で、使いまわしているかどうかは問題の本質じゃない。
管理下にあるかどうかが本質。
883デフォルトの名無しさん:2009/11/19(木) 10:23:05
>>881-882
よく読んでみなよ。 >>861 のやつは管理下にすらない。

「タスク」じゃなくて char 配列のほうな。ローカルな生ポインタ変数に入れて、
そのままスコープアウトしちゃってるみたい。

当たり前の主張を長文で繰り返す前に、「よく読んでない」と自分でわかってる
なら元記事をよく読めと。
884デフォルトの名無しさん:2009/11/19(木) 10:36:43

このサンプルでは以下の理由から、new char[]で確保した領域を明示的に解放する処理を省略しています。同様の理由で、他にもメモリの破棄を省略している部分があります。

* サンプルプログラムをなるべくシンプルにしたい
* タスク用メモリはプログラムの終了時まで解放しない
* プログラム終了時にはOSがプログラムに関連するメモリを解放してくれる
* 一般にdeleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、タスクリストの場合は実行中に解放する意味が薄い

上記の理由から、メモリを解放しなくても動作に問題はなく、他のプログラムへの影響もありません。推奨される方法としては、例えばタスクリストのデストラクタ
~CTaskList() を記述して、その中で上記のバッファを、
delete [] buf; のように解放します。この場合、bufをメンバ変数にしておく必要もあります。
885デフォルトの名無しさん:2009/11/19(木) 10:49:18
「禁無断転載」と明記された記事を意味もなく転載するのはおすすめしない。
せめて引用の形にとどめておけ。
886デフォルトの名無しさん:2009/11/19(木) 12:04:53
っていうか、いかなる場合でも
確保したメモリちゃんと解放すればいいんだよ。

メモリを解放するデメリットなんてないだろ?
もし、終了時に遅くなるとかいう話なら
「終了処理を速くするテクニック」として使えばいいだけの話。
それが必要になるときがくれば使え
887デフォルトの名無しさん:2009/11/19(木) 12:08:20
>deleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、
再利用されるとか考えないのかね?
888デフォルトの名無しさん:2009/11/19(木) 12:13:50
その機構部分は仮に良い という立場だったとして
new と delete がペアになっていない構造だから

別コードで本当にリークさせてる部分の追跡をするのに面倒じゃね?
889デフォルトの名無しさん:2009/11/19(木) 13:33:47
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?
890デフォルトの名無しさん:2009/11/19(木) 13:34:17
どうもしない
891デフォルトの名無しさん:2009/11/19(木) 14:50:59
なんで、サンプルで手抜きをするのかねぇ?
deleteなんて一行増えるだけじゃん。

いちいち言い訳を書くよりも
deleteを書けばいいじゃんか。
892デフォルトの名無しさん:2009/11/19(木) 14:52:56
deleteしてもメモリ返せないの?なんで?じゃあどうすんの?
893デフォルトの名無しさん:2009/11/19(木) 15:02:56
>>892
マジレスはしてあげないよw
894デフォルトの名無しさん:2009/11/19(木) 15:03:31
どうもしない

newしたときに再利用されるだろうな
895デフォルトの名無しさん:2009/11/19(木) 15:34:47
サンプルをシンプルにしたいからって理由で無茶すんなよなぁw
リーク検出とか使えなくなりそうだしなぁ
896デフォルトの名無しさん:2009/11/19(木) 16:12:06
>>893
無知は黙ってろハゲ
897852:2009/11/19(木) 19:05:22
物議を醸していますね^^;
作者の方は東大を出ておられますが、地頭が良いとこういう考え方になるのでしょうか・・・
ともあれ、今はnew、deleteはセットで書くよう心がけたいですね。
898デフォルトの名無しさん:2009/11/19(木) 19:44:29
deleteするしないはコードの本質でないと判断したんだろう。
まぁ論文ならそれでいいんだろうが、一般向け、しかも初心者が食いつきやすいゲームプログラミングの書籍で
それをやると何も考えずに模倣する馬鹿が出てきてしまうから、やめた方がいいと思うがな。
899デフォルトの名無しさん:2009/11/19(木) 19:46:38
メモリリークしてたらだめだ
実測しむ
900デフォルトの名無しさん:2009/11/19(木) 19:49:53
1Mのメモリーリークが100回起これば100M消費する
プログラムが終了すればOSが回収するが、
動いている間はそのまま。
901デフォルトの名無しさん:2009/11/19(木) 21:10:32
東大出てても糞コード書く奴はどうしようもないよ
しかも学歴が高いせいで自信だけはあるから逆にめんどい
902デフォルトの名無しさん:2009/11/19(木) 21:34:57
Cなら終了時まで解放しないメモリをfreeしないっていう層は結構いるから
その亜流なんだろう
903デフォルトの名無しさん:2009/11/19(木) 22:48:47
>>897
もちろんnew/deleteをセットで書いてもいいが
それよりスマートポインタを使うんだ
904852:2009/11/19(木) 23:01:20
>>903
COMでCComPtrを使ったことがあって、めちゃくちゃ便利でした。
自前のを作るとなると・・・うまく組めるかちょっと心配です(汗)
でも便利なのはたしかなので、勉強してみます。
ありがとうございます。
905デフォルトの名無しさん:2009/11/19(木) 23:04:08
shared_ptr < ・・・
906デフォルトの名無しさん:2009/11/19(木) 23:36:09
BCB5+Win環境です
char配列などを頻繁にnew・deleatする際、どっかのサイトで
win環境では固定サイズでnewしたほうが断片化しにくいと
書いてあったような気がするのですか
本当でしょうか?
あまりnewをいじりたくないので気になります
907852:2009/11/19(木) 23:45:36
>>905
おおお!
こんな便利なものがあったのですか!
VC++2008ならstd::で使えるそうですが、自分は2005ですね・・・
しかし、boostを導入すれば使えますね。
CComPtrと同じように使えるのであれば、慣れていますし、導入もし易そうです。

教えてくださって、ありがとうございました!
908デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/19(木) 23:56:21
std::multimap<int, int>::iteartor end = test.upper_bound(0);
でしたすみません
910デフォルトの名無しさん:2009/11/20(金) 00:10:27
されてません。
911デフォルトの名無しさん:2009/11/20(金) 01:05:18
>>906
new の回数を減らせば断片が減る(断片化しにくい)のはあたりまえ。

それ以前に、ほんとうに断片化による悪影響で困ってるのか?
Windows 上では、特にギガバイト単位のメモリ空間(アドレス空間)があたりまえな
最近の一般的な環境ではかなり稀なケースになると思うんだが。
912デフォルトの名無しさん:2009/11/20(金) 02:12:17
>>901
実際に動作させるコードでdeleteするしないの問題と、解説書でdeleteを省略するしないの問題を
区別できていないお前は多分低学歴なんだろうな
913デフォルトの名無しさん:2009/11/20(金) 02:13:44
実際に動作させるコードからかけ離れたコードを提示する解説書がそもそも問題
削っていい部分とそうでない部分があるが、こういうのを削っていいと思うようなら
糞コードと言われても仕方ない
914デフォルトの名無しさん:2009/11/20(金) 02:15:13
ま、万人向けの本でやっちゃだめだよな。
915デフォルトの名無しさん:2009/11/20(金) 02:17:50
ぶっちゃけこんなアホなコードを本気で擁護する奴なんて本人以外いるの?w
916デフォルトの名無しさん:2009/11/20(金) 02:28:12
>>912
省略したほうがシンプルでいいと思ったけど結局は言い訳がましい Q&A を書くハメに
なったってことで、解説書のための判断としても失敗だろ。

紙面の問題を考えても、 std::vector 使っとけば #include が1行増えるかもしれないって
程度だし。
917デフォルトの名無しさん:2009/11/20(金) 02:38:29
まぁ、全てを綺麗に書くことが正義という言語でもないし、本当に必要ならば手を汚す
こともあるけどな。>>884は手を染める理由としては全く不足だと思うが。
とりあえず買っちゃいけない類の本ではあるな。良い初心者は混乱し、悪い初心者は
汚れる。中級者以上なら他に投資すべき本があるだろう。
918デフォルトの名無しさん:2009/11/20(金) 03:10:28
確保したハンドルやリソースを開放しないままプログラムが終了しても
言語やOSの仕様でプログラム終了時に確実に回収することがわかっていて
かつ、リークしないこともわかっているなら、別に開放しないまま終わってもいいじゃないか。^^
たとえば、

int main() {
int* i = new int;
}

上のプログラムはメモリリークしていない。
なぜなら、ポインタが消失して削除不能になるのはプログラムが終了する瞬間であり
その直後にはすべてのリソースが回収されることが仕様で決まっているからだ^−^
美学とかいうなら別だが。
919デフォルトの名無しさん:2009/11/20(金) 03:28:08
classのお作法を守ってないからでしょ。後で書いた方?は直してるみたいだし
920デフォルトの名無しさん:2009/11/20(金) 03:37:02
あえてdeleteしない、なんて初心者向け解説本でやるべきじゃないよな。

「3D格闘ゲーム」ってことだから、おそらくキャラクタ2体分のオブジェクトを作って
プログラム終了まで開放しない、みたいなコードだと思うんだけど、
読者がそこから拡張していこうとした途端にメモリリークを起こす気がする。
921デフォルトの名無しさん:2009/11/20(金) 06:08:35
繰り返しのnewがでたらやばいんだって。
922852:2009/11/20(金) 08:12:39
この本はdelete問題の他にも、ちょっと「?」というか、もっと効率的な方法があるのでは?と
思ってしまうようなところもあるのですが、
アニメーション付Xファイルの読み込み、およびそれをゲーム中でアニメーションさせるところの
解説はものすごく参考になっています。
今までいくつかのWebサイトでそれを解説しているところも見てきましたが、
この本の内容が一番分かり易かったです。

アニメーションのための本質的なところ(動作、仕様レベル)だけ抽出して、
実装に向けたクラス設計や仕様は自分で改めて考えてからコーディングしていったら良いと思いました。
923デフォルトの名無しさん:2009/11/20(金) 09:00:43
分かりやすいように見えても、どこに罠が仕込まれてるか分からんのではなぁ
924デフォルトの名無しさん:2009/11/20(金) 09:06:43
糞コードを本にして売るほうも、本に書いてあるコードを吟味せずにそのまま使うほうもアホ
925デフォルトの名無しさん:2009/11/20(金) 09:12:37
Amazonレビューを見たら、そのアニメーションの解説も参考にするとまずそうな
雰囲気に見えるが…
まぁ、買っちまったら何とか活用したいんだろうけどなぁ…

つーかサンプルプログラムの作り方もひどそうだ
ゲームがコマンドライン引数でviewerに変わるらしいが、やってみたくてやっちゃった
のかな、使い勝手とか全然考えずにw
もちろん「コマンドラインの処理サンプルを入れたかったので」とか言い訳はいくら
でも思いつくが
926デフォルトの名無しさん:2009/11/20(金) 10:25:39
DLLとEXEでは使ってるアドレス空間が違うとのことなんですがポインタがどっちのアドレス空間に属しているかしらべる方法はありますか?
927デフォルトの名無しさん:2009/11/20(金) 11:15:06
>>918
そういう特殊な事例でしか当てはまらないものは
特殊な例としてあげればいいんだよ。

int foo() {
int* i = new int;
}
関数名を変えただけで、この処理はリークしているかもしれない。

int main() {
MyClass* i = new MyClass;
}
クラス名を変えただけだが、delete時にファイル削除とかしているかもしれない。

な? コードは修正されるもの。
そういうときに自分で罠を仕掛けてどうする。
928デフォルトの名無しさん:2009/11/20(金) 11:33:29
>>926
できるでしょうね
929デフォルトの名無しさん:2009/11/20(金) 11:44:16
連続稼働させるものや、多くメモリ確保する物では
メモリリークは致命的。
512K確保する関数を200回呼び出せば、合計で1ギガ消費する。
deleteしないでこれを放置するやつは超初心者
930デフォルトの名無しさん:2009/11/20(金) 11:45:57
ブラウザはよくリークする
931デフォルトの名無しさん:2009/11/20(金) 13:23:01
>>918
それはメモリリークだよ。
もう使わないからdeleteしていいのにdeleteしないままプロセス終了を迎えたら、それはメモリリーク。

「プロセス終了時に把握できているメモリリークがあっても特に問題無い」には反論しないけど、
「リークじゃない」はおかしい。

そのプログラムがメモリリークしてないなら、メモリリークしてるプログラムなんてこの世に無いよ。
932デフォルトの名無しさん:2009/11/20(金) 13:44:20
目立ってメモリリークしなければ無視でも良いけどね。
たとえば、4バイトのメモリリークで128M=2^24バイトたまるには、
400万回やらないといけない。
10秒に一回起こったとしても、400万回するには一年半ほどかかる。、
933デフォルトの名無しさん:2009/11/20(金) 14:14:47
まぁ、習慣的にリーク対策しないと、大事なとき忘れるし、コードの再利用したときも不具合を生みやすい。
俺は基本的にnewしないでスタックに確保するから、そういう問題はほとんどないな。
はやくスマートポインタが使いたいぜ。
934デフォルトの名無しさん:2009/11/20(金) 14:18:40
vcでメモリリーク検出できるからそれでいいよ。
わずかに残ったとしても致命的にはなりにくい。
なったら変更すればいいし。
935デフォルトの名無しさん:2009/11/20(金) 14:25:54
シングルトンな奴は基本 delete しねぇなぁ、俺は。
936デフォルトの名無しさん:2009/11/20(金) 15:10:46
new deleteはコンパイラ依存していますか?
別のコンパイラで確保したメモリを、VCでdeleteは出来ませんか?
937デフォルトの名無しさん:2009/11/20(金) 15:27:03
>>936
別のコンパイラどころか、同じコンパイラでも異なるDLLでnewしたオブジェクトをdeleteすることは
原則としてできません。(MFCの拡張DLLは別)
938デフォルトの名無しさん:2009/11/20(金) 15:34:39
new deleteはオーバーロードだってできるからな。
あえてやるひとはいないだろうけど、
自分以外誰にも使えないnewの実装だってありえる。
939デフォルトの名無しさん:2009/11/20(金) 15:37:30
そうだったんですか。
そうだとすると、DLLがメモリ確保してリターンしたら解放不可能になるんですか。
940デフォルトの名無しさん:2009/11/20(金) 15:40:48
んなこたーない
メモリを確保する関数 と 確保したメモリを開放する関数 を用意しときゃよい

fopen() と fclose() の関係
941デフォルトの名無しさん:2009/11/20(金) 15:49:42
DLL が提供しているのが newしたポインタを戻すだけで
その後始末の delete は呼び出し側がやってね  という造りはマズイ ってこと

DLL は 自前newしたものを戻すつもりなら それを受けて delete する部分も提供すべき

# で、後者を記述するのに安全を見て >>926 で保険かけたいんだけど… どうすれば良い?
# という流れになるのかな?
942デフォルトの名無しさん:2009/11/20(金) 15:50:14
Windows APIだとCreateなんたらでハンドル作ったら、
CloseHandleよびだしたりするね。
943デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/20(金) 16:03:32
内部実装に詳しいわけじゃないから適当にいうけど、
EXEから呼ばれるDLLがリンクしているalloc関数を実装しているライブラリ・・・が
OSにメモリ割り当てを要求して、OSが返してくれる適当なメモリ領域・・・・の
一部分をallocが適当に調節して返すんだから、
どっかOSが適当に決めた場所なんじゃないの?
945デフォルトの名無しさん: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デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/20(金) 17:48:12
C言語でWin32APIをさわっています。winbase.hに
WINBASEAPI VOID WINAPI OutputDebugStringA(__in LPCSTR lpOutputString);

と書いてあったんですが__inって何ですか?
948デフォルトの名無しさん:2009/11/20(金) 17:53:49
http://msdn.microsoft.com/en-us/library/aa383701(VS.85).aspx
まずは自分で調べてほしい。
949デフォルトの名無しさん:2009/11/20(金) 18:38:48
DLLとメモリのやりとりを確実にするには、(HANDLE, char*)のペアで
扱うのが良いと思いますが、
一方ではペアとして、一方ではchar*と自動的にキャストさせる方法はありますか。
950デフォルトの名無しさん:2009/11/20(金) 18:43:12
>>948
縛りの弱いconstのようなものでしょうか?
SAL解釈と言うんですね
ググったんですがなかなかそこまでたどり着けませんでした
951949:2009/11/20(金) 18:43:43
自作関数だと、ペアでもchar*でも受け入れるように出来ますけど
自作ではない関数に対しても、自動でキャストして通るように出来れば便利なんですが。
952デフォルトの名無しさん:2009/11/20(金) 18:46:22
何でもかんでも暗黙キャストしてると後ですごい不安になる
953950:2009/11/20(金) 18:46:57
>SAL解釈と言うんですね
SAL注釈ですね、間違えました
954デフォルトの名無しさん:2009/11/20(金) 18:47:31
double - int みたいな暗黙キャストを実現する方法はないですか?
955デフォルトの名無しさん:2009/11/20(金) 19:00:34
>>949
ごめん、なんでハンドルが出て来るのか分からない。
956デフォルトの名無しさん:2009/11/20(金) 19:05:55
>>946

HANDLE hHeap = HeapCreate(NULL, 0, 0); と char *p; のペアを 
char*型のように扱いたいって事なんです。
無理でしょうか?
957デフォルトの名無しさん:2009/11/20(金) 19:33:10
std::vector< boost::shared_ptr< T > > と boost::ptr_vector< T > はどちらを使っても同じでしょうか?
「一方ではこれができないから注意!」とかあったら教えてください m(_ _)m
958デフォルトの名無しさん:2009/11/20(金) 19:45:50
猿介錯
959デフォルトの名無しさん:2009/11/20(金) 19:52:27
よくわからないならvector<shared_ptr<T>>のほう使っとけ
960957:2009/11/20(金) 20:33:38
>>959
分かりました!
ありがとうございます!
961デフォルトの名無しさん:2009/11/20(金) 20:43:50
shared_ptrって余分に一回メモリ確保してない?あれは何なの?
962デフォルトの名無しさん:2009/11/20(金) 21:00:30
参照回数を共有するため、その変数を確保してる。
963デフォルトの名無しさん:2009/11/20(金) 21:00:34
関数の戻り値は、通常 値渡しですが
100Mほどのデータをもつクラスでも値渡しになりますか。
(値渡しのコストを下げるために) もし100Mがポインタに入っていて、
auto変数でリターンするとデストラクタが働いてメモリは解放されてしまいますが
newで確保した物をリターンすると、それは解放できなくなりますか。
964デフォルトの名無しさん:2009/11/20(金) 21:03:27
戻り値にクラスを持ってこずに引数を参照渡しにすればいいのですが
変数を用意する事無しに、リターンがクラスになっていると便利なことがあるんです。
965デフォルトの名無しさん:2009/11/20(金) 21:27:13
戻り値がクラスというのは意味不明。

オブジェクトを返すとして、たとえば、
 LARGE func() { return * new LARGE; }
というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。

LARGE & func( LARGE & inout ) {
 //LARGEを使った処理。
 return inout;
}
として、外で大きなデータを用意してやるか、
funcで全く新しいオブジェクトを作成したいと言うなら、newしてポインタを返せばよい。
966デフォルトの名無しさん:2009/11/20(金) 21:38:14
>>965
Qtでこんな関数をオーバーロードしろって言われてるんだけど、
何を返せばいいの?

QSize sizeHint(引数略)
{
  return ?
}
967デフォルトの名無しさん:2009/11/20(金) 22:05:09
QSizeオブジェクトでいいと思うよ。
968デフォルトの名無しさん:2009/11/20(金) 22:16:32
え? でも>>965・・・
969デフォルトの名無しさん:2009/11/20(金) 22:18:16
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

あとこんなのもあるんですが・・・
970デフォルトの名無しさん:2009/11/20(金) 22:20:50
QSizeオブジェクトを返すことが、ライブラリによって強制されてるんだから、従えよ。
971デフォルトの名無しさん:2009/11/20(金) 22:21:12
お前が何を聞きたいのかわからない
972デフォルトの名無しさん:2009/11/20(金) 22:23:15
> というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。
ってかいてるじゃないですか
973デフォルトの名無しさん:2009/11/20(金) 22:23:59
QSizeって大きくないでしょ。(というか100Mというサイズはどこから)
値で返しても何も問題ないじゃん。
974デフォルトの名無しさん:2009/11/20(金) 22:40:44
それ以前に

QSize sizeHint(引数略)

をオーバーロードするのに、
戻り値を参照やポインタにはできんだろ。
オーバーロードのルールを思い出すのだ。
975デフォルトの名無しさん:2009/11/20(金) 22:42:16
いや、戻り値を変えられないのはオーバーライドじゃろ。
976デフォルトの名無しさん:2009/11/20(金) 22:47:28
たまにいるよね(値|参照)(返し|渡し)の違いがわからない人って
まあわからないようなレベルでできることなんて高が知れてるから分かるまで値返しでいいんじゃないかな
977デフォルトの名無しさん:2009/11/21(土) 05:12:37
インテルコンパイラでコンパイルしている場合に#ifdef分岐させたい場合、
#ifdefの後何を書けばよいのでしょうか?
978デフォルトの名無しさん:2009/11/21(土) 05:16:39
defined (__ICC)
979デフォルトの名無しさん:2009/11/21(土) 05:35:04
http://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デフォルトの名無しさん:2009/11/21(土) 09:58:59
>>980
こことか見てた
Programing Place
ttp://www.geocities.jp/ky_webid/index_old.html
982デフォルトの名無しさん:2009/11/21(土) 12:57:09
ロベールの翻訳は分かりやすい
983デフォルトの名無しさん:2009/11/21(土) 13:17:19
>>982
どこが翻訳なんですか?
984デフォルトの名無しさん:2009/11/21(土) 16:38:20
自作クラスをcoutで出力するにはどうすれば良いですか?
985デフォルトの名無しさん:2009/11/21(土) 16:41:43
ここみたら無理そうなことがわかりました
諦めました
http://www.jah.ne.jp/~naoyuki/Writings/ExtIos.html
986デフォルトの名無しさん:2009/11/21(土) 17:00:01
そのページに書いてあるのは標準ストリームクラスの拡張であって、
君がやりたいのは標準ストリームクラスで自作クラスを出力することでしょ?
まったくの別件だと思うよ。

君が勉強すべきなのは、演算子オーバーロード。
987デフォルトの名無しさん:2009/11/21(土) 17:06:21
サンクス!です
988デフォルトの名無しさん:2009/11/21(土) 17:27:13
これで出来ることはわかりましたが、char*からsize分だけ渡すにはどうすればいいですか。


std::ostream& operator<<(std::ostream& os, const ustring& x) {
return (os<<*****): }
989デフォルトの名無しさん:2009/11/21(土) 18:15:23
>>983
多くのプログラミング書籍が洋書からの翻訳であることを揶揄したジョークだろう
よく書かれるコピペみたいなものだ
990デフォルトの名無しさん:2009/11/21(土) 18:22:42
>>988
C/C++言語の仕様で\0まで出力だと思うので、任意の場所に\0を突っ込んでやればいいと思うよ。
バッファのオーバーランやアンダーランに気をつけて。
991デフォルトの名無しさん: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デフォルトの名無しさん:2009/11/21(土) 18:39:11
>>991
変数でもないものの参照を返したいとか訳分からん
値を返すんだと不都合なの?
993デフォルトの名無しさん:2009/11/21(土) 18:39:28
>991
やりたい事は本当に operator[] で char* & を返す事なのか?
ch って char* なんだよな?
string と名のつく型で operator[] だったら普通 char& が返ると思うんだが。
994デフォルトの名無しさん:2009/11/21(土) 18:43:27
値で返すと
memcpy(buf, &str[0], size);
が実行できないんです。

error メモリ上に配置されなければならない

がでます。
static char*の参照返しだと出ません。
995デフォルトの名無しさん:2009/11/21(土) 18:44:35
わかりました。間違えてました。>>993さんのご指摘通り間違えしてました。
996デフォルトの名無しさん:2009/11/21(土) 19:05:39
>>988 たのみます 
char* , intが与えられたときに標準出力( << )に\0を含む文字列を出力したいです。
997デフォルトの名無しさん:2009/11/21(土) 19:31:43
>>996
その前に、どういうインタフェースにしたいのか考えれ。
operator<< をオーバーロードすると
cout << yourclass << endl;
のような書き方ができるわけだが、
char*とintの二つのパラメータを与えるなら
そういう書き方はできなくなる。
それとも const char * operator()( int ) みたいなメンバを持たせて
cout << yourclass( 文字数 ) << endl;
とかけるようにでもするかい^^
998デフォルトの名無しさん:2009/11/21(土) 19:37:28
stringは、string(ch, size)で、\0を含む文字列を
cout<<に渡せるじゃないですか。
この実装はどうやってるのかわかりたいです。
999デフォルトの名無しさん:2009/11/21(土) 19:45:50
templateクラスのメソッドってnewしたら使われてなくても全部実体化しちゃう?
1000デフォルトの名無しさん:2009/11/21(土) 20:03:01
>>998
コンストラクタの話とoperator<<の話がごっちゃになってるじゃないか^^
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。