うむごくろう
janeの隠し機能を発見したぞ! 1.まず半角入力に切り替える 2.Wキーを押しっぱなしにする 3.Wキを押しっぱなしにしながらsageのチェックするところをおもむろにクリック
v(^・^)v ← v(^・^)v
テンプレ終了。あとはお好きにどうぞ。
10 :
デフォルトの名無しさん :2010/05/09(日) 21:33:52
本が洋書ばっかだな amazonのリンクも英語版だし
翻訳されたものはちゃんとリンク貼ってるだろ。
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
訳書も似たようなもんじゃん・・・
>>14 それはあたりまえなわけだが、何が不満なの?原著が日本語な本が欲しいの?
少しくらいあってもいいんじゃない、と そんなに洋書訳書ばっかなのか
>>16 たぶんほんとにそうなんだと思う。少なくとも覚えが無い。それでも欲しいなら探してみれば?
ideoneっての、見るたびに登場人物の死にまくるアニメが思い浮かぶんだ
イデオンのことかあああ
トラウマものの名作だったな
25 :
デフォルトの名無しさん :2010/05/10(月) 00:19:02
柳田大喜び
これが出来たら、人に「私はC++できます」といえる判断基準みたいなものってありますか?
ありません。
みんなC++で何を作ってるの?
C++のコンパイラを作っています
同人ゲーム
Cのコンパイラを作ってます
>>26 これだけ理解してれば、組んで仕事しても安心だと思うよ。
const
参照とポインタの違い
RAII
例外安全
フェイルセーフ
>>32 いつも思うのだが、
> 参照とポインタの違い
これを理解できないってのが全く理解できないんだが。
ポインタを理解できないってのならその気持ちは分からんでもないが、
> 参照とポインタの違い
これがわからないとコンパイルが全く通らないコードになると思うんだけど。。。
違いがありすぎると思うが
うん。そりゃそうなんだけど、いざ「じゃあ挙げて」って言われると詰まるよね・・・って話。 人に説明できる基準=理解している だと思うんだ
同じと思っている人が多くて頭が痛い。
何が詰まるのかよく分からないが ポインタ 変数名の前に*を付けて宣言する 再代入できる ヌルポインタが存在する *をつけることで脱参照する &をつけることで得られる 右辺値に&をつけてもポインタは得られない(文法エラー) 参照へのdynamic_castでキャストが無効な場合はNULLが返される 参照 変数名の前に&を付けて宣言する 初期化しかできない ヌル参照は存在しない *をつけない状態で既に脱参照される &をつけない状態で直接初期化する const参照なら右辺値で初期化できる(テンポラリオブジェクトの寿命が延びる) 参照へのdynamic_castでキャストが無効な場合は例外が投げられる
ちんぽとまんこ位の違いがあんだろ
1つ誤植あるけど分かるだろうからいいや
ここ、テストに出るから。
参照は、戻りやメンバ変数にしない限り、寿命が参照元>参照なのが文法上保証できるのがいいね。
スレッド使うとそうでもないかと
>>43 これでいいか?
参照は、戻りやメンバ変数やスレッド間で使用しない限り、寿命が参照元>参照なのが文法上保証できるのがいいね。
すみません。こういうループを一重にする方法ありますか? for(a) for(b) for(c) for(d) for(e)
参照戻しがいまいちわからん
>>46 > 参照戻しがいまいちわからん
そんな用語俺もしらんわ。
参照戻しとわなんですか??????? template<class T> T &foo(bool x, T &a, T &b){ return x ? a : b; }
>>45 for(i) で i から a, b, c, d, e を算出
でも可能なら a, b, c, d, e でループした方がいい
あー戻り値が参照型のやつ
参照を返すだけだろ ポインタ返すのと大差ない
>>48 それは参照の戻りの寿命のほうが長くなるから不適切だね。
こんな感じ?メンバーのほうが寿命が長いからこんなことができる。
class hoge
{
int fuga;
int& get()
{
return fuga;
}
const int& get()const
{
return fuga;
}
};
vectorのoperator[]などが参照で戻してるね。でもベクターのサイズを変えると戻りの参照が無効になる危険がある。
>>52 const参照じゃないから問題はない気がする
まあ使い方によるが
>>51 そのまま代入できたりするから便利なんだよ。
>>51 ポインタで返すと戻り値のポインタをコピーされて遥か彼方で参照元がなくなった後にそのポインタを使われたりしてはまる。
参照だとスコープ外まで持ち出すことができないからそういうことを防止できる。
「参照戻し」がなんであるか意味不明な流れにいきなりそれを問う文章と同時に特に問題のないコード書き込むなんて皮肉以外の何物でもないだろ放っておけ。
>>55 int& func(){ int &x = hoge.get(); return x; }
ポインタなんてC99みたいな修飾子がない時点で最適化を抑制するから参照に置き換えられるなら置き換えろよ。
>>58 参照にすべきところをポインタにしたせいで生成されるコードが劣化するケースって、
たとえばどんなの?
参照にしたからって restrict みたいな制約(最適化の根拠)は生まれないよ。
参照のもとのオブジェクトがポインタを介して得られたものであると確かにrestrictの様なメリットは生まれないが、 参照が静的に行われる「置き換え」で解決される事を知っておくべき。 元のオブジェクトがポインタでない場合はその事をコンパイラは簡単に検知できるが、 スコープを横断してオブジェクトを共有する時にポインタを使っていては関数がインライン展開でもされない限りコンパイラは最適化を施す事ができない。
>>62 > 参照が静的に行われる「置き換え」で解決される
んなこたーない。
int& f();
void g()
{
int& x = foo(); // 静的に置き換えられるわけがない。
...
}
何言ってるのかよくわからんから
>>59 に答えるコードを出してくれないか?
64 :
62 :2010/05/11(火) 01:40:54
ごめん x = foo() じゃなくて x = f() ね。
>>63 それは前方宣言してるからだろう。少し言葉足らずだったから補足するが、置き換えで解決もできるということだ。
その部分に関してわざと曖昧に判別できる余地が残されているから最適化もたやすいと言っているんだよ。
gのxをfooの戻り値で初期化する場合、もしfooのの中身がその時点で分かっているとしたら、fのinline展開に関わらず
xが指し示すオブジェクトを特定できる時がある。
ポインタの場合は同等の最適化が乱雑になる。一旦動的に処理されるメモリアドレスの値がどのように扱われるかコンパイラが予測しなければならないから。
ポインタ型の中身は組み込み型の値であるからその予測はコンパイラの実行時予測のやりかたとして程度問題に扱われるが
参照はコンパイル時にある程度指し示す先が何かを判断しやすい。
>>65 コードは出してくれないの?
参照のときはその初期化元を辿ってがんばるのにポインタのときはあきらめるとか、
そんな中途半端な解析するコンパイラほんとに見たことあるの?
>>65 たいていの C++ コンパイラは C コンパイラとして成功したうえで作成されてるから、
ポインタにした途端に最適化が弱るなんてのは考えにくいと思うよ。
>>66 コードならfがint&じゃなくてint*返すやつでも想定してればいいよ。
中途半端な解析というか、実行時の動作までコンパイラが予測するのはかなりコストが掛かる。
コンパイラ作った事あるなら分かると思うけど、目の前の最適化を目的にしたコード生成は二の次でコンパイラは型レベルの検査や
解析木の生成に忙しく、込み入った最適化は後回しにされる。
しかし参照は「実行時の参照」ではなく「静的に解決できる参照」に視点を置いているので実行時の動作予測フェイズではなく
式解析における意味の判断の時点で「安全な置き換え」が可能なときがある。
ここでいう「安全な置き換え」とは実行時の予測で必要な「考えうるケース全てを検証する」方法(副作用のトレースなど)を排除しているのでスマートに処理ができ、
コンパイル時間への貢献も大きい。
ポインタしかなかった時代では単純に置き換えが可能なinline関数の展開でさえ、その間接参照された変数が
「他の変数の副作用をトレースしなくても最適化可能か?」という問題を解決できず、最適化が阻害されていた。
>>68 いや、 63 のコードじゃどんな最適化の有効無効が異なるのかわからないでしょ。
実行時の動作なんて予測しなくていいんだよ。ローカルなポインタ変数に初期化後の
書き込みがあるかないかなんて、基本的な最適化の段階で把握してないとおかしい。
参照をポインタにしたら最適化が抑制されるなんてことはなくて、ポインタで可能になる
初期化後の変更をするから最適化できないというならわかる。ただしその場合は単純に
参照に置き換えることはできない。
最適化にかかるコンパイル時間は確かに参照のほうが安くあがるかもね。
> ポインタしかなかった時代では単純に置き換えが可能なinline関数の展開でさえ、その間接参照された変数が
> 「他の変数の副作用をトレースしなくても最適化可能か?」という問題を解決できず、最適化が阻害されていた。
それ、昔話だよね?
inline void swap_p(int* a, int* b) { int x = *a; *a = *b; *b = x; } inline void swap_r(int& a, int& b) { int x = a; a = b; b = x; } void f(int& a, int& b) { swap_p(&a, &b); } void g(int& a, int& b) { swap_r(a, b); } g++ 4.3.4 の -O1 から -O3 まで、 f(), g() ともにまったく同じコードが生成されました。
参照でもポインタでも追跡不能なパターンは存在するが 参照で可能でポインタで不可能なパターンは今時ないだろ gccなんかはRTLになった段階でほぼ同一コードになるしな
実行時の処理の追跡がもっと軽い問題で済むから最適化が軽くなると言ってるんだよ。 最初からコストが嵩む問題が魔法によって軽くなるといってるんじゃなくて、いままでしなくてもいい処理をしていた部分が簡略化されるといってるんだ。 コード生成の結果は同じでもコンパイル時間も比較してくれないと話にならないよ。
>>72 > コード生成の結果は同じでもコンパイル時間も比較してくれないと話にならないよ。
あれ?
もしかして「最適化を抑制するから参照に」とか言ってた人とは別の人だったのか?
>>72 最適化としてコンパイラが行うべき処理が減るだろうというのには誰も異論は無い。
ポインタが「最適化を抑制」とか「最適化を阻害」とか言うのが現状にそぐわないという
話をしている。
別スレッドでタイムアウトするまで処理をトレースして最適化できるかどうかを判定するのならあると思うけど そんな極端な話じゃないよね。
>>75 ねーよw
そんな不安定なコンパイラがあってたまるか。
結局
>>58 ,62 あたりは、知ったか乙、ってことでいいんだよね?
なんか今まで 色々な煽りに煽り返したりとかしていたけど、 恋人ができたとたん全てがあほらしくなった。 まるで別人のごとき心境。
変人の間違いではなくって?
C++でコード書くと時って、みんなオブジェクト指向意識して書いてる? 単純にクラスとかの一部の機能をちまちま使うのはC++では無いって言われた
オブジェクト指向を理解してからもどってこい。
オブジェクト指向は利用するもの 共通ライブラリー以外のプログラムには必要ない 時間の無駄だ
おまえ最近メソッドとメンバ変数をすべてstaticにしろとかで炎上した老害だろw
>>78 書き込む前にオナニーをすれば無用な煽りは減らせるぞ
>>80 軽く使うならそれでもいいけど、せっかくC++使ってるんだからOOP意識して書いたほうが楽だよ。
OOP意識って人によって違くないか? 楽になるかどうかは書くコードによるだろ
そうそう、ちょっとしたコードだとクラスもなかったりする。
単純にセッターゲッター置いて、そこからアクセスするようにしてもOOP
>>89 まあある意味失敗したOOPだがな。
むしろC++は必ずしもOOPじゃなくても
プログラミングできるのがウリじゃないのか?
マルチパラダイムなのが良い点じゃないか。
>>90 オブジェクト指向は抽象的すぎて、理解した程度がみんな違うからね
>マルチパラダイムなのが良い点じゃないか。
その通り。言語仕様でジェネリックやオブジェクト指向に対応してるんだしね
しかし、Rubyが出てからかオブジェクト指向が最高となってるね
92 :
90 :2010/05/11(火) 22:54:05
俺はtemplate metaprogrammingが好きだからそういうこというんだな。 俺自身は書けねぇけどな!
質問です。c++でvectorとかstringはすごい便利ですがどうやって実現させているんですか? ヘッダファイル見たけどわからないです
>>93 わからない行に当たる度に参考書をあたれば、いつかわかります
コピーコンストラクタって普通に使ってもいいのですか? class CFoo { public: CFoo(const CFoo& src){〜} }; CFoo f1; CFoo f2(f1); ↑これって、問題ないですか?
問題ない
問題ないどころか、そうやって使うもんだろw
参照型の戻り値を受け取る側って参照型じゃないとだめなんですか?
>>99 参照を返すときには、返した先で左辺値として書くのが普通では?
別に値型でもいいしポインタに変換して受け取ってもいいよ 値型だとコピーが発生するけど
>>100 ちょっとよくわからなかった
普通というか、それ以外の書き方があるのだろうか
>>85 気にしなくていい。その記事が書かれた 2008 年当時でもたぶん、挙げられた例で
生成されるコードが変わるほど最適化が貧弱なコンパイラは生き残っていなかっただろう。
(その記事中にも生成されるコードが変わるような実例は挙げられていない)
え、出力コードが変わるって話だったの? 最初からコンパイラがちょっと楽できるねって話じゃないのか
typedef int (array_t)[10]; この型をnewで割り当てる場合、どう書けばいいですか?
>>106 std::vector<int> a(10);
よびだした時間間隔を測定する関数。boostいらず。win専用だが。 double timer(){ static int c=-1; static LARGE_INTEGER cl[2]; static double cnst; if(c==-1) { c=0; QueryPerformanceFrequency(&cl[0]); cnst=1000.0/cl[0].LowPart; QueryPerformanceCounter(&cl[0]); return 0; } c=1-c; QueryPerformanceCounter(&cl[c]); return (cl[c].LowPart - cl[1-c].LowPart)*cnst; }
>>106 何をしたいのかはっきり書こう
10要素の配列、の配列を作りたいのか
10要素の配列、を1つだけ作りたいのか
array_t を使って new int[10]; と全く同じ事をしたいのか
>>106 newは必ず型名が必要なので、次のようにする必要がある
typedef int (*array_t)[10];
array_t ap = reinterpret_cast<array_t>(new int[10]);
delete[] ap;
reinterpret_castはやべえな
背伸びはするもんじゃないな
typedef int array_t[10]; array_t* p = new array_t[20]; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { p[i][j] = i * j; } } delete[] p; array_t* q = new array_t; for (int i = 0; i < 10; ++i) { q[i] = i; } delete q; 単純明快なの
ミスった for (int i = 0; i < 10; ++i) { (*q)[i] = i; }
117 :
デフォルトの名無しさん :2010/05/12(水) 21:55:30
>>106 array_t* a = new array_t;
int* a = new array_t; delete[] a; C++って衝撃的な文法だよな 「配列はtypedefするな」ってのもよく分かるわ
御免ください x[][]形式でアクセスする int a[n][m]をnewで生成ってどうするんですか
int (*a)[10] = new int[100][10]; a[99][9] = 0; delete [] a;
素直にvector<vector<int>>使えよ
vectorなんて遅すぎて、実用には耐えれないだろ
>>124 いや十分速いだろ。
ただしC++0xでは。
>>124 環境も速度要求も示されていないところで何を言い出すんだ?
boost::array<boost::array<int, M>, N>
multiset<int> ms; ms.insert(3);ms.insert(2);ms.insert(4); ms.insert(4);ms.insert(1);ms.insert(5); としたとき、【A】multisetの中の一番小さいもの &二番目に小さいもの(1,2)を取得し削除する処理と 同様に、【B】multisetの中の一番大きいもの &二番目に大きいもの(5,4)を取得し削除する処理を書きたいです。 multiset<int>::iterator it = ms.begin(); int one = *it; ms.erase(it++); int two = *it; ms.erase(it); 処理Aは以上のコードで可能なのですが、処理Bができません。 multiset<int>::reverse_iterator it = ms.rbegin(); とすると ms.erase(it++); ができませんし、 multiset<int, std::greater<int>> ms; はエラーでコンパイルできません。 なにか上手な方法はありませんか?環境はVC++2010です。
>>129 ms.erase((++it).base()) じゃダメかい?
>>128 typedef boost::array<int, 10> array_t;
std::vector<array_t> v;
設定ファイルをシステムに取り入れたいんですけど フォーマットは何にすれば楽でしょうか?
aaa,bbb,ccc,ddd,のようなCSV方式でいいとおもうがね。 サンプルもいっぱいあるっしょ。
項目の順番を変える心配がないなら、CVSは楽だね。 それ以外だと、「項目=value」のInf方式もいいかもね。
どうもありがとう
136 :
134 :2010/05/13(木) 16:31:42
独自にフォーマット作ればいいやん。CSVは , の分の情報が冗長だし。
可搬性と拡張性を考えないなら構造体ごとfwrite()でもいいし
Boost.PropertyTree データ量をさほど気にせず、Boostに慣れてるならぶっちゃけ一番簡単。 設定用途程度なら何でも出来る。 XML, JSON, INI, INFO(Boost独自フォーマット)に対応してる。
ブーストはやめておけ。 PHPは標準でINIに対応しているからこれと互換にしておけば。 バイナリならシリアル化するやつをboost以外で用意する。
operator[][]のやり方。 #include <iostream> #include <vector> using namespace std; template<class T> class array { public: int m; vector< vector<T> > *vec; T& operator[](int n) { return (*vec)[m][n]; } }; template<class T> class arrays { vector< vector<T> > vec; array<T> prx; public: arrays(int x,int y) { vec = vector< vector<T> >( x, vector<T>(y) ); prx.vec = &vec; } array<T>& operator[](int m) { prx.m = m; return prx; } }; int main () { arrays<int> array(3,5); int m,n; for(m=0;m<3;m++) for(n=0;n<5;n++) array[m][n] = (m+1)*(n+1); for(m=0;m<3;m++) { for(n=0;n<5;n++) printf("%3d", array[m][n]); printf("\n"); }}
>>142 満足げにかいてるが、お前それ何してるのか分かってるのか?
int array[1][2];
って書けばいいだけジャンw
class arrayはやめろ
operatorで2重の[][]をやりたいときも出てくるだろ? データ参照するだけでなく何らかの処理も必要な場合は operatorでかくしか無い。
改良 変数名など変更 #include <iostream> #include <vector> using namespace std; template<class T> class retu { public: int m; vector< vector<T> > *vec; T& operator[](int n) { return (*vec)[m][n]; } }; template<class T> class nijyu_test { vector< vector<T> > vec; retu<T> ret; public: nijyu_test(int x,int y) { vec = vector< vector<T> >( x, vector<T>(y) ); ret.vec = &vec; } retu<T>& operator[](int m) { ret.m = m; return ret; } }; int main () { nijyu_test<int> A(3,5); int m,n; for(m=0;m<3;m++) for(n=0;n<5;n++) A[m][n] = (m+1)*(n+1); for(m=0;m<3;m++) { for(n=0;n<5;n++) printf("%3d", A[m][n]); printf("\n"); }}
突っ込みどころが多すぎるが Effective C++とMore Effective C++ を読んでから出直してこい
というか釣りだろw
>>122 の
>int (*a)[10] = new int[100][10];
このnewの戻り値変数、なんで int (*a)[10] になるんですか?
int[10]を100個分の配列確保したからint[10],int[10],int[10],…,int[10]という領域が 確保されてその先頭のアドレスであるint(*)[10]が返されたんだろ。
152 :
122 :2010/05/14(金) 07:43:57
int *a[100]; // *(a[10]) a[99] = new int[10]; (a[99])[9] = 0; cout << a[99] <<" "<< &(a[99])[0]; delete [] a[99];
以下のようなコードを -Wall -O2 オプションを付けてコンパイルすると strict_aliasing.cpp:12: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules /usr/include/c++/4.4/bits/stl_tree.h:175: note: initialized from here というwarningが出ます。 Hogeの別名Fugaを使っていることが原因のようですが、これは良くないプログラムなのでしょうか? また、解決方法はオプション変更以外にあるのでしょうか? #include <iostream> #include <map> using namespace std; class Hoge { __public: ____double val; ____Hoge( double d ) : val(d) { } ____bool operator<( const Hoge& rhs ) const{ ______return (val < rhs.val); ____} }; typedef Hoge Fuga; // これが悪いらしい int main(int argc, char* argv[]) { __map<Fuga,int> fuga2int; __fuga2int[ Fuga(100) ] = 1; __return 0; }
>>147 こいつ
>>146 、このスレで揚げ足とるときに必ず出てくる奴なんだよ。
日本語の変数つかってるからすぐ分かる。
うぜーからほっといてあげてください
>日本語の変数つかってるからすぐ分かる。 >日本語の変数つかってるからすぐ分かる。 >日本語の変数つかってるからすぐ分かる。 >日本語の変数つかってるからすぐ分かる。 >日本語の変数つかってるからすぐ分かる。
俺はテストプログラムのクラス名はいつも日本語だぜ。VC++10 #include <cstdio> class マンコ { public: void 挿入() { std::printf("あいう"); } }; int main() { マンコ i; i.挿入(); std::fgetc(stdin); }
virtual void xxx(const A& a) const { (void)a; } こういうコード見たんだけど何の意味があるんでしょうか?
昔は戻り値のある関数の呼び出しに対して、戻り値を使用しないでいるとコンパイラが「戻り値を無視している」と警告を出す場合があったから その式の副作用だけに期待して評価を無視する場合は明示的に(void)とキャストして警告が出ないようにしていた。 ただしC言語がANSIで規定される前の話だからそのコードを見る限りは何なのか判断できないな。
LINTだっけ? 昔そういうクソなツールがあって、その警告防止のため
ありがとうございました 得に意味は無いんですね
「この関数が戻り値を返してることは知ってるけど、敢えて無視してるんだぜ」 という表明にはなる
戻り値じゃなくて引数だろ
>>162 だから
>そのコードを見る限りは何なのか判断できないな。
って書いてあるだろ。
どこをどう見たらaが戻り値に見えるのか教えてくれ
わたし158だけど引き合いに出したのは副作用の可能性のある式としての関数だから157のコードでは何なのか判断できないって書いたんだけどそんなところで揚げ足取られても困るんだけど。
何こいつうざい
戻り値を返す関数に対しての(void)なら
>>161 の言うとおりだけど、
もともとaなんて何も意味ない式だし、よくわからんね。意味ないんじゃない?
>>161 は最近知った知識をひけらかしたかったんだよ
察してあげなよ
引数をコメントにして 引数使ってないよ!警告を出さないようにするってのを どっかで見たな virtual void xxx(const A& /* a */) const { }
最初から変数名を消せよ
171 :
169 :2010/05/15(土) 00:29:47
ああ、引数名を消すと可読性が悪くなるから 消さないって前提だった
別にならんが・・・
可読性は人それぞれ
doxygenに警告を出させない目的で引数名を書いて、 コンパイラに警告を出させない目的で'(void)引数'を使ってる。 引数名を書かなくてすむ方法があるならそうしたいが…。
>>175 doxygen のコメントは宣言だけに書いて、引数名を書かないのは定義だけにすればいい。
>>153 std::mapで警告されるのはgcc4.4のバグらしいよ。
引数と戻り値を間違える奴は消えてくれよ・・・
変数宣言を無くしてパフォーマンスは変わらないC/C++作ってくれよ。 関数の多重宣言は出来るから変数にも適用して 同名で異なる型の変数を自動で生成してくれよ。 変数宣言無くせれば見通し良くなる。
?
見ちゃダメ!!
今日明日は相談室は談話室になりました 新茶と新緑の薫りを楽しみながらで談話しせう
なんだか板全体的にレスが少ないね?あれのせい?
女の子の日?
185 :
デフォルトの名無しさん :2010/05/15(土) 22:56:16
ええい!女のプログラマなどいるものか!
ネカマならいますけどね(はぁと)
動的に確保するconst要素な配列って用途ある?意味ある?
あるよ
VC++2008インスコして、今C言語やってるんだが、SQL Serverとかのソフトが300MB級ばっかりでCの領域圧迫してて困ってる。 いずれデータベースとかの勉強しようとした時に多分これらのSQL系ソフトが必要になるんだろうけど、 今のとこデータベースやる予定ないから消したい。 VC++とSDKでの開発に当たり障り無い範囲でSQLなどの関係ないソフトを消したいんだけど、プログラムの追加と削除のところからテキトーにやっちゃって良いの? 何か消しちゃヤバいプログラムとかあったら教えてエロい人
いいよ
データベースでもMSSQLなんていらないから消しておk
192 :
189 :2010/05/16(日) 14:46:53
あぁそうなの。要らない子のくせしてめちゃくちゃ重いんだけどwww 合計600MB超えてるしww 消してくる。THX
193 :
189 :2010/05/16(日) 14:48:26
あとそうだ、.NET関連のは消さない方がいいの?
>>189 それよりハードディスク大きいやつに交換しろよ。
スレ違い。いいかげんにしろ。
MSSQL実務で使ってるとこあるんかなぁ?
>>189 VC++はC++コンパイラでCコンパイラじゃないよ。
C++コンパイラでC言語なんて止めたまえ
>>198 なんでやねん
拡張子を".c"にするとcコンパイラになるんだが
ぐぐったらVC++でCのソースを扱う方法がいっぱい出てくるだろうが
↓負け惜しみ
C99に未対応のコンパイラーでC使うって>< ↓上から目線で
C99とかC++0xとか使うのはやめろ 互換性と移植性が失われる
C++0xは使うぜ。auto,lambda,右辺値参照は一度つかったらやめられないぜ
そんなもん使ったら古いコンパイラでコンパイルできなくなるだろうが やめろ馬鹿
規格に合致したものを書いて移植性がないとか言われるとか辛いな、サム
GCC4やVS2010がないと使えないなんて泣き言が通ると思ってんの?
207 :
189 :2010/05/16(日) 20:59:34
>>198 いや既に出来てるんですけど・・・・・?
>>194 初期のVAIO(笑)でXPなんでショボいんですけどお金無いんですよ・・・・
placement newについてなんですけど template <class T> ・・・ { T *p = new (buffer) T(arg); p->~T(); operator delete (p, buffer); p = 0; } 上記のような流れが正しい扱い方だと思うんですが、以下の場合どう書くべきなのか困ってます @T *p;ではなくconst T *p;にした場合 operator delete (p, buffer);の引数は非constなのでコンパイルできない const_castを使うほかないと思うんですが、それって作法としてはどうなのかな、と ATがメンバにoperator delete (void *, void *);を持っている場合 TMPを使って適切に呼び出すことは可能ですが、C++を開発した人が最初からTMPを前提にplacement new/deleteを用意したとは思えません TMPを使わずに適切なoperator deleteを呼び出すことは可能でしょうか?
>>208 最初のソースから何かおかしい。
buffer がどう確保されてるのかわからないので、 operator delete () の呼び出しが
正しいのかどうか判別不能。
すいません書き忘れました unsigned char buffer[sizeof(T)]; を使うことを考えています
>>210 それなら operator delete () 呼び出しちゃダメ。
あと、アライメントに注意。
>>211 何もしない関数とは言え、newに対応するdeleteは一応呼び出した方が良くないですかね?
ねーよ
operator deleteはグローバルヒープにvoid*型のメモリを「もう使いませんよ」とOSの管理へ開放する関数。 placement newは既に存在するメモリ空間に対してオブジェクトを構築する構文。 この場合はoperator deleteする必要はない。
オーバーロードされてたらナニが起こるか分からないから呼ばないとだめだね オーバーロードされてないことが事前にわかるなら呼ばなくていい
test
>>216 いや、オーバーロードとか関係なく、呼ばなくていいから。
呼ばないとデストラクタが呼ばれないんじゃないの?
operator deleteを呼び出すのは、operator newで獲得したメモリを解放する時。 それ以外は絶対呼んじゃ駄目。 当たり前すぎることなんだけど、 new演算子とoperator new()の違い、及びdelete演算子とoperator delete()の違いが 区別できてないアホはウダウダ言い続ける。
>>221 わかってる人はわかってるが、さすがに「当たり前すぎる」はないだろう。
「new演算子とoperator new()の違い」なんて一見して何言ってるのかわかんないよ。
説明もしにくい。
>>221 君、発言から察するに追加引数ありとなしのoperator new|deleteを混同してないかね?
>>219 こういうやつが居ることを考慮して、 ::new (buffer) ... ってしとかないとダメなんだな。
>>222 は?
new演算子は、operator new()を呼び出してメモリを確保した後、コンストラクタを呼び出す演算子。
operator new()は、単純に指定した量のメモリを確保するだけの関数。
この程度のこと、知らないわけじゃあるまい?
オーバーロードできるのはoperator new()とoperator delete()のみ。
operator delete()の明示的な呼び出しと、デストラクタがどうのって話は全然関係ない。
>>219 ねーねー、m_countの初期値はいくつ?
あ、ごめん。 よく見てなかった。
>>225 知ってるけどわかりにくいって話だよ。特に「演算子」が operator の訳語であると知っていれば
なおさら。
::operator new(size_t)を呼んだら、::operator delete(void*)を呼ばないとだめ ::operator new(size_t, a_t, b_t, c_t, ...)を呼んだら、::operator delete(void*, a_t, b_t, c_t, ...)を同じ引数で呼ばないとだめ 同じように::operator new(size_t, void*)を呼んだら、::operator delete(void*, void*)を呼ぶ(ほうが対称性があって行儀が良いけどどうせなかで何もしないからべつに書かなくてもいいよ) そんで::new(a_t, b_t, c_t, ...)演算子は内部で::operator new(size_t, a_t, b_t, c_t, ...)を呼んでいるから対応する::operator delete(void*, a_t, b_t, c_t, ...)も呼ばないとだめ グローバルに関してはこれでおk?
>>229 1行目と3行目はわかるが、それ以外については何も言えないはず。
newの中のコンストラクタで例外が発生したら スタックが巻き戻されて引数が対応するoperator deleteに同じ引数を渡して呼ばれるね ということはC++の仕様を考えた人たちは operator newとoperator deleteはセットで考えてるはずだよ だから実際になんの意味がなくても呼び出すべきだし セットで扱う前提で書かれているのが良いコード
> newの中のコンストラクタで例外が発生したら > スタックが巻き戻されて引数が対応するoperator deleteに同じ引数を渡して呼ばれる そんな事実はない
いやいや呼ばれないとメモリリークするだろ
このすれ中途半端な知識を自信満々に披露して自爆するヤツ多すぎてワロタwww
>スタックが巻き戻されて ここが間違ってんじゃない?
すみません。defineマクロは使わない方がいいと聞いたのですが、何故ですか? 便利だと思うのですが。
言ったやつに訊け
>>237 過去の書き込みなので無理です・・・
考えられる使わない方がいい原因と言ったら、なにが挙がりますか?
定数定義なんかでは型の情報がない点がstatic constに劣るとか何かの本に書かれた希ガス。 仕事のプログラムでdefineマクロで関数みたいのを作ってるソースコードを見たときは可読性下がるなと感じた。 defineマクロの中でreturnとかされてて読みづらかったわ。
240 :
237 :2010/05/17(月) 12:23:02
const int N = 10; #define N 10 デバッガーでNの値が覗けるからintの方を使うとか、 #define MACRO(a) a+3 MACRO(3)*6 式を括弧でくくらないといけないという使い方。 #define MACRO(a) (a+3) aを括弧でくくらないといけない例もあったと思うけど自分で考えて。
>>236 #ifdefとかでフラグ的に使うものは別として、インライン関数で代用できるものは
きちんと型安全が保証されるインライン関数使えってことでは?
あと#ifdefもそれ自体が汚いと思わない?
>>236 マクロでひとくくりにされてもよくわからんな。
どんなマクロ定義が便利だという話?
243 :
237 :2010/05/17(月) 13:59:37
>>243 使おうとも思わんが。
#define MACRO(a) ((a)+3)
↓
inline int macro(int a) { return a + 3; }
でいいだろ
246 :
237 :2010/05/17(月) 14:46:54
>>245 inline はCの時代には無かったという話
>>246 C++相談室で何を言ってるんだおまえは?
breakとかreturnとか入れるのはイヤかも #define ErrorCheck(x) { if (!(x)) { printf("ERROR\n"); break; } } void foo() { for(;;){ ErrorCheck( bar() ); } }
そう。しかもマクロの中から別のマクロを関数のように呼び出していて 関数がどこまで実行されたのか分からないということがあって殺意を覚えたね。
マクロはただの置換で型レベルのコンパイラの検査が明確に入らないから、コンパイルエラーが出たときにエラーを除去したり スタックトレースで関数たどるのが地獄なんだよ。
コンパイラの検査が明確に入らないから、Boostなんかでは変態的な使い方が・・・ よくテストされてるものを使うだけならすごく便利だが マクロ満載のデバッグとかしたくないな
質問です fnc( string &s )とすると、 fnc( x.sunstr(10) ); が動かせないですが解決方法ありますか。
できるだけ参照を引数にして、不可能なら実体を受け取りたいのですが
fnc( string const&s )
トンクスです
追記。 x.sunstr(10)が参照で渡せないのは名前がついていない値「右辺値」だから。 現在のC++はconst参照で受けると、右辺値でも受け取れる仕様。 C++0xでは右辺値を参照で渡す構文も入ってくるらしい。 ちなみに、 fnc( const string &s)と fnc( string const &s)は同じね。
右辺値ってなんですか? 知ったか先生お願いします
思い当たる事があったら教えて欲しい。 VB6アプリからVC++アプリをShell関数で呼び出してる。 VV6アプリとVC++アプリのEXEは同じサーバ、同じ場所に置いてる。 VB6アプリを直接実行した場合、VC++のアプリは正常に動くんだけど WEBからVB6アプリを実行した場合、VC++アプリが正常に動作しない。 一応起動はするみたいなんだが、VC++アプリで定義してる 独自のライブラリ/インクルードファイルが上手くいってない感じ。 (独自定義の型使った宣言が入ってると落ちる) VB6から直接実行した場合は正常に動作するけどWEB経由するとダメってのが理解できない ライブラリとかインクルードファイルの環境設定がまずいなら ビルドの時点でアウトだよな? そもそもVB6アプリからなら問題ないってのが… こんなことあるの?
作業ディレクトリがブラウザのフォルダになっちゃってるとか?
>>257 左辺値→アドレスをとれる値
右辺値→アドレスをとれない値
includeと変数宣言をコンパイル時に自動でやってほしい。 必要なヘッダファイルを自動で生成するって言うこと・
プログラムで頻繁に使う処理は自分用includeディレクトリ用意してそこへ入れとくと良いな。 プログラム歴は長いが、いままでコピペして対処していた。 どの部分が改良してある最新版が分からなくなり不便だった。個人用共通include作ったら便利になった。
265 :
デフォルトの名無しさん :2010/05/18(火) 14:20:32
自分で作ったクラスをcoutで出力できるようにしたらどうしたらできますか?
コンパイル時にgcc msvc bccを判断するにはどうすればいいですか
ベンダ固有の定義済マクロで判定する。
それが判らないんですが 一覧はありますか
__GNUC__ _MSV_VER とかが定義されてるとかで
テンプレート引数の異なる、同じテンプレートクラスがあったとして それらの間でだけprivateメンバへのアクセスを許可したい friendを使わずに実装する方法はあるだろうか?
ない。だって違うクラスだから
アクセスを許可したいメンバだけ親クラスに分離してprotectedにするとか
ごめんなんかできそうな気がしたけど出来なかった
>>275 は忘れて
無理ですかぁ 自分でもプロクシとかディスパッチとか色々考えたけど出来ないっすわ・・・
>>280 ありがと。ものすごい勘違いしてたわ
placement deleteの場合、operator deleteの第2引数以降は、
placement newの第2引数以降と合わせないとダメなのね
ってことは、deleteするときにdelete対象オブジェクトのサイズって
operator deleteに渡されないの?
>>280 うわっBCC5.5.1だとdelete呼ばれない
バグってる
BCCはBCCという言語だから
>>283 きっちり調べたわけじゃないからアレだけど追加引数があるとダメっぽいね
整数一つ分余計に確保してそこに入れておくとか
追加の引数に整数への参照を渡して保存しておくとか
工夫すればできなくもないと思うけど・・・
placement newするときはアラインメントに気をつけなさいってよく聞くけど 実装非依存かつ標準C++で任意の型に対してアラインメントを揃えるにはどうすればいいの?
>>283 渡されません。
自動的に追加の引数を入れてくれるのは new 式の途中で呼ばれたコンストラクタから
例外が飛んだときだけ。
delete 式で呼ばれる operator delete () はポインタひとつあるいはポインタとサイズのふたつを
引数に取るものだけ。 (12.5. p5)
>>287 boost::aligned_storage を使う。あるいは真似る。
>>287 標準の範囲ではどうしようもない。
まあ、バッファをdouble型あたりで取っておけば、大抵の処理系で動作するとは思うけど、
保証はないので、素直にboostとかを使うほうがいい。
ところでalinged_storageって0xに入るんだっけ?
>>287 もともとMyClassのオブジェクトをnew MyClass;でつくって、
アドレスを保存しておいて明示的にMyClassのDestructorを呼び出す。
するとそのメモリ領域は確保されたまま何も乗っていない状態になるので、
そこで初めてplacement newで明示的にConstructorを発動すれば
はれてalignmentされた領域にplacement newできたことになる。
int buf[sizeof(T)/sizeof(int)+1]; これでアライメント取れてるよね
doubleが16バイトあったらどうすんだ
STL の Vector について質問です。 iteratorを使用して降順で対象を探し目標を erase にて削除はできるのですが、 昇順で reverse_iterator を利用しての削除はどのように行えばよいでしょうか? erase は reverse_iterator には対応してない様でした。 なにか参考になるサンプルなどをご紹介していただけますでしょうか・・・。 よろしくお願いいたします。
>>297 レスありがとうございます、このように書き直してみましたがいかがでしょうか?
前提として _ite は reverse_iterator 型となっております。
//削除部分
vector<xxx>::iterator _tmpIte = xxx_vec->erase( _ite.base() );
_ite = vector<xxx>::reverse_iterator( _tmpIte );
添削をお願いいたします。
自分で確かめろよ。
>>294 その保証はない。
>>295 そもそもdoubleでバッファをとってもdouble境界にアライメントされる保証もない。
301 :
デフォルトの名無しさん :2010/05/19(水) 16:28:40
coutとかcerrとかcinって出力先変えれませんよね? 変えれたとしてもそれは間違った使い方で、本当はcoutのクラスを作るのが ふつうですよね? 以上の理解であってますか? もし合っていましたらcoutのクラスを作る方法をおしえてください。
std::cout, std::cin, sdt::cerrは標準で用意されるストリーム形式の出力、入力、エラー出力。 ストリーム形式(型の静的多相性と動作)に互換があればそれぞれ自前で用意してもいいし、boostのasioなんかはその分かりやすい良い例になってる。 STLの範囲内だから適当にぐぐるよろし
なぜ間違っていると思っているのか詳しく説明して。
間違ってないのならそれでいいです。 有難うございました。
>>301 何を言っているのかわからん。
> 変えれたとしてもそれは間違った使い方で、本当はcoutのクラスを作るのが
coutのクラスってなんじゃい。
std::basic_ostream<char, std::char_traits<char> >だろう
他人が作った非PODクラス(変更はできない)の内容をファイルに保存し 次回起動時に読み込んでオブジェクトを復元したいんですが、これってぶっちゃけ一般解は無いですよね?
Protocol_Bufferだろ。 boostは使うのが困難。 こっちヘッダを生成して読み込むだけ。 自分でやること少なめ
変更禁止だと侵入型はダメだし、非侵入型だとprivateに触れないからboostでも無理じゃね?
あ、 > 他人が作った非PODクラス(変更はできない) か。そりゃ無理じゃねぇか。 やっぱり#define private publicが必要だな。
仮にそれやっても型消去されてたりしたらだめだな これは最強魔法#define private publicの敗北であるといわざるを得ない
今、VisualStudio C++ 2010でWin32アプリケーションの勉強をしているのですが いいサンプルコード集のダウンロード先や解説サイトないでしょうか?
ありがとうございます ・・・・コンパイル出来ないからSDKもダウンロードしないと
タコ娘ってなんでいないの? 居たら絶対可愛いよ。軟体動物の中で最も高知能だし、まったり天然と見せかけて秀才キャラなのは誰の目から見ても明らか。 イカ娘の立場は存在しない。
井口もいいけどタコス娘もいいな
関数のリターンでstringやchar* 使うと、 引数で参照やchar**使うより2倍メモリ使いますか。 関数内の一時領域と受け取り側で。
何を言ってるのかわからないが とりあえずRVOでぐぐれ
>>318 通常は戻り値最適化1(RVO)が行われるので一時オブジェクトは作成されず2倍消費することはない。
関数のリターンがchar*だった場合は、char**のコストと同じ。 むしろchar**の方がdereferenceのコストがひとつ多く発生するのでchar*の方が効率がいい。 どちらにせよ、クラスとポインタを同一で比べられるものではない。 ポインタ型だと編集や追加書き込みが発生しない場合に引数として受け取ったメモリ領域をそのまま返すという最適化もできるのだし、 事実std::stringもその様な最適化が既に施されているから素直にstd::stringを使えばいいと思うが。
ポインタで返すのはよせ
戻り値最適化されるとしたらmoveで返すのとどっちが効率いいんだ?
一緒
326 :
デフォルトの名無しさん :2010/05/19(水) 23:15:49
純粋な計算量としての見積もりと、最適化のノウハウを、 それぞれ別な問題として論じられる人が、 いないときは悲しいほど誰もいないのな
>>323 RVOは最適化なので必ず適用されるとは限らない。
moveは右辺値参照をサポートしていれば必ず適用される。
strstrの逆順サーチってありませんか。後ろからサーチするやつです。
>>329 std::find_end(s1, s1 + std::strlen(s1), s2, s2 + std::strlen(s2))
サンクス
332 :
デフォルトの名無しさん :2010/05/20(木) 12:38:36
"a.b.c.d".rindex(".") ==> 5 Rubyならこれだけで済むのに… C++糞すぎだろ
>>332 C++ でも std::string("a.b.c.d").rfind(".") と書けるわけで、そんなに違わない。
逆に C++ なら
>>330 で済むのに…オブジェクトの生成が必須になるRuby糞すぎ、
という立場もあるかもしれない。
どちらかと言うとRubyしか使えない332糞すぎ
いやRubyと大して違わない書き方で桁違いのスピードが出せる C++が凄すぎるんだよ。
複合型のアライメントは組み込み型のどれかのアラインメントに一致する これって真?偽?
>>336 C++規格としては真でも偽でもありません。
そんなことは規格に書いてなかったような
すまんググったら書いてあった どうやら複合型のアラインメントはメンバのなかで最大のアラインメントを持ってるやつと同じになるらしい ってことは再帰的に考えて組み込み型のどれかと同じになるってことだよね ただvtableとかについては書いてなかったからそのへんが気になる
じゃあ class x { char a; virtual ~x() {} }; は1バイトアラインになるわけですね。
STLのshared_ptrについて質問です。 参照をリセットした上で、今のリセットによってオブジェクトが解体されたかを知るすべはないのでしょうか? resetが参照をやめるのに使えるのですが、返り値がvoidのため、解体されたのかはわからないようです。
明示的にやるならnew deleteでいいじゃん。 その手間を減らすだけで、shared_ptrでしか出来ないことはないでしょ。
手抜きツールなだけで手間暇掛けられるなら自分で管理するのが良い。
>>339 規格で決まってるんだ?知らなかった。
「複合型」ってもしかして非PODなクラスは含まないのかな?
定義調べるのメンドクサ。ははは
wwwww
しかしどの型がどんなアラインメントを持つかは処理系定義
>>336 自明じゃないけど、論理追っていくと自然とそうなる
fopen と _wfopenは長いファイル名に対応していないんですが。 fopenと互換の長いファイル名に対応した関数はないですか?
自己解決 _wfsopenは長いファイル名に対応していました。
対応していなかった。 パスをロング用から元に戻していた。 \\?\付きのパス名です。 CreateFileはどのコンパイラでも\\?\対応だけど。 これ使うと、fopenとの互換性を保つのが一苦労。 既に作ってあるやつないですか。
CreateFileのHANDLE型とFILE*型は関係ありますか。 全関数を対応されるのは困難で CreateFileを自作関数で呼び出すけど、FILE*型をリターンして read writeやシークは既存関数を使いたいのですが。
あんじゃないの ハンドルなんて所詮void*だろ
354 :
デフォルトの名無しさん :2010/05/20(木) 21:30:37
ちょっとお聞きしたいことががが。 継承したクラスの型を知りたいのですがこんな場合可能でしょうか? class Base{} class Parent : public Base{} class Child : pubic Parent{} class Other : Base{} Parent* p = new Child(); Base* b = p; このとき b から Parentを取得できるかどうかってのが質問なのです。 typeid(b).name()やtypeid(*b).name()ではBase*かChildかどうかはわかりますが Parentがわからなくて・・・ よろしくお願いします。
>>354 typeidでは継承の関係は判別できない。
bからParentを取得するにはstaic_castまたはdynamic_castを使う
dynamic_castは仮想デストラクタが必要
static_castだな訂正
357 :
デフォルトの名無しさん :2010/05/20(木) 21:53:25
>>355 あーそうでしたか。ありがとうございます。
画面遷移でif文を使わずに基底クラス型に突っ込んで
中のオブジェクトの型で遷移するかどうかを判定したかったんですが
画面にも階層があるので中間的なクラスを判定に使いたくてできるかどうか
質問しました。
こんな感じです。
nowState = new Child();
while(nextがParentの派生クラスなら継続※←ここが問題){
Base* next = getNext(); //getNextはBase*で返すが中身はChild型またはOther型
}
nowState ⇒ next の間違いです。 ちなみにこれって不可能な考え方でしょうか?
Baseに仮想デストラクタ書いて(Base*を扱うなら書くべき) while(dynamic_cast<Parent*>(next)) でいいんじゃないの
>>359 おおお、いけました。ありがとうございます。
dynamic_castってこういう使い方ができるのですね(使ったことがなかった。。)
>>341 shared_ptr::unique()では役に立たない?
reset()を呼び出す前にunique()を呼び出してtrueだったら 自分しか所有してないからreset()すれば解体されるって感じか そもそもshared_ptrが適してるのかねその設計
>>341 weak_ptrつくってexpired()かな
>>362 自分で管理したいなら最初から自分で管理しろって話だよな
当たり前じゃないの? const教徒はムーブコンストラクタがconst付きの物をぶち壊してくれた方が嬉しいのか 変なの
>>366 そう?
>>365 のinitHoge2の戻り値はconstじゃないんだから
この結果は変だと思いますけどね。これで規格通りなの?
368 :
367 :2010/05/21(金) 09:57:17
あ、変じゃないわ。俺が寝ぼけてた。
>>361-363 お返事ありがとうございます。
>>361 それぞれのスレッドで
if (p->unique())
{
//特別な処理
}
p = shared_ptr<hoge>();
こんな感じにするわけですが、スレッドだと排他処理を別途書かない限り、両方でuniqueがFALSE返すことがありえますので無理かと。
>>362 適しているのかはわかりません。
現状では自前の参照カウントでやっています。
やろうとしていることがshared_ptrでも可能だったら、そちらのほうがベターだとと思ったしだいです。
>>363 weak_ptrを使ったとしても
スレッドA weak_ptr作成
スレッドB weak_ptr作成
スレッドA shared_ptr解放
スレッドB shared_ptr解放
スレッドA weak_ptr::expired()
スレッドB weak_ptr::expired()
と動作した場合、双方で「俺が消した」ことになってしまいます。
shared_ptrでの解放処理と、参照カウントの取得は、スレッド不可分でなければ成り立たないかと思います。
>>364 質問者じゃないが、そんなものあったのか…
fopen_sにしたら、エクセルで編集中のCSVファイルを開けなくなったので困ってたんだ
fopenの時は、共有モードなんてガン無視してたんかな。_sになって厳密になったのに、共有モードを指定する方法が無いからエラーになってた。
>>364 の使えば問題回避できるわ
>>364 サンク。長いファイル名と既存のC言語関数が使えるようになりました。
#include<windows.h>
#include<io.h>
#include<stdio.h>
iint main(){
HANDLE hd=
CreateFileA( "\\\\\.\\C:\\sample.txt", GENERIC_WRITE , FILE_SHARE_READ , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL);
FILE *fp=_fdopen( _open_osfhandle ( (int)hd, 0 ), "w+" );
char ch[]="test desu.";
fwrite(ch, 1, strlen(ch), fp);
fclose(fp);
}
全部ヘッダファイルに書きたい!!
>>369 デリータ渡しとけ。
しかしスレッド対応とか、そんな重要な情報を後出しするなよ…
なるべく多くのファイルが開ける、wfopen作ったよ。 #include<windows.h> #include<io.h> #include<stdio.h> #include<string> FILE* wfopen (std::wstring fname, std::wstring opt) { int flg, att; std::wstring fn(1<<15, L'\0'); int n=GetFullPathNameW( &fname[0], 1<<15, &fn[0], NULL); fn.resize(n); if( memcmp( &fn[0], L"\\\\\?\\", 8)!=0) fn = L"\\\\\?\\" + fn; att = GetFileAttributesW(&fn[0]); if(att==-1) { if( opt[0]==L'r' ) return NULL; else att=0; } if(opt[0]==L'a' || opt[0]==L'r' ) flg=OPEN_ALWAYS; else flg=CREATE_ALWAYS; HANDLE hd=CreateFileW( &fn[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , flg , att , NULL); FILE *fp=_wfdopen( _open_osfhandle ( (int)hd, 0 ), &opt[0] ); return fp; } static std::wstring char2wchar(std::string x){ int m=x.size(); if(m<=0)return 0; std::wstring y(m, L'\0'); m=MultiByteToWideChar(CP_ACP, 0, &x[0], m, &y[0], m); y.resize(m); return y;} FILE* wfopen (std::string fn, std::string opt) { return wfopen( char2wchar(fn), char2wchar(opt) ); } int main(){ FILE* fp = wfopen(L"c:/test.txt", L"wb"); char ch[]="This is a pen.";fwrite(ch,1,strlen(ch),fp); fclose(fp); }
>>373 ほんとにすいません。
自分の質問読み返して、スレッドだって書いてなくて愕然としました。
本当に申し訳ないです。
書いた後に、文章整理している段階で消してしまったようです。
デリータを渡しても、どちらのスレッドで解放されたかで処理をわけるのはできなくないでしょうか?
スレッドIDを見て、それで処理分けといった感じでしょうか?
いつ解放されたか、自動か手動か見極めるのは困難。 全手動でやれよ。
377 :
374 :2010/05/21(金) 14:18:43
GetFullPathNameWの性能が悪いや これ自分で作るしかないな
>>375 デリータ渡しても無理だと思う。
resetの特別版を実装したshared_ptrもどきを作るのが
一番簡単そう。
381 :
374 :2010/05/21(金) 15:49:59
32未満のコードが混じっていた場合になるべくopenできるようにした。 std::wstring fullpath( std::wstring path){ unsigned int n; if( memcmp( &path[0], L"\\\\\?\\", 8)!=0 ) { if( (int)path.find(L":")!=-1) path=L"\\\\\?\\"+path; else { std::wstring root; n=(1<<15); root.resize(n); n=GetCurrentDirectoryW(n, &root[0]); root.resize(n); path = L"\\\\\?\\"+root + L"/" + path; } } for( n=0; n<path.size(); n++ ) { if( path[n]<32 ) { path[n]=L'_'; continue; } if( path[n]==L'/' ) path[n]=L'\\'; } return path; } FILE* wfopen (std::wstring fname, std::wstring opt) { int flg, att; std::wstring fn=fullpath( fname ); att = GetFileAttributesW(&fn[0]); if(att==-1) { if( opt[0]==L'r' ) return NULL; else att=0; } if(opt[0]==L'a' || opt[0]==L'r' ) flg=OPEN_ALWAYS; else flg=CREATE_ALWAYS; HANDLE hd=CreateFileW( &fn[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , flg , att , NULL); return _wfdopen( _open_osfhandle ( (int)hd, 0 ), &opt[0] ); } FILE* wfopen (std::string fn, std::string opt) { return wfopen( char2wchar(fn), char2wchar(opt) ); }
>>380 codepadだと通るけどg++だと通らないですね
もしやと思って最初に書いたコードもg++でやってみたら通りませんでしたorz
すいませんcodepadが特殊だっただけ(?)みたいです
>>381 L"\\\\\?\\"
間違ってるぞ。\がひとつ多い
APIと違って hoge/../hoge/../
といったかけあがりパスなどを解決してくれないのもマイナス
384 :
374 :2010/05/21(金) 18:49:40
おおいか正解はなに? 手持ちに主にURLを一意化する関数ある。 手順掛かるけど。ファイルも可能。区切りが/だけど。 カレントディレクトリで無い場合も、rootにセットしたらできる。 std::wstring abspath(std::wstring path, std::wstring root){ cout<< wchar2char(path) <<endl; unsigned int n, k; if( (int)path.find(L":")==-1) { if(root==L""){ n=(1<<15); root.resize(n); n=GetCurrentDirectoryW(n, &root[0]); root.resize(n); } path = root + L"/" + path; } n=path.find(L"\\\\\?\\"); if(n==0) path=path.substr(4); std::vector<std::wstring> word; std::wstring s = L""; unsigned short int x; for( n=0; n<path.size(); n++ ) { x=path[n]; if( x<32 ) continue; if( x!=L'\\' && x!=L'/' ) { s+=path[n]; continue; } if( s.size()!=0 ){ word.push_back(s); s.resize(0); } } if( s.size()!=0 ) word.push_back(s); std::vector<std::wstring> abs; for(n=0; n<word.size(); n++) { if (word[n]==L".") continue; if (word[n]==L"..") { k=abs.size(); if(k>0)abs.resize(k-1); continue; } abs.push_back(word[n]); } path=L""; for(n=0; n<abs.size(); n++) path+=abs[n]+L'/'; k=path.size(); if(k>0) path.resize(k-1); return path; }
_open_osfhandleの第一引数をintにするとそれだけで64-bit not ready
386 :
374 :2010/05/21(金) 22:08:55
改善しましたよ。不正コードは除去してからGetFullPathNameWに渡すことにしました。 #include<windows.h> #include<io.h> #include<stdio.h> #include<string> std::wstring fullpath( std::wstring fname){ unsigned int n; std::wstring fn; for( n=0; n<fname.size(); n++ ) if( fname[n] >= 32 ) fn+=fname[n]; fname=fn; fn.resize(1<<15); n=GetFullPathNameW( &fname[0], 1<<15, &fn[0], NULL); fn.resize(n); if( fn.substr(0,4) != L"\\\\?\\" ) fn=L"\\\\?\\" + fn; return fn; } FILE* wfopen (std::wstring fname, std::wstring opt) { int flg, att; std::wstring fn=fullpath( fname ); att = GetFileAttributesW(&fn[0]); if(att==-1) { if( opt[0]==L'r' ) return NULL; else att=0; } if(opt[0]==L'a' || opt[0]==L'r' ) flg=OPEN_ALWAYS; else flg=CREATE_ALWAYS; HANDLE hd=CreateFileW( &fn[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , flg , att , NULL); return _wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), &opt[0] ); } int main(){ FILE* fp = wfopen(L"c:/aaa/../test.txt", L"wb"); char ch[]="This is a pen."; fwrite(ch,1,strlen(ch),fp); fclose(fp); }
387 :
374 :2010/05/21(金) 22:19:56
なんのコードなのか書きます。 255文字以上のパスや、\\?\付きのパスを読み込む fopen、 _wfopen互換関数です。 349 名前:デフォルトの名無しさん[sage] 投稿日:2010/05/20(木) 20:33:57 fopen と _wfopenは長いファイル名に対応していないんですが。 fopenと互換の長いファイル名に対応した関数はないですか?
駄目だ。原因不明だけど。削ったら日本語文字化けしたよ。 0-31はエンコードによらず制御コードしか入らない気がしてたけど。
原因は別でした。386で出来ました。
> c:/aaa/../test.txt Windowsなのにパスデリミタに / 使うバカって一体なんなの?
/でも通ることを実証したんだ。 \\?\c:/aaa/../test.txtをそのままCreateFileWに渡すとエラーになるから その変換がいる。\より手順が多い。
C:\\cd\gr\\//c/d/cd/cdf/.........\\\\\.////test00000000000000000000000.txt などでも通る必要ある。 試してはいない。
実証したって・・・ APIリファレンスに書いてないことしちゃいかんだろ。誰が保証するんだ。 ある日パッチ当てたら「動かなくなりました」でマイクロソフトのせいにする気か?
APIに渡す前に\に変換しているわけだが・・・ \で無いと通らないことも確かめてある。
言い方間違えたわ。 MDSN Libraryのwfopenの仕様に / が使えますって書いてあったのか? 書いてないなら使うな。wfopenがリファクタリングついでに実装変えたらどうするよ
wfopenは自作してある。_wfopenはマイクロソフト製。
この関数ならば、32767文字程度のパスまで作れるはずだ。やってはいない。 コード FILE* wfopen (std::wstring fname, std::wstring opt) { int flg, att; std::wstring fn=fullpath( fname ); att = GetFileAttributesW(&fn[0]); if(att==-1) { if( opt[0]==L'r' ) return NULL; else att=0; } if(opt[0]==L'a' || opt[0]==L'r' ) flg=OPEN_ALWAYS; else flg=CREATE_ALWAYS; HANDLE hd=CreateFileW( &fn[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , flg , att , NULL); return _wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), &opt[0] ); }
>>349 が始まりで、_wfopenは長いパスに対応していないから
wfopenという新規の関数をつくったというわけ。
普通のヘッダにwfopenという関数は入っていない。
>>397 >>394 >APIに渡す前に\に変換しているわけだが・・・
一体どこで変換してんだよwww
>>386 std::wstring fullpath
>>375 なんかもう要求仕様が
>>341 と全然違うようだけど、本当に想定してるシナリオはどんなのなんだ。
だが便利そうだ。 何かの時に使うかも試練。
C++ってwchat_tの扱いがいい加減だよな。mainからしてwchar_t版無いし、 いくつかの関数はマルチバイト版しか無いし、なんでこんなやる気無いんだろ。
そのへんは0xでちょっとはマシになるんじゃないの?
C 0xって何なの?来る来る詐欺なの?具体的に何が凄いの?
C 0xなんてねーよ。 C++学園の人々でも読んどけ。
揚げ足取りじゃなくて真面目に聞きたいんだが・・・・ C++ 0xって何が凄いの?
使い手がすごい
>>404 linuxがUTF8とEUCをスタンダードにしているからだろ。
あえてwchar_t関数を用意する必要がない。
文字の取り扱いが不便だけど、UTF8もEUCを1バイト単位だから。
誰が凄いって言ったんだ? 凄いと思うかどうかなんて人によるだろ 主観混じりの言葉に踊らされてないで自分で調べろよ
C++0xのchar16_tとchar32_tじゃないと使い物にならないと思うがなあ wchar_tなんてサイズが処理系定義だし
サロゲートや合成文字に正規化などがあるから キッチリ対応しようとするとややこしい BMPでもヒドイことになってるしなあ
windowsXP以上で動作するやつが良いです。BCC developerをエディタに使いたいです。
コンパイル時間はなんとGCCの1/9の速度。 たとえば、待ち時間が一回6秒違えば、10回で一分。600回で1時間変わります。 ちりも積もればで作業時間が短縮できます。 なのでビルドしてほしいです。 Compilation Speed TinyCC 2.27s GCC 20.0s
CコンパイラでSTL/Boostを使いたいと?
GCC やBCC につられて、TCCはC++コンパイラかと思った。 C++動かないならいらないや
コンパイル時間がBCCより速くて、STLが動くコンパイラは何かありますか。
コンパイル速度の向上は、プログラマーからコーヒーブレイクの時間を奪った 許さない! 絶対にだ!!
巨大プロジェクトだとすげー時間かかる いつも漫画読んでるわ
完成品をコンパイルするならいくら時間食っても寝ている間に出来ますが。 自作中のコンパイル時間を短くするために爆速コンパイラをみつけたいです。
最適化オプション全て切ったら速くなるかな?
早くなるがhello worldが2MBになる
動作確認てきればいいんで速いやつあげてください。
並列コンパイルの速度を上げるためにRAMを8G乗せた。
TinyCCをC++のコンパイラだと思って頓珍漢なことをいう人は、余程のうっかりさんか怠け者さんだから、 コンパイル時間の短縮を考えるよりも、 APIリファレンスを丁寧に読むとかロジックを慎重に考えるとかしてバグの作りこみを減らすほうが ずっと効率的だと思うが。
C言語を知らない世代なんだよきっと。
そのうちC++もそんな言語もあったねとか言われてるのかな
C++よりCの方が長生きするだろう
命名規則そろえたり、使わないメソッド封印する目的でstlやboostのアダプタ作るのってちょっと神経質すぎるかな?
>>434 それはありだと思うよ。
STLにdequeがあるのに、あえてstackもあるのはそういう意味だと思うよ。
C→組み込み用、OS用 C++→アプリ作成用 という感じで棲み分けが進みそう
うちではwinアプリ作成用はC++からC#になって来ている
C→64kbyte以下の組み込み C++ 組み込みからWinアプリまで何でもござれ。 C# 客先仕様Winアプリ こんな感じか。
まあ最近のオーバースペック気味のPCには少し性能を落とす傾向がある C#がぴったりなのかもしれんなあ 開発コストやスピードが半端なく安くて速いし
C#やるぐらいならPythonでいいじゃん
それはないな。C#はwindowsならどのパソコンでもうごくとおもうが Pythonは追加ソフトが必要。 C#は特にコンパイラ入れなくてもwindowsディレクトリに入っているかも知れないほど 身近な物
IronPythonいいよね
namespace aaa { class Boo { bbb::Foo foo; // 定義がない }; } namespace bbb { class Foo{}; } この状態を前方宣言で解決できるでしょうか?
無理です
namespace aaa { class Boo { bbb::Foo* foo; // 定義がない }; } namespace bbb { class Foo{}; } こうだった。
namespace bbb { class Foo; } namespace aaa { }
>>441 C#も.netランタイム入れなきゃならないけどね。
pythonで書かれたsvnクライアントインストールしたときはインストーラひとつで済んだけど。
>>440 最近のC#はジェネリックスもサポートしたしそれなりに使えるよ。でもtypedefとconstが無いのには泣かされるけどな。C++の代わりにはならないか。
>>439 フルタイムで働くC++エンジニア育てるのはメリット大きいけど結構大変なのはあるね。
>>386 だけど。これでオープンするとファイルが途中までしか読み込めない。
解決方法わかりますか
>>448 だけど。あれこれやったけど修正できず。
FILE*経由するのをやめることにした。
既存の関数は長いファイル名使えないし
>>386 はうまく動かないし
きわめて安全に使えるファイル操作ライブラリないですか。
36767文字のパスが読み込めて、装備も良いやつです。
451 :
448 :2010/05/22(土) 23:45:16
抜き出すとここの部分。実サイズと読み込みサイズが変わってしまう。 int main(){ wstring fn=L"aaaa"; int n; HANDLE hd=CreateFileW( fn.c_str() , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_ALWAYS , 0 , NULL); FILE* fp=_wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), L"r" ); fseek(fp,0,SEEK_END); n=ftell(fp); cout<<n<<endl; fseek(fp,0,SEEK_SET); string s( n,'\0' ); n=fread(&s[0],1,n,fp); fclose(fp); cout<<n<<endl; return 1; }
>>451 http://homepage1.nifty.com/herumi/prog/gcc-and-vc.html#LARGE_FILE
453 :
448 :2010/05/22(土) 23:54:23
どうすれば、実サイズと読み込みサイズが一致しますか。 サイズは100K以下ですが失敗します。
もしかして: テキスト (変換) モード
455 :
448 :2010/05/22(土) 23:59:51
このコードでも駄目ですが。"rb"指定。 出力。 3256 実 2974 読み込み #include <windows.h> #include <string> #include <iostream> #include<io.h> using namespace std; int main(){ wstring fn=L"aaaa"; int n; HANDLE hd=CreateFileW( fn.c_str() , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_ALWAYS , 0 , NULL); FILE* fp=_wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), L"rb" ); fseek(fp,0,SEEK_END); n=ftell(fp); cout<<n<<endl; fseek(fp,0,SEEK_SET); string s( n,'\0' ); n=fread(&s[0],1,n,fp); fclose(fp); cout<<n<<endl; return 1; }
HANDLE -> FILE* の変換失敗か、変換後のファイル操作で通常とは異なる移動しているのでは思ってます。
>>455 経験上、俺は標準ライブラリのシークは信用してない。
CreateFileWをFILE*にしないでread write seek を自作した方が確実か。
本格的なファイル操作はAPI使った方がいい。
C言語fopenの互換はやめて、API使ってfstreamの互換にすることにした。 全関数を作らなければならなさそうでそれならfstreamに合わせた方が楽なので。
ファイル位置取得してintにぶち込む馬鹿って・・・ LP64/LLP64であぼーん
>>457 単に君が CRLF ←→LF 変換を理解してないだけでは
>>461 seekなどしなくても、途中までしか読み取れないんだが。
実サイズ1M以下で値は知っているとして、これで失敗するんだ。
int main(){
wstring fn=L"aaaa";
int n;
HANDLE hd=CreateFileW( fn.c_str() , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_ALWAYS , 0 , NULL);
FILE* fp=_wfdopen( _open_osfhandle ( (intptr_t)hd, 0 ), L"rb" );
string s( 1<<20, '\0' );
n=fread( &s[0], 1, 1<<20, fp );
fclose(fp);
cout<<n<<endl;
return 1; }
>>462 バイナリモードでもはまることがあってな。
aaaaが2つあって違う方読んでんじゃねーの? 俺のVisual C++ 9の環境では正しく動いた。
>>455 その例だったら目で追えるでしょ。
freadで読んだ中身を1byteずつ表示してみて、aaaaの中身をバイナリエディタで見て比較したら、どうなってるかはっきりしない?
ディスク上のサイズと実ファイルサイズを取り違えてたり…さすがにないか
fstreamに似たやつつくってるけどうまくいかない。 4G以上、32767文字までのパスを扱える部分だけ 拡張出来ればいいのだが。 すでに作ってあるやつ無いの?
win32apiには64ビットでサイズやシークができるapiもあるよ
fopenかfstream互換で 4Gと長いパス使える完成がほしいです。 自分で作ってるけど手間掛かる。バグってる。
QtとかwxWidegetsのようなフレームワークには良いのは無いか?
>>470 手持ちのVC6で正常と思われる動作をしたよ。
ホントに抜粋じゃなくて
>>455 のコードだけでおかしくなるの?
それならPCが壊れてるんじゃあ…
テストコードがバグってりゃ世話ないよな
テストコードのテストコード書けばおk
∩ ∩ | | | | | |__| | / 一 ー\ 人人人人人人人人人人人人人人人人人人人人 / (・) (・) | < テストコードのテストコードがバグってたら > | ○ | < どうすればいいの? > \__ ─ __ノ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
最後のテストコードはプログラマの頭脳だが プログラマの頭脳もバグってるからやってらんない
4G対応、32767文字パス対応、元関数より高速を目指します。 Read WriteはこれだけでAPIいらず目指します。
>>477 iostream側じゃなくてstreambuf側を何とかするのが普通じゃないか
operator*をオーバーロードするときに、 a=b*c; となっていると、bはthisポインタで使うことができて、cは引数で持ってくると思うのですが、 b*cの値をaに入れるにはreturnを使うしかないのでしょうか?
コピーコンストラクタっていうやつでは
それは初期化だけだな。=をつくればいいんでは。
return *this;で参照返すのか
b::operator*(c){ return *this;} a::operator=(b){ ... } でいいんだろ?
A a = b*c; ならコピーコンストラクタが、 A a; a = b*c; なら代入演算子が動く 両方とも実装すればいい デフォルトで問題ないなら実装は不要だが
>>484 >>485 ああ、なんかそんな気がします。ちょっと考えてみます。
ありがとうございました
>>484-485 いやいや、二項の operator * で *this をいじったり返したりしちゃだめでしょ。
うは、かぶったごめん。
* と *= のどちらか一方が実装されていれば、 もう一方もそれで実装できる friend A operator*(const A& a, const A& b) { A c = a; return c *= b; } A& operator*=(const A& b) { A c = *this * b; return *this = c; } これ定石な まあ、処理に無駄が多い事もあるけど 実装の手間は小さい もちろん、どちらか一方はちゃんと実装するんだぞ
493 :
477 :2010/05/23(日) 19:31:41
テストしやすいように、コメントアウトの部分の書き換えだけで動作するようにしてみる。 #include <fstream> /* #include "fwstream.h" #define fstream fwstream */
>>494 サンクス
fp>>str; fp<<str;;のやり方調べたけどわからんかった。
メンバ関数なら出来るけど互換性が無くなるんだよな。
<<をメンバ関数としてオーバーロードすれば出来そうだけど。 fstreamが入出力を受け付けている型を全部書くしかないかなあ。
>>495 friendでoperator<<をオーバーロードするのくらい基本だろ?
まあそもそもstreambufの方を弄る方が正道だが
書き込んだらわかってきた。 テンプレートで任意の型を受け取って、ssacnf sprintfのC++版使えばいいか。 できそうな気はしてきたけど。
わからん
いい機会だから勉強すればいい
ちょうど、勉強したところだ MessageBoxで、いちいち、wsprintfとかで整形して出すのがめんどくさかったので msgbox << _T("ハンドル: ") << std::hex << hwnd << std::endl; って出来るようにした 調子に乗って、エディットコントロールも edit << _T("なんとか") << std::endl; edit >> text; 見たいな感じで扱えるようにしようと思ったら バッファとエディットコントロールの関係をどうすんのかとか 入力ってどのタイミングでバッファにコピーすればいいの?とか色々わけが判らなくなって挫折中...
>>502 stringstream 使えばいいんじゃないの?
<< >>スタイルは標準も採用してるとはいえど、気持ち的には邪道だろって思う
>>503 ありがとう
メッセージボックスは出来たんだ
エディットコントロールの場合、ユーザーが入力した内容とバッファの同期をどうするのかとか
一行のエディットコントロールと複数行のエディットコントロールで、バッファのフラッシュをどう制御するのかとか
そう言った所で悩み中
>>504 入門サイトのcinとかcoutを使えよってのを見てただけの時はそう思った
basic_streambufをカスタマイズして見たら納得した
cinとかcoutってのは禿げのジョークなんだよ。 演算子のオーバーロードを乱用するとこんな糞になりますって言いたかったんだよ。
google先生曰く、我々は演算子のオーバーロードを使いません。
googleなら out_string("text0").out_char('c').out_int(1).out_endline(); とかやってそう。
coutって中どうなってんの? <<ってビット演算となんか関係あるの?
何も関係ないからこそ<<が選ばれた ビット演算と誤解する文脈が発生しないように って禿が言ってた
>>508 普通にsprintf系を使ってると思いますが
>>511 -f関数はフォーマットの解析にメモリたくさん食べるから、std::coutのoperator <<みたいにtemplateの型特性で代替してると思うよ。
>解析にメモリたくさん食べる あまりにも無知
あまりにも無知ですみませんでした。 シビアな環境で開発していたのでつい印象で・・・
シビアな環境でtemplate? 意味が分からん
>>515 シビアな環境なら実行時解決よりコンパイル時解決のほうがいいのは当然だろ。
なんだ、メモリにシビアなのではなく、速度にシビアな環境の話か。 なら関係ないな。
printf() レベルの仕様の大きさだと、使いもしないコードがいっしょについてくるぶん メモリ(コードサイズ)的につらいという面もある。
たかだか数KBだぞ。DOS時代のprintfは。 当然printfなのだから、バッファ確保用のmalloc等も含めて。 ていうか、普通に8bit処理系だってsprintfくらい持ってる。 もちろん、それらを踏まえても、 その程度すらケチりたい環境というのが存在するのはわかっているよ。 でも、templateで各型毎に別関数の実体を作って持つのが容認されるような環境ならば sprintf程度がきつくなるとは思えないな。
俺の理解だと、templateはコンパイル時に解決され、不要な型のtemplateは実行時には存在しないはずだが...
521 :
sage :2010/05/24(月) 08:28:41
質問させてください。 子ウィンドウを管理するクラスを作り、メッセージループ等の処理を全てそのクラスで行いたいと思っています。 クラスには2つ関数があります。 クラスA: ウィンドウ・クラスの登録、CreateWindowを発行し子ウィンドウを作る クラスB: メッセージループの処理 ところが、クラスAのウィンドウ・クラスの登録の際、エラーが出てしまいます。 error C3867: 'Test::B': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&Test::B' を使用してください Bの関数をstaticで宣言すればエラーは発生しないのですが、なにか根本的に間違っている気がします。 アドバイスよろしくお願いいたします。
関数ポインタを要求してるところにメンバ関数ポインタを渡そうとしてるんだろうたぶん
523 :
521 :2010/05/24(月) 08:41:03
・実際のエラー箇所 wc.lpfnWndProc = B; 同じ書き方をしても関数Bがstaticだと関数ポインタになって、 staticでないとメンバ関数ポインタになる。 ということでしょうか?
staticでないメンバ関数を呼ぶためにはインスタンスが必要だろ。
525 :
デフォルトの名無しさん :2010/05/24(月) 23:27:56
#include <stdio.h> int main(void){ int n=1; float w,kei=0,heikin,max,min; while(1){ printf("%d件目のデータを入力してください-->",n); scanf("%f",&w); if(w==0) break; kei+=w; if(n==1){max=w;min=w;} if(w>max) max=w; if(w<min) min=w; n++; } heikin=kei/(n-1); printf("合計 :%.1f[kg]\n" "件数 :%d[件]\n" "平均値:%.1f[kg]\n" "最大値:%.1f[kg]最小値:%.1f[kg]\n",kei,n-1,max,min); return 0; } 最小値にループを抜けるための条件のW=0が代入されてしまいます breakでループを抜けたらその後の kei+=w; if(n==1){max=w;min=w;} if(w>max) max=w; if(w<min) min=w; の文は処理されないはずではないのですか?
526 :
デフォルトの名無しさん :2010/05/24(月) 23:31:31
いま人いないみたいなので他で質問します
>>525 ぱっと見だがheikinとやらの出力忘れてんじゃね?
それに最初に0が入力されたら未初期化のmax、minに触る事になるぜ
0除算は…平気か
C言語のお勉強?
scanfは仕様をよく知っていないと扱いが難しい
ファイル内の一部分をファイルとしてopenする方法ありますか? zip書庫のリードに使いたいのですが。 zipの中のzipの内容を解凍すること無く参照したいのですか゛。
ファイルを部分的に読みたい(内容に対して操作はしない)ってこと? zlibにファイルポインタとして、アーカイブの一部を渡したいってこと? それとも、zipアーカイブの中のファイルを解凍しながら直接読むストリームが欲しいってこと?
あるスコープで生成したらそのスコープ以外には保持されないことを保証するようなテクってある? newとかoperator&を禁止するのとこまでは考えたんだけどなんか不安です ちなみに用途は一時的なアダプタとかを考えてます
>>525 >>527 も触れているが最初に0が入力された場合、n=1 (初期値のまま)になるな。
その後のheikin=kei/(n-1);で0除算になる。
> の文は処理されないはずではないのですか?
なにをもって抜けていないと思うのだ?
> heikin=kei/(n-1);
これは heikin=kei/(n); に直すべき。0除算の問題もあるが、n は0以外の入力があった後、インクリメントされている。
つまり、n は入力個数に等しい。
なので、 heikin=kei/(n-1); の部分で-1するのは間違っている。
あと、最大値、最小値計算は if(n==1){max=w;min=w;} のほうほうでもまぁいいが、宣言時にでも必ず初期化しておくこと。
max=(もっとも小さい値)、min=(想定される最大値よりじゅうぶん大きい値)
それか、if(w==0) break; の前に持ってくるのでも良い。
if(n==1){max=w;min=w;}
if(w==0) break;
kei+=w;
if(w>max) max=w;
if(w<min) min=w;
どちらの方法を取るかで、最大最小値の表示が変わるが。
template <class T> void Func(T); int x; int &r = x; Func(x); Func(r); どっちでやってもT = intになるんだけど これって規格通りなの?
>>530 zipの中のzipの中のファイルにダイレクトにアクセス出来たら良いんですが。
普通にやると、一回zipを取り出さないと出来ないですよね。
なにか方法ないですか。
20Gのzipファイルは、2Gのzipファイル10個で構成されていたとすると 一個目のファイルの中身をロードするのに2Gぶん展開せずに 読み込めると良いんですが。
・書庫のフォーマットしらべて該当圧縮ファイルの先頭をさがしあてる。 ・その先頭から随時メモリに展開する。 メモリにロード出来ないならこんなんじゃね? ポインタの変わりにファイルの読み込み位置をシークするってことで。
ファイルをメモリにマップして、 先頭アドレスと後方アドレスを渡したら 順次にファイル名、サイズ、アドレスなどをリターンできるライブラリなどありますか? ここを自作するのがつらいです。
アドレスとサイズがリターン出来れば、 再びそれを同じ関数へ渡せば、階層ありのzipも読み込めるのですが。
>>537 ZIPのソースコードからコピーしてくればいいんじゃないかな?
BSDでころがってる。
サンクス 既存品は探しているながめているのですが。オープンしたファイルポインタを操作する様になっていて 書き換える部分が多くありげで成功するか不明です
>>531 型に対して、その型のインスタンスが自動変数しか存在しない事を保証したいの?
>>540 よく知らんけど、手っ取り早く済ませたいなら Susie のアーカイブプラグインに対応させてみるのも手じゃ?
ライセンスは分からんが。
>>533 ISO C++ 2003 5 [expr] p6
> If an expression initially has the type "reference to T", the type is
> adjusted to "T" prior to any further analysis, ...
ある程度大きいモノを作るときってnamespaceってつけたほうがいいのかな? 全クラスに定義するのめんどくさいなぁ
関数の被りを防ぐ目的だろう。 クラスでも防げるが。
547 :
デフォルトの名無しさん :2010/05/26(水) 15:58:07
色んなライブラリと併用したいならつけといたほうがいいよ。
ありがとうございます ボキャブラリーないからいい単語思い浮かばないなぁ
549 :
デフォルトの名無しさん :2010/05/26(水) 16:52:22
思いつかないときのネームスペース名はニックネーム+Lib、 恥ずかしいけどそんなにかぶらない。
fstream は入出力で開くことは出来ないんですか? これで書き込もうとしたらファイルが作られないです。 fstream fp ( fname, ios :: in | ios::out );
ios::in | ios::out は既にファイルがある場合に使うもの ファイルを作りたい場合は ios::in | ios::out | ios::app (既にファイルがある場合はそれをそのまま使う) ios::in | ios::out | ios::trunc (既にファイルがある場合は中身が消える) のどちらかを使う
JAVA風にフォルダ名=名前空間とか
フォルダとディレクトリって何が違うんですか><
名前空間はプロジェクト名がいいんでないかな
>>553 OSによって使い分けてる事もあれば、使い分けてない事もある
Windowsではディレクトリではないフォルダがある コントロールパネルとかマイコンピュータ
copy-constructor に explicit 付けるとなんでコピー障害起こるの?
ゼロックスか?
て
>>553 Windows3.1→Windows95の時に呼び方が変わっただけだろ
ディレクトリ ファイルシステムの要素 フォルダ シェル名前空間の要素 ディレクトリ以外にマイコンピュータやコントロールパネル等も含む
MSは用語のセンスが悪かったり一貫性がなかったりするんで 深く考えない方がいい
MacOSでもフォルダとディレクトリの関係は同様
今の流行は フォルダ でなく フォルダー メイン関数 は メーン関数 ですよ まぬがれる でなく まぬかれる ですよ
> 今の流行は フォルダ でなく フォルダー これはわかるけど、 > メイン関数 は メーン関数 ですよ これはキモイな。新聞の「メード喫茶」並に。 内閣府告示2号ってメーン関数とか言ってるの?
新聞でメイド喫茶って見たことない
それは、メインテナンスをメンテナンスといっているくらいですから。
範囲チェックのある配列作りたいのですが デバッグビルドでは範囲チェックつきクラスになって リリースビルドでは普通の配列になるようにすればどうすればいいですか? Array<int> boo(100); // int型で要素数100の配列 がリリースビルドでは int boo[100]; のように自動的に切り替わってくれるようにしたいのです。
vectorでいいだろ。範囲チェックは明示的に解除しないとvc++は常に入る。 マクロで制御せよ。
>>570 リリースビルドもチェック付きのままでいいと思うよ。
サイズ・速度ともに問題無かろう。
>>573 DSとかしょっぱい環境もあるので欲しいんです!教えてください!
DSってそんなしょっぱいのか
MSVC付属のSTLは、コンパイルされたコードを逆アセンブルするとすぐに分かるが、デフォルトでイテレータチェックコードが挿入されるようになっている。
Releaseでビルドしても、除去されない。イテレータチェックコードを消すには。次のように定義する必要がある。
#define _SECURE_SCL 0
たいていの場合、ファイルの先頭に
#ifndef _DEBUG
#define _SECURE_SCL 0
#endif
と、書いてやればいい。
http://anpcf.blog71.fc2.com/
assertは「プログラムが間違っている」という事を示すためのものでリリース時に消滅するのに、 汎用エラー処理マクロとして使ってる馬鹿がたまに居るから困る。
STLは使用出来ません! テンプレート使うとコード大きくなるし、オーバーヘッドも気になるので 普通の配列に変わるようにしたいんです!教えてください!
イヤだ!!
はじめからa[100]
#ifdef DEBUG #define ARRAY(type,name,num) std::array<num> name #else #define ARRAY(type,name,num) type name[num] #endif 最適化とか期待できないならマクロでも使えば? 俺だったら使わないけどw
templateで配列をラップしたクラスを作れ。 operator []をオーバーロードしろ。 ちなみにArray<int> foo(100);ではなくてArray<int, 100> foo;とかじゃないとint foo[100];には置き換えられないから注意しろ。
リリースビルドで動かなくなりそうだなw なんのためのデバッグビルドなんだか
#ifdef DEBUG ARRAY_AT(name,i) name.at(i) #else ARRAY_AT(name,i) name[i] #endif うん、これは使いたくないな
template< class T, int NUM > class Array { public: T& operator[](int index){ return a[index]; } private: T a[NUM]; }; こんな感じですか!これをどうやって置き換えるんですか!?
せっかくラップしたのにoperator[]でチェックはしないの? あとはマクロで普通の配列に置き換えるコード書けばおk
>>588 省略しただけです!マクロ教えてください!
>>590 それ配列にアクセスするマクロやないか!
宣言のマクロ教えてください!
宣言と言うかoperator[]内で、 #ifdef DEBUG { int n = sizeof(a) / sizeof(a[0]); if(index < 0 || index >= n){ throw(hogehoge); } } #endif return a[index]; とかしたら?
>>593 リリースビルドではテンプレートやクラスのオーバーヘッドを無くしたいんです!
マクロの定義の仕方くらい覚えようぜ
メモリの節約なら判るが。範囲チェック有り無しだけで全体の速度が低下するって 相当配列をぶんぶん回しまくっているか、たいした処理していない=配列を一巡して終了する程度 のプログラムだろ。 GUIとか画像処理とか他の箇所あれば大差は出ない。
もっとも簡単に作れる方法で作れよ。 こだわって良いところと意味ないところがある。 範囲チェックが常になくても、範囲外の読み書きあれば異常終了する。 デバッガでたどれば判明する。
>>596 メモリ4Mしかないんです!少しでも節約したいんです!
>>597 CodeWarriarで範囲オーバーしても何もおきません!
どこの設定をいじればいいんですか!?
一番メモリ食ってる部分から削れよ。アルゴリズムの変更の方が大きい。 windowsXPだけど、vectorと配列の違いってせいぜいexeサイズが80Kが200Kになる程度。 もっとも多く使っているところはないか
operator[]をinlineで宣言しろ
int *x=new int [100];をベースにして、 デバッグ版では、自作したoperator[]に渡せばいいじゃん。 上でも書いてあると思うが。マクロで書き換える。
>>601 クラス内の定義は自動的にinlineになるんじゃないんですか!?
>>602 難しくてわかりません!
int *x=new int [100];をベースにして、
ってなんのことですか!
クラス内に書かずにinlineされないから騒いでるのかと思ったけど違うのか?
こうだ。リリース版のみ。デバッグ版はマクロで作る。 #define ARR(T, A, n) T *A=new T [n]; int main() { ARR(int,x,10); // intt型配列を10個用意する。 }
>>604 テンプレートってクラス内にしか書いたことありません!外に出せるんですか!?
>>605 なんで動的にメモリ確保してるんですか!しかも解放してないじゃないですか!
テンプレート使うと不要にサイズがでかくなるからいやなんだろ。 リリースでは使わず、デバッグでは使えばいい。
>>608 だからその方法を最初から聞いてるんじゃないですか!オロローン!
動的確保の方が低メモリ環境優しい。必要なときにとって解放できる。 コンパイル時に決定しているx[100]を使うと、固定サイズメモリの確保が必要になる。 動的にすれば解放可能
またいつものやつか
>>603 どうしてそんなに「!」をつけるんですか。
>>608 いやいや、この場合使うケースと使わないケースでコストを全く同じにする方法があるから。
>>594 inlineでリリースモードだとreturn a[index];しか残らないからオーバーヘッドはないよ。
>>612 あなた達が教えてくれないからハイテンションになってるんじゃないですか!!
教えてくださいよ!
こうしろと。 #ifdef DEBUG #define ARR(T, A, n) 自作した範囲チェック付きのクラスか、 範囲チェックある既存クラスを呼び出す。 #else #define ARR(T, A, n) T *A=new T [n]; #endif
>>613 まじですか!コンパイラはそこまで最適化してくれるんですか!
じゃあマクロでいちいち置き換える必要ないじゃないですか!
最初からそこ教えてくださいよ!
vectorに範囲チェックが入る環境ならばこうだ。 #ifdef DEBUG #define ARR(T, A, n) vector<T> A(n); #else #define ARR(T, A, n) T *A=new T [n]; #endif
>>617 解放処理はどうするんですか!
デバッグとリリースで違う解放処理いれないといけないじゃないですか!
デバッグでもリリースでも同じように使えないと意味ないでしょ!
>>616 ごめん・・・。マクロは置き換えじゃなくて特定のモードのみコード生成っていう事もできるから
文脈上気づくと思ってた・・・。まさかあなたがこんなに無能だったとは予想に反していたから・・・。
こうだ #ifdef DEBUG #define DEL(A) A.swap( vector<T>() ); <- Tはどう求めるのかしらんが #else #define DEL(A) delete(A); #endif
動的配列とスタック配置の配列を混同したいのか単にレンジチェックしたいだけなのかはっきりしろ
>>619 おだまりスカポンターン!
>>620 なんで動的に確保させようとするんですか!固定配列で充分なんですよ!
馬鹿は放置でヨロ
625 :
620 :2010/05/27(木) 23:09:45
実行時型情報で型は特定できるけど、vector<int> vector<char>はコンパイル時に 確定しないと駄目だ。int、charと一致するか調査して適切な解放すれば良し。
626 :
620 :2010/05/27(木) 23:14:21
int a[30000];とint *a=new int[30000];なら後者の方が速いだろ。 常に前者で確保すれば、初期の固定スタックが巨大化するため。
>>626 本当ですか?なんか嘘くさいです!
まあでも僕も巨大な配列は動的確保します!
まあそれはどうでもよくて欲しいのはデバッグビルドのみの範囲チェックなんですよ!
628 :
620 :2010/05/27(木) 23:19:56
617 620 626を組み合わせればいい。 動的確保でvectorの標準範囲チェックを使う
デバッグ版は大きめのメモリあるPCで動かすならば。 #ifdef DEBUG #define DEL(A) ; <- 空行でよし。 関数や括弧抜ければ自動開放すめため。 #else #define DEL(A) delete(A); #endif
template< class T, int NUM > class Array { public: T& operator[](int index){ /*範囲チェック*/return a[index]; } private: T a[NUM]; }; #ifdef _DEBUG #define ARRAY(type,name,num) Array<type,num> name #else #define ARRAY(type,name,num) type name[num] #endif ARRAY(int,a,10); a[5]=100; a[10]=a[5]; // エラー これでいいじゃないですか!動的確保はなんの為にしてるんですか!
type name[num] これ動的確保だろ
すいません!うちの地方ではヒープからメモリ取得することを動的確保と呼んでました!
>>630 T& operator[](int index)
{
#ifdef _DEBUG
/*範囲チェック*/
#endif
return a[index];
}
こうしとけばマクロで切り替える必要も無い。
template <class T, int N> struct Array { #ifdef DEBUG typedef CheckedArray<T, N> type; #else typedef T type[N]; #endif }; Array<int, 100>::type a;
>>633 なんでですか!?最適化が効くからパフォーマンスに差は無くなるんですか!?
何か、C スレにも C++ スレにも凄いのが居座ってるなw
直よりテンプレート挟むほうが遅いだろ
コード生成の結果が同じなら直でもtemplate挟んでも同じに決まってるだろ。
>>632 コンパイラによっては、配列取得時に変数での確保は無理。
実装によるが、スタックが少量しかなければヒープから持ってくるだろ・。
同じか、遅いだな。 いつでも最適化されるとは限らない。
>>640 コンパイラが勝手にヒープから確保するんですか!?ほんとにそんなことあるんですか!
>>638 ,639,641
どっちなんですか!
643 :
デフォルトの名無しさん :2010/05/28(金) 00:02:37
>>642 > コンパイラが勝手にヒープから確保するんですか!?ほんとにそんなことあるんですか!
あるよ。
どこから確保しろなんて規定はない。
GCCは動的確保とは別なようだ。最大確保数が動的の方が上だ。 #include <stdio.h> #define N 270000 int main(){ //double x[N]; //int n=N; double x[n]; double *x=new double [N]; printf("ok"); getchar(); }
645 :
デフォルトの名無しさん :2010/05/28(金) 01:08:49
template <class T> class Serializable : public T, public ISerializable { public: Serializable() : T() {} template<class A0> Serializable(A0 a0) : T(a0) {} … template<class A0,〜class AN> Serializable(A0 a0,〜AN an) : T(a0,〜an) {} }; というのはどうか。
>>579 コード大きくなるってどうやって確認したの?
>>570 つーか boost::array で FA だな。
ム板は本当によく釣れますね!
釣れるというか、本人が馬鹿を晒してるだけなのにそれを叩いてる人に「釣れた」というのはちょっと日本語がおかしいとしか
>>646 参照・const参照を適切に切り替えてくれないのはこまらね?
はっきり言ってdispatchするだけならconst referenceで十分だよ。 Serializable(hogehoge(), fugafuga()); なんて事もできるし。 T内部でreferenceを持つために引数が非constなreferenceだったらどうしようもないけどw template <class T> class Serializable : public T, public ISerializable { public: Serializable() : T() {} template<class A0> Serializable(const A0 &a0) : T(a0) {} … template<class A0,〜class AN> Serializable(const A0 &a0,〜const AN &an) : T(a0,〜an) {} };
DSでstlもboostもさんざん使ってるけど何の問題もない。
配列は
>>648 と同じくboost::array(可変長なら当然vector)。
templateでコードが膨張するっても、サウンドやグラフィックと比べりゃたかが知れてる。
手書きしたとしてもどうせ同じくらいのサイズになるし、下手をするとtemplateを使うよりでかくなる。
標準ライブラリも、いまどきのは基本的に膨張対策されてるから問題なし。
654 :
デフォルトの名無しさん :2010/05/28(金) 08:34:02
名前空間とクラスの違いがよくわかんね
655 :
デフォルトの名無しさん :2010/05/28(金) 08:42:29
名前空間とクラスの違いがよくわかんね 関数名が同名で衝突するから名前空間を持たせる。 その前にクラスの名前が違えば別によくないですか? 連レスすみません。
クラスの名前が衝突する可能性がある
名前空間の名前が衝突する危険はないんですか?
そんなこといったらきりがないと思います
だったらクラスの名前が衝突しないように注意すれば充分じゃないですろか。
外部のライブラリ使う場面あるじゃないですか
じゃあこの事業は廃止ということで
boostのライブラリ化求む 1h、1libで高速ビルドのやつ
正直stlの名前空間はでかすぎると思うの
今一度、プロジェクトを洗濯致したく候。
ああ、選択の自由は大事だ
クラスは新しい型を宣言してその型のインスタンスを生成できるけど名前空間は単にスコープ解決演算子で空間解決するだけじゃん
667 :
デフォルトの名無しさん :2010/05/28(金) 14:49:50
インナークラスなどでネームスペースのような運用をすることをさしてるんだと思われ。 おれはやらないけどな。
インナークラスは前方宣言ができなくて #include 必須になっちゃうからダメだ。
名前解決のタメだけなら名前空間で過不足ないが、インナークラスはヘルパ作るのに結構使うし
private なら #include とか関係ないから問題ないな。
サブクラスすべてに対してnew以外での生成を禁じる方法はある?
無い
左様でござるか
C++にはfinalキーワードっていうのがないからね。
コンストラクタ隠して、factoryで何とかします
にんにん
こうですか!?分かりません><; class hogehoge{ private: hogehoge(){ ... } hogehoge(arg0_type arg0, arg1_type arg1, arg2_type arg2){ ... } public: static hogehoge *create(){ return new hogehoge; } static hogehoge *create(const arg0_type &arg0, const arg1_type &arg1, const arg2_type &arg2){ return new hogehoge(arg0, arg1, arg2); } };
char a[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; int b = *(int*)&a[0]; int c = *(int*)&a[1]; ってやるとcの値が0x22554433ってなるんですがどういう現象なんでしょうか?
エンディアンでぐぐれ
680 :
デフォルトの名無しさん :2010/05/28(金) 22:04:48
>>679 ググッたけどよくわかりません!
>>680 環境はDSです!もうちょい詳しく教えてください!
charとintではアラインメントが違う。更にintのエンディアンも言語では規定されていない。 ビッグエンディアンならデータ配置は0x55443322となり、リトルエンディアンなら0x44552233となるはずだが、 実際はa[2], a[3], a[4], a[1]の配置になっている。 これはそのDSの処理系とやらがビッグエンディアンでなおかつアラインメントが原因でエラーが発生しているのだろう。
684 :
デフォルトの名無しさん :2010/05/28(金) 22:12:32
バスエラーとかにならないんだな。
ところでさっきからDSで粘着してるやつは釣りに必死だから放置しとけ。
>>683 DSはリトルエンディアンです!
じゃあint型は4バイトアラインメントで配置しないとうまくキャスト出来無いってことですかー!
4バイトアラインメントじゃないアドレスからint型にキャストするにはどうすればいいんですか!!!
アラインメントを揃えた組み込み型に値をキャストしてビットシフトで代入すればいいよ^−^
688 :
デフォルトの名無しさん :2010/05/28(金) 22:15:59
>ビッグエンディアンならデータ配置は0x55443322となり、リトルエンディアンなら0x44552233となるはずだが、 何で16ビット単位を仮定してるんだ?
ビックリマンうぜー
umai
ビックリマン コーヒー チャッカマン
692 :
デフォルトの名無しさん :2010/05/28(金) 22:24:05
>>686 int c = a[4]<<24|a[3]<<16|a[2]<<8|a[1];
補数表現もしらないのにプログラミングしてんのか。
695 :
デフォルトの名無しさん :2010/05/28(金) 22:28:43
>>963 unsigned int uc = (unsigned int)c;
きっと printf("%d してるから無意味さ
ところでエンディアンは関係ないんですか!!?
エンディアン問題回避でビット演算しろって言っているんですよ^^
699 :
デフォルトの名無しさん :2010/05/28(金) 22:41:17
>>697 関係あるけど、リトルって決まってるんだよね?
アク禁解けて変なのが湧いた
ARMって32ビットのRISCなんだろ? この手のCPUってSHやMBとかもそうだけどエンディアン切り替えられるんじゃない? それよかエンディアンの問題というよりアライメントの問題じゃね? ARMって偶数番地やワードアクセスの制約とかないの?
エンディアン言ってるのは一人だけだろ
704 :
デフォルトの名無しさん :2010/05/28(金) 22:49:31
エンディアン切り替えたらOSが動かなくなったりするだろ。
char a[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; int b = *(int*)&a[0]; int c = *(int*)&a[1]; b 0x44332211 // 非常によくわかる。リトルエンディアンだから c 0x22554433 // エンディアンのせい?アラインメントのせい? ってなります! エンディアンの関係がよくわかりません!
関係性はねえよ
707 :
デフォルトの名無しさん :2010/05/28(金) 22:54:09
>>705 > c 0x22554433 // エンディアンのせい?アラインメントのせい?
0x55443322にならないのは、アライメントをまたぐから。
>>706 じゃあなんでエンディアン言い出したんですか!混乱するでしょが!
ごめん混乱させるためにわざと言ったwww
710 :
デフォルトの名無しさん :2010/05/28(金) 22:56:57
int型のエンディアンによって リトルエンディなんならこうするし int c = a[4]<<24|a[3]<<16|a[2]<<8|a[1]; ビッグエンディアンならこうするから int c = a[1]<<24|a[2]<<16|a[3]<<8|a[4]; エンディアンが関係ないわけじゃない。
>>710 お前の頭の中にはシフト演算しか無いのか
712 :
デフォルトの名無しさん :2010/05/28(金) 23:00:41
713 :
デフォルトの名無しさん :2010/05/28(金) 23:02:15
こうしなきゃダメってこと? int c = (int)a[4]<<24|(int)a[3]<<16|(int)a[2]<<8|(int)a[1];
すでに
>>682 で教えてくれてる人がいるじゃん
それとCPUのマニュアルぐらい読んでアーキテクチャ確認しろよw
715 :
デフォルトの名無しさん :2010/05/28(金) 23:07:45
717 :
デフォルトの名無しさん :2010/05/28(金) 23:16:59
おk。確認しただけ。
>>705 無茶なキャストしといて結果に何か期待するのが間違い。
キャストなんかしてるからエンディアンだのアライメントだの心配しないといけなくなる。
期待している動作があるなら素直にそのとおりのコードを書けよ。
安全で確実なファイル操作目指して開発してるけど。 WinAPI使ってfstream互換関数作るだけでずいぶん苦労かかるな。
本物のfstreamもwinAPIつかってるんだっけ?
>>720 というかC++の入出力ライブラリはOSのAPI使わないと実装できないのばかりだろ。
pimplパターンに最適なスマポを考えるとしたらどういう設計にするのがいいかな 既存のスマポシリーズだと帯に短し襷に長しって感じでどうもしっくりこない
boost::shared_ptrが襷に長しなのは分かるが、boost::scoped_ptrで帯に短しなのはなんで?
>>723 ボディクラスが自動生成したコンストラクタ・デストラクタ・代入を使うとバグになるから空でもcppに書かなくちゃならなくてめんどくさい
fstreamはいろいろと未完成度が高い。 WinAPIと同等の性能・機能を発揮して、fstreamと互換動作するやつは重要だ。
>>724 不完全型かどうかで定義が変わって欲しいと言うこと?
不完全型かどうか取得ってメタプロ的に可能なんだろうか
728 :
デフォルトの名無しさん :2010/05/29(土) 17:01:16
C++の既存のライブラリーのtraitsクラスで XXXtraits<int>.zero();ってやると0が返ってくるようなクラスありますか?
>>724 shared_ptrはその不完全型も正しくdeleteできるんじゃなかった?
その他のクラスにもデフォルトコンストラクター規定が必要になるからだめです。
じゃあdefault constructorがないclassをXXXtraitsに与えたらどんな動作を期待してるの?
template<class T> struct XXXtraits{ static T zero(){ return static_cast<T>(0); } };
自分で作る前に既存のライブラリーあったら手間がはぶけるので きいてみただけです。
is_integral, is_floating_point, is_pointer ならコンストラクタを呼ぶ、でいいんじゃない
もちろん。 特殊化以外はデフォルトコンストラクタよぶ
零元が定義できる型なら0から変換できることを期待してもいいんじゃないだろうか というわけでstatic_castに一票
FILE * src; dword unknown; dword filenum; HEADER * header; int i, j; src = fopen( archive, "rb" ); fread( &unknown, sizeof(dword), 1, src ); fread( &filenum, sizeof(dword), 1, src ); header = (HEADER *)malloc( filenum * sizeof(HEADER) ); fread( header, sizeof(HEADER), filenum, src );
ベクトルクラスが0から変換できるように作られてるとは思えない
プログラムは仮定が少ないほどいいんだからね。
あああ、間違えて送信してしまった 初心者スレでもなさそうだったから書き込むの辞めようと思ったのにorz せっかくですので… 字数制限で結構省略してしまっていますが… srcから7byte目まで変数に読み込むということは分かったんですが HEADER * headerという宣言がどういう働きをしているのか分かりません。 FILE *みたいなのはググれば出てくるのですが、HEADERというのは出てきません。 よろしければお願いいたします。 mallocも正直あまり分かりません…
>>742 HEADERはそのファイル固有の先頭のヘッダー情報の構造体と思われる。
ここはC++なのでCはCのスレで質問したほうが反応いいと思うよ。
>>743 cppでコンパイルされてたのでここに書き込んだのです。
すみませんでした。
どうも返答ありがとうございます。
おかげで謎が解けました。
HEADERで検索をかけてみたところ、最初の方で宣言されていました;;
どうやら見落としていたみたいです。
mallocも理解できそうなんで、大丈夫そうです。
ありがとうございました。
オブジェクトの実体をSTLコンテナに入れるときって、 以下のような感じだと、obj1とobj2のコンストラクタが呼ばれて、 push時にコピーコンストラクタが呼ばれて、 スコープから出るときにデストラクタが呼ばれるので3手間かかりますよね? vector<obj> v; obj obj1(...); obj obj2(...); v.push_back(obj1); v.push_back(obj2); オブジェクトのポインタを入れるなら、コンストラクタ1回で済みますけど、 自分でdeleteしないといけないですよね? vector<obj*> v; v.push_back(new obj(...)); v.push_back(new obj(...)); 自動でdeleteしてもらおうと思ったら、 boostのポインタコンテナ使うのが普通なんでしょうか?
バッファリング無し FILE_FLAG_NO_BUFFERINGを 付けないとWinAPIでファイルロード速度が低下するのが定説だったけどいまは直ってるぞ。 最新版のwinSDK、コンパイラいれてみそ。 これで面倒なクラスタサイズを気にすることなくかける。
ガベージコレクト入れとけ
>>745 shared_ptr使うのが普通
c++0xなら一手間ですむ。
v.push_back(obj(...));
obj1,obj2がpush後不要ならc++0xで以下のようにムーブセマンティックを使うと1手間ですむ。
v.push_back(std::move(obj1));
C++0xでムーブが導入されれば std::unique_ptrが使える
stlはコピー作るしかないとおもっていたよ。これは良いことを聞いた。
>>750 元の値が残ってるんだけど。これは正しい動作なんだろうか。
int main(){
vector<string > v;
string a="aaaaaaaa";
string b="BBBBBBBB";
v.push_back(std::move(a));
v.push_back(std::move(b));
cout<<a<<" "<<v[0]<<endl;
v[0]="CCCCCCC"; v[1]="DDDDDDDD";
cout<<a<<" "<<b<<endl;
return 0;
}
754 :
753 :2010/05/30(日) 00:59:44
とりあえずmoveは用意したけど実態は非対応でコピーしているってことですか
moveした後のものを使ったときの動作は未定義で 2010だと使うと死んだような気がするんだけど 場合によるのか
>>753 VC10で試したけど、ムーブはされてるようだけど。
どんな結果がでた?
デバッガーで見て内部のバッファーに残ってるというなら
string a="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
string b="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
で試してごらん。
文字列が短いときと長いときでは格納方法が違うようだ。眠いのでライブラリのコードは追ってない。
結果から見ると、文字列が短いときはstring内に格納されていて、長いときはヒープに格納されていたって事じゃないか?
stringってそんな事やってたのかw 知らなかった
758 :
753 :2010/05/30(日) 01:27:21
これでもaは残ってるけど。普通に全部出てくる。 int main(){ string a; for(int n=0; n<512*1024; n++) a+=('0' + n%10); vector<string > v; v.push_back(std::move(a)); v.resize(0); cout<<a<<endl; return 0; }
sizeof(string) が32。 stringでけーよ。これから気をつけよう。
>>758 VC10ではaは空になるよ。
STLが右辺値参照に対応して無いんじゃないの?
VC++2010のSTLは右辺値参照対応してるよ
762 :
753 :2010/05/30(日) 01:36:58
古いコンパイラだからな。すまん。
うん、
>>760 でVC10のSTLは右辺値参照対応してるからムーブされてaは空になってる。
>>753 ,758ではなんでaは空にならないのは何故かなって話。
まず753がどのコンパイラ使ってるかから始めないと まあ対応が微妙なコンパイラ使ってるってだけだろうけど
765 :
753 :2010/05/30(日) 01:44:04
Embarcadero C++ 6.21 for Win32 Copyright (c) 1993-2009 Embarcadero Technologies, Inc. だった。
767 :
753 :2010/05/30(日) 01:51:10
C++ Builder 2009/10 っていうやつだがな。 R-Value References yesだけど出来ないな
文法は対応してるけど ライブラリが対応してないとか? あるいは表が間違ってるんだろうか
int&& a=1;っていう宣言が通るか試してみればいい ダメなら文法的に非対応 通るならライブラリが非対応なだけだからSTLportかなんか入れれば使えるかもしれない
moveは別にsrcになるオブジェクトを空にする事は要求していない(たぶん) stringは参照カウントとCOWを使ってる実装があるから moveする際にきちっとポインタとかを0にして空のオブジェクトにするのも 参照カウントだけ増やして元のオブジェクトには何もしなくても(つまりただのコピー) どうせ消えるオブジェクトだからおんなじだよってことじゃないの? 短い文字列の場合newのオーバーヘッドを避けるためヒープじゃなくて固定長のバッファを使うからmoveの動作も異なる ということだと思う むろん確認はしていない
右辺値参照はソースを壊してもいいよってことだし、ムーブセマンティックもそれに倣うから空にすることは強制ではないだろう。
>>773 VC10のヘルプには載ったけど。左辺側が全てlessだったらtrueか。これはべんりだな。標準かどうかはしらないけど。
ということは !(a<b)かつ!(b<a)かつa!=bになるvectorの組みがあるわけか なんかいやだな
ん?文字列の比較と同じっぽいから問題なくね?
>>774 規格で lexicographical_compare の結果になると規定されている
lexicographical_compare は要するに strcmp(a, b) < 0 と同じような動きをするもの
配列の[]は、long long を入れられますか。64bitに対応したいのですが。 その場合は、型は何が標準になりますか。
>>779 size_t。
一般的な 64 bit コンパイラなら sizeof(size_t) == 8 になるはず。
サンクス。32bitと64bitを切り替えてくれる型なんですね。初めて知りました。
符号付きの ptrdiff_t も忘れずに
c++だとstd::size_tのほうがいいのか?
size_t も std::size_t も別に変わらんと思うが
整数の移植性含めた扱いが未だに良く分からない
>>783 <stdio.h>ならsize_tか::size_t
<cstdio>なら::std::size_t
現行のC++なら<cstdio>を推奨
cstdioにしたところで typedef implementation-defined size_t; namespace std { using size_t; } とされるだけやで
<cstdio>が内部で<stdio.h>をインクルードしているかどうかは処理系依存。 C++しかサポートしてないコンパイラなら<stdio.h>ではなく<cstdio>しか存在しない場合もある。 <stdio.h>はC++ではなくてCのライブラリだからな。C++である以上<cstdio>を使えということ。
規格見た 確かにstd内って書いてあるな
これ押さえておけば十分?これ以外に重要な整数型ある? size_t 符号無し整数 32/64bit自動切替 DWORD 符号無し整数 32bit long long 符号付き整数 64bit int 符号付き整数 32bit
DWORDとか失笑
ある程度の大きさがあればいいや→int 大きさがきっちり決まってる方がいい→int8_t、int16_t、・・・ ビット集合→uint8_t、uint16_t、・・・ unsignedは基本的には使わないこと
なんじゃそりゃ 意味分からん
winapiの参照引数値の標準がDWORDになってる事が多いが。
C++の規格にDWORDなんてあると思ってんの?
>>793 (x>=0)&&(x<10000)がunsignedだと(x<10000)だけですむじゃん。
>>798 unsignedは整数拡張でバグを生みかねないからsignedを使うべき
>ビット集合→uint8_t、uint16_t、・・・ と言いつつunsignedは使うなとか意味分からん
どんなバグだよ
unsignedにすべきものをsignedにすると 整数拡張以前の問題でバグになる部分が多々あると思うが
具体例を言えよ具体例を
unsigned int a = 1; signed int b = -1; assert(b < a); // -1 < 1 しかし assertion failed
比較で気をつけるのは常識じゃない
どうしてもって場合以外はunsignedは使わない
なんか後退した
むしろ必要ない限りsignedを使わないようにしてる
unsignedのintが0の時に--したらどうなるのっと……
結局値域に従って型を決めるという基本に忠実にするだけだよ
>>808 警告見て signed に修正するんじゃないの?
>>812 intが-2147483648のときに--したらどうなるのっと・・・・・・
>>812 2^(CHAR_BIT*sizeof(unsigned int))-1 になると規格で規定されている
気をつけろで済むならいいけどtemplateだとめんどくさいし0xになるとautoとかあるしハマるやつ結構でるとおもうよ ループカウンタにautoで面倒なイテレータの型記述をしないで済むぞやったー!とか言ってる奴もすでにいるしね 不要な場合の非負整数をつかわないと統一しておけばバグは確実に減らせる
ここでは^はxorじゃなくて累乗ね
>>815 そこはMIN_INTと書くべきだな
規格では処理系定義となっている
MAX_INTになるかもしれないし、例外が発生するかもしれない
>>818 そうやって std::vector::size との比較でキャストしまくりになるわけですね
分かります
警告が出るから問題ないんですけどね
>ループカウンタにautoで面倒なイテレータの型記述をしないで済むぞやったー!とか言ってる奴もすでにいるしね これ何か問題なん?
イテレータで符号付きがどうのこうのの問題発生しないしな
テンプレートだと「めんどくさい」とか・・・ どんな型でも大丈夫なように作れよ
>>825 ごめんよ
規格通りに書こうとすると説明面倒くさくて
確かにlong doubleとか有効なビット幅と一致しない処理系多いし
整数型だってそういう事あるだろうしね
0xのautoは本来conceptsと一緒になってはじめて安全に使える代物だからな・・・
負数つかうほうがバグるだろ。 キャストしたら正から負になったりするんだから。
キャストしたらどうのこうのってのは 符号付きも符号なしも同じじゃ・・・
上位一ビットの取り扱いが違うが
>>828 突っ込んだら負け?のような気がするんだが
ちょっとはDSのことも考えて発言してください!
符号付きを符号なしにキャストしようが 符号なしを符号付きにキャストしようが お互いに表現できない数の領域で問題になるのは同じだろw
ていうかsigned unsignedの暗黙変換を禁止するidiomとかないの? C++民ならまずそういうの探すところから始めるだろ
警告で十分
>>833 符号なしへのキャストで範囲外の場合の値はどうなるか規格で定められている。
符号つきへのキャストで範囲外の場合の値は処理系定義。
838 :
836 :2010/05/30(日) 15:38:00
>>837 うん。 >828 とは関係ない。 >833 が「同じ」と言ったんで、そうでもないよ、と。
問題になる事に変わりはないと思うが
五十歩百歩ではないだろうか 負数を符号無し型へキャストしてるようなコードとは極力関わり合いたくない え、string::npos?(∩ ゚д゚)アーアーきこえなーい
キャストを極力減らせればどっちでもええ
google先生が言うには >表現しているのが実際には数値ではなくビットパターンであったり、 >2の補数オーバーフローを定義する必要があるとき以外、uint32_t といった unsigned 整数型を使うべきではない。 >特に、数値が負にならないことを示すためだけに unsigned 型を使ってはいけない。代わりに、アサーションを使うこと。 らしい
STL(vector string)のsizeがunsignedだ。 符号無しでは警告多く出る。
符号付きでは警告が多く出る、の間違いでは
そうそうそうだった
google先生は例外禁止だからそもそもSTLも使ってないでしょ STL使う普通のプログラムじゃsizeとの比較を考えてsize_tが増えるのは当然の事
>>843 あー、それウザイよね。
だからといって unsigned を優先したりはしないんだけど。
外向けのインターフェースでは signed で、内部では負の値のチェックのあとに unsigned に
変換っていうのがいいかな。 boost::numeric_cast とか。
自分はなるべくunsigned つかうがな。 たとえばcharを-128〜127で扱うより、0〜255のほうが便利。 unsigned char *p =(unsigned char *)str;などする。
サイズ扱うならsize_t使おうよ
indexにsize_t使うヤツは信用できない
それ以外になに使うの
sizeとの比較で毎回キャストしてんのか キャストは基本的に悪というのが分かってんのかね
キャストなにもデータ変更しないだろ。 charとintとかサイズが異なるものは変化しているかもしれないが。 符号有り無しはコンパイル時だけチェックしていて 実行時には確認してないだろ。
なにがいいたいかといえば、キャストで性能低下、演算コストが増えるって事はないって事。 サイズと異なるキャストは除く。 char -> int など。これは前方に0が3つ入らないとまずいからな。
assert(idx < size_); これでは、まちがって引数に負の値を入れてしまい、なおかつ現在のサイズが非常に大きい場合にエラーを検知できない intにしていれば負数を検知できるので間違いが少なくなる そしてintとunsignedでどっちがアンダーフローのミスを犯しやすいかというと当然unsignedだ indexにはsignedを使うべきということがよくわかったね
>>856 変数宣言もしっかり書け、なに言ってるのかサパーリ解らん
size_tに負数を入れる奴の方が信用できねぇw
>>858 そのとおり!
信用できないやつがいるからこそ負数を検知すべきなんだ
勉強になったね
>>859 uint32_t idx = -1;
uint32_t size = 10;
assert( idx < size );
>>856 idxがsignedの場合、idxが負でもアサートされねーよ
>>854-855 お前何も分かってないな・・・
キャストはアップキャスト以外は常に危険性を孕んでるんだよ
C++型のキャストが何であんな面倒くさい形してるかよく考えろ
負数はよく使うからsingnedで統一してる。 せっかくだから俺はgoogle先生を信じるぜ!
暗黙変換のことも「キャスト」って言うの?変じゃない?
誰が言ってるの?
誰も言ってない
>>864 Cのキャストは何もしないから危険なんだろ。
いかなる型でもコンパイラがエラー出さなければ、強制で指定された型と見なされる。
実行時に動的な変化はしない。
コンパイル時に既になんの型か決まってしまう。
854 855は正しいだろう。
符号付き←→符号無しの変換は暗黙変換されちゃうから、そいつらについての議論で 「キャスト」した場合に限って特に言及されてるのが変な気がしたんだ。
size_tが64bitだって話からここまでしょーもない話題で盛り上がれるおまいらを尊敬する
警告出るような暗黙変換はキャストより危険なので キャストした方がマシ しかし、それよりはキャストが必要ないように組むのがベター
>>869 何を根拠にそんなことを言ってるの?
signed/unsigned の変換で専用の関数を呼び出すような実装だって規格の範囲内だろ。
> char -> int など。これは前方に0が3つ入らないとまずいからな。
>>874 is系関数は罠の塊だな
キャスト必須だ
int値をunsigned値の引数にチェックなしで渡してるのが問題なんだろ アホか
int test1(int index){ static std::vector<int> a(0xc0000000); // 適当にとったすごく大きいサイズ assert(index < a.size()); return a[index]; } こうですかわかりません
assertを汎用エラーチェックマクロと勘違いするなよ
#include <cstdio> #include <cstdlib> #include <cassert> #define SIZE 200 struct Hoge { void operator [] (unsigned idx) { assert(idx < SIZE); std::puts("...do something..."); } void operator [] (signed idx) { assert(0 <= idx); (*this)[static_cast<unsigned>(idx)]; } }; int main(void) { Hoge hoge; hoge[100]; // hoge[-1]; // hoge[200]; system("pause"); return 0; } ていうかこれでいいじゃん 既存のコードをいちいちラップするのメンドクセーけどさ
>>877 毎回チェックしろっていうなら singed 引数にして中でチェックしてほしい。
そうは思わんかね?
>>883 std::vectorはそうなってないし
そもそもオーバーフローを起こしている時点で問題 オーバーフローが起こる状況ならチェックを入れるのが当然
std::vectorを使ってないということか
お前らstd::vector好きすぎるだろ。
vector使いこなしてこそC++ そして俺はBetter C
生ポの変わりにスマポ、 動的配列はvectorでとかなら分かるんだが 負数を入れてしまう間違いを防ぐためだけに あまり使うことが無いとはいえ、最上位の1bitを 犠牲にしてしまうのはC/C++としてどうなのか 安全性を取るか、無駄を省くか、ここらへんは好みによって 違ってくる
無符号整数と実数で用は足りると思うんだけどな。
size_tを使うのは負数を入れる間違いを防ぐためじゃないよ サイズやインデックスの値域は 普通に符号なしでなければ表現できない・・・環境もあるってことだ
gcc4.3以降なら-Wsign-conversionで警告させることができるな。 vc++はわかんね。
>>894 残念ながらVCはでないね。
MinGWもインストールするべきかなあ?
seekpとseekgってなんで二つ用意してあるんですか? どっち使っても変わらない気がします。
istreamとostreamを継承してるから両方あるだけ どっち使っても構わない
pはput、gはgetの略な
サンクス read writeで別々に動作したりするのかと思ったりして、試してもそんなことなく。 判らなかったんです。
std::istream&にキャストして使うならseekgしか使えないし std::ostream&にキャストして使うならseekpしか使えない (dynamic_castすれば別だが) まあそういう事だ
ここまでsize_typeなし
size_type宣言が面倒くさい
assert使う人って何考えてるんですか? C++なんだからlogic_error例外出しましょうよ普通に
バグにlogic_error例外出す男の人って・・・
べつにassert的なマクロの中でabort()するかわりに例外投げてもいいと思うけどね レイヤが違うというならそれはまーそうだが
908 :
デフォルトの名無しさん :2010/05/30(日) 22:28:39
マクロきもい
>>891 超汎用目的である std::vector なら符号無しのインデックスもまぁやむをえない事情かも
しれないとは思うが、それを基本としてユーザーコードが真似るべきかというと、そうでは
ないだろうと。
>>904 ライブラリ実装のバグなんかで呼び出し元に logic_error 飛ばされても困る。
logic_error 飛ばすライブラリの実装は不完全だろ
std::vectorを使う結果 それに付随して符号なしを使わざるを得ないケースがあるということだ
符号なしで統一しろよ
符号なしなんか使ってられるかよ
デフォルトが符号付きか符号なしかの議論じゃないのかそれは
バグを発見しやすくする為に符号有りにするのか リリース時にバグがあっても問題ないように符号有りにするのか 値の入力元でチェックすればエラーチェックが伝播することは ないんだけど、全部チェックしたほうがいいんだろうか? でもそうすると普通の配列とか使えなくなるから ラップしないといけなくなるな…
符号付きは人間の利便性に合わせただけ。 機械にマッチしているのは符号無し。
919 :
デフォルトの名無しさん :2010/05/30(日) 23:44:24
機械にマッチしてるのはGF(2)の拡大体
アクセス出来る範囲が違ってしまうだろ。 4Gのファイルにアクセスするには、符号無ししかない。 符号無しでも範囲チェックは入れられるが。 []関数作って、ある程度以上かをチェック。
forのカウンタはsize_t使えば何の問題もない
vector使えば勝手に範囲チェックしてくれるんだがな。
>>923 中の人のチェックじゃ、サイズが非常に大きいときに[]に負数を渡した場合、エラーを検出できないんだよ
vectorのサイズを決めるときに検出できないんでしょ
64ビット時代では「サイズが非常に大きい時」は物理的にあり得ないんだがな 16エクスビバイトだぜw 32ビット時代でも、メモリは4Gのせられても OSの制限から全部使えなかったりするので 結局あり得なかったりする
ファイルストリ−ムなら?
>>924 size_tに統一すれば負数は使わない。
template <class Num> unsigned int check(Num n) { static_assert(std::numeric_limits<Num>::is_integer, "err"); static_assert(sizeof(Num) <= sizeof(unsigned int), "err"); assert(Num(0) <= n); return n; } std::vector<hoge> v(check(-10)); // assert std::vector<hoge> v(check(20.55) // static_assert v[check(1000000000000000)]; // static_assert std::vector<hoge> v(check(10000)); // Cool! v[check(100)] = hoge(); // Oh! fantastic! みなさんもこれ使っていいですよ!
> static_assert(sizeof(Num) <= sizeof(unsigned int), "err"); sizeofと値の表現長は全く関係ないんだが。 有効ビット数が得られないのと同じで、厳密に判定するには処理系ごとの規定する範囲をテーブルやtraitsに持って比較するしかない。
std::numeric_limits でいいかな? あ、 max(), min() は static_assert で使えないんだっけ?
constexprが実装されてるなら使える
安全整数キャストってboostにも無いのか?
numeric_cast
boostに無いものなんて無いよ
借金して、無いものはない。キッパリと同じか
今日の十代しゃべり場inム板はまだですか?
もう終了しました
無理なものは無理。この真理が通じない業界があるらしい。
プログラマの口から出る「無理」は8割が「めんどくさい」と同義。
Visual C++ では、C++/CLI 対応の場合、クラスからオブジェクトを生成する 場合「gcnew演算子」を使いますが、ネイティブC++の場合 new 演算子を使い ます。このあたりごっちゃになってよくわからないのですが、どう違いがあるのでしょういか?また現場ではどちらが良く用いられているのでしょうか?
DOTNET任せか、Cランタイム任せかでは。 僅かでもDOTNET混じれば、DOTNETに統一した方がメモリ管理にむだが無くなるんでは。
>>942 new演算子は単にヒープからメモリ確保の要請をOSに出して、その結果として要請された大きさを持つ空間の頭のアドレスをポインタとして取得でき、
使い終わったらdelete/delete[]でOSに確保要請したメモリ空間の管理権限を返します(開放)。
つまりnewによって取得したアドレスは、プログラムが管理しなければいけないメモリ空間のアドレスです。
そしてgcnewですが、OSの持つガーベージコレクタという自動メモリ管理機能に開放の管理を委ねます。
具体的には、プログラムの指定したタイミング(もしくはリソースが競合しなければプログラムの処理フローと無関係なタイミングで)
OSが「どこからも使用されていないメモリ空間」を検出し、自動でdelete/delete[]に当たる処理を行います。
C++のnewでとある型ExTypeの大きさを持つ空間をヒープから持ってくる場合、実行時に「それがポインタであるか」とか「組み込み型であるか」などといった情報は不明です。
全てコンパイル時に検査してしまうからです。これはメモリ解釈を比較的自由にやらせてくれる余地と無駄な情報を省くメリットがありますが、
OSから見ればどんな使われ方をするか分からないので柔軟な管理ができません。
そこでgcnewという処理系依存の機能を提供しているわけです。これ以上はCLIスレでどうぞ。
>>943 thanks
dot NET-->C++/CLI
C Runtime -->Native C++
こんなかんじですか、なるほど、例えば、メモリ管理のムダを考えなければ、
CLI のコードの中に、 NativeC++ もかくことができるのか。
>>944 大変詳しい解説ありがとうございました。なるほど、メモリ管理がポイントですね。
>>945 できないよ。
gcnewされるクラスTが内部でNativePointer pを持っていたらTの破棄時にpから先をたどれない
>>947 ポインタ、その破棄時、
そのポインタ について、なかなかおもいつかなかったです。そう考えるのですね。なるほどです
CLIでは、NativePointerをとにかくweek用に使いたいからref classの中にも入れさせろとは思うな。
twitterのプログラマクラスタで自慢しまくれ
これライセンスはなんだ?
C.C. 0
#ifndef _fwstream_h_ 規格書10ぺん読み直してこい
_fwstream_h_ // '_'で始まる識別子 #include <malloc.h> // #include <cmalloc>ではない class stringadr : public std::string // std::stringの継承 // 0 ではなく NULL の使用 // DWORD その他WinAPI の使用 // 「fstreamをfwstreamで置き換えれば使える。」 "..." が L"..." ではないので使えない // Cスタイルキャストの使用 // std::size_t が size_t ではない // 識別子"motosize" (笑)
boostでもstdでもいいけどshared_ptrってweak使わなくてもメモリ確保しちゃうじゃん あれ循環しないってわかってる時には使わないようにしたいんだけどそういうオプション無いの?
細かいところだけどintとlongの使い分けがよくわからんな。ビット数保証したいなら __int32と__int64の方が気持ち良くない? | long a = (long) (iti - b * (1 << 31)); | int n = SetFilePointer ( fp, a, &b, FILE_BEGIN ); 何コレ。DWORDをintに突っ込むな。
規格屋はなぜthisを参照にしなかったのか。アホだったのか
thisがreferenceではなくpointerなのはD&Eに理由が書いてあったけど具体的な内容はわすれた
intとlongとDWORDはどれでもいいけど。警告・エラー出たら書き換えた。 ほぼすべての箇所で32bit符号なし整数よく64bitいるのはファイル位置とサイズの所。 std::stringの継承は良くないの? テストコードで動いたからアップしたけど。手直ししてみるよ。 ライセンスはCC0で。
>>959 日本語版の47ページに書いてあるじゃん
「thisを導入した時はまだ、リファレンスというものはなかった。」
おれっちメンバ呼ぶときは必ずthis->つけちゃう方なんやけど〜
thisは「* const」なの?
>>960 #include <iostream>
#include <string>
class A : public std::string {
public:
~A() { std::cout << "~A()" << std::endl; }
};
int main() {
std::string* p = new A;
delete p;
}
昔はthisを書き換えられた気がする 今はできないから*const
どっちもデストラクタ呼ばれるな #include <iostream> #include <string> using namespace std; class A : public std::string { public: ~A() { std::cout << "~A()" << std::endl; } }; class B { public: ~B() { std::cout << "~B()" << std::endl; } }; int main() { A* p = new A; delete p; B* q = new B; delete q; }
std::mapである条件を満たした値をまとめて消したいんだけど、 そんな関数,ファンクタ,定形句、そういったものって何か無いかな?
>>966 std::string* にして delete できない
std::for_each()にラムダ式を組み合わせるとか
typedef std::map<T> Map; Map m; for (Map::iterator it = m.begin(); it != m.end(); ) { if (...) { m.erase(it++); } else { ++it; } }
>>968 stringと関係無いだろ。
#include <iostream>
using namespace std;
class A {
public:
A() { std::cout << "A start" << std::endl; }
~A() { std::cout << "A end" << std::endl; } };
int main() {
void *p = new A; delete p; }
>>971 おいおい
仮想デストラクタって知ってるか?
>>960 こんなレベルじゃ怖すぎて使えないなwww
メモリバッファとアドレスのペアを内部で使うだけでnewとかdeleteしてない。 あと、他所でもメモリ管理は手間かかるからstringで代替えしてる。 用途的にはこれでも一緒だけど、アクセスが一段階増えてみた目良くない。 class string_adress { public: string buf; long long adress; }
newで生成してるわけではないから別に問題はないが 何故継承した
string_adress x; と宣言したとき x.buf[n]とx.adressより、 x[n]とx.adressの方が良いからだよ。
>>970 やはり自分でループ書いて一個一個やるしか無いのかな
Erase-Removeイディオム的なものがあったらいいなと思ってたんだが…
クラスとして動作するstringに変数を追加して その追加した変数を外部からしか操作しないってのは 俺には違和感大有り 見た目悪くても構造体にすべきだろう
別々の定義でもいいんだけど。用途的にはこれでもいいけど。 string buf; long long adress; 関数での受け渡しの時に一変数の方が見やすい。 見た目、書く量減らすには継承になった。駄目か?
なにが問題なのか分かってて、隠蔽もできてるんなら使っても良いよ
変数はDWORDとsize_tと__int64に統一するか。 あとfopenも追加しよう。 DWORD (unsigned long) はWINAPIの要請で使うしかないな。 HTTP(S)も同じ操作にしようと思っているところ。
>>979 コード公開したいなら他人が弄り易いコードにすれば?
仮想デストラクタとか多重継承とかを考えれば普通そこで継承はない。
コード見る限り、addressはinaddrとoutaddrみたいな単独の変数にしてもよかったんじゃないか? まあstringadrでもいいけどせめてprivateにしよう。 というかなぜprivateにしなかったし。 itiって最初何のことか分からんかった。
構造体でいいんじゃない
ここまでadressのスペルミスに言及なし。
set<int> age; age.insert( 0 ); set<int>::iterator itr = age.find(0); if( itr != age.end() ){ *itr = 1; // 38行目 } をコンパイルすると、 hoge.cpp:38: error: assignment of read-only location ‘itr.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = int]()’ というエラーが出てくるのですが、原因が分かりません。 どうしたら解決できるでしょうか?
templateの練習のために自作スマポ作ってみた物の やっぱりboost使っておけばいいじゃんという結論に落ち着いてなんだかなぁ 自作スマポ練り込んで使ってる人って居ます?
989 :
デフォルトの名無しさん :2010/06/02(水) 15:54:26
多分だけど、setは格納してる値でソートするから、 外部から書き換えられるとソートされた 状態を維持できない(かもしれない)。 たから書き込み禁止にしてるんじゃないかな。 対処としては、検索して見つかったのをeraseして、新たな値をinsertする、とかじゃないかな。
991 :
989 :2010/06/02(水) 16:05:28
GCC だからそうなった。 GCCについて part9
>>988 scoped_ptrに動的削除子とdeep copyの機能持たせただけのやつは自作してけっこう使ってる
自作でshared_ptr以上のものってなるとしんどいけど、shared_ptrじゃオーバーだろって時は自作してもいいんじゃね?
>>987 std::setのイテレータはconst_iteratorってちゃんとエラーに出てるじゃん
insert()で入れなされ
994 :
デフォルトの名無しさん :2010/06/02(水) 18:26:30
オブジェクトの配列を引数として渡すことはできるでしょうか? { Object obj[8] func( obj ); } func( Object *obj ){ obj[0]->getobj(); obj[1]->getobj(); } みたいな、わかりづらくてすみません。
>>994 当然
オブジェクトのリファレンスも渡す事ができる
template <int N>
func(Object (&obj)[N])
{
}
>>994 おっとまった
obj[0]->getobj();
obj[1]->getobj();
これはおかしいな
obj[0].getobj();
obj[1].getobj();
こうか
obj->getobj(); だろ
ツリー構造のテンプレートライブラリってあります?
setとか2分木の可能性 触れる部分は少ないが 参考にはなる
というかリファレンスじゃないと渡せないだろ。 即値で渡すと配列型からポインタに変換されてしまって動かないし、要素数書いても無視される。 一方でリファレンス使えば勝手に変換されることもないので、 テンプレートで要素数推論してObject[N]型へのリファレンスで渡せば問題なく通る。
void func(int *p, size_t n); template <size_t N> void func(int (&a)[N]) { func(a, N); } 通はこうするよ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。