【初心者歓迎】C/C++室 Ver.69【環境依存OK】
レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん
2009/10/20(火) 16:10:55ただしその場合、質問者は必ず環境を書きましょう。
※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でのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か に置換すると見栄えだけはよくなります。
0002デフォルトの名無しさん
2009/10/20(火) 16:39:55お疲れさまです。
0003前スレ964
2009/10/20(火) 16:45:59atexit()で終了関数呼び出して
その中で
delete this;
なんてやったらだめなんでしょうかね?
0004デフォルトの名無しさん
2009/10/20(火) 16:56:21そこまでして自己破壊する理由は?
単にexit()を使わなければいいだけなのに敢えてそうしない理由が判らん。
0005デフォルトの名無しさん
2009/10/20(火) 17:11:15exit関数を使わなければよいことは分かってるんでしょう。
その上で、どうしてもexit関数を使いたいってことだろうから
余程の事情があるんだと思うよ。
好奇心からという可能性も。
0006デフォルトの名無しさん
2009/10/20(火) 17:46:34exitを使わない方法を検討した方がいいよ
0007前スレ964
2009/10/20(火) 18:18:100008デフォルトの名無しさん
2009/10/20(火) 19:37:58exitすれば自動変数のデストラクタが呼ばれないから無理です。
0009デフォルトの名無しさん
2009/10/20(火) 23:00:43というのはどうか。
hoge.~hoge();
0010デフォルトの名無しさん
2009/10/20(火) 23:14:07スタックが全部破棄された後なんだからダメだろうよ。
0011デフォルトの名無しさん
2009/10/21(水) 00:07:300012デフォルトの名無しさん
2009/10/21(水) 00:09:500013デフォルトの名無しさん
2009/10/21(水) 00:24:500014デフォルトの名無しさん
2009/10/21(水) 00:27:280015デフォルトの名無しさん
2009/10/21(水) 00:29:590016デフォルトの名無しさん
2009/10/21(水) 00:33:090017デフォルトの名無しさん
2009/10/21(水) 05:47:46制約が相当ひどいけど、少しずつマシにはなっている模様(例外が使えなかったのが
使えるようになったり)
0018デフォルトの名無しさん
2009/10/21(水) 11:01:080019デフォルトの名無しさん
2009/10/21(水) 11:03:220020デフォルトの名無しさん
2009/10/21(水) 13:11:16左上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";
}
0021デフォルトの名無しさん
2009/10/21(水) 13:13:10危ないから、xはポインタにしないで〜。
0022デフォルトの名無しさん
2009/10/21(水) 13:35:16#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;
}
0023デフォルトの名無しさん
2009/10/21(水) 13:41:06ありがとうございます!
0024デフォルトの名無しさん
2009/10/21(水) 14:41:16ファイルを開いて、1レコードづつ読みこんでから各項目ごとに決められた
バイト数で分けるのって、どうゆう関数を使えばいいんでしょうか
0025デフォルトの名無しさん
2009/10/21(水) 14:47:24fgets()
sprintf()
0026デフォルトの名無しさん
2009/10/21(水) 14:53:02たとえば適当な数列を並べて出力するプログラムがあったとして
それを文字列としてstringに入れるといった感じで
0027デフォルトの名無しさん
2009/10/21(水) 15:00:42大抵の環境なら、リダイレクトを使えばいい。
例えばWindowsなら
some.exe | other.exe
unix系なら
some | other
といった要領。
これなら前者は標準出力でいいし、後者は標準入力でいい。
必要なら、片方がもう片方をpopen()で起動してもいい。
双方向であったりパフォーマンスが要求されるなら事が足りないが、
先ずはこの辺りから始めては如何か。
0028デフォルトの名無しさん
2009/10/21(水) 15:08:32ありがとうございます。
やってみます
0029デフォルトの名無しさん
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);
0030デフォルトの名無しさん
2009/10/21(水) 16:06:35struct widget
{
    xxx method();
};
widget w, *p = new widget;
w.method(); // 参照を返したい
p->method(); // ポインタを返したい
// ↓のように使いたい
w.method().method().method();
p->method()->method()->method();
// ↓のような形は統一感がないから避けたい
p->method().method().method();
0031デフォルトの名無しさん
2009/10/21(水) 16:07:44実験してみたら、スタックが全部破棄される前にatexitで登録した関数で
デストラクタを走らせることができたよ。
0032デフォルトの名無しさん
2009/10/21(水) 16:10:29> w.method().method().method();
> p->method()->method()->method();
こっちのほうがよっぽど統一感がない。
そもそも.演算子はオーバーロードできない。
003329
2009/10/21(水) 16:15:48のところを
mii.dwTypeData = _T("メニュー");
mii.cch = wcslen(mii.dwTypeData);
にしたら一応出るようになりました。失礼しました〜。
0034デフォルトの名無しさん
2009/10/21(水) 16:54:410035デフォルトの名無しさん
2009/10/21(水) 17:31:57何がどう楽?
0036デフォルトの名無しさん
2009/10/21(水) 17:34:530037デフォルトの名無しさん
2009/10/21(水) 19:31:40template <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;
}
0038デフォルトの名無しさん
2009/10/21(水) 19:40:38std::accumulateに何の不満があるのか
0039デフォルトの名無しさん
2009/10/21(水) 19:46:33std::iterator_traits<Iterator>::value_type
0040デフォルトの名無しさん
2009/10/21(水) 19:50:08ありがとうございます。
たしかに、acumulate で総和は求まるのですが、総和を求めるということは
今回、例えであって、疑問の本質はIterator からT 型が推論できるテクニックが知りたいのです、
言葉足らずですみません。
0041デフォルトの名無しさん
2009/10/21(水) 19:51:20ありがとうございます
やっと、std::iterator_traits の意味が理解できました。
0042デフォルトの名無しさん
2009/10/21(水) 19:52:030043デフォルトの名無しさん
2009/10/21(水) 19:53:42〜はどう実装してるの? つミboost::hogehoge ←こいつマジアホ
0044デフォルトの名無しさん
2009/10/21(水) 20:03:020045デフォルトの名無しさん
2009/10/21(水) 20:04:260046デフォルトの名無しさん
2009/10/21(水) 20:04:270047デフォルトの名無しさん
2009/10/21(水) 20:06:42という引数を
template <class Iterator>
Iterator だけにして、Iterator からT 型を推論できないでしょうか?
総和を求めるプログラムを例として説明しますと
という書き始めであればよかったと
0048デフォルトの名無しさん
2009/10/21(水) 20:08:260049デフォルトの名無しさん
2009/10/21(水) 20:24:41これがベストかな。一応質問では推論できないか?というところが疑問文だから、
それに答えればいいのだろうけど。まあ、でも、誤解はしなかった。
0050デフォルトの名無しさん
2009/10/21(水) 22:36:30スタックが破棄される前なのか後なのか、どうやって確認したんだ?
0051デフォルトの名無しさん
2009/10/21(水) 22:37:13(*p).method().method().method() ですべて解決だ。
0052デフォルトの名無しさん
2009/10/21(水) 23:01:21template <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;
}
0053デフォルトの名無しさん
2009/10/21(水) 23:16:42typename 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;
}
0054デフォルトの名無しさん
2009/10/21(水) 23:17:13std::iterator_traits<ResultType>::difference_type
0055デフォルトの名無しさん
2009/10/21(水) 23:17:240056デフォルトの名無しさん
2009/10/21(水) 23:20:19イテレータの距離を求めるにはstd::distanceを使う。
005753
2009/10/21(水) 23:24:390058デフォルトの名無しさん
2009/10/21(水) 23:31:10皆さんありがとうございます。これでいいのかな?そして、この平均値を求める関数を、クラスに組み入れるにはどうしたらいいのでしょうか?
わざわざ、クラスに組み入れなくてもいいじゃんという、意見も聞こえてきそうなのですが、教えて頂けないでしょうか。
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;
}
0059デフォルトの名無しさん
2009/10/21(水) 23:35:00Hoge h; res = h.ave(f, l);
0060デフォルトの名無しさん
2009/10/21(水) 23:44:11couの型はvalue_typeじゃないだろ。
0061デフォルトの名無しさん
2009/10/21(水) 23:53:42error 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());
0062デフォルトの名無しさん
2009/10/22(木) 00:07:290063デフォルトの名無しさん
2009/10/22(木) 00:52:260064デフォルトの名無しさん
2009/10/22(木) 00:56:040066デフォルトの名無しさん
2009/10/22(木) 01:56:33こう修正しないとだめだな。
0067デフォルトの名無しさん
2009/10/22(木) 02:00:56std::accumulate使ってるんだからfirst<lastを仮定していいだろ
0068デフォルトの名無しさん
2009/10/22(木) 02:17:08size_t cou = distance( first, last ); // first と last の順番が逆
と修正。
0069デフォルトの名無しさん
2009/10/22(木) 06:52:00別のクラスオブジェクトをmainの自動変数で作って、exit呼び出し時にデストラクタが走ってない
ことを確認した。
0070デフォルトの名無しさん
2009/10/22(木) 08:12:32デストラクタが走らないとまずいね
0071デフォルトの名無しさん
2009/10/22(木) 10:10:50だからatexit()で走らせたんだろ。
0072デフォルトの名無しさん
2009/10/22(木) 10:28:26operator()()が返すのは単に(内部で持っている)平均値との差の平方じゃないか。
どうせなら、StandarDeviation(vec.begin(), vec.end())って関数にしてくれ(ぉぃ
# まぁ、既に手元には平均やら標準偏差やらを返すメンバ関数を持つ、クラスがあるから要らないけど。
0073デフォルトの名無しさん
2009/10/22(木) 12:35:16それがスタック破棄の前後と関係すると思ってるのなら勘違い。
0074デフォルトの名無しさん
2009/10/22(木) 12:51:35なぜ? スタックの破棄はオブジェクトの破棄を終えてから行うのでは?
0075デフォルトの名無しさん
2009/10/22(木) 13:15:55通常の関数脱出時の動作ではそうだけど、 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() にその処理を正しく登録することがほとんど不可能なんじゃないかと思う。
0076デフォルトの名無しさん
2009/10/22(木) 13:25:50なるほど。exit呼び出し時にはオブジェクトの破棄を行わないのだから、>>69では
確認になってないということね。だが、それでは、>>10の突っ込みがよく分からないが。
(>>75=>>10という意味ではない)
ただ、実験したのは>>9なので、君の言うとおり結局は問題ないでしょ。atexitに登録した
関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。
ほぼ無意味で、実用性のない手法だが、可能は可能ということで。
0077デフォルトの名無しさん
2009/10/22(木) 13:29:55意味がよく分からない。スタック上のオブジェクトが破棄されないのだから、
mainでの自動変数のデストラクタより、atexitに登録した関数でmainでの自動変数の
デストラクタのほうが先に走るのは当たり前だから。
0078デフォルトの名無しさん
2009/10/22(木) 13:42:35の使い方が変じゃないか?
>>10はそれを勘違いしてたのだろうか
>>73はスタックが保持されることを知らなかったのだろうか
とかでよくね
0079デフォルトの名無しさん
2009/10/22(木) 13:43:51○>>73は俺と同じく、スタックが保持されることが確実であることを知らない人だったのかな
0080デフォルトの名無しさん
2009/10/22(木) 13:45:11解放されてしまう可能性があると考えていたんだろう。で、実はその心配はないという話。
0081デフォルトの名無しさん
2009/10/22(木) 13:45:370082デフォルトの名無しさん
2009/10/22(木) 13:49:36変ではないと思うよ。
>>79
まあ、そういうことだね。
>>81
不可能ではないよ。実際やったので。
0083デフォルトの名無しさん
2009/10/22(木) 14:01:070084デフォルトの名無しさん
2009/10/22(木) 14:03:27>>76の最終行だね。
で、この話は前スレから続いてて、>>3に>>8が突っ込んで、>>9で冗談めかして書いた
という流れ。
0085デフォルトの名無しさん
2009/10/22(木) 14:04:53だから、間違いなくatexit()で呼び出されるように登録することは難しいといいたいのだろ。
少なくとも、exit()を使わないと言う同程度で済むもっとスマートな方法があるのだから。
0086デフォルトの名無しさん
2009/10/22(木) 14:07:33>>76
> atexitに登録した関数ではグローバル変数のポインタにmainでの自動変数のアドレスを代入して行った。
これでは駄目か?
> 少なくとも、exit()を使わないと言う同程度で済むもっとスマートな方法があるのだから。
例えば? 例外は話題にあったけど、それはパフォーマンスコストが高くなる可能性があると
いう意見があった。だが、例外でってこと?
0087デフォルトの名無しさん
2009/10/22(木) 14:09:39つまり、main内で自動変数のオブジェクトのアドレスをグローバル変数のポインタに
代入し、atexitに登録した関数内でそのグローバル変数のポインタから逆参照して
デストラクタを実行する処理を書いたということ。
0088デフォルトの名無しさん
2009/10/22(木) 14:17:27つーか例外コストを異常に高く考えすぎ
0089デフォルトの名無しさん
2009/10/22(木) 14:23:31正常系なら main まで return してくるのが望ましい。
異常系なら例外でおk。
0090デフォルトの名無しさん
2009/10/22(木) 14:24:55そんな方法、ふつうにいくつか関数呼び出してそれぞれに自動変数があるってだけで破綻するだろ。
0091デフォルトの名無しさん
2009/10/22(木) 15:39:42atexitで何とかするってのは元々ネタで、それが駄目とか言われたからやってみたって
流れなんじゃないの。
>>89
mainまでreturnしてくるってのは正しい手法ではあるが、普通であって、スマートではないな。
実際面倒だし。
0092デフォルトの名無しさん
2009/10/22(木) 16:38:36集計した金額を出力させたいのですがif文での作り方がわかりません。
誰か教えてください。
0093デフォルトの名無しさん
2009/10/22(木) 18:33:03前の商品番号を記録しておく
0094デフォルトの名無しさん
2009/10/22(木) 19:00:24メインスレッドのハンドルを取得する関数ってありますか?
0095デフォルトの名無しさん
2009/10/22(木) 19:05:22環境依存。まぁ、サブスレッド起動時に渡しておけば?
0096デフォルトの名無しさん
2009/10/22(木) 19:59:46> それが駄目とか言われたからやってみた
そんで、ほんとに出来たのかなあと思って突っ込んだらだんまりになっちゃったという流れ
0097デフォルトの名無しさん
2009/10/22(木) 20:00:58やれたところで糞設計すぎて全く話にならないのは確定なんだし
0098デフォルトの名無しさん
2009/10/22(木) 20:04:41{
virtual void method() = 0;
};
class widget : public iface
{
virtual void method() { ・・・ }
};
int main(void)
{
iface *p = new widget; p->method(); return 0;
}
こういう風に継承の過程で可視性を変えるのはありなんでしょうか?
0099デフォルトの名無しさん
2009/10/22(木) 21:03:15できたのは事実だし、だんまりでもない。スレを読み返せ。
>>97
やりもしないでやった気でいるよりもましだと思うぜ。
0100デフォルトの名無しさん
2009/10/22(木) 21:06:160101デフォルトの名無しさん
2009/10/22(木) 21:10:01>>90とかは?
0102デフォルトの名無しさん
2009/10/22(木) 21:13:43>>101
実用的でないことは重々承知してやってるんだろ。何を勘違いしてんだ。
0103デフォルトの名無しさん
2009/10/22(木) 21:14:39> やりもしないでやった気でいるよりもましだと思うぜ。
こんなのは、やらない方がマシの部類。
0104デフォルトの名無しさん
2009/10/22(木) 21:14:470105デフォルトの名無しさん
2009/10/22(木) 21:17:570106デフォルトの名無しさん
2009/10/22(木) 21:17:59それぐらいしか言えないか……。まあ、仕方ないよね。
0107デフォルトの名無しさん
2009/10/22(木) 21:18:57突っ込んでる側でも勘違いしてるのがいたんだから、それなりに役に立ってるとは思う。
0108デフォルトの名無しさん
2009/10/22(木) 21:20:29「やらない奴よりまし」は無い。やる奴がおかしいだけ。悪い意味で。
0109デフォルトの名無しさん
2009/10/22(木) 21:21:58別に勘違いしたままでもいいんじゃね、真人間は一生こんなクソコード書かないだろうし
0110デフォルトの名無しさん
2009/10/22(木) 21:23:01突っこみが間違ってると思ったからやったんじゃないか。実際間違っていたし。
スレをよく読めよ。思いこみだけで書かないでさ。
0111デフォルトの名無しさん
2009/10/22(木) 21:23:53exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。
0112デフォルトの名無しさん
2009/10/22(木) 21:25:21スタックは破棄されるだろ、デストラクタは走らないが
0113デフォルトの名無しさん
2009/10/22(木) 21:26:47>>75を読めよ。
> これに加えて 3.7.2 Automatic storage duration p1 から
> > The storage for these objects lasts until the block in which they are created
> > exits.
> ということで、スタックは保持されたままなので atexit() で自動変数のデストラクタを
> 呼びだしても問題ないみたい。
0114デフォルトの名無しさん
2009/10/22(木) 21:27:29直後じゃなくて最終的な話な
0115デフォルトの名無しさん
2009/10/22(木) 21:28:290116デフォルトの名無しさん
2009/10/22(木) 21:28:360117デフォルトの名無しさん
2009/10/22(木) 21:30:10プログラム終了時にスタックが破棄されるのは当然だろ。atexitで登録した関数が
呼び出される前にスタックが破棄されるわけではないってことだろ。認識大丈夫?
0118デフォルトの名無しさん
2009/10/22(木) 21:32:44>>86みたいなアホが粘るから、いい加減にしろ使い物にならねぇから、って話だろ
0119デフォルトの名無しさん
2009/10/22(木) 21:37:52話が逸れてるな。
実用的じゃないことぐらいみんな理解してる。
出来た出来たと言っているが、関数内からのexit時についても出来たのか、それとも出来なかったのか。
0120デフォルトの名無しさん
2009/10/22(木) 21:40:51何かずれてるぞ。>>86はatexitを使用するのは無意味だと認識してるだろ。
0121デフォルトの名無しさん
2009/10/22(木) 21:42:02認識大丈夫?の前に日本語大丈夫?と問いたい。
話の流れで、
> exit呼び出し後にスタックが破棄されると勘違いしてた奴にとっては別だろうな。
exit呼び出し後にはもちろんスタックが破棄されるよ。
>atexitのタイミングでは、必ずしもスタックが保持されないと勘違いしてた奴にとっては別だろうな。
0122デフォルトの名無しさん
2009/10/22(木) 21:45:01>>75を読んでも、exitしてからatexitに入るまでの間にスタックも静的記憶も
ヒープも決して破壊されない、という保証には見えない上に、そんな細かい
実用的にどうでもいい仕様は、仮に規格で規定されていたとしても処理系が
正しく準拠してくれることはほとんど期待できない。
あくまで仕様のテストとして(程度の低い曲芸だが)割り切るならまだしも、
実用にならないんだろうか、というような話を続けている奴が>>86のように
実際にいるから、いいかげんにしてくれ、って話になる。
0123デフォルトの名無しさん
2009/10/22(木) 21:46:08できたから書いてるんだろう。そう読めるが。
今自分でもやったらできたよ。
0124デフォルトの名無しさん
2009/10/22(木) 21:48:17・やるべきじゃないからもう実験も要らない
0125デフォルトの名無しさん
2009/10/22(木) 21:52:23少なくとも自動変数が保持されるのは書いてるように見える。
実用上どうでもいいとまで言いきっちゃうのはどうかと思うが。
自分には>>86が実用にならないんだろうかなどという話をしてるようには読めない。
0126デフォルトの名無しさん
2009/10/22(木) 21:53:45atexitに登録された関数の実行のタイミングぐらいは知っとけよ。
0127デフォルトの名無しさん
2009/10/22(木) 21:54:36実用にならないんだろうか
→実用に耐えうる場面もあるのではないだろうか
0128デフォルトの名無しさん
2009/10/22(木) 21:56:12つまり、ポインタは有効であることが保証されるが、free可能な領域を指していない可能性は大いにあると
0129デフォルトの名無しさん
2009/10/22(木) 21:58:460130デフォルトの名無しさん
2009/10/22(木) 21:59:440131デフォルトの名無しさん
2009/10/22(木) 22:06:17そんなふうには書いてないだろ。
0132デフォルトの名無しさん
2009/10/22(木) 22:11:33登録するというかっこいい超設計より、例外一発でmainまで脱出して終了する
方がコスト高いかもしれないと思ってることになるから、exitの実装より例外の
実装を勉強した方がいいとは思う
0133デフォルトの名無しさん
2009/10/22(木) 22:12:03いや、実際デキるのかもしれないけど状況はスルー力検定開催中だよ
0134デフォルトの名無しさん
2009/10/22(木) 22:15:33そこまで誤読できるのもすごいわ。勝手にやってな。
0135デフォルトの名無しさん
2009/10/22(木) 22:16:22勝手に書き込みをしている人にいちいち噛み付くのはなぜなのかしら〜♪
0136デフォルトの名無しさん
2009/10/22(木) 22:17:290137デフォルトの名無しさん
2009/10/22(木) 22:18:430138デフォルトの名無しさん
2009/10/22(木) 22:19:35>>134の時点でもう相手しても無駄かなと思えたってことだろ。アホですか。
0139デフォルトの名無しさん
2009/10/22(木) 22:21:04書いてるだろ
0140デフォルトの名無しさん
2009/10/22(木) 22:23:38○まともに反論できなくなってきちゃったから降りたいな
0141デフォルトの名無しさん
2009/10/22(木) 22:25:000142デフォルトの名無しさん
2009/10/22(木) 22:25:380143デフォルトの名無しさん
2009/10/22(木) 22:28:460144デフォルトの名無しさん
2009/10/22(木) 22:29:48>>85
> だから、間違いなくatexit()で呼び出されるように登録することは難しいといいたいのだろ。
間違いなくatexitに登録した関数が実行されるように登録するのは難しくないということを
言ってるんだろ。
0145デフォルトの名無しさん
2009/10/22(木) 22:31:170146デフォルトの名無しさん
2009/10/22(木) 22:32:04って話だろ
0147デフォルトの名無しさん
2009/10/22(木) 22:32:500148デフォルトの名無しさん
2009/10/22(木) 22:32:58無駄に面倒、という言い方にすべき。
0149デフォルトの名無しさん
2009/10/22(木) 22:33:45それは、勧められる話ではないが、グローバル変数を使えば難しくないだろ。
0150デフォルトの名無しさん
2009/10/22(木) 22:33:510151デフォルトの名無しさん
2009/10/22(木) 22:34:350152デフォルトの名無しさん
2009/10/22(木) 22:34:48バトルしてるつもりなの?w
0153デフォルトの名無しさん
2009/10/22(木) 22:35:32別に。
しかも実際に懸念通りの展開になってしまったようで。
0154デフォルトの名無しさん
2009/10/22(木) 22:37:18exitは基本的に正常終了のときに使うんだが。
ttp://www.linux.or.jp/JM/html/LDP_man-pages/man3/exit.3.html
> exit() 関数は、プロセスを正常に終了させ、 status & 0377 という値を親プロセスへ返す (wait(2) を参照)。
0155デフォルトの名無しさん
2009/10/22(木) 22:38:36揚げ足かどうかは認識の違いだな。元々ネタなんだし。
0156デフォルトの名無しさん
2009/10/22(木) 22:38:40正常系≠正常終了
0157デフォルトの名無しさん
2009/10/22(木) 22:39:32正常系でもプログラムをさっさと終わらせたいことだってある。
0158デフォルトの名無しさん
2009/10/22(木) 22:40:09それならば例外を使っても問題は無い
0159デフォルトの名無しさん
2009/10/22(木) 22:41:00変に乱用しなきゃいいだけ。
0160デフォルトの名無しさん
2009/10/22(木) 22:41:410161デフォルトの名無しさん
2009/10/22(木) 22:41:48自分もそう思うが、前スレで強く否定する人や正常系で例外を使うべきでないという
正論を言う人がいたりして、今は揺れているというのが実状。
0162デフォルトの名無しさん
2009/10/22(木) 22:46:30atexitを駆使してまで例外での脱出を避けるのは、goto絶対禁止とかそういう部類を
思い出すが。まぁ例外はコストがわずかに掛かるが。
とは言っても、例外を完全に排除して例外非対応コンパイルでもしない限り、例外
をthrowかcatchしなきゃ(例外仕様は当然書かない)効率は変わらない訳で、実際
のところはやっぱり宗教論争としか。
0163デフォルトの名無しさん
2009/10/22(木) 22:52:49いい加減何度も書くのもアレなんだが、元々ネタなんだよ。自分が担当者だったら、
C++でatexitなんて絶対使わない。(Cならデストラクタがない分、使えば便利なときも
あるかもしれない)
自分は元々さっさと終わりたいときは正常系で例外投げていたクチなんで、例外時に
予期しない重い処理が走る可能性があるとか、正常系で例外は投げるべきでないとか
言われると、ちょっとな。正論は強い。
自分が書いたコードで、「例外使っていて便利でしょ?」とか見せたとき、そんなことを
言われると、返す言葉もない。
0164デフォルトの名無しさん
2009/10/22(木) 22:53:510165デフォルトの名無しさん
2009/10/22(木) 22:55:01最初はともかく、いつの間にかネタじゃなくなってるようにしか見えない奴がいる
って話だろ
0166デフォルトの名無しさん
2009/10/22(木) 22:56:41関数を抜けるときに必要分POPしたりすんの?
0167デフォルトの名無しさん
2009/10/22(木) 22:57:010168デフォルトの名無しさん
2009/10/22(木) 22:59:43↓
何もやらないで文句言う奴よりまし
↓
どうせやらないことをだらだら無駄に実験垂れ流す奴よりまし
↓
取っ組み合い
0169デフォルトの名無しさん
2009/10/22(木) 23:01:07元々atexitを使ってるプログラムのデバッグをさせられるなんて可能性は十分に
考えられるよ。規格、仕様なら隅々まで知っていて損はない。
0170デフォルトの名無しさん
2009/10/22(木) 23:02:41そういう範疇の話から逸脱してきてるじゃん>>86は明らかに
0171デフォルトの名無しさん
2009/10/22(木) 23:03:45そういうふうにしか捉えられなかったとしたらすまなかった。
0172デフォルトの名無しさん
2009/10/22(木) 23:09:17こういう人は絶対に「お前の方が馬鹿だ」って態度を曲げないと思うけど、
まだ取っ組み合うの?
0173デフォルトの名無しさん
2009/10/22(木) 23:11:440174デフォルトの名無しさん
2009/10/22(木) 23:13:21馬鹿にはしてないよ。ちょっと深読みしすぎじゃないか。
0175デフォルトの名無しさん
2009/10/22(木) 23:15:480176デフォルトの名無しさん
2009/10/22(木) 23:17:070177デフォルトの名無しさん
2009/10/22(木) 23:17:320178デフォルトの名無しさん
2009/10/22(木) 23:20:070179デフォルトの名無しさん
2009/10/22(木) 23:33:34◎◎◎
◎◎◎
0180デフォルトの名無しさん
2009/10/23(金) 00:15:40DVDから起動したり、読み取りアクセスしかない場合はカレントディレクトリには出来ないのですが。
0181デフォルトの名無しさん
2009/10/23(金) 00:22:24tmpfile()
が使えるかも知れない
0182デフォルトの名無しさん
2009/10/23(金) 00:22:43環境変数で設定されているテンポラリフォルダに作る
0183デフォルトの名無しさん
2009/10/23(金) 00:39:16環境変数は、どの環境でも同じやり方で、確実にとれるんですか。
0184デフォルトの名無しさん
2009/10/23(金) 00:42:02そのファイルをリネームしたりしたいんです。
0185デフォルトの名無しさん
2009/10/23(金) 00:52:06ファイルのリネームだって環境依存だろうに
ディレクトリデリミタの問題だってある
せめてgccとかビルド環境を限定しないと答えられんのでは
素直にその手の事を吸収するライブラリを使うか
個別に書いて切り分ける方がいいと思うけど
0186デフォルトの名無しさん
2009/10/23(金) 02:03:04まさかこんなレスが来るとは予想できなかった
対象とするunixは何?
0187デフォルトの名無しさん
2009/10/23(金) 02:34:28Hogeクラスのデータメンバdataの型を
Hogeのコンストラクタの引数で決定したいと思っているのですが、
そうるすとdataの宣言の< >内が書けません。
どのようにすれば良いでしょうか?
0188デフォルトの名無しさん
2009/10/23(金) 03:08:22継承を使うべきところをテンプレートにしてるのが間違いに見える
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;
}
(以下略)
0189デフォルトの名無しさん
2009/10/23(金) 04:25:32それだと Hoge() を2回呼び出しただけで死ねる。 auto_ptr ぐらい使おうぜ。
0190デフォルトの名無しさん
2009/10/23(金) 08:50:58質問にはそこまで含まれてないんだからいいんじゃね
0191デフォルトの名無しさん
2009/10/23(金) 14:12:310192デフォルトの名無しさん
2009/10/23(金) 14:20:38FILEポインタを食う関数か、
ファイルネームを食って関数内で展開する関数か、
または実行ファイルの引数で指定するか。
0193デフォルトの名無しさん
2009/10/23(金) 15:54:06これをwhile(1)などでずっと繰り返しているとメモリがモリモリたまるのですが、
なぜでしょう?
どこかでログを取っているんでしょうか
またこれを防ぐ方法はありますか?
0194デフォルトの名無しさん
2009/10/23(金) 15:56:09貼り付けてみろ
0195デフォルトの名無しさん
2009/10/23(金) 17:23:47すいません、なりませんでした。気のせいでした
0196デフォルトの名無しさん
2009/10/23(金) 20:26:42上二つもプログラム引数って言ったりするもんなの?
0197デフォルトの名無しさん
2009/10/23(金) 21:20:380198デフォルトの名無しさん
2009/10/23(金) 22:25:270199デフォルトの名無しさん
2009/10/24(土) 02:12:09一つでも出現するか調べたいのですが速い方法ありますか。
調べる文字列がおおくなるほど、その個数分時間が増える方法しかわかりません。 = 一つ一つ調べる。
"HTML"
"html"
"?xml"
"?XML"
"<body"
"<BODY"
0200デフォルトの名無しさん
2009/10/24(土) 02:15:58正規表現(となるべく高速な正規表現エンジン)を使う。
0201デフォルトの名無しさん
2009/10/24(土) 02:24:090202デフォルトの名無しさん
2009/10/24(土) 02:27:41互いの単語の相関からマップを作って無駄な検索をしないで済むアルゴリズムは存在するけど
名前を思い出せない
0203デフォルトの名無しさん
2009/10/24(土) 02:36:400204デフォルトの名無しさん
2009/10/24(土) 02:39:11長くなりすぎるとバグる正規表現エンジンってどれ?
0205199
2009/10/24(土) 02:39:58ここで複数同時検索見つけました。 ラビン-カープ文字列検索アルゴリズム - Wikipedia
0206デフォルトの名無しさん
2009/10/24(土) 02:41:22秀丸と、Regrepに入ってる正規表現dllです。秀丸の場合、最大文字数制限があるんですが。
0207デフォルトの名無しさん
2009/10/24(土) 02:59:250208デフォルトの名無しさん
2009/10/24(土) 03:25:14検索文字列がそれだけなら
適当に作ってみようか?
0209デフォルトの名無しさん
2009/10/24(土) 03:35:060210デフォルトの名無しさん
2009/10/24(土) 04:21:34#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;}
0211デフォルトの名無しさん
2009/10/24(土) 04:59:56#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;
}
0212デフォルトの名無しさん
2009/10/24(土) 05:18:52文字列長が一定だといいけど
一文字や二文字程度が入ってくると、パフォーマンスが落ちるね。
0213デフォルトの名無しさん
2009/10/24(土) 05:20:57>>210,211 は検索文字列が4文字未満だと動かないよw
0214デフォルトの名無しさん
2009/10/24(土) 14:15:53ヒットしたら完全一致調べる。
ラビン-カープ文字列検索は一回ごとのハッシュ計算に手間かかる。
0215デフォルトの名無しさん
2009/10/24(土) 14:45:55#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"; }
0216デフォルトの名無しさん
2009/10/24(土) 16:54:08それは実測で速くなったの?
0217デフォルトの名無しさん
2009/10/24(土) 17:12:410218デフォルトの名無しさん
2009/10/24(土) 17:39:08それとも早いのと賢いので細かく使い分けるべきですか?
0219199
2009/10/24(土) 18:24:09tr1::regexは結果が間違えてるんだが。
211さんのはテストケースに書き換えるのが面倒で入れなかった。
215の方法 178秒
一つ一つstring::findで調べる方法 280秒
正規表現 鬼車 590秒
vc++2008 tr1::regex 868秒
0220デフォルトの名無しさん
2009/10/24(土) 18:35:170221デフォルトの名無しさん
2009/10/24(土) 18:40:050222デフォルトの名無しさん
2009/10/24(土) 18:42:22Ruby(オリジナル版には入ってないかも)、桜エディタ、
Bregexp.dllの後継bregonig.dllに使われている。
0223デフォルトの名無しさん
2009/10/24(土) 18:46:300224デフォルトの名無しさん
2009/10/24(土) 18:49:350225デフォルトの名無しさん
2009/10/24(土) 18:51:290226デフォルトの名無しさん
2009/10/24(土) 18:52:250227デフォルトの名無しさん
2009/10/24(土) 19:01:010228デフォルトの名無しさん
2009/10/24(土) 19:03:15ひとつのファイル内のみで使用できるって事ですか。
0229デフォルトの名無しさん
2009/10/24(土) 22:06:290230デフォルトの名無しさん
2009/10/24(土) 22:09:060231デフォルトの名無しさん
2009/10/24(土) 22:24:29memcmp( buf, "\x20\x45\x4D\x46", 4);
memcmp( buf, "0x200x450x4D0x46", 4);
memcmp( buf, "0x20454D46", 4);
0232デフォルトの名無しさん
2009/10/25(日) 00:04:570233デフォルトの名無しさん
2009/10/25(日) 00:06:110234デフォルトの名無しさん
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){}
};
0235デフォルトの名無しさん
2009/10/25(日) 09:46:31一般的にコンテナのインスタンスに依存せずに要素を指さない有効なイテレータを作る方法はないし、
nullや0から変換できるとも限らない。
0236デフォルトの名無しさん
2009/10/25(日) 09:52:13>nullや0から変換できるとも限らない。
なるほど、やはりそうですか自分もそんな気がしていました
なので、nullや0から変換する方法というのは、他に方法が無い場合仕方無しにやってます。
0237デフォルトの名無しさん
2009/10/25(日) 11:06:390238デフォルトの名無しさん
2009/10/25(日) 11:40:010239デフォルトの名無しさん
2009/10/25(日) 13:28:38もしできるならば、簡単な雛形を教えてください
それからSFINAE の使い方で、関数テンプレートの事例は検索すれば
いくつか出てきますし、「C++テンプレートテクニック」という本を読んでやり方は分かるのですが
クラステンプレートの事例が検索できません、もしかしてSFINAE はクラステンプレートには適用できないのでしょうか?
ここで言うクラステンプレートとは
template<class T>
class Foo {};
このような形式のことを意図します。
コンパイラはvs2005です。
0240デフォルトの名無しさん
2009/10/25(日) 13:29:340241デフォルトの名無しさん
2009/10/25(日) 14:54:02ファクトリー関数を挟めば適用できるよ
0242デフォルトの名無しさん
2009/10/25(日) 16:54:33>>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;
}
0243デフォルトの名無しさん
2009/10/25(日) 17:17:550244デフォルトの名無しさん
2009/10/25(日) 17:29:41継承により基底クラスのメンバー関数を使いたいのですが、今回の場合はどちらが基底クラスになってもかまいませんが
仮にFoo クラスに
int Widget();
というような関数が定義されて、基底クラスとした場合、Hoge クラスでそれを使えることはもとより
operator() も呼び出せるようにしたいのですが。
0245デフォルトの名無しさん
2009/10/25(日) 17:33:490246デフォルトの名無しさん
2009/10/25(日) 17:39:10それは何処に記述して、main() からどのように呼び出したらいいのでしょうか?
0247デフォルトの名無しさん
2009/10/25(日) 18:24:01無理。その二つのoperatorはそもそも継承可能な同一性を持たないから。
0248デフォルトの名無しさん
2009/10/25(日) 18:56:58int operator() とvoid operator () と違うから継承不可能なのでしょうか?
0249デフォルトの名無しさん
2009/10/25(日) 21:30:24ぜんぜん違う実装同士だとすごい困るんですけど・・・
0250デフォルトの名無しさん
2009/10/25(日) 21:35:12付けて困るんなら付けなきゃいいじゃん。
0251デフォルトの名無しさん
2009/10/26(月) 07:53:47class CHoge {
public:
CHoge(int x) { CHoge((float)x); }
CHoge(float x) { ... }
};
0252デフォルトの名無しさん
2009/10/26(月) 08:11:510253デフォルトの名無しさん
2009/10/26(月) 09:54:150254デフォルトの名無しさん
2009/10/26(月) 13:21:40class CHoge {
public: virtual void func() {...}
};
class CHogeEx: public CHoge {
public: CHogeEx() { func(); /* CHogeEx::func を呼びたい */ }
public: virtual void func() {...}
};
0255デフォルトの名無しさん
2009/10/26(月) 13:25:11× オーバーロード
○ オーバーライド
「ダメ」の意味がよくわからんが、 CHogeEx をさらに派生して func() をオーバーライドしていても
CHogeEx のコンストラクタで呼び出されるのは CHogeEx::func() になる。
つまり C++ のコンストラクタ(とデストラクタ)の中では仮想関数による動的多態は効かない。
0256デフォルトの名無しさん
2009/10/26(月) 13:25:170257デフォルトの名無しさん
2009/10/26(月) 13:25:530258デフォルトの名無しさん
2009/10/26(月) 16:03:48class 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なメンバ変数でもプリミティブ型であればクラス宣言内で定義しても良い、ということでしょうか?
0259デフォルトの名無しさん
2009/10/26(月) 16:12:51メンバ変数にほかのインスタンスへの参照として持たせたい→寿命がよくわからない→スマートポインタ
動的に確保して返す関数→値捨てられたら困る→スマートポインタ
メンバ変数を返す関数→外で参照を保存されたらバグる可能性がある→値返し
引数と返り値の参照について↑みたいにやってるんですが、もっと明確で安全な基準みたいなのってありませんか?
0260デフォルトの名無しさん
2009/10/26(月) 16:23:40さらにconstでなければならない
0261デフォルトの名無しさん
2009/10/26(月) 20:05:23オブジェクトの寿命で考えてみよう
0262デフォルトの名無しさん
2009/10/26(月) 20:42:06さらに int 型、じゃなかったっけ?
0263デフォルトの名無しさん
2009/10/27(火) 00:15:22staticでconstで整数型じゃなかったっけ。 超うろ覚えだが。
ちなみにVCの6か7ぐらいまではそれすらもできないので、enumハックという手法があったがそれはもう昔の話。
0264デフォルトの名無しさん
2009/10/27(火) 00:33:460265デフォルトの名無しさん
2009/10/27(火) 00:58:22・#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と例外仕様以外はだいたい標準準拠の立派な子に成長しました。
0266デフォルトの名無しさん
2009/10/27(火) 01:08:37なんのためのfinallyなんだよw
今ならBOOST_SCOPE_EXIT使うけど。
0267デフォルトの名無しさん
2009/10/27(火) 01:25:55ADLが標準に合致しないとか
Cライブラリがstd名前空間に含まれてないとか
問題山積みだけどね。
0268デフォルトの名無しさん
2009/10/27(火) 01:30:03C++以外ですら
0269デフォルトの名無しさん
2009/10/27(火) 02:05:172002/2003は見送ったところが多かった。
2005からかな、みんな使い出したのは。
0270デフォルトの名無しさん
2009/10/27(火) 06:53:04s.Up|=KEYDOWN(DIK_UP);
このソースの2行目の |= は何を表しているのでしょうか?
+=や-=ならちょくちょく目にしますが、|=というのは・・・?
0271デフォルトの名無しさん
2009/10/27(火) 07:02:26a += b は a = a + b といっしょ。
a -= b は a = a - b といっしょ。
a |= b は a = a | b といっしょ。
0272デフォルトの名無しさん
2009/10/27(火) 07:13:35ありがとうございます。
助かりました。
0273デフォルトの名無しさん
2009/10/27(火) 08:03:39a += b
の方が
a = a + b
よりも機械語の形式に近いと知って軽いカルチャーショックを受けるよな?
俺だけか?
0274デフォルトの名無しさん
2009/10/27(火) 08:11:33考えた事もなかった。
ADD A, B
こうゆう事?
0275デフォルトの名無しさん
2009/10/27(火) 08:27:14そうそう
CPUによっては3オペランドの四則演算もあるんだろうけど
ほとんどのCPUでは2オペランドが基本なんだよな
考えてみれば当たり前なんだが
昔々アセンブラを初めて触ったころ、へぇ〜と思った
BASICに代入付き四則演算子がなかったもんだから
なおさら、ほぉ〜と思ったな
0276デフォルトの名無しさん
2009/10/27(火) 08:35:330277デフォルトの名無しさん
2009/10/27(火) 09:02:29このスレで答える側の人たちは昔からプログラムやってる人が多いのかな?
BASICなんて見たことも触ったこともないな。
>>276
Cが簡単って人は俺にとって神に見える。
俺はJavaからC/C++に入ったからCがかなり難しく感じる。
涙でディスプレイが霞むほどに難しい。
0278デフォルトの名無しさん
2009/10/27(火) 09:06:010279デフォルトの名無しさん
2009/10/27(火) 09:47:37でもa(1:n)=a(1:n)+b(1:n)とか配列周りに関しては感動した
0280デフォルトの名無しさん
2009/10/27(火) 09:55:15難しいところはないんじゃないか。
C++は全然違うけど。
0281デフォルトの名無しさん
2009/10/27(火) 10:10:47VisualBasicも基本的にはBASICだということを忘れてないかい?
C++は言語仕様が大きすぎて
ソフトを作るためにC++使ってるのか
C++の深淵を知るためにC++を使ってるのか
分からなくなる
0282デフォルトの名無しさん
2009/10/27(火) 10:14:43なんか作ろうとして、その途中でつまずいたりアイデアを思いつくと言語の勉強が始まって、気づいたら半日過ぎてたとか良くある
0283デフォルトの名無しさん
2009/10/27(火) 10:41:15そういえばVBなら少し触ったな。
基本的にはVBもBasicか。あまりにイメージが違いすg・・・
今までJavaでWeb系の開発やってていっぱしのプログラマ気取ってたんだが
C++の難しさになみだ目。C++の何が難しいって、そもそも実現しようとする事柄が難しい。
プログラミングの第一線から退いた先輩方から「オブジェクト指向ができるなんてすごいね」
なんて言われて「いや、そんな事ないですよ(フフ」なんて言ってたんだが
C++を勉強し始めた今になって猛烈に恥ずかしくなってきた。
あんたらがやってきたことに比べれば、俺がやってるWebのプロジェクトなんか屁みたいなもんですよと。
あんたらがもっと若かったら純粋なオブジェクト指向の言語においても俺より優秀な技術者になってんだろと。
今度先輩に現役時代の話を聞いてみよう。
チラ裏ごめん。
0284デフォルトの名無しさん
2009/10/27(火) 11:22:38たまたま時代のニーズによって勉強した物が違うだけじゃん
でも確かにC++の深淵を〜は確かにそういう嫌いがあるよね……
0285デフォルトの名無しさん
2009/10/27(火) 11:30:48ドラクエ1を64KiBに収めるとかどんな拷問かと…
memcpyさえないレベルから作るわけで
そもそもC言語とか一切使ってないんだろうなぁ
0286デフォルトの名無しさん
2009/10/27(火) 12:23:39ところで、C++は巨大と言われるけど、一つ一つの機能をどうコンパイルされるか
把握しながら理解すれば、そこまでバカみたいな巨大さは感じないなぁ。
とは言っても、応用が色々と奥深いけど。
0287デフォルトの名無しさん
2009/10/27(火) 13:04:29他の言語はLLぐらいしかあまり使ってないので。
たしかに大きいなとは思うけど、必要だから大きいのであって、無駄なものは
そんなにないと思うんだが。
0288デフォルトの名無しさん
2009/10/27(火) 13:50:29複雑怪奇に感じてそれを巨大だと表現したりするんだろう
無駄だとかじゃないんだ
0289デフォルトの名無しさん
2009/10/27(火) 14:11:26C++は直接見えない部分の注意点が多すぎると思う
コンストラクタでの例外とか>>251みたいなのとか
多重継承とか
デストラクタの動作タイミングとか
STLの諸々とか
無駄ではないけど複雑すぎるんだよね
メモリイメージさえできてれば使えるCに比べると
間違いなく問題ないコードを書いていると確信できるまでに
必要な知識量があまりに多すぎる
だからといってJavaでは中途半端すぎて満足できないw
0290デフォルトの名無しさん
2009/10/27(火) 14:20:09もう――――――――
もう何時間―――― こうしているのか――――
蹴っても――――
いくら蹴っても――――――――
不安がなくならない!!!
ってことだよな。CとC++の最大の違いはw
0291デフォルトの名無しさん
2009/10/27(火) 14:27:44ちゃんと理解してないと安心して使えない言語なのが悪い、というのも一理あるし、
理解してればCより遙かに安全で気楽になったりもするし
0292デフォルトの名無しさん
2009/10/27(火) 15:00:59C++とCの最大の違いは、仕様変更の荒波にどれほど楽をして対応できるかどうかではないかな。
0293デフォルトの名無しさん
2009/10/27(火) 15:04:46する者が全員それを読めばいいんじゃないか。
0294デフォルトの名無しさん
2009/10/27(火) 15:06:51Effective C++はじめ、そこらじゅうに名著がありますよ。
もちろん、業務としてC++を使う人たちは全員読んでいますが。
0295デフォルトの名無しさん
2009/10/27(火) 15:40:29流儀はある程度決めておかないと収集つかないけど。
気分的には「巨大」というのはわからないでもない。CとC++と両方
のやり方がかぶってる部分がかなりあるから、機能面だけから考えれば
不要な部分が多い。互換性は重要だから無駄ではないのだけど。
0296デフォルトの名無しさん
2009/10/27(火) 15:54:28qsort関数以外を使用して番号順にソートしたいのですが何かいい方法があれば教えてください。
例)
F016 C002
C002 C015
H001 F016
C015 H001
H009 H009
左のデータをソートし、右のように並び替えたいです。
0297デフォルトの名無しさん
2009/10/27(火) 15:55:32struct 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じゃ困る
0298デフォルトの名無しさん
2009/10/27(火) 15:57:36宿題スレへどうぞ。
0299デフォルトの名無しさん
2009/10/27(火) 16:03:18読み込みが終わったらソートできてる状態にすればいいと思う
0300デフォルトの名無しさん
2009/10/27(火) 16:16:01それは当然だが、それらを読まない人が多いから巨大だとか言われるわけで、それらを
簡単にまとめた物を言っている。原理を詳しく知りたかったら原著を読めばいいし。
C++には新規参入など要らないということであれば話は別だけど。
0301デフォルトの名無しさん
2009/10/27(火) 20:32:58でもその「深淵を覗いている感じ」は、なかなか他の言語では得難いものがあるよねw
なにか、つきあいの長い人に意外な一面を発見する喜び、みたいな。
0302デフォルトの名無しさん
2009/10/27(火) 20:38:170303デフォルトの名無しさん
2009/10/27(火) 20:56:090304デフォルトの名無しさん
2009/10/27(火) 22:59:45z = x/y を
if ( y < 十分小) z=十分大 else z=x/y
にしとけ
0305デフォルトの名無しさん
2009/10/27(火) 23:22:03std::numeric_limits<double>::epsilonとか使うといいんじゃないか。
0306デフォルトの名無しさん
2009/10/27(火) 23:34:040307デフォルトの名無しさん
2009/10/28(水) 01:20:430308デフォルトの名無しさん
2009/10/28(水) 04:24:21struct func_obj_wrapper {
func_obj_wrapper(func_obj& f) : f_(f) {}
void operator()(hoge &h) { f_(h); }
func_obj& f_;
};
0309デフォルトの名無しさん
2009/10/28(水) 12:02:15> 実数の内部表現は処理系依存。
…なんだけど、IEEE-754 な環境だと普通に
x / 0
= ±∞ (x != 0)
= ±NaN (x = 0)
じゃなかったっけ?
0310デフォルトの名無しさん
2009/10/28(水) 15:39:16簡単な方法は無いでしょうか?
std::hex だと小文字になってしまうし・・・。
0311デフォルトの名無しさん
2009/10/28(水) 15:55:47std::ios::uppercase
0312デフォルトの名無しさん
2009/10/28(水) 16:05:06速答ありがとうございました。
うまく大文字に変換できました。
0313デフォルトの名無しさん
2009/10/28(水) 18:48:07for (p = lhs.begin(); p < lhs.end()-6; ++p) {
}
lhs.end()-6 の表記が間違っていると思うのですが、どのように書いたらいいでしょうか?
0314デフォルトの名無しさん
2009/10/28(水) 19:08:14それと、size()が6以下だとまずいね。
0315デフォルトの名無しさん
2009/10/28(水) 19:11:06lhsの先頭から終わりの6つ前まで走査したいってこと?
それなら
for(size_t i = 0; i < lhs.size() - 6; ++i){
// lhs[i]でアクセス出来る
}
でいいと思うが
0316デフォルトの名無しさん
2009/10/28(水) 20:50:020317デフォルトの名無しさん
2009/10/28(水) 20:55:02if (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では。
0318デフォルトの名無しさん
2009/10/28(水) 20:57:50フォールトトレランス性はあるけど、コンテナの種類が変わると使えなくなる可能性がある。
0319デフォルトの名無しさん
2009/10/28(水) 21:02:02n++だとしても、ループ内でnの値が変わったら停止しなくなる。
0320デフォルトの名無しさん
2009/10/28(水) 21:04:53ちゃんと読め
0321デフォルトの名無しさん
2009/10/28(水) 21:08:58ステップが1でないループやカウンタが任意の値に変わるようなループは
普通じゃないんで、使う側がそれを想定したコードを書くべきではあるが、
普通はそんなことを想定しなくてもいいと思うよ。
0322デフォルトの名無しさん
2009/10/28(水) 21:27:00!= → <=
値が小さいとき、どちらもループするが、!=では飛びこえても停止しない。
同じ事を説明しているだけだがな。
0323デフォルトの名無しさん
2009/10/28(水) 21:35:120324デフォルトの名無しさん
2009/10/28(水) 21:43:186周や7周して何事もなかったかのように続行されてはあとで大変なことに。
だから「5周で終わらなきゃだめ!」って言う条件を
「まぁ、5周以上になったら適当なところで終わってね」なんて緩めたりしない。
0325デフォルトの名無しさん
2009/10/28(水) 21:47:450326デフォルトの名無しさん
2009/10/28(水) 21:51:52それは「5周以上」じゃなくて「5周以下」じゃね?
1→7とかなって2周で終わる。
あと、i!=5 と i<5 は事後条件に違いがあるから
どちらが適切かは事後条件次第じゃないかと。
で、forにおいて日常的に!=を使うか<を使うか、++iを使うかi++を使うかは
効率の問題とかもあるんだけど、結局は宗教論争なんだよね。
cout と printfに並ぶくらい。
0327デフォルトの名無しさん
2009/10/28(水) 21:54:310328デフォルトの名無しさん
2009/10/28(水) 21:57:15いちいち言及しないと気になる?
0329デフォルトの名無しさん
2009/10/28(水) 22:06:47・・・うそw
for文の宗教論争はGoogle Coding Standardsにも出てくるけど
「まぁ、好きにしろよ」っていうオチだったと思う。
0330デフォルトの名無しさん
2009/10/28(水) 22:07:49C++を学び初めて四日目です (VC++2008です)
ドラクエ風戦闘プログラムの勇者の攻撃だけの部分を作ってみたんですが、
クラスのオブジェクトが生成できてないとかメンバ関数が何故か使えないとかで困ってます
オーバーロードが多重定義だというのはググったんですが、関数は一つしか定義してないはずなので多重定義といわれても分かりません……
どうにか問題を解決してもらえないでしょうか
ちなみにオーバーロードやらポインタやら継承やらはまだ勉強してません
あと他の部分のコードでこうしたらいいよ、とかあれば教えてください
0331デフォルトの名無しさん
2009/10/28(水) 22:08:280332デフォルトの名無しさん
2009/10/28(水) 22:09:20修正が大変だわな。
0333デフォルトの名無しさん
2009/10/28(水) 22:13:30それがまた宗教論争の種なわけだ。
サッターは時期尚早の再不適化はやめようと書いているけれども
果たしてコンパイラの最適化能力をどこまで信じないかという問題もある。
>>332
こちらの問題にはメイヤーズが答えている。
どのコンテナにも使えるコードを書けると思ってはいけない。
・・・一般論では宗教論争にしかならないのはこのため。^^
0334デフォルトの名無しさん
2009/10/28(水) 22:14:44< や <= で比較可能なことは保証されてるのかよ。
== と != は確実に保証されてるけどな。
0335デフォルトの名無しさん
2009/10/28(水) 22:15:25けど、バグは潰せないんで、やっぱ自分は!=かな。
0336デフォルトの名無しさん
2009/10/28(水) 22:17:00!= に統一すると、停止しないバグに遭遇する危険。
整数型なら< >にしとけ
0337デフォルトの名無しさん
2009/10/28(水) 22:18:25宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。
時期尚早の最適化は止めよう。
↓
最適化と仕様の実装とは別の話。仕様は!=。
どのコンテナにも使えるコードを書けるとは思ってはいけない。
↓
だが、多くのコンテナに変更可能なコードを書くことは悪ではない。
0338デフォルトの名無しさん
2009/10/28(水) 22:18:59とか中で追加してたら、バグ発生するだろ。
バグでないのに。
0339デフォルトの名無しさん
2009/10/28(水) 22:19:18見てるところがちがんじゃない?
どうも「endl」でエラーが出てるよ。
endlってそういう使い方しないと思うんだけど。
0340デフォルトの名無しさん
2009/10/28(水) 22:19:34バグはassert等で対応するべきであって、仕様を曲げるのはおかしい。
0341デフォルトの名無しさん
2009/10/28(水) 22:21:40保証されている。ランダムアクセスイテレータは<や<=が使用可能。
0342デフォルトの名無しさん
2009/10/28(水) 22:23:09停止しないバグがあるならバグを直すべき
0343デフォルトの名無しさん
2009/10/28(水) 22:23:31そういうのは>>321で議論から除外されてる。
0344デフォルトの名無しさん
2009/10/28(水) 22:23:47>宗教論争と言うけど、いろんな引用してるけど、ピントが合ってないよ。
そう、あなたのおっしゃるとおり。
あなたにはピントが合ってないように見えるけど
そう主張している側からはピントぴったりにしか見えてない。
for文の宗教論争史(あるかどうかしらないけど)を調べると
今まさにあなたの反論がそのまま出てくるよ。
0345デフォルトの名無しさん
2009/10/28(水) 22:26:06いやいや、それは逃げてるだろう。
仕様と最適化の問題は答えが明らかだろう。
0346デフォルトの名無しさん
2009/10/28(水) 22:27:260347デフォルトの名無しさん
2009/10/28(水) 22:29:36まぁまぁ。^^
いちどそのあたりの宗教論争を調べてみるとおもしろいよ。
まったくかみ合わない論争だから。w
ちなみに、自分はさっきの引用が「正しい」とか「的を射ている」とは思ってないよ。
かみ合わないのを承知で引用している。
0348デフォルトの名無しさん
2009/10/28(水) 22:33:57まぁ使いにくいんだけど
0349デフォルトの名無しさん
2009/10/28(水) 22:57:08あと、各case節の終わりでbreakしなくていいのかい?
0350デフォルトの名無しさん
2009/10/28(水) 22:58:18そんな雰囲気だったが、そんなことしてどうすんのとは思う。
自分は!=を使う。理由はそれが仕様だから。バグは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
0351デフォルトの名無しさん
2009/10/28(水) 23:24:160352デフォルトの名無しさん
2009/10/28(水) 23:36:43実装の中身が生ポインタならば、というような仮定はしたくないからな
0353デフォルトの名無しさん
2009/10/29(木) 00:24:43ちょっとイテレータを弄ろうとするとend()に++したり、begin()に--出来ないから
一々チェックを入れる必要が出てきて非常に面倒。でも普通のポインタも保証無いんだっけ?
0354デフォルトの名無しさん
2009/10/29(木) 00:40:510355デフォルトの名無しさん
2009/10/29(木) 00:43:413行目以降の意味が全くわからんけどとりあえずboost::nextとboost::priorでぐぐれ
0356デフォルトの名無しさん
2009/10/29(木) 00:51:280357デフォルトの名無しさん
2009/10/29(木) 01:07:16そうでない処理系もあるかもしれないけど。
0358デフォルトの名無しさん
2009/10/29(木) 01:11:34参照とインライン展開だと、ひとつもメモリの生成しないですむが
ポインタは32bit か64bitの変数を生成するからな。
でも計測可能なほどかは微妙だが
0359デフォルトの名無しさん
2009/10/29(木) 01:30:24使ったっていいんだけどな。そっちの方がわかりやすいなら。
0360デフォルトの名無しさん
2009/10/29(木) 02:22:07リンク先を見ずに言うが、「的を射ている」と書いてるよ。
当を得ているとすべき、的を得るもあながち間違いとは言い切れない
という意見もあるけど、何で「的を得ている」についてのアンカーを?
0361デフォルトの名無しさん
2009/10/29(木) 03:31:220362デフォルトの名無しさん
2009/10/29(木) 05:02:1710、19行目のInt型の引数に0を代入する処理はどういった効果があるのでしょうか?
引数の値はコンストラクタ呼び出し時に上書きされるので、無意味に見えるのですが・・・
19行目のClsA(n1)は初期化子の書き方だと思うのですが、ClsAという変数はありません。
何をしているのでしょうか?
0363デフォルトの名無しさん
2009/10/29(木) 05:14:350364デフォルトの名無しさん
2009/10/29(木) 05:24:05int main(){
int iii = NULL;
iii = 1;
}
0365デフォルトの名無しさん
2009/10/29(木) 05:39:080366デフォルトの名無しさん
2009/10/29(木) 05:52:38>>1のアップローダーでコンパイルしたところ、エラーになったため、理解できました。
ヌルの扱いはコンパイラ依存なんですね。
ありがとうございます。
初期化子の方がまだわからないのですが、教えて下さる方いませんか?
0367デフォルトの名無しさん
2009/10/29(木) 06:11:25引数リストでの代入式はデフォルト引数の指定。
ClsA(n1) は基底クラスの初期化。
0368デフォルトの名無しさん
2009/10/29(木) 06:45:57変数だけでなく、コンストラクタも初期化子で初期化できるんですね。
というと、基底クラスの関数も初期化できそうですね。
ありがとうございました。
0369デフォルトの名無しさん
2009/10/29(木) 11:03:45>>362は納得できたからいいけど。
0370デフォルトの名無しさん
2009/10/29(木) 13:04:11iがそもそもなんだかわからないので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;
0371デフォルトの名無しさん
2009/10/29(木) 13:11:21iはCTaskIterクラスのインスタンス。名前から察するに、CTaskListのイテレータなのだろう。
i.HasNext()はiが指しているlistに次の要素があるかどうかを返す関数だと推測する。
いずれにしろ、この際WinCrypt.hは関係なさそうだな。
0372デフォルトの名無しさん
2009/10/29(木) 13:13:27for 文の最初で for (int i = 0; ..... ) のように変数宣言できることをご存じない?
それとも int i(0); のような書き方で変数が初期化できることをご存じない?
0373デフォルトの名無しさん
2009/10/29(木) 13:24:02VisualStudioの誤動作だったんですね。
>>371>>372
CTaskIter i(list)は、CTaskIterクラスの引数がCTaskListになっているコンストラクタを呼び出してたんですね。
いろいろ勘違いしていました。ありがとうございます。
0374デフォルトの名無しさん
2009/10/29(木) 14:27:18インスタンスを生成する途中でコンストラクタも呼び出すけど。
0375デフォルトの名無しさん
2009/10/29(木) 14:28:570376デフォルトの名無しさん
2009/10/29(木) 14:31:58そんなこと言うと、変数の初期化だとか変数の定義だとか、もっと言い換えできるぜ。
0377デフォルトの名無しさん
2009/10/29(木) 14:32:540378デフォルトの名無しさん
2009/10/29(木) 14:35:38「コンストラクタの呼び出し」と「インスタンスの生成」って、そんなに違うか?例えばどこが?
その違いは「インスタンスの生成」と「変数の定義」よりも大きいんだよね?
0379デフォルトの名無しさん
2009/10/29(木) 14:36:02CTaskIter i(foo); // B
Aがコンストラクタ呼び出しの構文だろ?
Bが変数定義。
0380デフォルトの名無しさん
2009/10/29(木) 14:37:38この場合は自動インスタンスの生成だから、スタックからメモリを確保する作業が
含まれるな。
自動インスタンス生成と変数定義は変わらん。インスタンス生成と自動インスタンス
生成は違う。
0381デフォルトの名無しさん
2009/10/29(木) 14:39:36では、これは何でしょう?
0382デフォルトの名無しさん
2009/10/29(木) 14:40:14void* p; に対して、 CTaskIter* q = new(p) CTaskIter(foo);
0383デフォルトの名無しさん
2009/10/29(木) 14:43:43「自動」ってつければそうなるね。
後だしジャンケンっぽいけど、言いたかったことはわかったからまぁいいや。
0384デフォルトの名無しさん
2009/10/29(木) 14:46:360385デフォルトの名無しさん
2009/10/29(木) 15:00:11そのインスタンスの位置情報(使用しているアドレスの先頭)をCtaskIter型のiという名前で定義した変数に割り当てている。
ということでしょうか?
書いてて自分でよくわからなくなってきたんですが、おそらく間違っていないでしょう。
間違っていないで下さい。
>>384
CTaskIterクラスのデフォルトコンストラクタを呼び出してインスタンス化し、
そのインスタンスの位置情報(略)をCtaskIter型のiという名前で定義した変数に割り当てている。
ひっかけ・・・?
0386デフォルトの名無しさん
2009/10/29(木) 15:03:300387デフォルトの名無しさん
2009/10/29(木) 15:03:40ありがとう。救われた気持ちです。
iという名前で、CTaskIter型の戻り値を持ち、引数が無い関数のプロトタイプ宣言です。
0388デフォルトの名無しさん
2009/10/29(木) 15:04:170390デフォルトの名無しさん
2009/10/29(木) 15:08:05じゃなくて
T t(param);
を使いたい時ってどんな時だろう。何かあった気もするけど。
0391デフォルトの名無しさん
2009/10/29(木) 15:08:510392デフォルトの名無しさん
2009/10/29(木) 15:28:22正解しちゃってすみませんと思いながら書き込んだのにこのざまですよ。
0393デフォルトの名無しさん
2009/10/29(木) 15:42:52とは言え、CTaskIter i(void);と書くのも気持ち悪いなw
0394デフォルトの名無しさん
2009/10/29(木) 16:00:130395デフォルトの名無しさん
2009/10/29(木) 18:21:56BCCDeveloperを使ってDXライブラリを使う設定したはずなんですが、DXLib_lnitとDXLi_Endで未定議の関数とエラーがでます。
ググッて調べてみてもわからず...
どなたかアドバイスいただけないでしょうか。
0396デフォルトの名無しさん
2009/10/29(木) 18:30:520397デフォルトの名無しさん
2009/10/29(木) 18:43:320398デフォルトの名無しさん
2009/10/29(木) 18:46:32みなさんありがとうございます。
今はコピペできないので帰宅したらエラーメッセージをコピペします。
0399デフォルトの名無しさん
2009/10/29(木) 18:46:440400デフォルトの名無しさん
2009/10/29(木) 19:05:56explicit widget(type);
widget w = widget(t);
0401デフォルトの名無しさん
2009/10/29(木) 19:06:14核心を突いてるなぁ
0402デフォルトの名無しさん
2009/10/29(木) 19:07:24explicit使うと下の書き方は出来なくなるだろ
widget w(widget(t)); でも関数とみなされるかもしれないから
widget w((widget(t))); が一番安全だな
0403デフォルトの名無しさん
2009/10/29(木) 19:09:58下記の二つのソースは、出力を行う関数の内部的な動作を除き
まったく同じ意味になるのでしょうか?
あまり要領を得た質問とは言えず、心苦しいばかりですが
もしも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は同じ値(アドレス値)が表示される。
0404デフォルトの名無しさん
2009/10/29(木) 19:12:27//C++の場合
Test t1;
Test *t2;
t2 = &t1;
こう。
じゃないとメモリリークする
0405デフォルトの名無しさん
2009/10/29(木) 19:15:55VCとCODEPADでコンパイル通ったよ
最適化されてないとコピーコンストラクタ挟まれるっぽいけど・・・
0406デフォルトの名無しさん
2009/10/29(木) 19:58:49なぜnewした方だけがメモリリークするのでしょうか?
ポインタはnewしたしないにかかわらず、deleteしないとメモリリークしてしまうものだと思っているのですが・・・
今回の場合、Test *t2 = new Test();でもTest *t2;でもdeleteをすると実行値エラーが出てしまいます。
結局newしない書き方でもメモリリークするように見えるのですが、違うのでしょうか?
0407デフォルトの名無しさん
2009/10/29(木) 20:08:200408お約束
2009/10/29(木) 20:12:510409Java厨
2009/10/29(木) 20:20:110410デフォルトの名無しさん
2009/10/29(木) 20:21:26何も考えずに shared_ptr 使えばいいよ
0411デフォルトの名無しさん
2009/10/29(木) 20:31:34とりあえず、こだわりが無いなら素直にVC++2008EEにした方がいいと思うが。
昔はWindowsで比較的素直に使えるフリーコンパイラがBCCくらいしか無かったが、
今はVC++EEがあって、ぶっちゃけBCCより遙かにまともに動くし、Windowsだと
VC++以外全く考えられてないのも普通だし。
0412デフォルトの名無しさん
2009/10/29(木) 20:48:560413デフォルトの名無しさん
2009/10/29(木) 20:55:11C++の場合、これで作られるのは参照じゃなくて値(インスタンス)。つまり、
そのソースではインスタンスが二個作られてる。
Test *t2 = new Test();の方は、new Test()がヒープ上にインスタンスを生成して、
それを指すポインタを返す。で、t2というポインタ変数に代入する。
C++では、ヒープ上に生成したインスタンスは必ずdeleteしなきゃ駄目なので、
delete t2;をしないとリークする。これが忘れやすくて危険だから、専用のクラスを
作って、コンストラクタでポインタを記憶してデストラクタでdelete、という手法が
ある。いわゆるスマートポインタで、有名なのはshared_ptr。既に標準ライブラリに
入ってる処理系も多数あり。無くてもBoostライブラリを入れればおk。
これをポインタ以外に広げて、例えばファイルハンドルをコンストラクタで生成や
記憶などして、デストラクタでクローズ、というように、資源の確保と開放を専用の
クラスに包んでしまうのがRAIIという概念で、資源リーク回避の基本技。
0414デフォルトの名無しさん
2009/10/29(木) 20:56:19push_backでイテレータは無効化される
push_backの後でイテレータを拾い直すならおk
0415デフォルトの名無しさん
2009/10/29(木) 21:12:21これからは生ポインタ引き数でいいところは生にしよう
0416デフォルトの名無しさん
2009/10/29(木) 21:15:47vector<Objects*>::iterator it;
for(it=v_obj.begin(); it != v_obj.end(); it++){
if(ある条件){
push_back(new Objects());
}
}
0417デフォルトの名無しさん
2009/10/29(木) 21:16:310418デフォルトの名無しさん
2009/10/29(木) 21:17:30>>412 なの?
0419デフォルトの名無しさん
2009/10/29(木) 22:10:51vector<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());
}
0420デフォルトの名無しさん
2009/10/29(木) 22:12:32別にテンポラリのvectorを作って、ループの中ではテンポラリの方に追加しておいて、
ループを抜けてから連結。
あと、激しくメモリリークの予感。
0421デフォルトの名無しさん
2009/10/29(木) 22:21:38把握しました。
>>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を書けば良さそうですが
ローカル変数に関してはこれを使っておけば安心できそうです。
ためしに近々使ってみます。
ありがとうございます。
0422デフォルトの名無しさん
2009/10/29(木) 22:23:54生ポインタをコンテナに突っ込むのはやめれ、どうしてもというならshared_ptr を使うと幸せになれる
0423デフォルトの名無しさん
2009/10/29(木) 23:28:100424デフォルトの名無しさん
2009/10/29(木) 23:37:25やりたがってることがイマイチわからないけど、そのコードから受け取れるものだけで言うなら、
ループ内でこうすればいいんじゃないの?
if (ある条件) {
v_obj.push_back(new Objects());
break;
}
今回の君のコードからは、一つでも「ある条件」を満たすものを見つけたら
もうその時点でループは用済み、という状況がうかがえるので。
そういうこと(何をやりたいか、何をやらなくていいか)をちゃんと書いて欲しいんだけどな、
質問する時は。
0425デフォルトの名無しさん
2009/10/29(木) 23:52:52ループは最初から最期まで全てのイテレータである処理をしてます。
(*it)->do_something();
途中でbreakするわけにはいかないです。
この方法だとif(ある条件)が複数回満たされた場合に1回しかpush_backしませんが、
今回はこの方法で私の問題は解決しました。複数回できればなお嬉しいですが。
0426デフォルトの名無しさん
2009/10/29(木) 23:59:06もう他に新事実が無いというのなら、for文の前にint count = 0;でも置いて、ループ内で
if (ある条件) {
++count;
}
として、あとからcount個の要素を追加すればいい。
0427デフォルトの名無しさん
2009/10/30(金) 00:09:070428デフォルトの名無しさん
2009/10/30(金) 00:15:53shared_ptrのconst参照という手もあるよ。
>>421
メンバ変数もshared_ptr使っておくほうがいい。デストラクタでdeleteだと抜けがある。
0429デフォルトの名無しさん
2009/10/30(金) 01:02:22リークする、と断言したのは、
1:Test t1;
2:Test *t2 = new Test();
3:t2 = &t1;
としたときに2でヒープに確保した領域をdeleteできなくなるから。
0430デフォルトの名無しさん
2009/10/30(金) 02:53:47まだ何か誤解があるぽ。
> Testクラスにポインタを使用しているメンバ変数があった場合、そのメンバ変数に
> 割り当てられたヒープ領域が開放されない(リーク)というおまけが付いてくると。
そうではなく、Testクラスのインスタンスがnew Test()によってヒープ領域に生成
されるが、CやC++では、ヒープに確保したメモリ領域は自分で解放する必要がある。
newで確保したならdeleteで。mallocならfreeで。new[]ならdelete[]で。
だが、そのコードでは、newでヒープに確保したメモリ領域を指すポインタはt2に
まず代入されるが、t2 = &t1;の時点で上書きされるので、newした領域がどこに
あるか分からなくなる。つまりdeleteできないので、普通に考えればリーク確定と
いうこと。Testクラスのインスタンスそのもののメモリ領域がリークする。
0431デフォルトの名無しさん
2009/10/30(金) 07:32:21デフォルトコンストラクタをprotectedとして宣言、定義して、インスタンス化拒否を明示するのか
コンパイラが自動的に生成するのを用いるのか、どちらが妥当なんでしょうか。
0432デフォルトの名無しさん
2009/10/30(金) 07:40:35なんでそんな余計なコードを書こうかなんて思うの?
0433デフォルトの名無しさん
2009/10/30(金) 10:04:21shared_ptrは一般的なんですね。
レスポンスが少し気になるところですが、使っておきます。
>>429
new Test();がdelete不可なんですね。把握しました。
※newして生成したインスタンスを格納した変数は、deleteせずに他の値を格納すると
デストラクタ内で処理されているか、スマートポインタを使用していない限り必ずリークする。
>>430
昨日は少し混乱していました。
Testクラス内にメンバ変数がなくても、newした段階で最低1byteは使用するため、結局deleteできなくてリークすると。
今度こそ完全に理解しました。
0434デフォルトの名無しさん
2009/10/30(金) 10:10:52大丈夫、未だ勘違いしている。
生成したインスタンスのポインタを格納しているポインタ変数に、他の値を格納してしまうと
単純に、最初のインスタンスのポインタが失われるのであってデストラクタも何も走らない。
まさに、>408だな。
0435デフォルトの名無しさん
2009/10/30(金) 10:37:19デストラクタ内で適切に処理しておけば問題ないと考えていましたが、書き方によってはリークするんですね。
ヒープに確保した領域が行方不明になるような書き方してたら
コンパイルエラーにしてくれればいいのにというのは甘えですか?
0436デフォルトの名無しさん
2009/10/30(金) 10:54:292:Test *t2 = new Test();
3:foo->bar(t2);
4:t2 = &t1;
この場合leakするかどうかは 3 の内容に依る。不完全
な警告をコンパイラに実装して「警告が出てないから
leakしてない」なんていう阿呆を産み出すよりは出さな
い方がマシ。
0437デフォルトの名無しさん
2009/10/30(金) 11:02:31適切に書くことによってリークしないのだ。
--
Test * func() {return new Test();}
--
void someOtherFunc()
{
func();
}
--
これでもリークするわけだが、例えばfunc()が別のコンパイル単位にあるとしたらどうやって検出しろと?
0438デフォルトの名無しさん
2009/10/30(金) 13:07:17関数のプロトタイプ宣言のように見えますが
そうすると戻り値がvoidで関数の名前がInitで引数は無し?*の意味は・・・?
.h.cppのどちらにもInitを実装しているような箇所は見当たらないし
3行目はどうゆう意味なのでしょうか?
0439デフォルトの名無しさん
2009/10/30(金) 13:10:32//Common.h
1: struct STAGE {
2: const wchar_t* Name;
3: void (*Init)();
4: int TopTime;
5: };
0440デフォルトの名無しさん
2009/10/30(金) 13:13:270441デフォルトの名無しさん
2009/10/30(金) 13:14:16引数も戻り値もない関数へのポインタ。
わからない単語はぐぐればいいと思うよ
0442デフォルトの名無しさん
2009/10/30(金) 13:14:21型がよく判らないときは、括弧に注目。この場合、Initに*がついていてそれが括弧で拘束されている。
つまり、Initはポインタ変数であることが判る。
それが指しているものは、void ()()となるので、戻り値のない、引き数もない関数となる。
要は、void func()という関数と同じ型の関数ポインタであるInitの宣言。
0443デフォルトの名無しさん
2009/10/30(金) 13:36:04メモリ領域はコード、データ、ヒープ、スタックの4種類にわかれている。
//関数ポインタ。コード領域へのポインタ。
void (*Init)();
//普通のポインタ。データ領域へのポインタ。
int *a;
//deleteしないとリークするポインタ。ヒープ領域へのポインタ。
int *a = new int();
//スタックは今のところ使い方がよくわからないので割愛。
構造体の中に関数ポインタを入れておくと、より汎用的なコーディングができる事がある。
助かりました。
0444デフォルトの名無しさん
2009/10/30(金) 13:39:29ヒープに確保されないオブジェクト、つまり自動変数とかはスタックに確保されて、
スコープアウトしたらデストラクトされる。
0445デフォルトの名無しさん
2009/10/30(金) 13:58:05補足ありがとうございます。
//普通の変数。スタック領域に実態がある。
int main(){
int a;
Cls b;
}
//普通の変数。データ領域へのポインタ。
class Cls{
public:
int a;
TestCls b;
}
//これはスタック違いかな?メモリ領域のスタックの事ではなく、スタックという機能?
#include <stack>
template<Class T, class Container = deque<T> > class stack{};
0446デフォルトの名無しさん
2009/10/30(金) 14:01:46*が付いてなければおよそポインタではない
まだ何か勘違いしてない?
0447デフォルトの名無しさん
2009/10/30(金) 14:21:55スタックってデータ構造もあるけど、それに近い機能をもったメモリ領域がある。
関数とかの中で、
{
/*DoSomething...*/
}
のように記述するとブロックとして認識されてそのブロックの中で宣言された自動変数はブロックを抜けると破棄される。
これをスコープという。ブロックは入れ子にしたりして何個でも作れる。
ポインタなどはポインタ変数は破棄されるが、指してる先をdeleteするような器用さはない。
ちなみに、以下は
class Cls{
public:
int a;
TestCls b;
};
どっちの宣言も自動変数。
sizeofで見てみるとわかると思うけど、sizeof(int)+sizeof(TestCls)の領域が確保されることになる。
C++の参照型は、
Cls& <- 一度しか初期化できない参照。
Cls* <- 何度でも初期化できる参照。名前はポインタと呼ばれる。
javaだとクラスを宣言すると無条件でC++でいうCls&の形をしたポインタが使われるみたいだ。ちなみに俺はJAVAは初心者以下だ。
0448デフォルトの名無しさん
2009/10/30(金) 14:37:27よく分かってないことは書かないことにしましょうか
0449447
2009/10/30(金) 14:47:30vtableは使ってないから説明してない。
仮想関数のオーバーライドの説明だけど、
C++の上書きオーバーライド(virtual function)は、大雑把に言って関数ポインタを上書きすることで実現している。
そのためにはクラスのメモリのどこかに関数ポインタのリストを持つためのポインタを持つことになる。
基本的にこれはメモリを操作してかきかえる類ではないのであることを知っていればいい。
で、仮想関数を持ったクラスをsizeofをすると関数ポインタのリストのポインタ変数のサイズ分増分して返ってくる。
0450デフォルトの名無しさん
2009/10/30(金) 15:06:07×//普通の変数。データ領域へのポインタ。
○//普通の変数。スタック領域に実態がある。
なんかもう滅茶苦茶ですね。
書き間違いと勘違いといろいろまざ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の入る余地がありません。
ちょっと試行錯誤してきます。
0451デフォルトの名無しさん
2009/10/30(金) 15:29:092.受け入れるオブジェクトの型は、ユーザーの入力などにより動的(実行時)に変化する。
以上より仮想関数テーブルが必要になる。
450のように、静的(コンパイル時)に型が限定できる場合ばかりではないということ。
0452デフォルトの名無しさん
2009/10/30(金) 15:29:31基本的にグローバル変数も自動変数というルールに違いはない。
それは、グローバルスコープに宣言されているという前提になる。
あと、ちょっと妙な書き方をしてしまったので訂正するが、
class Cls{
public:
int a; //スタック領域に格納されている自動変数
TestCls b; //同上
};
上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。でも動作は自動変数と変わらない。
deleteした瞬間がスコープ終了の瞬間。
あと、オーバーライドの話。
C++のオーバーライドはvirtualをつけなかったら、上書きされない。よって、vtableも生成されない。
つまり、基本的には、そのクラスで宣言されたそのメンバ関数が呼ばれる。
virtualをつけてオーバーライドされる前提のメンバ関数は継承先で上書きすることができる。
virtualの上書きされた関数は、基底でも上書きされた関数を呼ぶ。
もちろんインスタンスは実装したクラスのインスタンスじゃないといけないけども。
0453デフォルトの名無しさん
2009/10/30(金) 15:43:11>>450 の言うデータ領域って、たとえばimmutableな文字列定数とかを格納するところかな??
static constの変数とか。
0454デフォルトの名無しさん
2009/10/30(金) 15:59:330455デフォルトの名無しさん
2009/10/30(金) 16:25:02ttp://codepad.org/Pldw34mI
1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。
何も問題ありません。頭が爆破寸前です。
>>452
>上のクラスをnewしたら、自動変数とされる領域もヒープに確保される。
おkです。
>でも動作は自動変数と変わらない。
>deleteした瞬間がスコープ終了の瞬間。
自動変数の定義は、「関数内で宣言された記憶クラス指定子の付かない変数」ですよね?
deleteさえしっかりやれば、newしたものも自動変数と同じ振る舞いをすると。
>>453
>>450のソースのコメントは間違い・・・?
下記2種「以外」の変数が格納される領域がデータ領域?
・グローバル変数
・自動変数
0456デフォルトの名無しさん
2009/10/30(金) 17:10:43C++におけるメジャーなメモリ領域は2つ。
一つはスタックと呼ばれる領域。一つは、ヒープと呼ばれる領域。
スタックは宣言したときに確保されてスコープが終了したら破棄されることを約束された領域。
ヒープはメモリのプールで必要なときに確保して不要になったらユーザの責任で開放する。資源は有効に。
で、コード領域やデータ領域というのはコンパイラやOSの最適化によって発生した領域。
たぶん、データ領域は何度も参照されるような定数データを効率よく回すための機構で基本的に書き込み禁止。
で、たぶん、コード領域はプログラムコード自身をOSがロードした領域。
なので、後の2つはC++の仕様外だと思う。
0457デフォルトの名無しさん
2009/10/30(金) 18:40:54静的記憶期間(static付きやグローバル変数など)のオブジェクトの置き場なのだから、
データ領域はスタック・ヒープと同列に扱おうよ。
規格書でも(言葉は違うけど)その3つの概念は出てくることだし。
0458デフォルトの名無しさん
2009/10/30(金) 19:24:41→このままでは、ClsSuper::test(), ClsSub1::test(), ClsSub2::test()のどれとしてコンパイルすればいいのかわからない。
このコードで言うと、sub1, sub2 superのどれを表示していいかわからない。
ここまでは大丈夫?
次に、ClsSuperの隠しメンバ変数にpTestFunctionという関数ポインタを追加して、
実行時、インスタンスが生成時にその関数ポインタへ使用すべきメンバ関数を代入するようにする。
ClsSuper *s; には使用すべき関数ポインタが含まれているので、
コンパイル時に s->test(); という文を、関数ポインタからの呼び出しに翻訳する。
実行時に、sがどの型をさしていようと適切な関数ポインタが指定されるので、問題なく実行できる。
> 1と入力するとsub1が表示され、1以外を入力するとsub2が表示されます。
というのは、仮想関数テーブル(=関数ポインタのようなもの)が仕事をしてるから。
とりあえずコメントにも補足書いたけど、以上が仮想関数テーブルが必要な理由。
http://codepad.org/uuPlC3eO
0459デフォルトの名無しさん
2009/10/30(金) 20:26:13>>457も言ってるけど、スタックとヒープと静的の三つとした方が。
静的記憶は普通に読み書き可能なことが多いんじゃないかな、x86では。dsセレクタで
アクセスされるようなセグメントに配置するのが一般的な気がする。
リードオンリーの定数はむしろ、コンパイル時点で埋め込んじゃう気がするし。
0460デフォルトの名無しさん
2009/10/30(金) 20:47:25コンパイル時に固定サイズの領域を割り当てるのがスタック。
スタック不足になるのは、メモリが足らないからではなく
予測以上に初期の固定メモリを使い切ったため。
物理的には、スタックもヒープも違いはないので、
多くメモリ確保するなら動的=ヒープがいい。
0461デフォルトの名無しさん
2009/10/30(金) 21:00:19今の私の認識と、説明していただいたメモリ領域の説明がだいたい一致するので
メモリ領域に関しては大丈夫そうです。
>>460
>多くメモリ確保するなら動的=ヒープがいい。
私がはじめに学んだ言語ではそのあたりを気にしながらコーディングしていましたが
c++においてはまったく意識してませんでした。
メモリをいっぱい使うような処理をする場合には気をつけてみます。
>>458
40行目で正しく関数が呼べてるのは仮想関数テーブルがあるからなんですね。
コーディングしている分には見えないものですが、内部的には説明してくださったような動作になっていると。
今日1日でc++に対する理解度がだいぶ深まった気がします。
0462デフォルトの名無しさん
2009/10/30(金) 21:05:380463デフォルトの名無しさん
2009/10/30(金) 21:08:23スタックは、はじめに確保した領域を使い回すだけだからOSとのやりとりはなく
高速。
0464デフォルトの名無しさん
2009/10/30(金) 21:11:40スタック ヒープに違いはないが
生成と破棄に関しては違いが出るってこと。
長いこと(10秒以上とか)保持するなら、
生成コストは無視できるから
安定性のためヒープを使う方が良いな。
0465デフォルトの名無しさん
2009/10/30(金) 22:07:18一般的なスタックは、pushするかスタックポインタを移動させることで積み上げて、
破棄する時はスタックポインタの移動だけで終わるから、ヒープに比べたら圧倒的に
確保も解放も高速だぞ。
0466デフォルトの名無しさん
2009/10/30(金) 22:08:280467デフォルトの名無しさん
2009/10/30(金) 22:26:53確保方法に違いはあっても、どちらも同一の(実)メモリつかうんだよ。
OSに問い合わせるか、C言語が管理している領域に問い合わせるかだけ。
スタックでさえ仮想メモリに移動することもある。
OSや他のアプリからみれば特殊な物ではない。
0468デフォルトの名無しさん
2009/10/30(金) 23:41:54>>466がほとんどの環境で正解。
0469デフォルトの名無しさん
2009/10/30(金) 23:44:38以下ループ
0470デフォルトの名無しさん
2009/10/31(土) 01:50:360471デフォルトの名無しさん
2009/10/31(土) 03:11:390472デフォルトの名無しさん
2009/10/31(土) 03:48:03デバッグでは作成できて、リリースしてビルドすると
ライブラリ ***testdll.exp を作成中
LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。
ビルドログは "***" に保存されました。
testdll - エラー 1、警告 0
と表示されてできません
どうすればできるのでしょうか・・・・・
0473デフォルトの名無しさん
2009/10/31(土) 03:52:30「エントリーポイントを定義しなければなりません」
↓
エントリーポイントを定義すればできる
これぐらいの推測ができないようじゃ、前途多難だな。
0474デフォルトの名無しさん
2009/10/31(土) 11:53:200475デフォルトの名無しさん
2009/10/31(土) 12:31:50template<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); // こんな感じでコンテナの要素数を求めたいのですが
}
0476デフォルトの名無しさん
2009/10/31(土) 12:34:410477デフォルトの名無しさん
2009/10/31(土) 12:42:59vector::size() をこのように使っているのですが
これでは、イテレータを渡しても、当然のことですがエラーになってしまいます、
なんとかイテレータを渡して、そのコンテナのサイズがわからないものかと思案しています。
template <class Container> inline
size_t Size(const Container& c)
{ return c.size(); }
0478デフォルトの名無しさん
2009/10/31(土) 12:55:040479デフォルトの名無しさん
2009/10/31(土) 13:02:22ボトルネックの個所で
スタックだろうがヒープだろうがメモリの確保解放するコード書くのは論外だろう
0480デフォルトの名無しさん
2009/10/31(土) 13:09:48秒間一万回程度の半端なボトルネックだと、スタックかヒープかで致命的な事態に
なるだろうな。
まぁ、違いを知った上で、大差無いと判断したところで使うのは最初から問題無い。
「違わない」と断言するのは激しく問題があるってだけ。カーネルに落ちる場合は
スタックの数万倍も重いことがある訳で。
0481デフォルトの名無しさん
2009/10/31(土) 13:10:09関数オブジェクトを作っていて、引数が多くなってしまい
なんとか、減らせないものだろうかと思い質問したしだいでした
要素へのポインタを所持しているコンテナを引き渡すのなら、
要素数を引き渡すだけのことなので、同じくらいのコストがかかりそうで
あききらめますが、要素へのポインタを所持しているコンテナを引き渡して
要素数を求める方法へ関心があります、単純な実装例をご教示願えませんか。
0482デフォルトの名無しさん
2009/10/31(土) 13:29:210483デフォルトの名無しさん
2009/10/31(土) 13:45:50イテレータのペア(開始と終端)を取る関数オブジェクトなら
std::distance(it1, it2) で [it1-it2)間の要素数が求められるよ。
0484デフォルトの名無しさん
2009/10/31(土) 14:20:44ひとつのイテレータからコンテナの要素数を求める一般的な方法はないよ。
実装依存の機能でそういうのがあるか、自分で実装すれば可能。
beginとendがあるなら>>483のでいける。
0485デフォルトの名無しさん
2009/10/31(土) 18:59:20>実装依存の機能でそういうのがあるか、自分で実装すれば可能。
もし仮に実装するなら、どんな感じになるのでしょうか?
まずは、イテレータのアドレスを取得しなければならないのはわかるのですが
それ以降の展開が想像できません、向学のために概略だけでも教えてもらえないでしょうか。
0486デフォルトの名無しさん
2009/10/31(土) 19:11:13MinGW だとイテレータはコンテナのアドレスを持ってるようだ
0487デフォルトの名無しさん
2009/10/31(土) 20:54:210488デフォルトの名無しさん
2009/10/31(土) 21:51:29元のイテレータの派生クラスかラッパークラスを作って、そいつに要素数か親コンテナのポインタを持たせる。
しかし、親コンテナの要素数が必要な処理ってどんなだ?
コードをさらしてみる気はないか?
0489デフォルトの名無しさん
2009/10/31(土) 21:56:41元のをを渡せよ。
0490デフォルトの名無しさん
2009/10/31(土) 22:09:550491デフォルトの名無しさん
2009/11/02(月) 21:07:20パッと見どうゆう動作をするのかわからないから、危険な香りがするのですが。
例えば、タスクシステムを使っていて、とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
一見メモリリークするコードに見えます。
0492デフォルトの名無しさん
2009/11/02(月) 21:13:44基本的にそういうことはドキュメントに書いておくべきことじゃないかなぁ。
読まない人もいるみたいだけどね。読みやすいドキュメントって言うのもむずかしいけど。
0493デフォルトの名無しさん
2009/11/02(月) 21:13:49何を使っても酷いことになる人はどこにでもいるよ
0494デフォルトの名無しさん
2009/11/02(月) 21:28:12そんな事言ったらoperator+をオーバーロードしてマイナスの動作を
させるへそ曲がりな事だって出来るぞ
仕様書でちゃんと最初に決めとけ
0495デフォルトの名無しさん
2009/11/02(月) 21:46:43危険だよ。だから是非使うべきだと感じないなら使うものではない。ただ、例えば、
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
0496デフォルトの名無しさん
2009/11/02(月) 22:15:04基本的には使わないだろう。企業に限らず。
でも、例えば多倍長整数クラスとか、有理数クラスとか、ベクトルクラスとかを
作るなら、operator+を定義しても恐らく誰も間違わない。そういう場合は使う
方が楽という判断も十分有力だし、それでも使わないという判断もやはり有力。
0497デフォルトの名無しさん
2009/11/02(月) 22:17:08無闇やたらと使うのは糞設計だが、完全排除すれば良設計というものでもない。
0498デフォルトの名無しさん
2009/11/02(月) 22:28:050499デフォルトの名無しさん
2009/11/02(月) 23:31:40俺は argument 一つの constructor はやっぱり explicit 付けてる。
operator overloading の方はたまに使う時がある。
0500デフォルトの名無しさん
2009/11/03(火) 03:04:260501デフォルトの名無しさん
2009/11/03(火) 06:28:54× オーバーライド
○ オーバーロード
あと、タスクシステム死ね。
> とあるクラスをnewするとそのクラスをタスクに追加したりするような仕組みの場合
> 一見メモリリークするコードに見えます。
具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?
0502デフォルトの名無しさん
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
}
0503デフォルトの名無しさん
2009/11/03(火) 14:50:37void Debug::create_debug_message(const char *format, ...)
{
char tmp_str[100];
va_list ap;
va_start(ap, format);
vsprintf(tmp_str, format, ap);
}
0504デフォルトの名無しさん
2009/11/03(火) 14:58:300505デフォルトの名無しさん
2009/11/03(火) 15:54:29リハビリしとかなきゃ
0506491
2009/11/03(火) 18:00:50多倍長整数クラスの+のように、直感的にわかるような動作をするものなら演算子のオーバーロードをしても良いが
基本的に多用するものではないということですね。
>>501
>×オーバーライド
間違いを確認しました。
>具体的なデメリットがわかってるのに、なんでそのうえで一般論を持ち出す必要があるの?
デメリットがあっても、それを打ち消すようなコーディングの仕方や
デメリットを凌駕するメリットがあれば、演算子のオーバーロードを積極的に使っていこうと考えていたからです。
私はC++を勉強しはじめてまだ日が浅いので、私の知らない何かがあるのかもしれないと思い、質問させてもらいました。
一般的な演算子のオーバーロードに対する考えが聞けて、とてもためになりました。
ありがとうございます。
0507デフォルトの名無しさん
2009/11/04(水) 12:21:15業種によっても違うんじゃないかな。
私のところは画像処理や数値計算関係なので座標の足し算とかベクタの掛け算なんかが
頻発するので演算子オーバーロードはあるとないとじゃ大違いだから。
0508デフォルトの名無しさん
2009/11/04(水) 16:41:27内積にすんのかな
0509デフォルトの名無しさん
2009/11/04(水) 16:48:040510デフォルトの名無しさん
2009/11/04(水) 17:07:21いずれにせよ、ベクトルや行列使った数値計算とかは
オーバーロードしないとコードが読めなくなるからリスクとの
トレードオフとして悪くないと思う。
0511デフォルトの名無しさん
2009/11/04(水) 17:18:02って考えるとなんか夢が広がるような気がするよね
実際には関数呼び出しだって同じなんだが、表記的に
高水準(抽象的)・低水準(具体的)の混在具合が脳汁出そう
0512デフォルトの名無しさん
2009/11/04(水) 17:59:50演算ライブラリによっては敢えて用意していないね。
それでもスカラ積があるだけでも随分違うけど。
0513デフォルトの名無しさん
2009/11/04(水) 21:19:06だけど、内積でも別に文句言うほどじゃないかな
0514デフォルトの名無しさん
2009/11/04(水) 21:55:010515デフォルトの名無しさん
2009/11/04(水) 21:59:47は、実際使ってみると割と平気だったりするんだよな。
ただ、見慣れない問題に直面する可能性も高いから、やっぱりお仕事だと微妙かな。
boost::formatとか激しく便利ではあるんだけど。
0516デフォルトの名無しさん
2009/11/04(水) 22:57:49数Bやり直せw
0517デフォルトの名無しさん
2009/11/04(水) 23:06:14おまえこそやり直せ
0518デフォルトの名無しさん
2009/11/04(水) 23:14:190519デフォルトの名無しさん
2009/11/05(木) 03:19:55ベクトル積=外積
0520デフォルトの名無しさん
2009/11/05(木) 08:51:58va_endわすれてるぞ
0521デフォルトの名無しさん
2009/11/05(木) 09:18:300522デフォルトの名無しさん
2009/11/05(木) 09:24:310523デフォルトの名無しさん
2009/11/05(木) 09:48:19{
class A;
};
namespace World
{
class B;
};
ヘッダーファイルに上記のように書いたところ、
class Bの所属がなぜかHello::World::Bとして扱われてしまい、
コンパイルエラーになります。これはコンパイラのバグでしょうか?
環境はwinXP x86 VC++ 2008Expressを使ってます。
0524デフォルトの名無しさん
2009/11/05(木) 10:01:37523自体は正しい
0525デフォルトの名無しさん
2009/11/05(木) 10:03:150526デフォルトの名無しさん
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' を使用しています。
0527デフォルトの名無しさん
2009/11/05(木) 11:10:32namespace Helloが閉じていない。
# まぁ、想定の範囲内だな。
0528デフォルトの名無しさん
2009/11/05(木) 11:11:50まで書くとvisual studio のインテリセンスがWorldや
ヘッダーに書いた他のnamespaceを全部含んでしまっているように表示します。
World::やその他のネームスペースからはHelloを参照することはありません。
0529デフォルトの名無しさん
2009/11/05(木) 11:14:220530デフォルトの名無しさん
2009/11/05(木) 11:14:300531デフォルトの名無しさん
2009/11/05(木) 11:32:52floatとdoubleはどっちが速いですか?
0532デフォルトの名無しさん
2009/11/05(木) 11:39:13一概には言えませんが、doubleで組んで速度に不満があったら両方実測して比較すればよいでしょう。
0533デフォルトの名無しさん
2009/11/05(木) 11:43:23昔は、doubleに変換されるという説もあったが、いまは直に計算する。
0534デフォルトの名無しさん
2009/11/05(木) 11:45:13計算だけではなく、メモリサイズと呼び出し時間が短縮できる。
0535デフォルトの名無しさん
2009/11/05(木) 11:52:000536デフォルトの名無しさん
2009/11/05(木) 12:10:080537デフォルトの名無しさん
2009/11/05(木) 13:15:380538デフォルトの名無しさん
2009/11/05(木) 16:20:320539デフォルトの名無しさん
2009/11/05(木) 16:43:18だから用途が限られる
画面座標とか
0540デフォルトの名無しさん
2009/11/05(木) 17:46:270541デフォルトの名無しさん
2009/11/05(木) 18:05:170542デフォルトの名無しさん
2009/11/05(木) 18:58:150543デフォルトの名無しさん
2009/11/05(木) 19:14:310544デフォルトの名無しさん
2009/11/05(木) 20:29:16class は ; いるけどさ。
ていうか namespace {} に ; つけないで普通に使っているんだが…
0545デフォルトの名無しさん
2009/11/05(木) 20:35:520546デフォルトの名無しさん
2009/11/05(木) 20:46:170547デフォルトの名無しさん
2009/11/05(木) 21:08:49class foo { int bar; } buzz;
namespace foo { int bar; } buzz; // ← これだけ明らかにおかしく見えれば大丈夫
0548デフォルトの名無しさん
2009/11/06(金) 10:11:30>534、>535は正しいが、速度よりも>539の問題の方が通常は問題になるので、doubleを使っておくのが無難。
ポインタ演算については>542、>546の通りだが、>543の言うように「インデックス」が何を指しているかが問題。
0549デフォルトの名無しさん
2009/11/06(金) 13:20:14DLL使うと、中間ファイルを生成してから追記するので遅いです。
100Mのzipファイルならそれをopenして追記したいです。
0550デフォルトの名無しさん
2009/11/06(金) 13:31:390551デフォルトの名無しさん
2009/11/06(金) 13:33:270552デフォルトの名無しさん
2009/11/06(金) 13:36:35このwebサイト収集するやつは、zip追記してます。
でもC言語でやってないです。
http://www.unixuser.org/~euske/python/webstemmer/index-j.html
0553デフォルトの名無しさん
2009/11/06(金) 14:01:44外人がいいやつ作ってくれました。
これで追記出来ました。
http://www.wischik.com/lu/programmer/zip_utils.html
0554デフォルトの名無しさん
2009/11/06(金) 18:19:57> doubleを使っておくのが無難。
それは微妙。どっちが向いてるのか考えるべき。ちょっと考えれば大体正解が選べるし。
例えば、APIがfloatを要求してるような場合はfloatが無難。
floatは精度に注意、floatとdoubleを無駄に混在させるのはアホ、SSEでは圧倒的に速度
が違う、SSE使わないならほんの僅かにfloatが速い、くらいであとは自己判断かな。
0555デフォルトの名無しさん
2009/11/06(金) 20:10:200556デフォルトの名無しさん
2009/11/06(金) 20:12:50え?
0557デフォルトの名無しさん
2009/11/06(金) 20:14:14typedef struct
{
std::vector<int> foo;
std::vector<float> bar;
}
HOGE;
これを値渡しすると、各vectorのコピーコンストラクタはちゃんと呼ばれるんでしょうか。
0558デフォルトの名無しさん
2009/11/06(金) 20:17:36それも環境次第だとは思うけど、少なくとも整数の符号拡張みたいに単純にはいかない。
フォーマットの変換が必要だから。
x86のFPUだと相当なコストがかかるけど、SSEなんかだとどうかは知らない。
0559デフォルトの名無しさん
2009/11/06(金) 20:24:57ヒント : C++では基本的にclass と struct は同等の扱い
デフォルトのprivateとpublicが違うだけ
0560デフォルトの名無しさん
2009/11/06(金) 21:13:15ヒントより短い答え:呼ばれます。
0561デフォルトの名無しさん
2009/11/06(金) 22:03:450562デフォルトの名無しさん
2009/11/06(金) 22:24:42俺のちんこよりは小さいから
0563デフォルトの名無しさん
2009/11/06(金) 22:50:31よく読めてないけど、オンメモリで展開、追加、圧縮をやってるんじゃないの?
0564デフォルトの名無しさん
2009/11/06(金) 23:55:53新人「大丈夫ですよ先輩。sizeofで見たらたった80バイトです」
0565デフォルトの名無しさん
2009/11/07(土) 00:00:20値渡しすると馬鹿みたいにpushの荒らしになる
rep movsが使えないのはpushが逆順になるからだろうな
それなら簡単なループ組んで転送すればいいと思うのに
pushを配列数分吐くもんだからexeが巨大になって馬鹿みたい
0566デフォルトの名無しさん
2009/11/07(土) 00:00:29追記は新規に作ったファイルだけだった
既存ファイルには追記できなかった
追加しようとしたらデータ初期化されたよ
0567デフォルトの名無しさん
2009/11/07(土) 00:09:08http://www.tnksoft.com/reading/zipfile/arczip.php
http://www.tnksoft.com/reading/zipfile/nonarc2.php
0568デフォルトの名無しさん
2009/11/07(土) 00:17:40無圧縮zipならできるかな
0569デフォルトの名無しさん
2009/11/07(土) 00:20:34圧縮して、バイナリ比較して、「追記」が実現可能かどうか見てみたら。
無圧縮でもそれやってみたら。
0570デフォルトの名無しさん
2009/11/07(土) 00:30:05絶対出来るはず
0571デフォルトの名無しさん
2009/11/07(土) 01:25:110572デフォルトの名無しさん
2009/11/07(土) 01:39:470573デフォルトの名無しさん
2009/11/07(土) 02:11:520574デフォルトの名無しさん
2009/11/07(土) 02:18:32それで何か問題でも?
0575デフォルトの名無しさん
2009/11/07(土) 02:23:41変数の初期化に使われているよ
特に配列だと間違いなく出てくる
0576デフォルトの名無しさん
2009/11/07(土) 02:34:11ポインタや参照が使えない状況ってのが思い浮かばない。
0577デフォルトの名無しさん
2009/11/07(土) 02:55:20それが必要な状況?それは↓
0578デフォルトの名無しさん
2009/11/07(土) 03:36:480579デフォルトの名無しさん
2009/11/07(土) 06:46:060580デフォルトの名無しさん
2009/11/07(土) 07:46:51とかってありなの?
VCだと中の変数ゼロになるんだけど
0581デフォルトの名無しさん
2009/11/07(土) 08:04:270582デフォルトの名無しさん
2009/11/07(土) 08:11:190583デフォルトの名無しさん
2009/11/07(土) 08:15:20書き換えれば理論的には可能なはずなんだ。
でも正しいセットの仕方が判らない。
0584デフォルトの名無しさん
2009/11/07(土) 11:04:21http://www.pkware.com/documents/casestudies/APPNOTE.TXT
0585デフォルトの名無しさん
2009/11/07(土) 11:15:530586デフォルトの名無しさん
2009/11/07(土) 13:03:04追記くらいライブラリないのかよ
0587デフォルトの名無しさん
2009/11/07(土) 13:18:34ファイルヘッダ
圧縮データ
ファイルヘッダ
圧縮データ
....
ファイルヘッダ
圧縮データ
アーカイブインデックス(>>583のいう情報フォーマット部分)
てなってるから最後の圧縮データとアーカイブインデックスの間に
追記のファイルヘッダと圧縮データを入れて
アーカイブインデックスにも追加できればいける
7zとかcabなんかのソリッド圧縮形式だと
LZ77の辞書とエントロピー圧縮のコンテキストが必要だから
オンメモリでもいいから一度展開作業をしないと追記できない
ちなみにJavaScriptで無圧縮zip作るひとがいるくらいだから
圧縮をzlibですればzipのフォーマット自体はそれほど難しくない
0588デフォルトの名無しさん
2009/11/07(土) 13:39:270589デフォルトの名無しさん
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()
0590589
2009/11/07(土) 14:13:08コピーしたり展開したら時間かかるが、追記はコピーより速くできた。
0591デフォルトの名無しさん
2009/11/07(土) 14:49:150592デフォルトの名無しさん
2009/11/07(土) 16:25:07Bar(): x(m_x), m_x() { }
Foo &x;
private:
Foo m_x;
};
初期化子の実行順序は、初期化子の順序ではなくて変数宣言の順序だと記憶していますが、
(例のコードではどちらにせよxが先だと思います。)上のようなコードを書くと、xの初期化から
始まって何物でもないm_xを参照してしまうはずなのにVisual C++のコンパイラは警告すら発し
ません。
このようなコードは避けるべきということは言うまでもないですが、コンパイラがまったく順序に
関知しないというのはいかがなものでしょうか、と。
0593デフォルトの名無しさん
2009/11/07(土) 16:32:20Zipは追記できないという説に対して
ZipもZip64も追記できたと言うこと
0594デフォルトの名無しさん
2009/11/07(土) 17:13:59嫌だったらC++使うなカス
0595デフォルトの名無しさん
2009/11/07(土) 17:14:59例えば aaa.h, bbb.h, ccc.h
の3つが互いにインクルードしている場合、
全体で使用できるためにはどのファイルで定義すればいいのかわからん
0596デフォルトの名無しさん
2009/11/07(土) 17:21:080597デフォルトの名無しさん
2009/11/07(土) 17:21:08#includeはそこにテキストがそのまま展開される。
#include "aaa.h"
#include "bbb.h"
#include "ccc.h"
なら aaa.h が真っ先に展開される。
しかし、非ローカルなスタティック変数の初期化順とかいう話になるのなら
それはそれは難しいことに。
違ったかな。ほほほ。
0598デフォルトの名無しさん
2009/11/07(土) 17:30:310599デフォルトの名無しさん
2009/11/07(土) 18:04:330600デフォルトの名無しさん
2009/11/07(土) 18:08:02{
using namespace boost::lambda;
// ここでbindとか_1とか使う
}
// ここでは using namespace は無効
0601デフォルトの名無しさん
2009/11/07(土) 18:10:360602デフォルトの名無しさん
2009/11/07(土) 18:11:450603デフォルトの名無しさん
2009/11/07(土) 18:12:27グローバルでもいいんじゃないですかね。
0604デフォルトの名無しさん
2009/11/07(土) 18:34:43だからまとめて共通ヘッダに入れてグローバルusingしてる
0605デフォルトの名無しさん
2009/11/07(土) 18:37:120606デフォルトの名無しさん
2009/11/07(土) 18:43:32結構めんどくさくね?
0607デフォルトの名無しさん
2009/11/07(土) 19:01:18あんまり気にしたことないなぁ。って言うか末尾にSEXついてるの多すぎ。
マイクロソフトの技術者はどんだけ欲求不満なのか、と。
0608デフォルトの名無しさん
2009/11/07(土) 19:01:19std::と打ったほうが楽
0609デフォルトの名無しさん
2009/11/07(土) 19:06:03sexわろたw
気にしたことなかったけど確かにそうだな
0610デフォルトの名無しさん
2009/11/07(土) 19:16:11インライン展開を期待するときなんか、あえて構造体の値戻しを使ったりする。
0611デフォルトの名無しさん
2009/11/07(土) 19:41:390612デフォルトの名無しさん
2009/11/07(土) 19:43:12みたいに定義不可能な面があるから、依存するな、とかEffectiveC++に書いてあった
ような気がしなくもない
0613デフォルトの名無しさん
2009/11/07(土) 19:52:020614デフォルトの名無しさん
2009/11/07(土) 20:01:16Google的に、コンストラクタでは単純な初期化にとどめて、複雑な初期化はInit()で
やれ、というコーディングを採用してれば、初期化順序で悩むことも無い気がする
0615デフォルトの名無しさん
2009/11/07(土) 20:17:490616デフォルトの名無しさん
2009/11/07(土) 21:00:39コンストラクタから初期化を追い出す必要は無いよ。
Init() 呼ぶくらいならグローバルなポインタに new すればいいじゃん。
0617デフォルトの名無しさん
2009/11/07(土) 22:58:310618デフォルトの名無しさん
2009/11/07(土) 23:26:560619デフォルトの名無しさん
2009/11/07(土) 23:31:200620デフォルトの名無しさん
2009/11/07(土) 23:36:58追加の引数が無い奴はグローバルにすると全体に影響が出るから気をつけてな。
0621デフォルトの名無しさん
2009/11/08(日) 00:09:48グローバルだと目的のクラス以外でもオーバーロードされてしまう
staticメンバだと目的のクラスだけオーバーロードされる
ということでしょうか。基本的にはstaticメンバにしたほうがよさそうですね
0622デフォルトの名無しさん
2009/11/08(日) 00:12:34影響範囲については、だいたいそういうこと。
細かい話をすると、クラスの奴は派生クラスでも使われる。
あと、追加の引数が無い奴をグローバルに置くのはオーバーロードじゃなくて置き換え、な。
0623デフォルトの名無しさん
2009/11/08(日) 15:27:46dynamic_castは遅いけど変換不能な場合NULLを返す
static_castは早いけど変換不能でも知らせてくれない
これ以外の違いってなんかある?
0624デフォルトの名無しさん
2009/11/08(日) 15:34:01その派生クラスがその基底クラスを仮想継承している場合、static_castは使用できない
(両方に当てはまる場合、どちらも使用できない)
0625デフォルトの名無しさん
2009/11/08(日) 19:45:51マジすか初めて知った
確かにできてもあんまり意味はないけど
0626デフォルトの名無しさん
2009/11/08(日) 20:18:33HogeBase* hoge;
Hoge2 *p = new Hoge2;
hoge = p;//基底があってなかったらコンパイルエラー吐く。
0627デフォルトの名無しさん
2009/11/09(月) 01:46:580628デフォルトの名無しさん
2009/11/09(月) 01:56:390629デフォルトの名無しさん
2009/11/09(月) 02:49:460630デフォルトの名無しさん
2009/11/09(月) 03:04:02違う
クラスが複雑になるとクロスキャストしたい局面はよく現れる
0631デフォルトの名無しさん
2009/11/09(月) 03:04:46○継承関係が複雑になると
あ、継承関係が糞設計なんだろって突っ込みは無しな
そういう事を言い出すとキリがなくなってしまうんで
0632デフォルトの名無しさん
2009/11/09(月) 03:24:180633デフォルトの名無しさん
2009/11/09(月) 03:49:06ほうら来た
だからそういう突っ込みは無し
人間そこまで完全な奴はいない
特にある程度プロジェクトが進んでしまっていると
今更設計を変えられない事も多い
0634デフォルトの名無しさん
2009/11/09(月) 03:55:13それで何とか勝負するしかないって事はあるだろう、仕事なら。
0635デフォルトの名無しさん
2009/11/09(月) 04:06:190636デフォルトの名無しさん
2009/11/09(月) 04:06:540637デフォルトの名無しさん
2009/11/09(月) 04:14:02糞設計をしてしまうことはあるし、気付いた時には引き返せないこともあるから、
使う時は使うべき。設計は変えられないが他の方法でどうにかしよう、というのは
最悪だから。
でも、そういう事態になったなら設計が糞だったんだ、という認識はすべき。
0638デフォルトの名無しさん
2009/11/09(月) 04:50:41それは当たり前だろう
そんな事はわざわざ言わなくても誰でもわかっている
0639デフォルトの名無しさん
2009/11/09(月) 04:58:390640デフォルトの名無しさん
2009/11/09(月) 04:59:420641デフォルトの名無しさん
2009/11/09(月) 23:38:14ベスト5ぐらいには他にどんなのがあるの?
0642デフォルトの名無しさん
2009/11/09(月) 23:54:09ボーランドとかTurboとか
0643デフォルトの名無しさん
2009/11/10(火) 01:28:560644デフォルトの名無しさん
2009/11/10(火) 10:52:510645デフォルトの名無しさん
2009/11/10(火) 12:31:110646デフォルトの名無しさん
2009/11/10(火) 17:03:07コードパッドのほうだと期待通りに動くんですけど
僕の使ってるコンパイラ(VC++EE2008)ではdelete[]が確保したサイズじゃなくてクラスのサイズを引き数に渡してしまいます
これは規格で定まっていないんじゃなくて僕が使ってるのがただのクソッタレコンパイラということですか?
0647デフォルトの名無しさん
2009/11/10(火) 17:47:50「シェア」の意味によって違ってくるだろうな。
使ってる人数か?コンパイルされたコードの走っている台数か?
商用に限るのか?学生の講義とかも含めるのか?日本なのか世界なのか?
コンパイルされたコードの走ってる台数だとOSなんかも入って
ちょっとナンセンスになるから、結局人数なんだろうけど。
そうすると組み込み系とかはそんなに多くないと思う。
0648デフォルトの名無しさん
2009/11/10(火) 17:56:12size_tを引数にとるoperator delete[]なんて規格にあったっけ?
0649デフォルトの名無しさん
2009/11/10(火) 18:00:260650デフォルトの名無しさん
2009/11/10(火) 21:53:50int型の引数nに応じて、配列の大きさを決めたいのですが、コンパイルすると
「定数式が必要です」とのエラーメッセージが出て失敗します。
どうすれば私の意図する動作が可能になるでしょうか?
int* getTest(int n, int o[], float r) {
int p[n][2];// = new int[n][2];
//省略
return *p;
}
0651デフォルトの名無しさん
2009/11/10(火) 22:17:15配列の大きさはコンパイル時に決定されなければならない。
0652デフォルトの名無しさん
2009/11/10(火) 22:38:07配列の大きさを指定できるのは一番右側のoperator[]内だけ
0653デフォルトの名無しさん
2009/11/10(火) 23:39:180654デフォルトの名無しさん
2009/11/10(火) 23:42:36関数内でnewやmallocしてそのポインタを返すのは危険きわまる。
C++なんだから、vector<vector<int>>を参照渡しするのがいいと思う。
0655デフォルトの名無しさん
2009/11/10(火) 23:44:320656デフォルトの名無しさん
2009/11/10(火) 23:55:55shared_ptrを使えばいいんだけどね。std::tr1::shared_ptr<std::string>とか
長くなりがちなのがちょっと。
0657デフォルトの名無しさん
2009/11/11(水) 00:13:10コピーと代入のコスト結構馬鹿にならんし
寿命と例外安全考えて使わなくていいところは使わないほうがいいと思うんだし
0658デフォルトの名無しさん
2009/11/11(水) 00:41:54おいデタラメ書くな
0659650
2009/11/11(水) 02:52:29こんな感じでしょうか?
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] = の部分をどう書いてもエラーになってしまいます。
0660デフォルトの名無しさん
2009/11/11(水) 04:08:450661デフォルトの名無しさん
2009/11/11(水) 09:13:010662デフォルトの名無しさん
2009/11/11(水) 10:01:28そこで new はおかしいし、それじゃインスタンス作りようないでしょ。
(vector の大きさも指定していない)単に、
vector<vector<float> > v = vector<vector<float> >(n,vector<float>(2,0));
…
return v;
とかいう話?(次元 nx2 で良いのか知らんが)
それにしても cast をたくさん使ってるね。
0663デフォルトの名無しさん
2009/11/11(水) 10:04:12CPUの中の人は結局doubleで計算するわけ?
0664デフォルトの名無しさん
2009/11/11(水) 12:14:43x86系CPU+Visual C++では、そう(doubleじゃなくてlong doubleだけど)。
x64だとちょっと違ってて、多分floatで計算してると思う。
詳しくはx87FPUとSSE演算を調べてみてくれ。
重要なのはx64+WindowsだとFPUレジスタがDisableされていること。
0665デフォルトの名無しさん
2009/11/11(水) 13:50:25プロジェクトに悪意あるメンバーがいたらメモリリークさせられるぞ
0666デフォルトの名無しさん
2009/11/11(水) 13:59:530667デフォルトの名無しさん
2009/11/11(水) 14:25:35対象ウィンドウを検索して存在すればCWnd::SetWindowPos()で最前面にもってきて
CWnd::RedrawWindow()で再描画、ということを行っています。
対象ウィンドウが他のウィンドウに隠れている場合はこれでいいんですが
もともと最前面にある場合は、再描画の処理は不要だと思うのでスキップしたいのですが
最前面であるかどうかはどう判断すれば良いのでしょうか?
CWnd::GetWindow()でいろいろやってみているんですがうまくいきません。
0668デフォルトの名無しさん
2009/11/11(水) 15:41:34>x64+WindowsだとFPUレジスタがDisableされていること。
されてねえよ
タスクスイッチの時もスレッド切り替えの時もちゃんとFPUはsaveするように
仕様が変わった
0669デフォルトの名無しさん
2009/11/11(水) 16:06:54::EnumWindows()とかでどうか
不安ならそれに::GetWindow()を組み合わせる
0670デフォルトの名無しさん
2009/11/11(水) 16:24:152進数から10進数への変換方法がわかったので
入力した2進数を10進数で表示する関数を作ったのですが
32桁あるときだけ答えが空白になってしまいます。
問題がある箇所を教えてください、お願いします。
環境はxp homeのvisual studio 2005です。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10099.txt
0671デフォルトの名無しさん
2009/11/11(水) 16:58:16CPUのコストはわかりませんが、少なくともメモリの使用量は同じに見えますが、どうでしょうか?
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: }
0672デフォルトの名無しさん
2009/11/11(水) 17:21:01コンパイラと環境によって違いますとしか言えない
最適化が優れたコンパイラなら float x そのものを消去してしまうと思う
0673デフォルトの名無しさん
2009/11/11(水) 17:31:12処理省略の部分でxは使っている事とします。
変数は静的な領域に確保するわけですから、どのコンパイラでもメモリの使用量はかわらないように見えるんですが、違うのでしょうか?
0674デフォルトの名無しさん
2009/11/11(水) 17:33:00そうとも言えない
とにかくコンパイラの吐いたコードを見るしか確かめる手はない
0675デフォルトの名無しさん
2009/11/11(水) 17:33:52横から、付け加えるなら、省略された部分の処理内容も影響する。
場合によっちゃあ処理フローまでガラッと変わる。
0676デフォルトの名無しさん
2009/11/11(水) 17:33:57それなら変わらないだろうという予測が立つ
しかしあくまでも予測だという事を忘れないように
0677デフォルトの名無しさん
2009/11/11(水) 17:36:51言語仕様では、静的変数の振舞は定義されていても、実装方法までは定義されていないので、
本当に静的な領域に確保されるかどうかは、コンパイラの出力したコードを見ないとわからない。
もっとも、一度確認したからといって、次にコンパイルしたときは違う結果になっているかもしれない。
0678デフォルトの名無しさん
2009/11/11(水) 17:39:07あくまで予測ですがね。
0679671
2009/11/11(水) 18:25:50コストに関しては曖昧な感じですし
for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。
ありがとうございました。
0680デフォルトの名無しさん
2009/11/11(水) 18:46:12つーか80:20の(ry
0681デフォルトの名無しさん
2009/11/11(水) 19:02:03>for文の中に書くと気持ち悪いので、forの中でしか使わない定数でも外だししときます。
そりゃ逆だ。
「スコープはなるべく小さく」といわれている。
0682デフォルトの名無しさん
2009/11/11(水) 19:03:200683デフォルトの名無しさん
2009/11/11(水) 19:04:03C++はスマポがあるからいいんだが
0684デフォルトの名無しさん
2009/11/11(水) 20:45:41いコードが出た(龍本レベルでもあり得ないと思うんだ
が…)。
しかしまぁ、人間にとってもスコープ狭い方が読むとき
に気にすべき情報が減るので読み易い。
0685デフォルトの名無しさん
2009/11/11(水) 21:48:52const int c = 10;
for(int j = 0; ・・・
}
でもこれってちょっとダサくない?
インデント深くなるし
0686デフォルトの名無しさん
2009/11/11(水) 22:05:040687デフォルトの名無しさん
2009/11/11(水) 22:34:36コピーコンストラクタには「*this = コピー元;」とだけ書いて
operator=()のほうに処理を集約してしまうことって、なにかまずいことはありますか?
0688デフォルトの名無しさん
2009/11/11(水) 22:40:080689デフォルトの名無しさん
2009/11/11(水) 22:40:42ならなくてもメンバ変数が全部初期化された後
すぐに代入することになるから無駄な処理が発生する
0690デフォルトの名無しさん
2009/11/12(木) 02:14:40コピーコンストラクタと代入演算子で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を
(ムーブ代入演算子を定義して)使う方法も使えるけど、ここでは取り上げない。あしからず。
0691デフォルトの名無しさん
2009/11/12(木) 03:17:23これ未定義の動作にならない?
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();
}
0692デフォルトの名無しさん
2009/11/12(木) 04:00:58C++において、関数ポインタを使う意義は何があるでしょうか?
言い換えれば、具体的にどのような事をするときに便利なのでしょうか
どなたかお願いします・・・
0693デフォルトの名無しさん
2009/11/12(木) 04:48:35C++でも使う例というと、関数テーブルかなぁ。
たとえば、ユーザーの入力したコマンドに応じた動作をしたい場合(以下コードは適当)、
typedef int(*Cmd)(T* args);
Cmd command = { &CommandA, &CommandB ... }; // 関数テーブル(関数ポインタのリスト)
みたいなのを用意した上で、それをこんな風に実行する。
int Execute(int cmd, T* args) { return (command[cmd])(args); } // cmdの値はユーザーの入力次第
もちろん、switch (cmd) { ... } で分岐させてもいいけど、それだと各コマンドに対応する関数を
色々切り替えたい時とかには少々不便だし、コマンドの総数が3桁だったりするとswitch文が長すぎちゃう。
まぁその辺は結局作りたい物次第なわけだけど。
世の中に無数にあるはずの、オリジナルのスクリプト言語(ゲームエンジン用でも何でも)のコードには、
関数テーブルが山ほど出てきそうだなぁ。
0694デフォルトの名無しさん
2009/11/12(木) 09:09:50インタ使ってれば無理に関数ポインタ使わなくてもいい
気がする。
0695デフォルトの名無しさん
2009/11/12(木) 09:36:520696デフォルトの名無しさん
2009/11/12(木) 10:10:150697デフォルトの名無しさん
2009/11/12(木) 12:27:45Win32を使うと嫌でもコールバックを使う場面に出くわすよ
0698デフォルトの名無しさん
2009/11/12(木) 16:09:11使えるけど使わないほうが無難だな。 ->* とか .* とか見たくないよ。
C++的には operator()()がいいかも。
0699デフォルトの名無しさん
2009/11/12(木) 20:26:120700デフォルトの名無しさん
2009/11/12(木) 21:49:51構造体の初期化でmemsetを使うと問題があると聞きました.
ループ文でまわしている場合,毎回初期化する必要があるんですが
どうすればいいんでしょうか?
ポインタ配列です.
typedef struct{
0701デフォルトの名無しさん
2009/11/12(木) 21:52:430702700
2009/11/12(木) 21:52:57どうやって初期化すればよろしいのでしょうか?
0703デフォルトの名無しさん
2009/11/12(木) 22:24:39ありがとうございます.
実際にはポインタで宣言しているのですが,
Hoge *hoge
hoge = malloc(sizeof(Hoge) * 100);
for(i = 0; i < 100; i++){
hoge[i] = {0};
}
でいいんですかね?
0704デフォルトの名無しさん
2009/11/12(木) 22:32:050705デフォルトの名無しさん
2009/11/12(木) 22:53:040706デフォルトの名無しさん
2009/11/12(木) 22:57:05それはC++。
0707デフォルトの名無しさん
2009/11/12(木) 22:59:330708デフォルトの名無しさん
2009/11/12(木) 23:00:04for(i = 0; i < 100; i++)
hoge[i] = foo;
0709デフォルトの名無しさん
2009/11/12(木) 23:00:350710デフォルトの名無しさん
2009/11/13(金) 00:44:58に応じて何種類か用意しておいてコピーすればいいと思
うんだけど、この場合何も考えずに {0} で初期化する
と未定義動作だっけ?
0711デフォルトの名無しさん
2009/11/13(金) 01:01:580712デフォルトの名無しさん
2009/11/13(金) 01:55:16この質問は>>700だぞ? 一行目でちゃんと「Cです」って言ってるじゃん。
「>>703だけ見て」ってお前、>>703だけ見ること自体がヴォケなんだよw
0713デフォルトの名無しさん
2009/11/13(金) 07:12:50規格の 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
0714デフォルトの名無しさん
2009/11/13(金) 10:25:48そうでないなら、>708で。間違っても、一部のロートルの世迷言に釣られてmemcpy(hoge + i, & foo, sizeof(foo))なんてしないように。
0715デフォルトの名無しさん
2009/11/13(金) 10:53:37こういうことなんだが。
struct {
union {
void *p;
void (*func)(void);
float f;
double d;
} u;
} s = {0};
0716デフォルトの名無しさん
2009/11/13(金) 10:56:01今規格見た。最初のメンバが初期化されるんだな。
0717デフォルトの名無しさん
2009/11/13(金) 11:59:14最初のメンバと違う型で参照したら処理系依存ってことか
0718デフォルトの名無しさん
2009/11/13(金) 12:47:56文字コードは0xa1 0xa3です。
偶然にaaaa 0xa1、0xa3 bbbb となった場合が判断できないですが。
0719デフォルトの名無しさん
2009/11/13(金) 12:59:15探したい対象が文字列のように、EUCエンコードされていることが保証されているなら、
0xa1から遡って0x80以上のコードが偶数個連続していたらその0xa1が1バイト目。
遡るのが嫌なら、先頭から監視するしか。
0720デフォルトの名無しさん
2009/11/13(金) 13:02:24今考えてるのは、unsigned char配列にデータを読み込んで0xXX, 0xYY, 0xZZ, ・・・のような形式で出力するプログラムを作り
コンパイル前に一度実行してdata.datに保存。利用者側は
unsigned char data[] =
{
#include "data.dat"
};
と書いて使う。という感じなんですが・・・
0721デフォルトの名無しさん
2009/11/13(金) 13:07:32トンクス
0722デフォルトの名無しさん
2009/11/13(金) 13:09:09windows限定なら、標準のリソースとして埋め込めばいいのでは。アイコンなど。
0723デフォルトの名無しさん
2009/11/13(金) 13:53:35文字化けや不要コードの埋め込みなどが原因と思うけど
いい具合に出来なかった。
0724718
2009/11/13(金) 14:05:360725デフォルトの名無しさん
2009/11/13(金) 14:21:20手間かかるけど、文字化け多発するよりかは良いか。
0726デフォルトの名無しさん
2009/11/13(金) 15:47:40試したところ効かなかったのですが
using boost::shared_ptr;
shared_ptr<Hoge> pHoge = shared_ptr<Hoge>( new Hoge( 3 ) );
pHoge->
↑で出したい
0727デフォルトの名無しさん
2009/11/13(金) 16:18:310728デフォルトの名無しさん
2009/11/13(金) 16:45:12スコープ付きの識別子の別名定義ができれば便利なのに
0729デフォルトの名無しさん
2009/11/13(金) 16:51:330730デフォルトの名無しさん
2009/11/13(金) 16:52:48かな、カナ、漢字など。UTF16らしいが文字コードがよくわからん。
EUC -> UTF16 -> SJIS OR EUCと何度も変換するしかないのか。
0731デフォルトの名無しさん
2009/11/13(金) 17:11:00試したけどダメっぽいです。コンパイルは通るんですが
何か根本的な間違いをしてるのかも・・・。
ひとまず諦めます
0732デフォルトの名無しさん
2009/11/13(金) 17:13:00それじゃ型限定じゃん
変数や関数の別名を参照や関数ポインタ使わずに楽に短くしたいんだよ
0733デフォルトの名無しさん
2009/11/13(金) 17:16:05インテリセンスするための情報収集が狂っちゃうと、そういうことがおきるねー
リビルドや
中間ファイル(.obj や .res .scc .pdb .pch .ilk .idb .ncb .plg .bsc まだあるかも)を完全に消してのビルドで
復活したりするよ。
0734デフォルトの名無しさん
2009/11/13(金) 17:40:31C#のusing的なやつ(しかもスコープ限定)が欲しいってことか。
0735デフォルトの名無しさん
2009/11/13(金) 18:07:55混ぜるな危険
0736デフォルトの名無しさん
2009/11/13(金) 18:18:15まぁ俺も sockaddr_in 辺りは memset でクリアしちゃ
うけどさ。
> そのコードがCで、今後C++に転用する可能性を排除で
> きるのならmemset()でもいいんでない?
厳しく言うと >>715 みたいなのは union を struct に
しても memset はアウトだよな?
0737デフォルトの名無しさん
2009/11/13(金) 19:05:49http://www.kijineko.co.jp/tech/superstitions/initialization-by-memset.html
0738デフォルトの名無しさん
2009/11/13(金) 20:29:57リンク先あっているのか?
A a[10] = {0} で a[0]〜a[9] のすべてが0クリアされるのか?
static なら保障されているが、auto な配列ではダメなのでは?
0739デフォルトの名無しさん
2009/11/13(金) 20:30:49ダメくない
0740デフォルトの名無しさん
2009/11/13(金) 20:44:04確認しました。
明示的に初期化される、ただし、一部しか明示されていない場合は、残りは 0 で初期化される、これは
auto でも static でも同じとのことですね。
thanks a lot.
0741デフォルトの名無しさん
2009/11/13(金) 23:45:42もしやと思ってSP1にアップデートしたらstd::tr1::shared_ptで出来ました!
今までアップデートしてなかったんだなぁ…
0742デフォルトの名無しさん
2009/11/14(土) 03:37:57半角スペースのある領域を""で囲っても、
ひとつの区切りとしてくれないみたいですが、
それができる方法がありましたら教えてください。
sscanf("\"abc de\" 5", "%s%s", s1, s2);
0743デフォルトの名無しさん
2009/11/14(土) 03:39:42面倒でもstrtok()使え
0744デフォルトの名無しさん
2009/11/14(土) 03:46:130745デフォルトの名無しさん
2009/11/14(土) 04:23:51ありがとうございます。
やはり、自前で実装ですか・・
やってみます。
0746デフォルトの名無しさん
2009/11/14(土) 04:31:300747デフォルトの名無しさん
2009/11/14(土) 04:51:18ありがとうございます。
試してみます。
0748デフォルトの名無しさん
2009/11/14(土) 05:52:57"%s"ではなく、"\"[^\"]"を使えばOK!
0749デフォルトの名無しさん
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]で定義しているのでアクセス可能かと思いますが
一つ目はどうやって認識しているのですか?
0750デフォルトの名無しさん
2009/11/14(土) 07:23:150751デフォルトの名無しさん
2009/11/14(土) 07:38:56有効桁数が減ります
0752デフォルトの名無しさん
2009/11/14(土) 07:55:40アクセスの仕方は一緒でも
渡されるものの内容が違います
0753デフォルトの名無しさん
2009/11/14(土) 08:49:47>test_func(*a[y])
>test_func(a[][y])
>で全て同じ定義だと思うのですが
ちがいます
0754デフォルトの名無しさん
2009/11/14(土) 09:51:11一つ目と二つ目は違いますが二つ目と三つ目はおなじですよね?
ポインタのポインタとして渡された先頭のアドレスが渡された関数で
アドレスしか渡してないのにその内部構造が定義したように認識されているのはなぜなのでしょうか?
0755デフォルトの名無しさん
2009/11/14(土) 09:54:11二番目と三番目で渡している型は
配列を指すポインタであって、ポインタのポインタではありません
0756デフォルトの名無しさん
2009/11/14(土) 09:58:06少なくとも2と3はまったく違う
1と2は一緒とみなしてよいときとそうではない場合がある
0757デフォルトの名無しさん
2009/11/14(土) 11:56:11ありがとうございます。
試してみます。
0758デフォルトの名無しさん
2009/11/14(土) 15:26:21xは初期化されず
コピーコンストラクタへいくね。
これってたまたま不定値によっては動作がおかしくなりそうだが。
メモリ確保してあるかどうかのフラグの部分でおかしな動作したよ。
0759デフォルトの名無しさん
2009/11/14(土) 16:03:10コピーコンストラクタは初期化処理の一種なわけだが。
CLASS の定義がバグってるんじゃね?
0760デフォルトの名無しさん
2009/11/14(土) 16:10:49コピーコンストラクタは、xが初めて生成されたのか不明で
初期化して良いのかわからないと思ったんです。
コピーコンストラクタは初期化時にしか使われないんですか。
代入と一緒の気がしてました。どちらの場合も対応しないといけない気がしてました。
0761デフォルトの名無しさん
2009/11/14(土) 16:13:36コンストラクタはぜんぶ初期化処理。
初期化後のコピーは代入演算子で定義する。
0762デフォルトの名無しさん
2009/11/14(土) 16:15:040763デフォルトの名無しさん
2009/11/14(土) 19:12:15>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は全く同じ意味。
0764763
2009/11/14(土) 19:15:55よく読むと A a[x][y];
を渡したいみたいだね。
それならば、>763の3か4を使う。
1,2ではダメ。
0765763
2009/11/14(土) 19:23:23何度もすまん。
>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);
}
0766デフォルトの名無しさん
2009/11/14(土) 19:45:18期待通りに出力が行えません。
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
※ファイル名を格納してる変数の型は、他の処理でも使用している都合上、変更できません。
0767デフォルトの名無しさん
2009/11/14(土) 19:52:03試してないけど、こうじゃない?
_ftprintf_s(fileStream, _T("FILE %s\r\n"), static_cast<LPCTSTR>(csvFile));
可変長引数に渡す場合にクラスからの暗黙の変換は効かない。
CString 使うなら TCHAR を扱うように統一しないと。
Cスタイルキャストは無しで。
0768デフォルトの名無しさん
2009/11/14(土) 19:52:150769デフォルトの名無しさん
2009/11/14(土) 19:54:38_T マクロ無しにしたら?
0770デフォルトの名無しさん
2009/11/14(土) 19:59:58大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、
この場合問題なのはfprintf_sの"%s"にLPTSTRを渡してることだと思う。
つまりtprintf系の関数を使うのが正しい
>>769
それは間違ってる。むしろ至る所に_Tマクロを使うべき
0771766
2009/11/14(土) 20:09:45ありがとうございます。
>>767-770
C言語と比べると全然違うんですね。
Cを少しかじったことがあるので、書けると思っていたら全然でした…。
0773デフォルトの名無しさん
2009/11/14(土) 20:19:0295/98対応する必要があるとかかわいそうな人なんてもう、そうそういない
だろうし、ワイド文字列きめうちのほうがトラブルがなくて楽だよ。
それにジェネリックテキスト使っていたって、本当にワイド文字列と
マルチバイト文字列の両方に対応できてるコード書けてるかってのもあるし。
両方で動くように意識して書いてるやつなんて少数派だし、_UNICODEありと
なしでコンパイルが通るかとか、テストを両方でやってるところとかまで
いくと壊滅状態だろうし、事実上ジェネリックテキストなんて機能してないよな。
0774デフォルトの名無しさん
2009/11/14(土) 20:21:28> 大昔はともかく、いまのCStringはLPCTSTRとして扱ってもかまわないようにできてるから、
へー。いまの可変長引数の ... 部分に渡したときも LPCTSTR への暗黙変換が入るのかー。
いったいどういう仕組みで?
クラスに operator LPCTSTR () を持ってるだけじゃ、そうはいかないよね?
0775デフォルトの名無しさん
2009/11/14(土) 20:25:03一般的な話ならそれでもいいんだけど、ここでは CString を使ってて、
その型は変えられないと質問者が言ってるんだから _T() が要るだろ。
0776デフォルトの名無しさん
2009/11/14(土) 20:25:58>>770じゃないけどCSimpleStringT<>のソースは大分前に見たよ
データメンバがポインタ1個でvtblもないから
メモリレイアウトがTCHAR*と同じになってるんだよ確か
0777768
2009/11/14(土) 20:29:40CStringへ代入はできるけど
0778766
2009/11/14(土) 20:31:31出力はできるようにはなったのですが、日本語が含んでいるとクエスチョンマークの
文字列が並んでしまいます。
これはやっぱり、上で説明されている変換がうまくいっていないからですか?
0779デフォルトの名無しさん
2009/11/14(土) 20:32:44setlocale(LC_CTYPE, "");
とかやろう!
0780デフォルトの名無しさん
2009/11/14(土) 20:32:49http://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
こいつのデマに騙されたんじゃね?
0781デフォルトの名無しさん
2009/11/14(土) 20:37:51#include <cstdio>
#include <atlstr.h>
int main()
{
CStringA s = "world";
std::printf("hello, %s\n", s);
}
うちではこのコードはVC7.1でもVC9でも動くよ
まあ推奨はしないってか誰もしてないと思うけど
0782デフォルトの名無しさん
2009/11/14(土) 20:41:17古いATLの利用を考えているならキャストするのが安全だろうけど、
最近のはreinterpret_cast相当の操作でも安全に使えるようにできているから必要はない。
というのはATLの解説書のどれかに書いてあったはず
0784781
2009/11/14(土) 20:52:17#include <cstdio>
#include <atlstr.h>
int main()
{
CStringA s = "world";
std::printf("hello, %s %d\n", s, 123);
}
これがちゃんと動きます。
0785774
2009/11/14(土) 21:08:10把握した。なるほど。
開発者はがんばって大丈夫なようにしたけど、外向けの仕様としてはキャストが必要と
書かれたままになってるってことだね。ちょっと不憫だな。まぁ古い実装を使ってる場合や
可変長引数の実装方法の違うコンパイラを使う場合にはやっぱり問題になるんで、
しょうがないところかとは思う。
>>780
デマじゃなかったみたいね。
0786デフォルトの名無しさん
2009/11/14(土) 21:12:38http://codepad.org/A8sFOqoG
こんな感じで仮想関数使いたい場合、とりあえず思った通りに動くんだけど、
*baseとした時点でBase型に補足されるということはないんですか。
0787デフォルトの名無しさん
2009/11/14(土) 21:14:290788デフォルトの名無しさん
2009/11/14(土) 21:17:350789デフォルトの名無しさん
2009/11/15(日) 14:40:570790デフォルトの名無しさん
2009/11/15(日) 14:48:000791デフォルトの名無しさん
2009/11/15(日) 14:56:550792デフォルトの名無しさん
2009/11/15(日) 15:11:29これは実際に速くなるのですが、500個になると困ります。
0793デフォルトの名無しさん
2009/11/15(日) 15:12:39アセンブラなどわかりません。
0794デフォルトの名無しさん
2009/11/15(日) 15:15:320795デフォルトの名無しさん
2009/11/15(日) 15:18:520796デフォルトの名無しさん
2009/11/15(日) 16:54:400797デフォルトの名無しさん
2009/11/15(日) 23:16:34もう少しマシにしようか
300個が0なら150個目を調べる
それも0なら75個目と225個目を調べる
それも0なら・・・・
非0である確率が高いならともかく、そうでないなら最初から順々に調べたほうがマシだな
0798デフォルトの名無しさん
2009/11/16(月) 00:13:52えっ
0799デフォルトの名無しさん
2009/11/16(月) 00:20:580800デフォルトの名無しさん
2009/11/16(月) 00:22:43学生はIT土方になるために必死に勉強しとけ
0801デフォルトの名無しさん
2009/11/16(月) 01:54:58なんで?
そもそも memcmp() 呼び出しが 単純なループ処理より速いってどんな環境?
(つーか、まさか毎回if判定してないよな?)
0802デフォルトの名無しさん
2009/11/16(月) 01:56:41いや普通、ループは毎回判定してるぞw
0803デフォルトの名無しさん
2009/11/16(月) 02:05:47・charではなく、もっと大きな(intとか)のサイズでアクセスし
・毎回判定するのではなく、数十個単位とかを|してから判定することにして
・さらに、場合によってはプリフェッチ的なアクセスの仕方も行う
というようなことをすれば、
・もしかしたら
・あなたの使っているCPUやOS、及びコンパイラと使用ライブラリ限定で
・データによっては
・気休め程度には
速くなる可能性はあるかもね。
0804デフォルトの名無しさん
2009/11/16(月) 11:02:47virtual ってvoidばっかりなのですが
0805デフォルトの名無しさん
2009/11/16(月) 13:34:53基本的にはできない。
例外として共変戻り値がある。
0806デフォルトの名無しさん
2009/11/16(月) 16:46:54グローバルな定数であれば別にガツガツ使用しても問題ないのでしょうか?
0807デフォルトの名無しさん
2009/11/16(月) 16:57:15変数がかぶることと思う。
ネームスペースやオブジェクト指向も
変数名、関数名がかぶらなくなることが大事思う。
0808デフォルトの名無しさん
2009/11/16(月) 16:59:04公開する部分はのぞく。
グローバル定数も変数も公開するで無ければなるべく範囲を縮める。
0809デフォルトの名無しさん
2009/11/16(月) 17:02:19グローバル使うのはあほですよ。
大して時間食わないし、変数生成がボトルネックなることはまれ。
時間食ってることが確認できてから変えれば良いんです。
なるべく生存範囲が短くなるようにするのが吉
0810デフォルトの名無しさん
2009/11/16(月) 17:02:270811デフォルトの名無しさん
2009/11/16(月) 17:07:16ありがとうごじあました
0812デフォルトの名無しさん
2009/11/16(月) 17:08:01モジュール間でのカプセル化という意味合いの方が大きい。
0813806
2009/11/16(月) 17:29:33ありがとうございます。
0814デフォルトの名無しさん
2009/11/16(月) 18:25:46とか、書き方を変えると、
error C2440: '<function-style-cast>' : 'overloaded-function' から 'float' に変換できません。
とか出ます、仮想関数をはじめていじくっているのでどうすれば良いかわかりません
仮想関数のオーバーライド中では引数のメンバの型を変えてはいけないのですか?
0815デフォルトの名無しさん
2009/11/16(月) 21:24:18スレ違い。↓こっち行け。
http://pc12.2ch.net/test/read.cgi/tech/1187922645/
0816デフォルトの名無しさん
2009/11/16(月) 21:59:01個人的には思う
つーか、初心者が一番やらかしやすいのは、関数スコープがふさわしい物をファイル
スコープに出してしまうことじゃないかと
0817デフォルトの名無しさん
2009/11/16(月) 22:23:03�@画像データをPROJECT内に保管しておいて必要な部分を切り取って表示する方法ってありますか?
�AWIN32とmfcとで方法が違うかもしれませんが、ゲームを作成するのに向いているのはどっちでしょうか?
※開発環境(といえるほどのレベルではないのですが・・・)VISUALSTUDIO2005でvista32bitです。
入門書とかも何冊か読んでみたのですが、自分が求めている情報がズバリ載っているわけではいないので、
質問させていただきました。詳しい方がいらしたらぜひアドバイス願います。
0818デフォルトの名無しさん
2009/11/16(月) 22:29:581、ビットマップの管理方法で違う。APIに任せるなら、loadImageしてBitBltなどのAPIを使う。
自前で管理するなら、配列いじるのと変わらない。が、約束事はある。
2、どっちでも作れるから、作りやすいほう選べ。CかC++か位の違いしかない。どっちにもお約束事はある。
0819デフォルトの名無しさん
2009/11/16(月) 23:09:48外部からファイル読み込むのもグローバル変数だから使用禁止
0820デフォルトの名無しさん
2009/11/16(月) 23:17:27#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
を入れてしまいたいのです。
それとも、上のものだけが書かれた二重インクルード対策付きヘッダも別に用意して、
各クラスのヘッダからちゃんとインクルードするべきですか?
0821デフォルトの名無しさん
2009/11/16(月) 23:19:43#ifndef HOGE_API
#ifdef HOGE_EXPORTS
#define HOGE_API __declspec(dllexport)
#else
#define HOGE_API __declspec(dllimport)
#endif
#endif
0822デフォルトの名無しさん
2009/11/16(月) 23:22:58同じ名前で内容の全く同じマクロなら何度定義してもいいことになってる。
(厳密にはもう少し複雑な規定があるけど)
0823デフォルトの名無しさん
2009/11/16(月) 23:46:26何度定義してもよいということが仕様として存在するのですね。
安心しました。ありがとうございます。
0824デフォルトの名無しさん
2009/11/16(月) 23:49:24E-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という画像ファイルを扱おうとしています。
0825デフォルトの名無しさん
2009/11/16(月) 23:54:460826デフォルトの名無しさん
2009/11/16(月) 23:55:490827デフォルトの名無しさん
2009/11/16(月) 23:59:30効果的な使い方がわからん
_CrtSetBreakAlloc(1162);で止めて下に出てるツリーを開いていくやり方以外やったことない
教えて
0828デフォルトの名無しさん
2009/11/17(火) 00:07:56_CrtSetBreakAlloc()って知らんからググってみたら、メモリリークの箇所を
調べるみたいなことが書いてあった。
勉強になるなぁ。
変数の中身をみるって、適当にブレイクポイントでとめて、ウオッチで見るとかじゃなくて?
0829デフォルトの名無しさん
2009/11/17(火) 00:10:220830デフォルトの名無しさん
2009/11/17(火) 00:13:03すげえな、サンクス
0831デフォルトの名無しさん
2009/11/17(火) 05:38:130832デフォルトの名無しさん
2009/11/17(火) 06:05:27プログラム暦2年だけど何やってたんだ俺wめっちゃ簡単に割り出せるやんw
0833デフォルトの名無しさん
2009/11/17(火) 06:32:320834デフォルトの名無しさん
2009/11/17(火) 06:36:33swapですれよ
0835833
2009/11/17(火) 06:47:540836デフォルトの名無しさん
2009/11/17(火) 07:26:26v.size() * sizeof(T)
でいいんでしょうか?
実装によっては何か詰め物でも入っているのではないかと不安なんですが。
0837デフォルトの名無しさん
2009/11/17(火) 07:40:570838デフォルトの名無しさん
2009/11/17(火) 07:54:16そのサイズを使った操作が何であるかによっては危険な予感がする。
0839デフォルトの名無しさん
2009/11/17(火) 08:22:29ありがとうございます。
>>838
内容をファイルに書き出したいんです。
0840デフォルトの名無しさん
2009/11/17(火) 15:26:130841デフォルトの名無しさん
2009/11/17(火) 17:07:07ostreamのシフト演算子を定義すればいいと思うよ。
v.size() * sizeof(T) だと、vtableがあったら色々まずい。
0842デフォルトの名無しさん
2009/11/17(火) 17:21:330843デフォルトの名無しさん
2009/11/17(火) 17:42:42これってさ、Tによっては<<定義しても動作しなくね?
0844デフォルトの名無しさん
2009/11/18(水) 00:58:340845デフォルトの名無しさん
2009/11/18(水) 01:16:44いやそういう下らん揚げ足取りはいいから
0846デフォルトの名無しさん
2009/11/18(水) 01:20:59動作しそうで動作しない T の例をひとつでも挙げてみてくれ。
そうじゃないと、当たり前のことを聞かれてるだけにしか見えん。
0847デフォルトの名無しさん
2009/11/18(水) 17:25:58ていう考えは古いですか。
0848デフォルトの名無しさん
2009/11/18(水) 19:48:32静的メンバはクラスが存在する前からあるはずなのに、なんでクラスの外で再宣言しなくてはならないんですか?
0849デフォルトの名無しさん
2009/11/18(水) 20:19:01その場合、各翻訳単位の間で重複してクラスの静的変数を定義しない為。
ヘッダファイルにグローバル変数を書いて共有するときも、externで宣言しといてどこかで一度だけ実体の宣言をするよね。
0850デフォルトの名無しさん
2009/11/18(水) 21:00:32ngの部分でコンパイルエラーが出てしまいます
VC++2008EEのエラーメッセージによると引数があいまいだから、ということなんですが
どうすれば曖昧さをなくせるのかちょっとわかりません
うまいことstd::endlを渡す方法はありませんか?
0851デフォルトの名無しさん
2009/11/18(水) 21:40:11endlの型を調べよう
0852デフォルトの名無しさん
2009/11/18(水) 21:48:59というように親クラスが子クラスを保持しているとします。
子クラスはプログラム動作中、たくさんnewでメモリを確保します。
プログラム終了時、CChild内でdeleteせず、CParentでだけdeleteすれば、
CChildがそれまで確保してきた領域も伴ってdeleteされるのでしょうか?
というのも、ある書籍についてたサンプルコードを見ると、newしまくりなのに、
それらがdeleteされる記述がぜんぜんないんです・・・
最も最上位のクラス(他の下位クラスを保持している)を最後にdeleteしてるところ
くらいしか考えられない・・・
よろしくお願いします。 m(_ _)m
0853デフォルトの名無しさん
2009/11/18(水) 21:51:28とりあえずその書籍の名前を
0854デフォルトの名無しさん
2009/11/18(水) 21:56:050855852
2009/11/18(水) 22:01:00「3D格闘ゲームプログラミング」という本です。
不思議なことに、サンプルのVC++プログクトでビルド実行してプログラムを終了させたとき、
リークがある場合にVC++のログ出力に出てくるメモリリークバイト数が出て来ず、
正常終了できたかに見えます・・・
>>854
スマートポインタを使っているようにも見えません・・・
一例として
ヘッダファイル内
char* xxx
C++ファイル内
xxx = new char[ strlen( yyy ) + 1 ];
で、xxxはどこでもdeleteされていません。
VC++上でソリューション内を検索もしましたが見つかりませんでした・・・
0856デフォルトの名無しさん
2009/11/18(水) 22:09:260857852
2009/11/18(水) 22:21:50追跡してみましたが、見当たらず・・・
そういえば、newされたやつの多くはSTLのvectorにpush_back()されています。
ヘッダーファイル内
#include <vector>
using namespace std;
vector<CChild*> Child;
C++ファイル内
Child.push_back( new CChild() );
何か関係があるのでしょうか?
このvectorはポインタのコンテナになっていて、やはりどこかでそれらのポインタの先にある
実体領域を解放してやる必要がありますよね?
0858デフォルトの名無しさん
2009/11/18(水) 22:24:300859デフォルトの名無しさん
2009/11/18(水) 22:26:10とりあえずステップ実行して、本当に開放されないのか一行ずつ確認してください。
0860デフォルトの名無しさん
2009/11/18(水) 23:01:08クラスの外に書くのは、宣言ではなく定義。
0861852
2009/11/18(水) 23:01:49ttp://cgi32.plala.or.jp/higpen/book/shtPro/qa.shtml#program10
違う書籍の違うプログラム部のところの話ですが、
たぶん、これと同じことだと思います。
なんと、解放はOSに任せられるとのこと。
あまり行儀は良くないですよね^^;
よほどプログラムの動きやOSのメモリ管理に精通してないととてもできないw
でも勉強になりました。
みなさん、ありがとうございました。 m(_ _)m
0862デフォルトの名無しさん
2009/11/18(水) 23:19:45プログラミングを勉強する本にそういう書き方をするのはいかがなものだろうか…
0863デフォルトの名無しさん
2009/11/18(水) 23:26:330864デフォルトの名無しさん
2009/11/19(木) 00:25:35そんなこと言ってると、ごちゃごちゃ言ってないで std::vector 使えカス、ってバカにされちゃうよ。
0865デフォルトの名無しさん
2009/11/19(木) 00:29:15日付見たらごく最近なのな。著者が不勉強なんだろうと思う。
0866852
2009/11/19(木) 00:57:36多態を使わなければ、クラスのインスタンスのvectorを使ってもOKみたいですね。
vector<CXXX> xxx;
CXXX x;
xxx.push_back( x ); // xxxコンテナへのコピーになる
これだったら、領域確保はvectorがしてくれるので楽ちんですね。
これでいきます。
ありがとうございました。
0867デフォルトの名無しさん
2009/11/19(木) 01:51:300868デフォルトの名無しさん
2009/11/19(木) 01:53:450869デフォルトの名無しさん
2009/11/19(木) 02:41:35IDE のインテリジェンス機能が動かなくてもいいならそれでもいいよ
0870デフォルトの名無しさん
2009/11/19(木) 02:57:340871デフォルトの名無しさん
2009/11/19(木) 03:00:380872デフォルトの名無しさん
2009/11/19(木) 03:30:02それだったか、感謝。
0873デフォルトの名無しさん
2009/11/19(木) 08:16:43それはメモリリークそのものだろw
そんなレベルで本書くなよ…
0874デフォルトの名無しさん
2009/11/19(木) 08:47:42説明は下手糞だけど、最初に確保したメモリをプールしておいて使いまわす手法じゃないの?
だとしたら、そういうのはリークとは呼ばないよ。
MoreEffectiveC++にもちゃんと書いてあるし。
違ったらごめんな。
0875デフォルトの名無しさん
2009/11/19(木) 08:48:47○使いまわして、最後まで(プログラムのコード内では)解放しない手法
0876デフォルトの名無しさん
2009/11/19(木) 08:57:25まぁメモリ以外のリソースだと解放してくれなかったりすることもあるけど。
0877デフォルトの名無しさん
2009/11/19(木) 09:29:20ちゃんと管理できているものは「リーク」とは呼ばないって話だよ。
0878デフォルトの名無しさん
2009/11/19(木) 09:34:03初期化の順番はメンバの宣言順と決まっている。
コンストラクタの記述方法で明示などできない。
無知なオマエ悪い。
0879デフォルトの名無しさん
2009/11/19(木) 09:38:59よく読んでみなよ。 >>861 のやつは使いまわしてすらいない。
0880デフォルトの名無しさん
2009/11/19(木) 09:39:33リークと呼ぶだろw
0881デフォルトの名無しさん
2009/11/19(木) 10:06:29だから、
>タスク用メモリはプログラムの終了時まで解放しない
が、「deleteを呼ばない」という意味ではなく
「プログラム終了まで使用している領域である」という意味ではないか、と言っている。
使用している(管理している)領域なんだから、deleteするコードが無くても問題ない。
もちろん、その「タスク」が、プログラムの中で際限なく増えていく
(あるいそのタスクを指す領域を見失っている)ようなら問題だが
俺はコードを読んでないので、どういう構造なのかは明言できない。
だから、「よく読んでないが」「説明は下手糞」と書いた。
そして、(明示的にdeleteを呼んで無くても)管理下にあるものはリークとは呼ばない。これは確実。
0882デフォルトの名無しさん
2009/11/19(木) 10:07:54管理下にあるかどうかが本質。
0883デフォルトの名無しさん
2009/11/19(木) 10:23:05よく読んでみなよ。 >>861 のやつは管理下にすらない。
「タスク」じゃなくて char 配列のほうな。ローカルな生ポインタ変数に入れて、
そのままスコープアウトしちゃってるみたい。
当たり前の主張を長文で繰り返す前に、「よく読んでない」と自分でわかってる
なら元記事をよく読めと。
0884デフォルトの名無しさん
2009/11/19(木) 10:36:43このサンプルでは以下の理由から、new char[]で確保した領域を明示的に解放する処理を省略しています。同様の理由で、他にもメモリの破棄を省略している部分があります。
* サンプルプログラムをなるべくシンプルにしたい
* タスク用メモリはプログラムの終了時まで解放しない
* プログラム終了時にはOSがプログラムに関連するメモリを解放してくれる
* 一般にdeleteで解放したメモリはOSには返却されず、プログラムの内部に保持されたままとなるため、タスクリストの場合は実行中に解放する意味が薄い
上記の理由から、メモリを解放しなくても動作に問題はなく、他のプログラムへの影響もありません。推奨される方法としては、例えばタスクリストのデストラクタ
~CTaskList() を記述して、その中で上記のバッファを、
delete [] buf; のように解放します。この場合、bufをメンバ変数にしておく必要もあります。
0885デフォルトの名無しさん
2009/11/19(木) 10:49:18せめて引用の形にとどめておけ。
0886デフォルトの名無しさん
2009/11/19(木) 12:04:53確保したメモリちゃんと解放すればいいんだよ。
メモリを解放するデメリットなんてないだろ?
もし、終了時に遅くなるとかいう話なら
「終了処理を速くするテクニック」として使えばいいだけの話。
それが必要になるときがくれば使え
0887デフォルトの名無しさん
2009/11/19(木) 12:08:20再利用されるとか考えないのかね?
0888デフォルトの名無しさん
2009/11/19(木) 12:13:50new と delete がペアになっていない構造だから
別コードで本当にリークさせてる部分の追跡をするのに面倒じゃね?
0889デフォルトの名無しさん
2009/11/19(木) 13:33:470890デフォルトの名無しさん
2009/11/19(木) 13:34:170891デフォルトの名無しさん
2009/11/19(木) 14:50:59deleteなんて一行増えるだけじゃん。
いちいち言い訳を書くよりも
deleteを書けばいいじゃんか。
0892デフォルトの名無しさん
2009/11/19(木) 14:52:560893デフォルトの名無しさん
2009/11/19(木) 15:02:56マジレスはしてあげないよw
0894デフォルトの名無しさん
2009/11/19(木) 15:03:31newしたときに再利用されるだろうな
0895デフォルトの名無しさん
2009/11/19(木) 15:34:47リーク検出とか使えなくなりそうだしなぁ
0896デフォルトの名無しさん
2009/11/19(木) 16:12:06無知は黙ってろハゲ
0897852
2009/11/19(木) 19:05:22作者の方は東大を出ておられますが、地頭が良いとこういう考え方になるのでしょうか・・・
ともあれ、今はnew、deleteはセットで書くよう心がけたいですね。
0898デフォルトの名無しさん
2009/11/19(木) 19:44:29まぁ論文ならそれでいいんだろうが、一般向け、しかも初心者が食いつきやすいゲームプログラミングの書籍で
それをやると何も考えずに模倣する馬鹿が出てきてしまうから、やめた方がいいと思うがな。
0899デフォルトの名無しさん
2009/11/19(木) 19:46:38実測しむ
0900デフォルトの名無しさん
2009/11/19(木) 19:49:53プログラムが終了すればOSが回収するが、
動いている間はそのまま。
0901デフォルトの名無しさん
2009/11/19(木) 21:10:32しかも学歴が高いせいで自信だけはあるから逆にめんどい
0902デフォルトの名無しさん
2009/11/19(木) 21:34:57その亜流なんだろう
0903デフォルトの名無しさん
2009/11/19(木) 22:48:47もちろんnew/deleteをセットで書いてもいいが
それよりスマートポインタを使うんだ
0904852
2009/11/19(木) 23:01:20COMでCComPtrを使ったことがあって、めちゃくちゃ便利でした。
自前のを作るとなると・・・うまく組めるかちょっと心配です(汗)
でも便利なのはたしかなので、勉強してみます。
ありがとうございます。
0905デフォルトの名無しさん
2009/11/19(木) 23:04:080906デフォルトの名無しさん
2009/11/19(木) 23:36:09char配列などを頻繁にnew・deleatする際、どっかのサイトで
win環境では固定サイズでnewしたほうが断片化しにくいと
書いてあったような気がするのですか
本当でしょうか?
あまりnewをいじりたくないので気になります
0907852
2009/11/19(木) 23:45:36おおお!
こんな便利なものがあったのですか!
VC++2008ならstd::で使えるそうですが、自分は2005ですね・・・
しかし、boostを導入すれば使えますね。
CComPtrと同じように使えるのであれば、慣れていますし、導入もし易そうです。
教えてくださって、ありがとうございました!
0908デフォルトの名無しさん
2009/11/19(木) 23:54:42test[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 の順番になると保障されていますか?
0909デフォルトの名無しさん
2009/11/19(木) 23:56:21でしたすみません
0910デフォルトの名無しさん
2009/11/20(金) 00:10:270911デフォルトの名無しさん
2009/11/20(金) 01:05:18new の回数を減らせば断片が減る(断片化しにくい)のはあたりまえ。
それ以前に、ほんとうに断片化による悪影響で困ってるのか?
Windows 上では、特にギガバイト単位のメモリ空間(アドレス空間)があたりまえな
最近の一般的な環境ではかなり稀なケースになると思うんだが。
0912デフォルトの名無しさん
2009/11/20(金) 02:12:17実際に動作させるコードでdeleteするしないの問題と、解説書でdeleteを省略するしないの問題を
区別できていないお前は多分低学歴なんだろうな
0913デフォルトの名無しさん
2009/11/20(金) 02:13:44削っていい部分とそうでない部分があるが、こういうのを削っていいと思うようなら
糞コードと言われても仕方ない
0914デフォルトの名無しさん
2009/11/20(金) 02:15:130915デフォルトの名無しさん
2009/11/20(金) 02:17:500916デフォルトの名無しさん
2009/11/20(金) 02:28:12省略したほうがシンプルでいいと思ったけど結局は言い訳がましい Q&A を書くハメに
なったってことで、解説書のための判断としても失敗だろ。
紙面の問題を考えても、 std::vector 使っとけば #include が1行増えるかもしれないって
程度だし。
0917デフォルトの名無しさん
2009/11/20(金) 02:38:29こともあるけどな。>>884は手を染める理由としては全く不足だと思うが。
とりあえず買っちゃいけない類の本ではあるな。良い初心者は混乱し、悪い初心者は
汚れる。中級者以上なら他に投資すべき本があるだろう。
0918デフォルトの名無しさん
2009/11/20(金) 03:10:28言語やOSの仕様でプログラム終了時に確実に回収することがわかっていて
かつ、リークしないこともわかっているなら、別に開放しないまま終わってもいいじゃないか。^^
たとえば、
int main() {
int* i = new int;
}
上のプログラムはメモリリークしていない。
なぜなら、ポインタが消失して削除不能になるのはプログラムが終了する瞬間であり
その直後にはすべてのリソースが回収されることが仕様で決まっているからだ^−^
美学とかいうなら別だが。
0919デフォルトの名無しさん
2009/11/20(金) 03:28:080920デフォルトの名無しさん
2009/11/20(金) 03:37:02「3D格闘ゲーム」ってことだから、おそらくキャラクタ2体分のオブジェクトを作って
プログラム終了まで開放しない、みたいなコードだと思うんだけど、
読者がそこから拡張していこうとした途端にメモリリークを起こす気がする。
0921デフォルトの名無しさん
2009/11/20(金) 06:08:350922852
2009/11/20(金) 08:12:39思ってしまうようなところもあるのですが、
アニメーション付Xファイルの読み込み、およびそれをゲーム中でアニメーションさせるところの
解説はものすごく参考になっています。
今までいくつかのWebサイトでそれを解説しているところも見てきましたが、
この本の内容が一番分かり易かったです。
アニメーションのための本質的なところ(動作、仕様レベル)だけ抽出して、
実装に向けたクラス設計や仕様は自分で改めて考えてからコーディングしていったら良いと思いました。
0923デフォルトの名無しさん
2009/11/20(金) 09:00:430924デフォルトの名無しさん
2009/11/20(金) 09:06:430925デフォルトの名無しさん
2009/11/20(金) 09:12:37雰囲気に見えるが…
まぁ、買っちまったら何とか活用したいんだろうけどなぁ…
つーかサンプルプログラムの作り方もひどそうだ
ゲームがコマンドライン引数でviewerに変わるらしいが、やってみたくてやっちゃった
のかな、使い勝手とか全然考えずにw
もちろん「コマンドラインの処理サンプルを入れたかったので」とか言い訳はいくら
でも思いつくが
0926デフォルトの名無しさん
2009/11/20(金) 10:25:390927デフォルトの名無しさん
2009/11/20(金) 11:15:06そういう特殊な事例でしか当てはまらないものは
特殊な例としてあげればいいんだよ。
int foo() {
int* i = new int;
}
関数名を変えただけで、この処理はリークしているかもしれない。
int main() {
MyClass* i = new MyClass;
}
クラス名を変えただけだが、delete時にファイル削除とかしているかもしれない。
な? コードは修正されるもの。
そういうときに自分で罠を仕掛けてどうする。
0928デフォルトの名無しさん
2009/11/20(金) 11:33:29できるでしょうね
0929デフォルトの名無しさん
2009/11/20(金) 11:44:16メモリリークは致命的。
512K確保する関数を200回呼び出せば、合計で1ギガ消費する。
deleteしないでこれを放置するやつは超初心者
0930デフォルトの名無しさん
2009/11/20(金) 11:45:570931デフォルトの名無しさん
2009/11/20(金) 13:23:01それはメモリリークだよ。
もう使わないからdeleteしていいのにdeleteしないままプロセス終了を迎えたら、それはメモリリーク。
「プロセス終了時に把握できているメモリリークがあっても特に問題無い」には反論しないけど、
「リークじゃない」はおかしい。
そのプログラムがメモリリークしてないなら、メモリリークしてるプログラムなんてこの世に無いよ。
0932デフォルトの名無しさん
2009/11/20(金) 13:44:20たとえば、4バイトのメモリリークで128M=2^24バイトたまるには、
400万回やらないといけない。
10秒に一回起こったとしても、400万回するには一年半ほどかかる。、
0933デフォルトの名無しさん
2009/11/20(金) 14:14:47俺は基本的にnewしないでスタックに確保するから、そういう問題はほとんどないな。
はやくスマートポインタが使いたいぜ。
0934デフォルトの名無しさん
2009/11/20(金) 14:18:40わずかに残ったとしても致命的にはなりにくい。
なったら変更すればいいし。
0935デフォルトの名無しさん
2009/11/20(金) 14:25:540936デフォルトの名無しさん
2009/11/20(金) 15:10:46別のコンパイラで確保したメモリを、VCでdeleteは出来ませんか?
0937デフォルトの名無しさん
2009/11/20(金) 15:27:03別のコンパイラどころか、同じコンパイラでも異なるDLLでnewしたオブジェクトをdeleteすることは
原則としてできません。(MFCの拡張DLLは別)
0938デフォルトの名無しさん
2009/11/20(金) 15:34:39あえてやるひとはいないだろうけど、
自分以外誰にも使えないnewの実装だってありえる。
0939デフォルトの名無しさん
2009/11/20(金) 15:37:30そうだとすると、DLLがメモリ確保してリターンしたら解放不可能になるんですか。
0940デフォルトの名無しさん
2009/11/20(金) 15:40:48メモリを確保する関数 と 確保したメモリを開放する関数 を用意しときゃよい
fopen() と fclose() の関係
0941デフォルトの名無しさん
2009/11/20(金) 15:49:42その後始末の delete は呼び出し側がやってね という造りはマズイ ってこと
DLL は 自前newしたものを戻すつもりなら それを受けて delete する部分も提供すべき
# で、後者を記述するのに安全を見て >>926 で保険かけたいんだけど… どうすれば良い?
# という流れになるのかな?
0942デフォルトの名無しさん
2009/11/20(金) 15:50:14CloseHandleよびだしたりするね。
0943デフォルトの名無しさん
2009/11/20(金) 15:55:17typedef 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);
こうした場合メモリはどっちに確保されるの?
0944デフォルトの名無しさん
2009/11/20(金) 16:03:32EXEから呼ばれるDLLがリンクしているalloc関数を実装しているライブラリ・・・が
OSにメモリ割り当てを要求して、OSが返してくれる適当なメモリ領域・・・・の
一部分をallocが適当に調節して返すんだから、
どっかOSが適当に決めた場所なんじゃないの?
0945デフォルトの名無しさん
2009/11/20(金) 16:37:27//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!
ンンンンンンンンンンンンンンンン-
0946デフォルトの名無しさん
2009/11/20(金) 17:01:03// 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(); }
0947デフォルトの名無しさん
2009/11/20(金) 17:48:12WINBASEAPI VOID WINAPI OutputDebugStringA(__in LPCSTR lpOutputString);
と書いてあったんですが__inって何ですか?
0948デフォルトの名無しさん
2009/11/20(金) 17:53:49まずは自分で調べてほしい。
0949デフォルトの名無しさん
2009/11/20(金) 18:38:48扱うのが良いと思いますが、
一方ではペアとして、一方ではchar*と自動的にキャストさせる方法はありますか。
0950デフォルトの名無しさん
2009/11/20(金) 18:43:12縛りの弱いconstのようなものでしょうか?
SAL解釈と言うんですね
ググったんですがなかなかそこまでたどり着けませんでした
0951949
2009/11/20(金) 18:43:43自作ではない関数に対しても、自動でキャストして通るように出来れば便利なんですが。
0952デフォルトの名無しさん
2009/11/20(金) 18:46:220953950
2009/11/20(金) 18:46:57SAL注釈ですね、間違えました
0954デフォルトの名無しさん
2009/11/20(金) 18:47:310955デフォルトの名無しさん
2009/11/20(金) 19:00:34ごめん、なんでハンドルが出て来るのか分からない。
0956デフォルトの名無しさん
2009/11/20(金) 19:05:55HANDLE hHeap = HeapCreate(NULL, 0, 0); と char *p; のペアを
char*型のように扱いたいって事なんです。
無理でしょうか?
0957デフォルトの名無しさん
2009/11/20(金) 19:33:10「一方ではこれができないから注意!」とかあったら教えてください m(_ _)m
0958デフォルトの名無しさん
2009/11/20(金) 19:45:500959デフォルトの名無しさん
2009/11/20(金) 19:52:270961デフォルトの名無しさん
2009/11/20(金) 20:43:500962デフォルトの名無しさん
2009/11/20(金) 21:00:300963デフォルトの名無しさん
2009/11/20(金) 21:00:34100Mほどのデータをもつクラスでも値渡しになりますか。
(値渡しのコストを下げるために) もし100Mがポインタに入っていて、
auto変数でリターンするとデストラクタが働いてメモリは解放されてしまいますが
newで確保した物をリターンすると、それは解放できなくなりますか。
0964デフォルトの名無しさん
2009/11/20(金) 21:03:27変数を用意する事無しに、リターンがクラスになっていると便利なことがあるんです。
0965デフォルトの名無しさん
2009/11/20(金) 21:27:13オブジェクトを返すとして、たとえば、
LARGE func() { return * new LARGE; }
というのは結局コピーしてるし、メモリが回収不能になるので、絶対にだめ。
LARGE & func( LARGE & inout ) {
//LARGEを使った処理。
return inout;
}
として、外で大きなデータを用意してやるか、
funcで全く新しいオブジェクトを作成したいと言うなら、newしてポインタを返せばよい。
0966デフォルトの名無しさん
2009/11/20(金) 21:38:14Qtでこんな関数をオーバーロードしろって言われてるんだけど、
何を返せばいいの?
QSize sizeHint(引数略)
{
return ?
}
0967デフォルトの名無しさん
2009/11/20(金) 22:05:090968デフォルトの名無しさん
2009/11/20(金) 22:16:320969デフォルトの名無しさん
2009/11/20(金) 22:18:16あとこんなのもあるんですが・・・
0970デフォルトの名無しさん
2009/11/20(金) 22:20:500971デフォルトの名無しさん
2009/11/20(金) 22:21:120972デフォルトの名無しさん
2009/11/20(金) 22:23:15ってかいてるじゃないですか
0973デフォルトの名無しさん
2009/11/20(金) 22:23:59値で返しても何も問題ないじゃん。
0974デフォルトの名無しさん
2009/11/20(金) 22:40:44QSize sizeHint(引数略)
をオーバーロードするのに、
戻り値を参照やポインタにはできんだろ。
オーバーロードのルールを思い出すのだ。
0975デフォルトの名無しさん
2009/11/20(金) 22:42:160976デフォルトの名無しさん
2009/11/20(金) 22:47:28まあわからないようなレベルでできることなんて高が知れてるから分かるまで値返しでいいんじゃないかな
0977デフォルトの名無しさん
2009/11/21(土) 05:12:37#ifdefの後何を書けばよいのでしょうか?
0978デフォルトの名無しさん
2009/11/21(土) 05:16:390979デフォルトの名無しさん
2009/11/21(土) 05:35:04Apparently 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 ...
0980デフォルトの名無しさん
2009/11/21(土) 05:37:040981デフォルトの名無しさん
2009/11/21(土) 09:58:59こことか見てた
Programing Place
ttp://www.geocities.jp/ky_webid/index_old.html
0982デフォルトの名無しさん
2009/11/21(土) 12:57:090983デフォルトの名無しさん
2009/11/21(土) 13:17:19どこが翻訳なんですか?
0984デフォルトの名無しさん
2009/11/21(土) 16:38:200985デフォルトの名無しさん
2009/11/21(土) 16:41:43諦めました
http://www.jah.ne.jp/~naoyuki/Writings/ExtIos.html
0986デフォルトの名無しさん
2009/11/21(土) 17:00:01君がやりたいのは標準ストリームクラスで自作クラスを出力することでしょ?
まったくの別件だと思うよ。
君が勉強すべきなのは、演算子オーバーロード。
0987デフォルトの名無しさん
2009/11/21(土) 17:06:210988デフォルトの名無しさん
2009/11/21(土) 17:27:13std::ostream& operator<<(std::ostream& os, const ustring& x) {
return (os<<*****): }
0989デフォルトの名無しさん
2009/11/21(土) 18:15:23多くのプログラミング書籍が洋書からの翻訳であることを揶揄したジョークだろう
よく書かれるコピペみたいなものだ
0990デフォルトの名無しさん
2009/11/21(土) 18:22:42C/C++言語の仕様で\0まで出力だと思うので、任意の場所に\0を突っ込んでやればいいと思うよ。
バッファのオーバーランやアンダーランに気をつけて。
0991デフォルトの名無しさん
2009/11/21(土) 18:30:02STLは使えません。
あと、別の質問があるのですが。
クラスのメンバ関数で、
char* & operator [] ( int n ) { return &(ch[n]); } だとエラーになります。
char* & operator [] ( int n ) { static char*p=&(ch[n]); return p; } だと通るのですが
同時にアクセス来た場合に困ります。
衝突しない参照渡しはどうやればいいですか。STL stringみてもよくわかりません。
0992デフォルトの名無しさん
2009/11/21(土) 18:39:11変数でもないものの参照を返したいとか訳分からん
値を返すんだと不都合なの?
0993デフォルトの名無しさん
2009/11/21(土) 18:39:28やりたい事は本当に operator[] で char* & を返す事なのか?
ch って char* なんだよな?
string と名のつく型で operator[] だったら普通 char& が返ると思うんだが。
0994デフォルトの名無しさん
2009/11/21(土) 18:43:27memcpy(buf, &str[0], size);
が実行できないんです。
error メモリ上に配置されなければならない
がでます。
static char*の参照返しだと出ません。
0995デフォルトの名無しさん
2009/11/21(土) 18:44:350996デフォルトの名無しさん
2009/11/21(土) 19:05:39char* , intが与えられたときに標準出力( << )に\0を含む文字列を出力したいです。
0997デフォルトの名無しさん
2009/11/21(土) 19:31:43その前に、どういうインタフェースにしたいのか考えれ。
operator<< をオーバーロードすると
cout << yourclass << endl;
のような書き方ができるわけだが、
char*とintの二つのパラメータを与えるなら
そういう書き方はできなくなる。
それとも const char * operator()( int ) みたいなメンバを持たせて
cout << yourclass( 文字数 ) << endl;
とかけるようにでもするかい^^
0998デフォルトの名無しさん
2009/11/21(土) 19:37:28cout<<に渡せるじゃないですか。
この実装はどうやってるのかわかりたいです。
0999デフォルトの名無しさん
2009/11/21(土) 19:45:501000デフォルトの名無しさん
2009/11/21(土) 20:03:01コンストラクタの話とoperator<<の話がごっちゃになってるじゃないか^^
10011001
Over 1000Threadもう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。