【初心者歓迎】C/C++室 Ver.50【環境依存OK】
1乙です。 これか?
4 :
デフォルトの名無しさん :2008/02/28(木) 00:08:26
age
あっちの方がかっこよかったけどこっちのが早いからこっちか。
6 :
デフォルトの名無しさん :2008/03/14(金) 21:41:58
class Point { public: Point(); void setPoint(Point p); void printPoint(); private: double x, y; }; このクラスって、x,yに値を代入できますか?
7 :
デフォルトの名無しさん :2008/03/14(金) 21:47:04
double d; d=1.2-1.1 0.09999999999 d=1.0/10.0; 0.1 この違いは何故((((;゜Д゜)))?
基本的に浮動小数点数では実数を正確に表せない 浮動小数点 誤差でググるんだ
9 :
デフォルトの名無しさん :2008/03/14(金) 21:54:07
>8 いえ、それは分かるのですがどちらも答えが0.1で循環小数になるのに なぜ割り算の方だけ正確な答えが出るのか聞きたいのです。
10 :
デフォルトの名無しさん :2008/03/14(金) 22:01:11
>>9 1.0 とか 10.0 は誤差なく正確に表現できるが、
1.1 とか 1.2 は正確に表現できない (誤差が含まれている) から
誤差というのはだんだん蓄積するので、もともと誤差が含まれているもの同士を演算すると、さらに誤差が大きくなる
ん、こっち先使うのか?
質問です int *num = new int[100*100*100]; これを0で初期化したいのですが どうやればいいのでしょうか forループで回す以外の方法ありますか?
memset
17 :
デフォルトの名無しさん :2008/03/14(金) 22:07:35
>12 あ、演算結果じゃなくてそっちのほうの誤差だったんですね。
>>14 std::fill, std::fill_n
スタックに確保して自爆しよう!
>>14 int *num = new int[100*100*100]();
22 :
デフォルトの名無しさん :2008/03/14(金) 22:51:11
i--; なんとなく顔文字に見える(--;)
えー
配列で要素を確保する場合、デフォルトコンストラクタなら要素ごとに呼べるよ。
26 :
デフォルトの名無しさん :2008/03/14(金) 23:16:30
>>23 intクラスのデフォルトコンストラクタを呼ぶという発想もできない奴
>>14 配列 new なんて忘れて std::vector にするのがいいよ。
28 :
デフォルトの名無しさん :2008/03/14(金) 23:23:51
間違ってVisual C++スレで聞いてしまったのでこちらで。 class test{ int i; test(){ test(1); } test(int i){ this->i = i; } } こんな感じでコンストラクタをオーバーロードし、コンストラクタからコンストラクタを呼び出すことはできないのでしょうか?
確かできないはず C++0xでは出来る様になるらしい
>>28 現行の規格ではできない。 C++0x が普及するまでは private な初期化関数を
使うのがベスト。元々代入でいい(初期化にこだわらない)なら、違いは無い。
今はできない。けどC++0xにそういう話があった気がする。
32 :
30 :2008/03/14(金) 23:27:57
うは。みんな C++0x 待ち遠しいんだな。
33 :
デフォルトの名無しさん :2008/03/14(金) 23:28:04
>>29-31 短時間で返答ありがとうございました。
初期化関数を検討してみます。
出来ないというのは嘘だな。 コンストラクタ内でコンストラクタを呼び出すことはできる。 しかし、JAVAのように望んだ結果にはならない。
placement newを使えばできるかも? new(this)test(1); とか いろいろ怖いけど
今でもコンストラクタは呼べたような気がする。 環境依存かもしれないが。 確かメンバ初期化子は無視されたはず。
呼べるけど今は一時オブジェクトができるだけじゃないのか。
ああ、そうなるのか。
superがあると確かに便利
superのコンストラクタは初期化子で呼べるけど、何か別のことを言ってる?
多重継承可能な言語でsuperはありえないな
むしろECMAScript風に配列を返せば
他人が書いた基底クラスに、こんな書き方がありました class Base { public: virtual void f() = 0; protected: Base() {} ~Base() {} }; 基底クラスのデストラクタは仮想にするべきなんですよね?でも、この基底クラスのデストラクタは仮想じゃない… 単なる書き忘れか?とか思ったんですが、よく見ると、デストラクタはprotectedになってます。ということは、 Base *p = new Derived(); delete p; // Base::~Base() はprotectedでアクセスできないのでコンパイルエラー となると思います。ちょっと混乱したんですが、こうすると、 「派生クラスをnewして基底クラスでdeleteができなくなる代わりに、仮想デストラクタにしなくても問題ない」ということでしょうか。 わざわざこうして仮想デストラクタにしない理由は、速度の理由でしょうか (それとも、new/deleteなんてしないで、普通にスタックに置いて使って欲しいっていう意味が込められてる?
あってる。 既定クラスでdelete出来なくなるかわりに、いちいち仮想関数が呼び出されるオーバーヘッドがなくなる。
Baseのポインタからインスタンスの破棄をしなくてもいい場合は処理速度を優先してそうする。 基本的に仮想関数を使うというのは、基底クラスからは静的には“見えない”関数を実行時に扱えるようにする為のもの。
C++のプログラムだけでラジオは作れますか? AMとかFMの?
プログラムを走らせるハードによるんでないかい?
48 :
デフォルトの名無しさん :2008/03/15(土) 11:17:00
ローカルでポインタのポインタを作る場合って、 2回newしないといけないのでしょうか? 例えば、下のようなことをしないといけないですか? int** getPointerPointer() { int i = 123; int* p = new int;//int値のためのメモリをロック(1回目) *p = i; int** pp = new int*;//intポインタのためのメモリをロック(2回目) *pp = p; return pp; } それともポインタのポインタだけnewすれば、 必要なメモリを全部ロックしてくれるんでしょうか?
>>41 単一継承している時だけ使えるのなら問題はない。
>>48 >ローカルでポインタのポインタを作る場合って、
>2回newしないといけないのでしょうか?
ローカル変数としてポインタのポインタを作りたいだけなら、int **p; と宣言するだけでいい。
>それともポインタのポインタだけnewすれば、
>必要なメモリを全部ロックしてくれるんでしょうか?
そんなことはない。自分でnewしたものしか確保されない。
そもそも
>>48 のコードを見ると、newしているとのはintとint*だけで、ポインタのポインタ(int**)はnewしていないが。
自分がやろうとしていることをうまく説明できていない、または
自分がその関数のなかで何をしたいのか整理できてないでしょ。
51 :
50 :2008/03/15(土) 11:46:16
>そもそも
>>48 のコードを見ると、newしているとのはintとint*だけで、ポインタのポインタ(int**)はnewしていないが
なんか変なこといってた。ゴメン、無視して。
何をやりたいのかよく分からないという点に間違いは無いから 完全に無視されても困るかな。 こういう関数があった場合、 void show(const int* const* array_2dim, int i_size, int j_size) { for(int i = 0; i < i_size; ++i) { for(int j = 0; j < j_size; ++j) { std::cout << array_2dim[i][j] << ", "; } std::cout << std::endl; } } こういう風に使うなら new なんて要らないし、 const int array0[] = { 1, 2, 3 }; const int array1[] = { 4, 5, 6 }; const int array2[] = { 7, 8, 9 }; const int* const array_2dim[] = { array0, array1, array2 }; show(array_2dim, 3, 3); こういう風に使うなら new を2回使う。 int** array_2dim = new int*[3]; for(int i = 0, n = 1; i < 3; ++i) { array_2dim[i] = new int[3]; for(int j = 0; j < 3; ++j, ++n) { array_2dim[i][j] = n; } } show(array_2dim, 3, 3);
ていうかロックってどこから出てきたの?
メモリの確保のことをロックとか俺用語使ってる気がする。
というと、もしかしてmalloc()はマ・ロック?
マルロック
えむ あ ろっく
memory allocation lock それをロックするなんてとんでもない!
59 :
デフォルトの名無しさん :2008/03/15(土) 16:03:21
マルチスレッド処理を勉強してます。 現在、別スレッドからメインスレッドで処理するときはPostMessageを使ってますが、 他によい方法はありますか。
良いかどうかわからないけど、自前で処理キューを作って メインループをMsgWaitForMultipleObjectsでまわすとか・・・
>>60 よくこの文章の意味が判ったなぁ。
>別スレッドからメインスレッドで処理する
普通に解るけど
マルチスレッドスレか Win32API スレに行った方がいいと思うが。
とあるメソッドの中で オブジェクトを生成してあれこれする時 newして操作するのと 一時オブジェクトとして生成して操作するのは どちらのほうが一般的なんでしょうか?
new する必然性があるなら new するし、 そうする必然性が無いなら積極的には new しない。
66 :
デフォルトの名無しさん :2008/03/15(土) 21:12:33
vectorで、循環しているやつをつくりたいときはどうすればよいですか? つまり、 vector<int> a(10); のとき、 a[10]と書いてa[0]の意味になってくれるとうれしいんですが。 いまは添字をif文で判定してます。
i が必ず正なら a[i % 10] でいける。
継承してoperator[]をオーバーライドすればいいんじゃね。 イテレータはしらね
仮想デストラクタでない vector の継承は危険だな。 内包して似たクラスを作った方がいい。
もしかしたらboost.circular_bufferでいいのかもしれない
71 :
48 :2008/03/15(土) 21:38:34
>>50 ありがとうございます。
ポインタのポインタはローカル変数で使うのでなく、
関数内で作った後、関数外の色んな場所で使います。
色んな場所で使うんですが、
中身を一括で変更しないといけない時があったので、
ポインタのポインタにしました。
52 は無視か・・・。
某RPGの白魔法風にメアロケとかなんかそういう呼び方ないの?w
75 :
48 :2008/03/15(土) 22:54:31
いや、無視したわけじゃないんですが。 イマイチ言わんとしていることがよく分かりませんでした。 下の用途でも、 int** array_2dim = new int*[3]; ←は、 int* array_2dim[3]; ←でいいんじゃなかと思うんですが。
>>75 配列のサイズがコンパイル時に決まるならそれでいいし、
コンパイル時に決まらないなら new するしかない。
new するしないかはやりたいことによって決まるのであって、 int** を使うから new を使うとかそういうことで決まるものではない。
コンストラクタの中で冷害が起きるとデストラクタは呼ばれるの?
オブジェクトの生成が終わってないのでデストラクタは呼ばれない。
まだできてないモノの後始末をどう付けろというのだ
でも構築済みのメンバ変数のデストラクタは呼ばれる。
>>79 構築済みの基本クラスとメンバ変数の分は呼ばれる
自分のは呼ばれない
一次元配列のアドレスを関数に渡して手を加えたいんだけど、 できれば例文を使ってやり方を示していただけませんか
>>79 他の人が書いてる通り、構築済みメンバのみ呼ばれる。
あと、コンストラクタから例外を出してはいけないという迷信を信じないようにね。
>>85 #include <iostream>
void add(int* x, const int* y, int size) {
for(int i = 0; i < size; ++i) {
x[i] += y[i];
}
}
void show(const int* x, int size) {
for(int i = 0; i < size; ++i) {
std::cout << x[i] << ", ";
}
std::cout << std::endl;
}
int main() {
int a[5] = { 1, 2, 3, 4, 5 };
int b[5] = { 5, 4, 3, 2, 1 };
add(a, b);
show(a);
}
>>87 ありがとうございます。メモ帳に保存して勉強します。
サイズ渡すの忘れてたよw add(a, b, 5); show(a, 5); な。
90 :
デフォルトの名無しさん :2008/03/15(土) 23:41:30
>>67-69 ありがとうございます。とりあえず67さんの方法でやってみようと思いますが、68と69さんの方法って
どうやればいいですか?いちおうこんな感じに書いてみたのですが、template <class T>
class cvector : public std::vector<T>
{
T operator[](int n) {
return this[n % this->size()];
}
};
91 :
デフォルトの名無しさん :2008/03/15(土) 23:43:06
http://pc11.2ch.net/test/read.cgi/streaming/1202224933/ 740 :ゴキ ◆KBolwFjGFs :2008/03/02(日) 16:10:33 ID:XSKtFMSK0
いつになったら五期鬼太郎43・44・46・47話うpしてくれるんですか><
750 :ゴキ ◆KBolwFjGFs :2008/03/02(日) 17:10:36 ID:XSKtFMSK0
いつになったら五期鬼太郎43・44・46・47話うpしてくれるんですか><
762 :ゴキ ◆KBolwFjGFs :2008/03/02(日) 23:15:47 ID:XSKtFMSK0
いつになったら五期鬼太郎43・44・46・47話うpしてくれるんですか><
772 :ゴキ ◆KBolwFjGFs :2008/03/03(月) 02:23:17 ID:FCp+FnG70
いつになったら五期鬼太郎43・44・46・47話うpしてくれるんですか><
811 :ゴキ ◆KBolwFjGFs :2008/03/04(火) 00:55:53 ID:4/B+VsKZ0
いつになったら五期鬼太郎43・44・46・47話うpしてくれるんですか><
assert(n >= 0); がないと危険だな。 まあそれはいいとして、 vector を継承すると std::vector<T>* v = new cvector<T>; とした場合に delete v; の動作が未定義だし、 vector<T>& に渡せるけど、 operator[] が仮想関数じゃないから危険だな。
this 使うなら (*this)[n % size()] だし、 operator[](n % size()) でもいいな。
いくらなんでも std::vector<T>* は無いだろw
int -> size_t public -> private
n に負の数を渡した場合のチェックが出来ないのが size_t の悩みどころだな。 リングバッファだと 「範囲外のインデックス」 ってのが存在しないから 0 <= n && n < size() なら有効・・・とかできないし。
リングバッファならむしろ負の数サポートが欲しいところ。 v[-1] == v[size()-1]
98 :
デフォルトの名無しさん :2008/03/16(日) 00:26:29
>>92-97 ありがとうございます。
アドバイスを総合して実装してみたのですが、コンパイルが通りません。
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class cvector : public std::vector<T> {
T operator[](const int n) const {
int index = (n >= 0) ? n : this->size()-n;
// assert(n >= 0);
return (*this)[index % this->size()];
}
};
int main(){
cvector<int> vec;
vec.push_back(11);
cout << vec[0];
return 0;
}
コンパイルエラーはこうです。
test.cpp:6: error: 'T cvector<T>::operator[](int) const [with T = int]' is private//T operator[](const int n) const {の行です。
test.cpp:15: error: within this context // cout << vec[0]; の行です。
どうかもうすこし教えてください。
>>98 エラーメッセージそのまんまだろ。何がわからないんだ?
private ってのは危険だから private 継承しろって意味じゃないのか
operator[]の前行にpublic:
102 :
デフォルトの名無しさん :2008/03/16(日) 00:45:09
>>100 private継承しようとするとpush_backが使えなかったので、public継承にしました。
>>99 これってどう継承してもよびだせないということですか?
class cvector -> struct cvector >int index = (n >= 0) ? n : this->size()-n; this->size()-nだとリングにならないよ (n >= 0) ? n : (size() - (-n % size())); あと、 と書くとレスに連続した半角空白を入れられる
operator[] が private だから呼べねーよ! ってコンパイルエラーだな。
負の数を認めない型の値の最上位ビットが立っているかどうかなら、 1 << (sizeof(type) * 8 - 1) とand取ってifすれば得られるぜ。
そこまでして符号無しにこだわる必要は無いと思うというか、 その時点で引数を符号無しにするべきではないと思うというか。
符号なしにしないとオーバーライドできない、っていうか、 operator[]はvirtualじゃないからオーバーライドできない。
ならオーバーロードで
そもそも vector を public 継承しようとしている時点であれというか。 vector とは性質的に別ものだから内包して自分でメンバ定義していくのが正しい。 単純な委譲で済む関数はインライン関数にしとけばインライン展開されるだろうし。 どうしても継承したいなら private 継承して、 size() とかそのままでいい関数は using する。
つうか普通このケースでは包含だよなぁ
111 :
デフォルトの名無しさん :2008/03/16(日) 01:42:27
質問よろしいですか? 0 1 2 3 4 5 6 7 8 このようになっている時にクラーメルの公式のように(掛け算ではありませんが) 1+5+6というふうにするにはfor文でどのようにすればいいのでしょうか?
int data[3][3]; とするならば int sum = 0; for(int i=0; i<3; i++) { int x = data[i][(i + 1) % 3]; sum += x; } // sum = 1+5+6 = 12
3つしかあり得ないならハードコーディングするのも手だと思う。 for 使うなら % だろうけど、逆向きの時は少し注意が必要(i が負になるとマズい)。
配列アクセス用のインデクステーブルを作るとか
115 :
デフォルトの名無しさん :2008/03/16(日) 02:05:33
>>112 ,113
すいません、言葉が足りてませんでした
配列は固定ではなくN×N行列で
ポインタを*paとする時
pa pa+1 pa+2
pa+3 pa+4 pa+5
pa+6 pa+7 pa+8
でどう求めるかということでお願いします
[i][(i + 1) % 3] を [i * N + (i + 1) % N] にするだけでしょ。
for 使うなら % だろうけど、逆向きの時は少し注意が必要(i が負になるとマズい)。
118 :
デフォルトの名無しさん :2008/03/16(日) 02:21:37
>>116 i=0 0*3+(0+1)%3 = 0
i=1 1*3+(1+1)%3 = 3
i=2 2*3+(2+1)%3 = 7
こうなるんじゃないんですか?
小学生からやりなお(ry
122 :
デフォルトの名無しさん :2008/03/16(日) 02:26:54
>>119 すいません勘違いしてました
どうもありがとうございました
毒餃子は中国工場内での混入がほぼ間違いなくなったよな。 濃度は3000ppmって。。漬け置きレベルらしいな。 シナはどこまでも外道。オリンピック開催させるなよ。
125 :
デフォルトの名無しさん :2008/03/16(日) 11:41:33
102です。以下のように実装してみて、動作することを確認しました。でも2点質問させてください。 (1)vectorを継承した方で、size()はusingsしておけばいいといわれましたが、やり方がわかりません。 でも知りたいのでどうか教えてください。 (2)同じくvectorを継承した方で、public継承するのはよくないと言われましたが、(繰り返しになりますが) private継承するとpush_back等のvectorクラスの機能が使えないと思います。ここはどうするべきなのでしょうか? template <typename T> class ring_vector { public: T operator[](const int n) const { int index = (n >= 0) ? (n % v.size()) : (v.size()-(-n % v.size())); return v[index]; } std::vector<T> v; }; template <typename T> class ring_vector2 : public std::vector<T> { public: T operator[](const int n) const { int index = (n >= 0) ? (n % this->size()) : (this->size()-(-n % this->size())); return std::vector<T>::operator[](index); } };
>>125 (1)レスを追ってないから知らん
(2)転送関数
Linux+gccでCPUの型番や周波数などを取得する方法を教えてください
128 :
103 :2008/03/16(日) 13:00:16
>int index = (n >= 0) ? (n % v.size()) : (v.size()-(-n % v.size()));
>>103 のは元のソースがreturn [index % size()];なので、それを前提としてたんだけど・・・。
return v[index];にするなら、負の数の方も、もう一度%しないと、
n == -size() のとき、return v[size()]; になっちゃうよ。
129 :
103 :2008/03/16(日) 13:02:20
return v[index]; を return v[index==size()?0:index]; にするのでも良いけど。
>>125 ring_vectorの方で良いよ。
継承するの変だと思うし。
system("cat /proc/cpuinfo");
クラスで場合によっては定義しない変数は宣言できますか? ありましたら、どうすればいいか教えてください。
template <typename T> class ring_vector3 : private std::vector<T> { typedef std::vector<T> parent; public: T operator[](const int n) const { int index = (n >= 0) ? (n % this->size()) : (this->size()-(-n % this->size())); return parent::operator[](index); } using parent::push_back; }; みたいな。
使わなくても定義は必要じゃね
だから、仮想デストラクタを持たないvectorを継承すんなよw
そろそろvirtualから離れようぜ
139 :
133 :2008/03/16(日) 13:48:13
何か問題が?
>>139 使い方によってはvectorのデストラクタが呼ばれないことがある。
141 :
133 :2008/03/16(日) 13:56:17
使い方?vector<T> *にキャストする話? 出来るの?private継承なのに。
>>141 定義をそれ以上いじらなければ問題ないっしょ。
std::vector<T>* p() {return this;}
みたいなメンバ関数を追加したりすれば、
privateな継承でも基底のポインタが得られるので、
単にprivate継承であるというだけで常に安心できるわけではない。
それをdeleteしたら吹くw
そんなメンバをつくって、しかもdeleteしちゃうような輩は、 vector<int> v;を使わせても delete &v[1];とかするだろうなw
イテレータは循環するようにしなくていいのか?
ちょw end()どこだよw コンテナじゃないんだし、いらないっしょ
どのイテレータをインクリメントしてもendと等しくはならない、とか
STLのアルゴリズムに食わせられないじゃん
>>134-135 extern BMPImgData bmpA;
extern BMPImgData bmpB;
class BMPImgData {
public:
HDC mHdc;
int w; //幅、高さ
int h;
int anmx;
int mv;
//・・・・
//↓bmpAには不要
POINT ptgt; //リアルマップ座標(移動)0~10
POINT tgt; //目標リアルマップ座標
POINT Root[MAX_MAPX][MAX_MAPY]; //マップ座標
//・・・
BMPImgData();
~BMPImgData();
};
多次元とか宣言すると不安で不安で。
もしかして宣言ってメモリ確保しなければ全然処理重くならないですか?
すげえ初歩ですが。
メモリを喰うのが嫌ならクラスを分けるか、 動的に確保するしかないかと
>>149 bmpAに不要なメンバを BMPImgData から除去して、BMPImgDataを継承した別クラスBMPImgData2にそのメンバを追加すれば?
BMPImgData bmpA;
BMPImgData2 bmpB;
もちろん、クラス名は適切に。
152 :
デフォルトの名無しさん :2008/03/16(日) 15:13:50
namespace AAA { void func() {} } class Hoge { friend void AAA::func(); }; とするとコンパイルできません。どうすればよいですか?
>>152 >どうすればよいですか?
コンパイルエラーのメッセージを書く。
そのメッセージについて
>>152 が何を考えて、何が分からないのかを書く。
エラーメッセージの内容を調べて無いなら、調べてから出直し。
154 :
149 :2008/03/16(日) 16:02:00
>^^ むかつくからやめろ
^^;
157 :
デフォルトの名無しさん :2008/03/16(日) 16:20:40
--;
(;:. @u@)
vectorやらlistを使用する際 コンストラクタで指定した長さ以上の要素を食わせるとどうなるのでしょうか?
ああ、すいません 要素数20のlistに21個目の要素を追加しようとするとどうなるのかなぁと
int型の変数をchar型の配列にするにはどうすればいいのでしょうか?
>>161 STLのコンテナは、追加はいくらでもやってよい。
コンストラクタで要素数を指定するのは、
あらかじめメモリを確保しておくことで、後から再確保するのを防ぐ、単なる最適化に過ぎない。
165 :
164 :2008/03/16(日) 18:17:49
すまん、reserveと勘違いした。 コンストラクタで指定した要素数は、ちゃんと要素が追加されるよな。
v[20] = 1; とかで追加した気になってるかもしれないから 「追加」 の定義をきちんと聞いておいた方がいいぜ。
>>166 それは既存要素に対する代入だろ。sizeには反映されない。
下手したらコンテナの整合性を壊す。
て、
>>166 は言いたいんだと思う。
>>162 やりたいことをもっと明確に説明しないと回答のしようが無い。
たとえば12345という値を持つint型変数があったとして、どのような状態のchar配列が欲しいんだ?
>>162 int型をchar型の要素数4(とは限らんが)の配列として扱うの?
それなら共用体になるが
ありがとうございます 共用体しらべてみます
>>170 エンディアンには気をつけてな
どうせsprintfとかいうオチだとは思うが
メッセージのファイルはあったか?あったらそれを直接クリックしてみな。
>>173 なかったです、正常動作している友人のプロジェクトフォルダを丸ごとZIPで送ってもらったら
DEBUGフォルダがありましたが、自分のほうでは生成されなくなってました
ウイルス・・・じゃないよな? 今までは正常に実行できてたんだよな?
ないってことは、コンパイルされた結果のファイルが無いんだな。 リビルドして、出力ウインドウにエラーメッセージがないか確認するべし。 プロジェクトのプロパティーページのリンクの項の出力ファイルのパスを確認しよう。その友人のプロジェクトが絶対パスになってないか?
VC2005 って Vista に対応してたっけ?
Vista対応パッチがあるという話は聞いたゾ。俺Xpだからよくわかんね
>>176 // test.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
これに
int main(void) { return 0;}
これを書き足してリビルドしたら
1>------ すべてのリビルド開始: プロジェクト: test, 構成: Debug Win32 ------
1>プロジェクト 'test'、構成 'Debug|Win32' の中間出力ファイルを削除しています。
1>コンパイルしています...
1>stdafx.cpp
1>test.cpp
1>コードを生成中...
1>マニフェストをリソースにコンパイルしています...
1>リンクしています...
1>LINK : 前回のインクリメンタル リンクで C:\Users\owner\Desktop\Documents\Visual Studio 2005\Projects\test\Debug\test.exe が見つからなかったか、ビルドされませんでした。フル リンクを行います。
1>LINK : warning LNK4067: エントリ ポイントがあいまいです。'mainCRTStartup' が選択されます。
1>マニフェストを埋め込んでいます...
1>ビルドログは "file://c:\Users\owner\Desktop\Documents\Visual Studio 2005\Projects\test\test\Debug\BuildLog.htm" に保存されました。
1>test - エラー 0、警告 1
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========
で、ぱっとみは何とかなったみたいです 再度printfをためしてみます 一旦ありです
えー
mainは一個でいいです。どちらか一方だけにしましょう。
182 :
デフォルトの名無しさん :2008/03/17(月) 04:09:01
イテレータを循環に、ってできるのですか?
演算子オーバーロードすればできるんじゃね?
自分でイテレータを作れば。
185 :
デフォルトの名無しさん :2008/03/17(月) 09:09:35
>>183-184 自分でイテレータってつくれるんですか?
あと、演算子のオーバーロードでできるんでしょうか?
できるっていってるじゃない。
187 :
デフォルトの名無しさん :2008/03/17(月) 10:44:58
>>186 もうちょっとだけ具体的に言ってみてよ。
189 :
デフォルトの名無しさん :2008/03/17(月) 11:09:18
独自イテレータのつ•く•り•か•た
質問すればいいじゃん
191 :
デフォルトの名無しさん :2008/03/17(月) 11:16:27
ググッたけどわかりませんでした。
class iterator {}; できあがり。 これ以上具体的な回答は、質問が具体的でない限りあり得ない。
ありえないのはオマエの禿頭
ムキになるなよw
ムケてるのはオマエの禿頭
ムケてないのか…
包茎で無能じゃ救いようがないよ・・・
198 :
デフォルトの名無しさん :2008/03/17(月) 14:39:59
包茎で無能だけど禿げてはいないぞ(怒)
しまった……全部に当てはまる……。
包茎で禿げてるから、無能と呼ばれないように頑張るわ……
包茎で禿で不能です
operator==とかの引数の対称性って手動で保守するしかないんですか? こういうやつ↓ bool operator==(const A& lhs, const B& rhs) {...} bool operator==(const B& lhs, const A& rhs) // これを自動化したい { return rhs == lhs; }
boost
>>202 Boost.Operatorsにまとめられている。
その例だと、Aがequality_comparable<A, B>を継承して、
operator==(const A& lhs, const B& rhs)を定義すれば、
operator==(const B& lhs, const A& rhs)とoperator !=が作られる。
205 :
デフォルトの名無しさん :2008/03/17(月) 22:56:40
大体の人はよく使う関数などをまとめた個人用ライブラリを作ってると思うのですが どのように管理しているんでしょうか? * mylib/*.{h,c} と一つのディレクトリにヘッダとソース。 * mylib/include/*.h,mylib/src/*.c で mylib/lib/libmylib.a とか。 普通のライブラリ風に。 で使うときにはどうしてます? * mylib ごとコピーして? * mylib/include/ とかにパスを通してる。で -lmylib どうすると楽なのか悩んでます。
不良債権が流行った頃 護送船団とか何とか叩いておいてアメリカがこの様なわけだが
>>205 コンパイラオプション (多分 -I) + makefile
クラスAがあり、クラスBがクラスAのインスタンスのポインタpを持っている形のプログラムがあります。 クラスAにはchar変数textがあり、クラスBからsprintf(p->text, "test");を実行します。 この時エラーが起きてプログラムが強制終了するのですが、何かおかしな手順を踏んでいるのでしょうか?
if文とfor文だけで一次元配列を大きい順にソートしたいんですけど 自分の力量では出来ませんでした。 やり方を教えてください。
ぬう。言葉が通じない
>>208 ・pがAのインスタンスを指していない。
・pが指しているAのインスタンスはすでに死んでいる。
・A::textが5byteに満たない。
・sprintfの前までに何かメモリを壊している。
・その他
この中のどれなのか判定してやるから、ソースを貼れと言ってるの
意味をはき違えました。 コードが非常に長いので今編集しています。
class Task { public: void Add(Task *obj, LPCSTR name);//インスタンスを登録する関数です。 Task* Find(char *name);//インスタンスのポインタを返す関数です。 void Do();//登録されたインスタンスのExec();を実行 protected: virtual void Exec(); } class Font : public Task { public: char text[10]; protected: void Exec(){ cout << text << endl; } } class Edit : public Task { public: Init(){ font=(Font*)Find("font"); } void setFont(){ sprintf(font->text, "text"); } private: Font *font; protected: void Exec(){ setFont(); } }
main() { Task task; task.Add(new Font(), "font"); task.Add(new Edit(), "edit"); while(true) task.Do(); } 色々大量に省きましたが大体こんな感じです。
218 :
208 :2008/03/18(火) 00:33:47
すいません、自己解決しました。
EditのInit()はどこで呼ばれてんの
>>205 これ俺も気になる。なかなか話題にもならないし、ぐぐっても出てこないし、
みんなどうしてるって疑問は昔からあった
俺は mylib/include、mylib/source、mylb/lib にして、
include、lib にパスを通す派
221 :
208 :2008/03/18(火) 00:45:27
>>219 Add内に実行する部分があるのでそこで実行されてます。
上のだと省いてます。
インスタンスの登録順序のせいでポインタが格納できていないのが問題でした。
>>220 コピーしたら元を変更したときにコピーした数だけ更新してまわらないといけないだろ。
ディレクトリ分けてパス指定するのが当然だから、話題にもならないんじゃない?
Visual C++で FileInfo^ fi = gcnew FileInfo(filename); __int64 size = fi->Length; のように取得したファイルサイズを32bitに変換し、さらにリトルエンディアンに変換した後、 バイナリでファイルに書き出したいのですが、何か良い方法はありますか?
225 :
208 :2008/03/18(火) 01:01:47
文字列代入でつまりました。 LPTSTR text; _stprintf(text, "text"); これでエラーが起こるのですが、正しくはどうすればいいのでしょうか?
>209 とりあえず速度とか、プログラムらしさというのを全く気にしなくて良いなら(勉強の一貫なら) 一度、数字の書いたカードを手作業で並べ替えてみるといいかもしれない。 そのときの手順を1つ1つメモしていくんだ。
>>223 VC++なら、x86だから元々リトルエンディアンですが。
つーか、下位バイトから順番に出力すればいいのでは?
230 :
208 :2008/03/18(火) 01:08:08
>>227 ありがとうございました。
TCHAR関係すべて勘違いしていました。
231 :
202 :2008/03/18(火) 01:30:50
>>203 ,204
レスthx
いろいろなoperatorを定義する時に便利そうですね。
でも、operator==だけを見ると、あまり便利に感じないです。
// Hoge.cpp
#include "A.h"
#include "B.h"
bool operator==(const A& lhs, const B& rhs) {...}
というのを考えていたので、Aに修正を加えないといけないのがちょっと・・(Bはそのままというのも気になる)。
普通に定義することにします。
209です。ググったりしたのですが難しいです。 よろしければ手直ししていただけませんか。Visual C++ 6.0です。 int hairetu(int jun[N]){ int max,j,k,retu[N],jun2[N]; for(j=0;j<N;j++){ jun2[j]=jun[j]; } for(k=0;k<N;k++){ for(j=0;j<N;j++){ if(max<jun[j]) max=jun[j]; jun[j]=jun2[k]; } retu[k]=max; max=retu[k]; } for(j=0;j<N;j++){ jun[j]=retu[j]; } return(jun[N]); }
233 :
デフォルトの名無しさん :2008/03/18(火) 02:12:58
開発環境はVS6、コードはANSIです。 _msize()ってmalloc()やrealloc()などで 指定したメモリサイズを返すと思ってましたが、 つなげるランタイムライブラリによって変わるのですか? 現状でコンパイルオプション「コード生成」の「使用するランタイムライブラリ」を 「シングルスレッド(デバッグ)」にすると指定したサイズ、 「シングルスレッド」にすると指定したサイズから直近の16の倍数値が返ってきます。 これってC言語をする人にとって知ってて当たり前のことなんですか? それともオプションで調整できることなんですか?
234 :
205 :2008/03/18(火) 02:17:24
>>207 ,220
やっぱりそういう感じになるんですかね。
>>222 そう思ったんですけど頻繁に mylib は更新されて少し前に書いたものが
コンパイル通らなくなったりして結局使ってる側を修正しないといけなかったりで…
どうするといい感じに管理できるのかなぁと。
235 :
208 :2008/03/18(火) 02:17:32
>>232 バブルソートでググってみ。
選択ソート、挿入ソートでもOK。
それでダメなら、並び変えるときに自分がどういう手順を追っているか考えてみ。
10 8 3 5 7 1 6 2 4 9
↓
1 2 3 4 5 6 7 8 9 10
1つずつ動かして、その手順を元にコード起こす。
>>232 とりあえず要素5つくらいの配列を考えて、そのプログラムを動かすと配列の要素がどう変わっていくかを
紙の上で1ステップずつ書き出してみな。
・勉強したアルゴリズムの通りに並んでいかないなら、プログラムのロジックが間違っている。
・ググって調べたアルゴリズムがまだ理解できていないなら、まずはそれを理解するとこ。
アルゴリズムの説明が欲しいなら、どこか適切なスレへ。
・自分で書いたプログラムがどういう動作になるのかを追えないなら、勉強不足。
C言語の仕様的に分からないことがあるなら、また質問してみれば?
237 :
デフォルトの名無しさん :2008/03/18(火) 02:24:24
>>232 qsort()じゃだめなんですか?
勉強の為にソートロジック作るなら
クイックソートやマージソートやバブルソートなどで検索すればコードがでてくると思いますよ。
参考までに一番単純なバブルソートの例を
void bubble_sort(int a[], int n)
{
int i, j, t;
for (i=0; i<n-1; i++) {
for (j=n-1; j>i; j--) {
if (a[j-1] > a[j]) {
t = a[j];
a[j] = a[j-1];
a[j-1] = t;
}
}
}
}
>>233 _msize()ってANSIじゃないでしょ。
239 :
デフォルトの名無しさん :2008/03/18(火) 02:30:14
>>238 う・・・だったみたいですね。
Win32APIやMFCでなくコンソールアプリケーションで作成に訂正です。
240 :
233 :2008/03/18(火) 02:33:14
long lGetSize = 0; char *pcDat = NULL; pcDat = realloc(NULL, 1); lGetSize = _msize(pcDat); printf("1 = %ld\n", lGetSize); → シングルスレッド(デバッグ)での結果=1 → シングルスレッドでの結果=16 pcDat = realloc(NULL, 13); lGetSize = _msize(pcDat); free(pcDat); printf("13 = %ld\n", lGetSize); → シングルスレッド(デバッグ)での結果=13 → シングルスレッドでの結果=16 pcDat = realloc(NULL, 17); lGetSize = _msize(pcDat); free(pcDat); printf("17 = %ld\n", lGetSize); → シングルスレッド(デバッグ)での結果=17 → シングルスレッドでの結果=32 って具合です。
>>235-237 ありがとうございます。
qsortも使い方が分からないのでとにかくif文とfor文でやることにしていました。
>>237 さんのバブルソートの例を見ながら組み上げたいと思います。
>>240 _msizeの動作は詳しく無いから想像だけど…。
リリース版では効率化のために1とか13とか中途半端なバイト数で確保せずに、16バイト単位で領域の割り当てをするけど
デバッグ版ではデバッグしやすいように指定したバイト丁度を割り当てているのでは?
(実際には管理領域やメモリ破壊検知などのためにもっと余分に割り当てているだろうけど。)
243 :
233 :2008/03/18(火) 02:52:02
>>242 確かにこの現象が判明したのはリリースでのコンパイルですが、
デバッグで「使用するランタイムライブラリ」を「シングルスレッド」に変えるだけでも同じ現象になるのです。
これはもうランタイムライブラリの仕様としか言いようがないのでしょうか?
同じコードなのに違う動作をするというのはどうも納得いかないのです。
(オプション変更によってコンパイルorリンクエラーになるならまだわかりますが・・・)
これがC言語をする人にとって周知の事なら自分の知識不足として納得しようかと思い書き込みましたw
>>243 MSDNによれば
>ヒープに割り当てられたメモリ ブロックのサイズを返します。
と書いてある。
あくまで「割り当てられたサイズ」であり、これは「要求したサイズ」とは必ずしも一致しない。
>同じコードなのに違う動作をするというのはどうも納得いかないのです。
ランタイムライブラリに依存する処理なのだから、リンクするランタイムライブラリが異なれば
結果が異なることは特に不自然ではないと思う。
>これがC言語をする人にとって周知の事なら自分の知識不足として納得しようかと思い書き込みましたw
すでに出ていることだけど _msizeはANSIの標準ではなく MS固有のAPIでしかないのだから、
C言語をする人にとって周知の事というわけではない。
245 :
233 :2008/03/18(火) 03:20:59
>>244 言ってることはわかるのですが、
それならデバッグ用のランタイムの動作はデバッグなしのランタイムとあわせるべきじゃないかと思いますね。
例えば、デバッグでステップ実行で確認したのにデバッグ外すと動作変わるなら、デバッグの意味ないですよね。
とりあえず周知でないこととオプションで対応できるようなことでないのはわかりました。
247 :
デフォルトの名無しさん :2008/03/18(火) 06:05:02
下のプログラムは ファイル名を入力させて 検索文字列を入力して 「該当ファイルの検索文字列を含む行を全て表示するプログラム」です しかしながら実行すると下のコードの getlineがすっとばされてしまい こちらから検索文字列の入力を行うことができません なぜですか?
#include <iostream> #include <string> #include <vector> #include <fstream> using namespace std; int main() { string s; vector<string> v; cout << "Input filename" << "\n"; cin >> s; ifstream in(s.c_str()); while(getline(in,s)) v.push_back(s); cout << "検索文字列"; //↓の入力がすっとばされてしまう getline(cin,s); for(vector<string>::size_type i = 0;i < v.size();i++){ if(v[i].find(s) != string::npos) cout << i << ":" << v[i] << "\n"; } return 0; }
249 :
247 :2008/03/18(火) 06:12:54
環境はcygwinを使っています
250 :
sage :2008/03/18(火) 06:49:59
getlineの定義は istream &getline( char *バッファ, streamsize 文字数 ); istream &getline( char *バッファ, streamsize 文字数, char 境界文字 ); ですよね cin.getline(s,MAXSIZE) にしたらだめでしょうか
ファイル名で入力した際に入ってきた改行文字が残っているんではないですか getline(cin,s) の前に cin.ignore(); で一文字削ってみては
>>244 の補足になるけど、malloc/calloc/reallocも
標準では、指定された大きさ「以上」のメモリを確保するとなっていて、
ぴったりちょうどの大きさを割り当てなければならないという決まりはない。
>>245 そもそも_msize()==(要求サイズ)という条件に依存しようとすることが間違い。
>>244 にあるとおり、この条件が常に成立するなどとは、MSは言っていないはず。
処理系依存ってやつ。
>>245 > 例えば、デバッグでステップ実行で確認したのにデバッグ外す
> と動作変わるなら、デバッグの意味ないですよね。
デバッグビルドでデバッグし易いようにコードが変わるのは、よくある
こと。デバッグビルドとリリースビルドで動作に違いがないなら、デバッ
グビルドの意味ないじゃん。
デバッグビルドだとちゃんと動くけどリリースビルドにすると落ちるとか言うのはよくあるよな。 たいていは初期化不足だけど。
>デバッグの意味ないですよね あるよ。 デバッグビルドとリリースビルドの違いで困るプログラムは、 まずいプログラムだから、それを自覚することが出来る。
C言語とか意味わかんね 柴田望洋ってどうなの?
柴田望洋についての話に進める前にC言語を意味分かるようにする事の方が先決というか それを先にやらないと柴田望洋について話しても何も分からないと思うというか C言語すら分からないようじゃ柴田望洋についての話も分からんだろうというか それ以前に柴田望洋の話はマ板でやれ。
1:#include <iostream> 2:#include <string> 3: 4://using namespace std; 4: 6:class Foo { 7:private: 8: std::string s; 9: 10:public: 11: string getValue ( void ) { return s; }; 12: void setValue ( const string s_in ) { s = s_in; }; 13:}; 14: 15:int main ( void ) { 16: Foo f; 17: f.setValue("abcd"); 18: std::cout << f.getValue() << std::endl; 19: return (0); 20:} これをコンパイルすると、次のメッセージが出てコンパイルエラーになってしまいます。 "foo2.cpp", 行 11: エラー: 型の名前が予期される位置に "string" があります. 4行目のusingステートメントを有効にするとコンパイルできます。 何が間違ってるのでしょうか? Cは経験あるのですが、C++はド素人で良く分かりません(T_T
4,8,11行目を見て、何か気付かないか?
namespaceや名前空間でググれ
うわ、自分で書き込んだレスみたらすぐ分かったw エディタで見てるときはどうしても気付かなかったのに。 お目汚しすいませんでした・・・
_beginthreadexで大量にスレッドつくってそのスレッドの処理が終わったらグローバル 変数に1足していく ってしたいんですがどうもたまに同時にアクセスしてしまうようでぶっ飛んだ 数字になってしまいます。 どうすれば上手くいきますか?
ミューテックスとか使ってロックしろ
InterlockedIncrementでもいいかも
class test { public: test(){ array = new double[100]; InitArray(); } void InitArray();//array内をすべて初期化 double get(int x){ return array[x];} private: double *array; } こんなクラスがあるとき、他クラスでインスタンスを作り、 get(N);(N<100)を実行するとエラーが起きるのですが、 どこがおかしいのでしょうか?
>>267 何も問題はなさそうだが。
get呼び出しの辺りとか、InitArrayの中とか、
もう少し見せてくれれば、何かわかるかも。
>N<100 実は N=-1 だったとかw
templateの利用価値がイマイチわかりません 全ての型に対して一様に動作しないといけない状況ってSTL以外にめったに無いと思うのですが・・・
まあSTLだけでも十分に価値がある。 ほかによくある使い道を挙げるとしたら、 ポインタの類(auto_ptr, shared_ptrとか) charとwchar_t(例えばstd::coutとstd::wcout、 std::stringとstd::wstring、CStringAとCStringWとか)
ライブラリ実装者にとって、templateは汎用性のための強力な手段。 そうでない人にとっても、少し汎用的なコードを書きたいときには有用だし、 メモリ使用量や処理速度を改善するような使い方もできる。
charとwchar_tのためのテンプレートということはそれ以外のものをとった場合の対応はどうなるのでしょうか?
>>270 どこでエラーが起こってるのかデバッガで追えばいいよ。
>>274 何もしないか、あの手この手でエラーにするかの2択。
std::basic_string(stringとwstringのtypedef元)とかだと
32ビット整数型を要素にしてUTF-32文字列にするという風に、
char/wchar_t以外でも使えないわけではない。
>>275 やっと解決しました。
単純なミスしてました。
新たな問題が発生したのでよろしくお願いします。
クラスが2つあります。
クラスは互いにインスタンスをポインタとして取得しておく必要があります。(互いの変数を取得しあうため。)
しかし、互いのヘッダをincludeしあい、メインで両方のクラスのヘッダをincludeするとループが生じ、コンパイルできません。
この場合どういった手を打てばいいのでしょうか?
インクルードガードしたらいいと思うよ。
>>276 意図しない型についてはエラーを出すことも出来るのですか
使い道が無いか少し意識して考えてみようと思います
インクルードガードは#pragma onceとは違うのでしょうか?
インクルードガードって、言語仕様として用意するべきだと思わない?
別に必要ない
>280-281 正確には、#pragma onceはインクルードガードの実現手段の1つ、じゃない? >284 importみたいな?
>>284 間に合ってるから「用意するべき」と言うほど必要ではないと思う
言語規格にあればいいかもねって程度
>>286 #pragma once は環境依存だろ。
あ、そこに突っ込んでるわけじゃなかったんだ。
std::pair って、<map>をインクルードすれば使えるけど、 必要最小限のファイルってなんですか?
<utility>
>>291 ありがとうございます。
<utility> って pair しか入ってないんですね。
どう使ったらいいのかわからない namespace rel_ops ってのも入ってるぜ。
gcc の utility を見てみたら確かに rel_ops ってやつありました。 =を定義するだけで!=を自動で定義してくれるとか、 便利といえば便利かもしれないですね。 Boost にもそんなコンセプトのものがあったような。
多分物凄く初心者な質問なんですが。 if(!InitApp(hCurInst)) return FALSE; if(!InitInstance(hCurInst, nCmdShow)) return FALSE; こういったifの条件式に!関数名だけが来ている時は何を基準に真偽を判定しているんでしょうか? その関数が成功したか否かでしょうか?
基本的に0かNULLなら偽、さもなくば真なので、 !が前にそれが逆転する。
>>295 関数の返り値見ないことにはなんともいえない。
>>295 if(!expr) は if(expr == 0) と同義。
>>295 一応補足。
関数の値として0が返ってきたからといって、
それが失敗を意味するとは限らないです。
InitApp 本体のソース又はドキュメントを読みましょう。
300 :
デフォルトの名無しさん :2008/03/19(水) 13:22:25
>>295 それ猫でもWinプログラムのコードだろ
C言語の基礎を学んでから読みなさい
>>298 InitAppの返り値の型のoperator !と==によって変わらないか?
>>301 C++でオーバーロードされていればな。
まあ
>>295 の質問には実害ないだろ。
なおCでは真実。
オープンソースプロジェクトでの関数名や変数名の付け方で、もっとも一般的なものは何ですか?
英語です
C++のLONG型を出力するには変換指定文字列は何を使えばいいのでしょうか?
どういたしまして
なにこの流れ
310 :
デフォルトの名無しさん :2008/03/19(水) 19:17:25
>>305 C++なら普通は変換指定文字列なんて使わない気が
VC8 VisualStadio2005 c++ プロジェクトからビルドして実行する分には問題ないのですが、作成されたexeを実行すると「メモリが不足しています。」 とエラーが出ます。 Release/Debugの両方とも同じ結果でした。 newで止まっているっぽいのですが、メモリが不足するほど読み込んでないのになぜエラーが出るのかと言う疑問と プロジェクトから実行するとなぜ問題のないのかが気になります。 後者に関して、本来(exeファイル)ならかけられている制限が取り払われた状態になっているのでしょうか。
「プロジェクトから実行」とはどういうこと?
typedef struct { int initialized; int num; void *in_event; void *out_event; int resp; void *lock; AA_T callback; } AA_T; static AA_T aa = {0, -1}; /* ここの初期化の意味は? */ : こんなコードを見たのですが、aa = {0, -1} の部分は、どこを初期化してるんでしょうか? これは、単に static AA_T aa; と書いておけば、aa のメモリー領域が全て0で初期化される気がするのですが。
>>313 最初の 2 つが 0, -1 で初期化され、
あとは全て 0 で初期化される。
つまり、num を -1 にしたかったんだろう。
ところで、AA_T が AA_T をメンバに持ってるのはいいのか?
315 :
311 :2008/03/19(水) 22:23:51
>>312 VisualStadioでVC++Projectを開き、その状態で(ビルドをして)実行することです。
>>312 GUIのメニューから実行するということだろ。
317 :
313 :2008/03/19(水) 22:40:12
>>314 なるほど、判りました。
> ところで、AA_T が AA_T をメンバに持ってるのはいいのか?
すみません。
ここは、記載ミスで AA_T callback => AA_CB_T callback でした。
なるほど
#include <cstdlib> int main(int argc, char* argv[]) { std::atexit(0); return 0; } 'std' : 識別子がクラス名でも名前空間名でもありません。 というエラーが出ます。環境はVC2008EEです。 どういうことですか?
インクルードパスの設定がぶっ壊れたんじゃないか? 俺も2008 EEだが問題なくコンパイルできる。
321 :
デフォルトの名無しさん :2008/03/19(水) 23:11:19
struct Pair { public: Pair(int a, int b) : a_(a), b_(b) int a_; int b_; }; Pair p(1, 2); みたいに書くことがあると思うんですが Pair を値として返す関数 Pair getPair(int x) { Pair p(1, x); return p; } って書きますよね。 getPair(int x) を1行で return xxx ; って書く方法はないでしょうか。 ポインタを返すのであれば return new Pair(1, x); とかけますがそんなのをイメージしています。
ありがとうございます。 こんな簡単だったとは。。
class Hoge { public: Hoge(int n) : n_(n) {} protected: const int n_; }; Hoge h1(3); // これは OK Hoge* h2 = new Hoge(4); // これもOK Hoge* hoges = new Hoge[3]; // これがだめ ↑のようなコードで配列の確保がだめな理由と回避方法を教えてください。 よろしくお願いします。 const にしているのはインスタンス作成後に変更がないからです。
Hogeにデフォルトコンストラクタを定義する
>>321 Pair なんて構造体をいちいち作らなくても std::pair ってそのまんまのが標準で用意されとるべ。
ヘッダファイルは utility 。
>>325 コピーコンストラクタを用意して、
std::vector に対して push_back していくといいよ。
>>326 さん
ありがとうございます。
class Hoge {
public:
Hoge() : n_(0) {} // 追加
Hoge(int n) : n_(n) {}
protected:
const int n_;
};
Hoge h1(3); // これは OK
Hoge* h2 = new Hoge(4); // これもOK
Hoge* hoges = new Hoge[3]; // OK になった
for (int i = 0; i < 3; i++) {
hoges[i] = Hoge(1234); // これはNG
}
うまくいきましたが別の所でひっかかりました。
引き続きお願いします。
まあ、この場合はデフォルトのコピーコンストラクタでいいけどね。
>>328 さん
ありがとうございます。
ちょっと都合がありまして配列を使いたいのです。
難しいでしょうか。
>>327 さん
分かりにくくてすみません。
Pair は例として挙げただけでした。ごめんなさい。
>>331 vector が使えないって、組み込み?
placement new を使うといいよ。
>>329 n_を非constにし、コピー代入演算子を定義する。
>>329 そりゃ
せっかくn_をconstにして変更不可能にしてるのに
hoges[i] = Hoge(1234);
とかで変更できたら逆に困るじゃないか。
変更するなら非constにしないと。
>>335 変更したいんじゃなくて、初期化したいんだと思われ。
>>335 さん
すみません。そのあたりが良く分かっていないです。
Hoge* hoges = new Hoge[3];
では入れ物だけを用意したイメージなのですがそこが違っていてデフォルトコンストラクタが呼ばれてしまうってことですよね。
確保した領域の1番目に Hoge(1234) 、2番目に Hoge(3456) を入れたいんですが、 const のままでは無理なのでしょうか。
>>337 まぁ、そんな気はしてた。
>>338 残念ながら入れ物だけじゃなくて中身も用意するのがC++流
結論だけいうとconstのままでも不可能ではない。
ただplacement newとかconst_castとかの黒魔術が必要になるからお勧めできない。
素直にconst外すのが良いと思う。
>>339 さん
丁寧にありがとうございます。
黒魔術を見てみたい気もしますがw
> 中身も用意するのがC++流
これで納得しました。
ところでデフォルトコンストラクタ以外で中身をつくることはできるのでしょうか?
最後の delete は別に hoges をそのまま使ってもいい。 と考えると、vp_hoges はまあ要らない。 まあ、うっかり delete[] hoges; なんてすると悲惨なことになるので、 それを戒めるためにとりあえず vp_hoges を使ってる。 実用する時は別に vp_hoges は要らないと思う。
>>340 さん
ありがとうございます!
new(&hoges[i]) Hoge(HogeInit[i]);
ここで placement new を使って初期化した中身が確保されるメモリ領域を指定しているのですね。
勉強になります。
ご親切にありがとうございました。
new っていうヘッダが placement new を提供しているのですね。 これもまた勉強になりました。
345 :
319 :2008/03/20(木) 00:21:14
>>320 どうもです。
インクルードファイルからPlathomeSDKのcrtを外したらエラーが出なくなりました。
346 :
デフォルトの名無しさん :2008/03/20(木) 08:42:25
配列を参照で渡せますか? int a[10]; の時、 void func(int* const &a); void func(int a[10]); void func(int (&a)[10]); とか書くとコンパイルはできるのですが、どれもポインタ渡しになっているようです。 (sizeof()をやると配列なら40が返るはずだけど、4が返るから) どうやっても配列のままで渡せないというのは、どうやれば確認できるでしょうか。
渡せる void foo(int (&a)[10]);
なにいってんだ俺 そうじゃなくてsizeofでちゃんと大きさかえってない?
349 :
デフォルトの名無しさん :2008/03/20(木) 08:54:55
>>347-348 返ってる。じゃあやっぱり渡せるのですかね?
こんな感じ?
template <int N>
void foo(int (&a)[N]);
std::basic_string<CHAR> と std::basic_string<WCHAR> の中身を変換する方法はありますか? VC9です。
2種類挙がってるので補足してみる。
>>351 はC標準。
mbstowcs実行前にsetlocaleでロケールを指定する。
setlocaleはプロセス単位の変更を行うためスレッドセーフでない。
そのため、通常はmain最初の方でsetlocaleする。
>>352 はC++標準
ロケールはstd::localeとして引数で渡される。
※ 当然スレッドセーフ
どちらの方法も、ロケールが無いと
charの正体(Shift_JISなど)が分からないので、
指定する必要があるが、
標準ロケールを指定しておけばおk。
まるで標準がスレッドセーフを保証しているかの様な誤解を与えそうだな
相談室スレにも似たことあったけど 「正確でない」より「正確には、こう」という書き方の方が 有用だと思うんですよね
役所の窓口みたいな根性の奴が多いから。
なんでもかんでも、全部教えてもらえるって思うなよ。
>>355 そうとも言えない。答えを書いちゃうと、自分で調べようとしない癖がつくから。
ま、答えを求めてるなら教えても良いんだけど、それだと成長しないからね。
wikiとかにも居るよな。 〜の記述が間違ってますよ、とかコメントする奴w 気付いたならお前が訂正してやれよっていうw
間違ってることは分かってても、正しい答えまでは知らない場合もあるからなぁ。
>>359 理解した。確かに回答者同士でやり合いが始まると質問者はポカーンだ。
規格の記述を抜粋しても初心者は読まない 正確にわかりやすく書くのは実は結構大変 かと言って間違いをスルーするのも初心者に誤解を与えかねない →マンドクセ →煽り気味に間違いを指摘又はググレカス →荒れる そんな感じ
変換できました。
経験的にプログラマには三種類あって ・規格は絶対。 ・規格は参考に過ぎない。 ・規格?何それ美味しいの? 前二者は互いに敵対関係。
俺も昔は全部教えるのは良くないと思ってたけど、 ・調べない奴はどう言っても調べない ・調べた後の奴にとっては時間の無駄 ・寸止めしたところで調べ方は理解できない ・知識量によっては寸止めされていることに気付かない ・ログの蓄積にならない ・場合によっては荒れる ・一部の回答者が回答した気分になりたいだけ ということがある点で、質問には端的に全部答えてしまった方が 双方に手間が無くて良いのではないかと思うようになった。
C99だけどね
369 :
デフォルトの名無しさん :2008/03/20(木) 17:53:45
見たけど、落ちてないし調教下手だし。
371 :
デフォルトの名無しさん :2008/03/20(木) 18:09:56
既出だと思うけど、この動画の char * argv[] って、 他にも char **argv, char argv[][] など色々ある中で、 初心者に教えるとしたら経験上どれが最も良い?
char* argv[] だと思う。 文字列の配列って感じがするし。
というか、char argv[][] はねーな。
引数の char *argv[] と char **argv は同じ型だけど char argv[][] は違うよ
*[]でいいとおもう。 ポインタのポインタとか言うとなぜか途端に分からなくなる奴いるし
const char * const * const argv で。
377 :
デフォルトの名無しさん :2008/03/20(木) 18:18:04
動画の char * argv[] って * を2つの半角スペースで挟んでるのは意図的かなぁ。 int* a が int *a より良いのは賛成。 でも、int* a,b; が int* a; int* b; と同じでないと知ると 初心者はCが嫌いになるw
int *p; はまだいいけど、 int *&r = p; とか逆に分かりにくい。
381 :
デフォルトの名無しさん :2008/03/20(木) 18:26:21
int *&r って、確かに。勉強になりました。 動画見て「初心者には scanf を教えるしかないか」と思ったけど、 wikipedia みて、scanf 復権!という流れなのを知ったのがつい先月。
>>380 いや、今はmainの引数の話だからってことだと思うよ。
>>380 規格にはconstをつけていいとは書いてない。
>>381 流れをkwsk
つか別にscanfで困ることって無いと思うけどね
>>383 処理系定義を許してるからportability無視すれば何でもありだけどな。
386 :
デフォルトの名無しさん :2008/03/20(木) 18:46:51
>> 384 ごめん、wikipwdia じゃなかったのかも。履歴を調べても見つからない。 「セキュリティの問題からこれまで scanf を使うべきではないという指摘が あったが、正しく対処すれば問題は生じない。そのため scanf 自身が 使ってはならない関数とは言えない」 というような意味の文章をみたと思ったんだけど。 先輩方からscanfは絶対使うなと言われ、これまで従ってきたので。
getsは絶対使うな、だけど、scanfを絶対使うなって言ってる奴は、よく分かってないだけ。
使ってはならないとは思わないが、正しく使いづらい関数ではあると思う。 初心者向けの本に登場させるのであれば、正しい使い方を必ず載せるべきだ。
初心者は使うなでいいんじゃね
390 :
デフォルトの名無しさん :2008/03/20(木) 18:58:52
>>387 了解。初心者に scanf から教育して OK なんだ。
その際は、wikipedia にあるように、
char a[20];
scanf("%s", a);
ではなくて、
char a[20];
scanf("%19s", a);
と教えないといけないわけか。
もちろん、
char a[20];
scanf("%19[^\n]%*[^\n]", a);
getchar();
を最初から教えるという手もあるけどw たぶん初心者には無理。
初心者を使うな の間違いじゃね?w セキュリティに関わるような場所に初心者を使う意味がわからん
実用では、fgetsしてsscanfがいいとこ取りのような感じで便利。
>>390 scanfにfgetsにと使い分ければいいじゃないか
なんでも一つで済ませようとするのはイクナイ
scanf の幅指定に変数が直接は使えないのが不便だよな。 フォーマットを動的に生成するしかないってのが。 printf は * があるのに。
395 :
デフォルトの名無しさん :2008/03/20(木) 19:08:07
GCC 4.0 ではextern宣言では配列はポインタにすべし、ということらしいのだが 配列を実際に定義しているところはどのように修正すればよいのだろうか
進んで使わなくても良いと思う。
397 :
デフォルトの名無しさん :2008/03/20(木) 19:09:50
>>393 了解。ちなみに私もfgetsとsscanf派。
先輩からの指導では、scanf は禁止だったが sscanf はOKだった。
Cを教える学校の先生って大変なんだろうな。
そう考えると初音ミクのCプログラミングの動画は奥深いw
399 :
デフォルトの名無しさん :2008/03/20(木) 22:42:53
質問です。 class Base { : }; class Child1 : public Base { : }; class Child2 : public Base { : }; void main(void) { Base* A = new Child1(); : ↑こうやって作ったインスタンスの破棄の際、とりあえずtypeidで分岐させてから 適切な型にダウンキャストして破棄する方法を現在取っています。 if (typeid(*A) == typeid(Child1)) { delete(dynamic_cast<Child1*>(A)); } else if (typeid(*A) == typeid(Child2)) { delete(dynamic_cast<Child2*>(A)); } else { delete(A); } } しかしこれだと派生型が増えれば増えるほどコードがずらずら長くなってしまうので、 もしもっとスマートな破棄の方法があれば教えて頂けませんか。
>>399 Baseクラスに仮想デストラクタを定義する。
>>400-401 デストラクタをvirtualにしとけば、そもそもキャストは不要ってことでいいですか?
どうもありがとうございました。
面倒くさいので、 string s; getline(cin, s); の方向で
404 :
デフォルトの名無しさん :2008/03/20(木) 23:10:44
クラスのオブジェクトを1万個とか作る場合、 クラスにstaticの変数や関数を持ってない方が処理は速いのでしょうか?
>>404 んなことないんじゃないの?
クラスのstatic変数って、単にグローバル変数をクラスのスコープで隠してるだけだし。
406 :
404 :2008/03/20(木) 23:19:51
ありがとうございます。 グローバル変数かクラスのstaticにするか迷ってたので、 クラスのstaticにすることにします。
func_bで例外が送出される可能性がある場合はfunc_aでも関数宣言時にthrow(...)指定する必要があるの? void func_a() throw(exception){ func_b(); }
func_aがfunc_bから投げられた例外を処理できるならもう投げなくてもいいんじゃね? func_bから投げられた例外をfunc_aの呼び出し元に通知する必要があるなら投げればいい。
409 :
408 :2008/03/20(木) 23:57:03
はぅ、そういうことを聞いてるんじゃなかった・・・
void func_a() throw(...){ func_b(); }
例外指定は必須のものではない。 必要だと思えば付けるし、必要でないと思うなら付けない。
例外指定なんてexportに匹敵する位使われてないな 強いて使うならデストラクタにthrow()書く位
モデルクラスのswapper関数もかな。
迂闊な使い方したら unexpected で強制終了だからな。 かといって unexpected を避けるために例外握りつぶすのもどうなんだ? って感じ。 握りつぶすなら unexpected なくてもいいじゃん?
415 :
デフォルトの名無しさん :2008/03/21(金) 02:38:00
クラスのコンストラクタの中で、 thisポインタをグローバル変数に格納しても、 正常にオブジェクトのアドレスが保存されるでしょうか?
>>415 コンストラクタが失敗しなければ、Yes。
どうもありがとうございます。
googleで、"c++ \n"といれて検索しているのですが、 欲しい結果が出ません。
#include <iostream> #include <math.h> using namespace std; const int rate=44100; int p(double q, int f, int t) { const double pi=3.1415; double x; x=sin(2*pi*f/rate*q); cout << int(x*127+128+0.4999); cout << "\n"; if (f<t) p(q,f+1,t); return 0; } int main(void) { p(440.0 , 0, rate); return 0; } このプログラムで、\nが何を意味しているのか 分からないです。
>>420 図書館や本屋で立ち読みとかすればいい。
>>421 ダウト。endlはそれだけの機能ではない。
【C++】 std::vectorを使った場合、メモリはどこの領域に確保されるのでしょうか? ググッたところテンポラリ領域だと出てきたのですが、テンポラリ領域が 何処にあるのか分かりません。 また、PCの場合とマイコンでは確保される領域に違いがあるのでしょうか? 関数名 { char buffer[256] ← スタックに確保 char* buffer = new char[サイズ]; ← ヒープに確保 std::vector<char> buffer(サイズ); ← ? }
>>426 std::vectorは大抵の場合は内部でヒープにメモリ領域を確保してデータを取り扱っている。
それ以外に方法がない。
428 :
426 :2008/03/21(金) 10:41:06
>>427 ありがとうございます。
ということは、テンポラリ領域 = ヒープでFA?
それは実装次第だろ。 つーか、テンポラリ領域って何だよ。
430 :
426 :2008/03/21(金) 10:51:59
>>429 なんだろ??
テンポラリ = 一時的な
あ、なんとなく分かりました。
そんな未知の領域があるのかと思ってました。
ありがとうございます。
[C言語] jnethack を EUC-JP から UTF-8 化しようとしています。 jnethack には japanese/jlib.c というファイルがあり、その中で、 void jputchar(int c) { static unsigned int buf[2]; jbuffer((unsigned int)(c & 0xff), buf, NULL, NULL, NULL); }
432 :
431 :2008/03/21(金) 12:47:27
int jbuffer( unsigned int c, unsigned int *buf, void (*reset)(), void (*f1)(unsigned int), void (*f2)(unsigned int, unsigned int)) { static unsigned int ibuf[2]; unsigned int c1, c2; unsigned char uc[2]; unsigned char *p; if(!buf) buf = ibuf; if(!reset) reset = tty_reset; if(!f1) f1 = tty_jputc; if(!f2) f2 = tty_jputc2; c = c & 0xff; if(!(buf[0]) && (is_kanji(c))){ buf[1] = c; ++buf[0]; return 0; }
433 :
431 :2008/03/21(金) 12:48:26
else if(buf[0]){ c1 = buf[1]; c2 = c; if(IC == output_kcode) ; else if(IC == EUC){ switch(output_kcode){ case JIS: c1 &= 0x7f; c2 &= 0x7f; break; case SJIS: uc[0] = c1; uc[1] = c2; p = e2sj(uc); c1 = p[0]; c2 = p[1]; break; default: impossible("Unknown kcode!"); break; } }
434 :
431 :2008/03/21(金) 12:49:02
else if(IC == SJIS){ uc[0] = c1; uc[1] = c2; p = sj2e(uc); switch(output_kcode){ case JIS: c1 &= 0x7f; c2 &= 0x7f; break; case EUC: break; default: impossible("Unknown kcode!"); break; } } f2(c1, c2); buf[0] = 0; return 2; } else if(c){ f1(c); return 1; } reset(); return -1; } となっており、2バイトの EUC-JP や SJIS ならなんとかなりそうですが、 1-3バイトの UTF-8 だと、jputchar のコードを書き換えないといけなさそうです。 なんか良いアイデアはありませんか?手詰まりで困っています。 よろしくお願いいたします。
テンプレートメタプログラミングってマクロ関数をものすごくした物みたいな認識でおk?
>>431-434 UTF-8対応のキモの部分だろうから、自分で頑張れよ。
問題がもっと小さく具体的にならないと、こういう場ではアドバイスしにくいよ。
437 :
431 :2008/03/21(金) 15:35:27
>>436 うーん、やっぱりそうすか。
2バイトベッタリなコードなんで、もう UTF-8 対応を諦めて、
EUC-JP で妥協しようかとも思っています。
ありがとうございました。
一応EUC-JPにも3バイト文字があるけどな
>>431 どうしたいのか分からんけど、
内部コードはUTF-16で良いんじゃね?
サロゲートも抜きで。
440 :
431 :2008/03/21(金) 18:01:17
>>439 うーん、良いアイデアかと思って調べてみたけど、内部コードを UTF-16 にしたら、
printf では UTF-16 のコードをだだ流しになって、LANG=ja_JP.UTF-8 環境では文字化けしそう。
問題の jputchar がなんとか内部コード UTF-8 に対応すれば、
printf 系はそのままにできるんじゃないかと思ってます。
c++で可変個引数を使うとき foo(first,...)の書式を使うか 引数に配列を取るか 引数にvectorやlistをとるか どれが一番無難でしょうか
442 :
デフォルトの名無しさん :2008/03/21(金) 19:04:38
int* char*が無難だと思うが 個数が渡せない C++限定で良いならvector
>>441 型は固定なん?
固定じゃないなら、下二つを行う場合は
CVariantみたいななんても入るクラスを作る必要があるよ。
va_list
445 :
デフォルトの名無しさん :2008/03/21(金) 19:12:41
俺は新JISかな
cout << "hoge" << endl; あたりを参考にすると C++ 風の可変個引数になると思う。
きもー
boost::formatの悪口はそこまでだ
>>443 今回は固定で大丈夫ですが
型も変わる場合はそれ用のクラスかテンプレートが必要になるのでしょうか?
format(""), a, b, c; みたいに表現することもできなくはない。 コンマ演算子をオーバーロードすることも可能だからな。
>>450 型が固定なら何でも大丈夫。
型が不定の場合、vectorや配列だと何が困るかというと、
vector<???>の???に入る型が決まらないということ。
決まった基底クラスがあるならまた別なんだろうけど。
そこで boost::any ですよ!
本当に可変個引数が必要なのか考えるのも悪くないよ
質問です。 環境はlinux(euc-jp)、gcc3.4、ソースの文字コードはshift-jis。 -fshort-wcharオプションでwcharを4バイトから2バイトに変更したのですが、 そうしたらwprintfの出力が上手くいかなくなってしまいました。 (-fshort-wcharオプションを使わなければ出力されます。) 例: set_locale(LC_ALL,""); wprintf(L"aaaaa\n"); // wcharを2バイトにすると出ない... wcharが2バイトの状況でwprintfを使用するためにはどのようにすればよいのでしょうか?
456 :
デフォルトの名無しさん :2008/03/21(金) 22:47:30
構造体をnewで作成して使う場合、 こんな感じで中身を入てるのですが、 STRUCT_TYPE* pvar = new STRUCT_TYPE; (*pvar).x = a; (*pvar).y = b; (*pvar).z = c; STRUCT_TYPE var = {a, b, c}; のように { } を使って1行で書く方法ってないでしょうか?
C++標準でないが、コンパイラによってはコンパウンドリテラルが使えるかも。
C++0xに入る筈
とりあえず関数とかマクロとかつくっとけば?
>>456 もし、毎回書くのが面倒、という話なら生成関数作れば良いと思う
462 :
456 :2008/03/21(金) 23:36:29
ありがとうございます。 構造体もコンストラクタ作れるとは。 クラスと変わらないですね。 コンパウンドリテラルはうちでは使えないっぽかったです。
>>462 structはすべてのメンバがpublicなclassと等しいことになってる。
464 :
デフォルトの名無しさん :2008/03/21(金) 23:51:06
VC.net2003でWinInetを使用したプログラムを書いて実行すると ウイルスバスター2008が下記レジストリの記入を拒否しました(危険度:高)と出ます。 HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Proxy Server なんとか回避する方法はないでしょうか?
>>463 途中にprivate:と書けるので、正確じゃないな。
・アクセス指定を書く前のデフォルトがpublic
・アクセス指定を書かずに継承したとき、public継承
じゃなかったっけ
すいません 質問と言えるかどうかは微妙ですが 1本198円の清涼飲料水1本と、1本138円の牛乳2本を購入し、 千円札で払った場合のお釣りを求めよ。 ただし、5%の消費税を追加し、お釣りの額は整数とする。 なお、消費税を四捨五入するかどうかは自由とする。 という問題が出されて、 #include <stdio.h> int main(void) { int a = 1000,b = 198,c =138, d = (int)(b + c * 2); printf("%d\n",a - d); return 0; } 自分はこう記述したら答えが模範解答と食い違っていて、なおかつ ※変数を使わず解いても良いが、使えば後で変更が楽である。 ※キャスト変換を忘れている場合は減点とする。 ※答えを実数にした場合も減点とする。 ※計算方法によっては答えが微妙に異なる。 とあったのですが、自分の解き方であっていたのでしょうか? どうも複数正解があるようで・・・
467 :
431 :2008/03/22(土) 00:24:21
5%の消費税はどこ?
468 :
465 :2008/03/22(土) 00:26:48
using namespace std; wstring s; wcin >> s; wcout << s << endl; ってやると何入力しても出力がなくてwcinが無効になっちゃうんですけど どういうことでしょうか?
470 :
デフォルトの名無しさん :2008/03/22(土) 00:59:56
wstring環境は不完全って事
>>455 wprintf()の中身も -fshort-wchar でコンパイルする必要あり。
で、wprintf()が2バイトのwchar_tを想定して書かれているとは思えない
ので、たぶんムリ。
gcc の w 系はまともに動かなかった気がする。
w系っていうとなんかワロス系って感じがするなw
書いててそう思ったw
475 :
デフォルトの名無しさん :2008/03/22(土) 02:55:07
>>466 の完璧な回答はこうだろ。
#include <stdio.h>
int main()
{
/* 本当は64bit整数にすべき */
int juice = 198;
int milk = 138;
/* 浮動小数点の誤差を回避するために一万倍にする。 */
int amount = juice * 10000 + milk * 10000 * 2;
int total = amount * 105 / 100;
int round_down = total / 10000;
int round_up = (total + 9000) / 10000;
int half_adjust = (total + 5000) / 10000;
printf("切り捨て = %d, 切り上げ = %d, 四捨五入 = %d\n",
round_down, round_up, half_adjust);
return 0;
}
しかし
>>466 の使っているコンパイラはLSI-Cなのでintがオーバーフr
>>476 しかも初代ペンティアムで浮動小数てn(ry
478 :
デフォルトの名無しさん :2008/03/22(土) 04:35:52
C++でコマンドライン引数から受け取った文字列を int型にしたいんですがどうすればいいんですか?
Cと同じでよろし。
>>478 main関数の引数として文字列受け取った後
なんとか変換する
481 :
478 :2008/03/22(土) 04:52:05
コマンドラインから数字受け取ってソートするプログラムなんですけど こんな感じでおkですか? 一応ちゃんと動作しました #include <iostream> #include <vector> #include <algorithm> #include <sstream> using namespace std; int main(int argc,char* argv[]){ int x; vector<int> v; for(int i = 1;i < argc;i++){ istringstream iss(argv[i]); iss >> x; v.push_back(x); } sort(v.begin(),v.end()); for(vector<int>::iterator i = v.begin();i != v.end();++i){ cout << *i << " "; } return 0; }
482 :
455 :2008/03/22(土) 10:21:18
回答頂きありがとう御座います。 -fshort-wcharしつつ、wprintf使うときはwcharからu32に コピーするとかしか手がなさそうですね。 -fshort-wcharするとw系ライブラリ自体が使い物にならなくなっちゃうって事ですね。 腐ってる...
-fshort-wcharは自分が使いたいから使うというより、 アーキテクチャの都合から使用が要請されるという類のオプションだと思っている。 #例えばWindowsとか。
ライブラリも-fshort-wchar付でコンパイルすればいいだけだろ 腐ってるな
struct A{ struct{ int x; }; }; //1 A a{{4}}; //2 A b; b.x=4; この1と2って何が違うんでしょうか?1はコンパイラによってできないと思うんですが、 できるとしたらそのメリットはまとめられる以外に何かあるんでしょうか?
>>485 1は初期化するコードが発生しない。最初から初期値がメモリに存在するようになる。また、constが使える。
なるほど、定数のみなら早いんですね?
488 :
デフォルトの名無しさん :2008/03/22(土) 16:04:47
テンプレート型の値を返す関数で、エラーの場合NULLを返しているんですが、 テンプレート型にクラスを設定すれば上手くいくんですが、 構造体を設定すると、int(NULL)が構造体の型に変換できません、 というエラーが出てしまいます。 テンプレート型の値を返す関数で、エラーが発生した場合、 戻り値はどうするのが一般的なのでしょうか?
490 :
488 :2008/03/22(土) 16:13:03
申し上げましたが。何か違ってますか? こんな感じです。 template <typename T> T get(int idx) { if(エラーの場合) return NULL; return T型の値; }
491 :
488 :2008/03/22(土) 16:15:59
あと、列挙型もNULLじゃダメでした。
int なら0とか-1を返すのがスタンダードじゃないの?
特殊化でいいじゃん
あーごめん。構造体を返す場合か。 そういう場合は戻り値はboolにして、引数で操作対象のポインタか参照を 受け取る方が書きやすいかも。 template <typename T> bool get(T &ret, int idx) { if(エラーの場合) return FALSE; ret = T型の値; return TRUE; }
例外投げろや
boost.optionalを使うってのはどうか?
497 :
488 :2008/03/22(土) 16:57:02
みなさん、どうもありがとうございます。 例外を使うことにしました。 他の方法も、知らなかったので勉強になりました。 もう一つ考えたのが、エラーの場合0でクリアした値を返すというものなんですが、 これって T がポインタだった場合NULLを返してることになるのでしょうか? T var; ZeroMemory(&var, sizeof(T));//varを0でクリアする return var;
>ポインタを0でクリア 大抵の場合はNULL=0なので、問題は無い。 しかし極まれにNULLポインタの値が0じゃない環境もあると、 昔脅されたことがあるので、将来組み込みとかやる時は思い出してね。
499 :
488 :2008/03/22(土) 17:13:57
ありがとうございます。 たぶんやることは無いと思いますが、覚えておきます。
>>497 Tをかなり限定してしまう方法だな。
例外以外だったら、std::pair<T,bool>を返して、boolのほうでエラーを示せば?
JIS X 3014 の 4.10にポインタと0の関係が記述されている。 ---------------------------------------------------------------------- ゼロと評価される右辺値をもつ整数型の汎用整数数式を、空ポインタ定数と呼 ぶ。空ポインタ定数は、ポインタ方に変換することができる。その結果は、そ の型の空ポインタ値となる。空ポインタ値は、オブジェクト先ポインタ型又は 関数先ポインタ型のどんな値とも区別できる値とする。同じ型の二つの空ポイ ンタ値は、比較で等しくなるものでなければならない。空ポインタ定数から、 cv修飾付きの方へのポインタへの変換は、単一の変換となり、ポインタ変換の 後で修飾変換を行うことはない。 Tがオブジェクト方の場合、型"cv Tへのポインタ"の右辺値は、型"cv voidへの ポインタ"の右辺値に変換することができる。"cv Tへのポインタ"から"cv voidへのポインタ"への変換結果は、あたかもそのオブジェクトが、型Tの最派 生したオブジェクトであるかのように(すなわち、ある基底クラスの部分オブジェ クトとしてではなく)、型Tのそのオブジェクトがある記憶域の先頭位置を指す ものとする。 Dをクラス型とし、BをDの基底クラスとする場合、型"cv Dへのポインタ"の右辺 値は、型"cv Bへのポインタ"の右辺値に変換することができる。ただし、Dから 基底クラスBをアクセスできない場合、又はBがあいまいな場合、その変換を必 須とするプログラムは、不適格とする。変換の結果は、派生クラスのオブジェ クトの中の基底クラスの部分オブジェクトへのポインタとする。空ポインタ値 は、目的の型の空ポインタ値に変換される。
>>482 そもそもどうして-fshort-wcharを使いたいの? ふつうは使う状況には
ならないはずだけど。環境が4バイトのwchar_tを提供しているならその
まま使うべきっすよ。
#pragma comment(lib, "") ってcppに書くのかヘッダーに書くのかどっちがいいですか?
普通はヘッダー
505 :
503 :2008/03/22(土) 18:43:07
理由も教えていただけると非常に助かります
俺はlib使ってる部分がcppにあるならcppで、 inlineとかでヘッダにあるならヘッダに#pragma書いてるな
どこに書いても同じ。 強いて言うなら変更したい時にコンパイル時間の少なくなるよう、 単独の .cpp ファイルを作ってそこに書くのがベスト。
>>464 プログラム側の意思で回避出来たら意味ねーだろw
どうせうにこーどとかつかうのまどだけだろ
プロジェクトファイルやMakefileで指定するのが一番だよ
ある関数でメモリアクセスが何回起こってるか調べるのに お勧めなシミュレータってありますか?
512 :
デフォルトの名無しさん :2008/03/22(土) 21:08:26
親クラスのメンバ関数の引数に、 子クラスを使うことってできないのでしょうか?
そんなことはない 使える
この順で書くと、 class Parent{ void func(Child var){}//Childがまだ宣言されてないからエラー、 }; class Child: public Parent{}; この順で書くと、 class Child: public Parent{};//Parentがまだ宣言されてないからエラー class Parent{ void func(Child var){} }; になってしまうのですが、どう書けばいいのでしょうか?
>>514 class Child;
class Parent{
void func(Child var);
};
class Child: public Parent{};
void Parent::func(Child var){}
Child* じゃないと駄目じゃね?
>>516 それは互いをメンバにもってるときじゃないか?
518 :
503 :2008/03/22(土) 21:35:06
ありがとうございました ヘッダーには処理を書かない派なのでcppに書きたいと思います。
#pragma comment(lib, "")って処理なのか…?
521 :
503 :2008/03/22(土) 21:46:38
いえ、そうではなく 関数の定義はcppに書くということです。 lib使ってる部分ということです。
>>510 プロジェクトファイルでの設定は見づらいから
俺は #pragma の方が好みだな。
ソースファイルの受け渡しだけでも設定が有効だし。
>>521 ??
523 :
503 :2008/03/22(土) 21:58:12
//ヘッダー #pragma once void f(); //cpp #include "header.h" #pragma comment(lib, "lib") void f() { lib_f(); // ←ここでlibの関数を呼んでるのでcppに#pragmaを書く。 } こういう解釈だったのですが何かおかしかったでしょうか・・・
524 :
503 :2008/03/22(土) 21:59:01
//ヘッダー #pragma once #include "lib.h" void f(); ヘッダーはこうでした
std::stackに入れたものをせらせするとdelete9f@;jrt?
526 :
514 :2008/03/22(土) 22:04:33
やりたい処理は、ゲームの当たり判定処理なんですが、 当たり判定のための領域を表す、抽象クラスBoundsを作り、 その子クラスにCircle、Rectなどを作りました。 当たり判定をするときは、Bounds型の変数を使って、 以下のように判定ををしてます。 Bounds* bd1 = new Circle(); Bounds* bd2 = new Rect(); BOOL result = bd1->isCrashed(bd2); この書き方で、Circleの isCrashed(Rect* p) を呼びたいんですが、 なんか上手い方法はないでしょうか。 今は各オブジェクトにクラスタイプを表す変数を持たせて、 Bounds の virtual BOOL isCrashed(Bounds* p) で、 子クラスのisCrashed(Bounds* p) を呼び、 そこでタイプ変数により isCrashed((Rect*)p) とpをキャストして、 子クラスのisCrashed(Rect* p) を呼び出してます。
>>523 #pragma comment(lib, "...") は
どこかのファイルに書いてありさえすれば、
どのファイルに書いてあってもいい。
>>526 それは典型的なデザインパターンのひとつのVisitorパターンですね。
ダブルディスパッチとも言うかな
struct Circle;
struct Rect;
struct Bounds{
virtual bool isCrashed(Bounds*) = 0;
virtual bool isCrashed(Circle*) = 0;
virtual bool isCrashed(Rect*) = 0;
};
struct Circle : Bounds{
bool isCrashed(Bounds*p){return p->isCrashed(this);}
bool isCrashed(Circle*p){return puts("Circle Circle");}
bool isCrashed(Rect*p){return puts("Circle Rect");}
};
struct Rect : Bounds{
bool isCrashed(Bounds*p){return p->isCrashed(this);}
bool isCrashed(Circle*p){return puts("Rect Circle");}
bool isCrashed(Rect*p){return puts("Rect Rect");}
};
529 :
528 :2008/03/22(土) 22:25:31
ああ、これだと引数の左右が入れ替わるな。 衝突判定だから左右入れ替わっても問題ないとは思うけど。
>>524 lib.h内の関数を呼ぶとビルドにlibが必要なら、
#include "lib.h"
#pragma comment(lib, "lib")
をセットで書いた方が良いと思う。cpp, h 関係無く。
型を問わずに格納できるListの様な物を作りたいのですが 参考になるようなものはないでしょうか?
>>532 listだと1種類の型しか格納できないので
一つのlistに沢山の型が詰め込めるようにしたいのです
list<boost::any>で解決
535 :
503 :2008/03/22(土) 22:43:29
>>530 了解しました。
ありがとうございます。
よほどの場合で無い限りは boost::ptr_list<BaseClass> を使って 派生クラスを new して突っ込む方がいい気はするけど。
537 :
514 :2008/03/22(土) 22:48:16
>>529 ありがとうございます。上手くいきました。
しかし、引数の左右を入れ替えることまで計算済みじゃないんでしょうか?
これだと、Circle::isCrashed(Bounds*p)で無限ループになってしまいます。
struct Circle : Bounds{
bool isCrashed(Bounds*p){return isCrashed(p);}
bool isCrashed(Circle*p){return puts("Circle Circle");}
bool isCrashed(Rect*p){return puts("Circle Rect");}
};
>>505 ヘッダーに書いておくと、勝手にライブラリを選択してくれて便利かもな。
これは使わせてもらうよ。
>>537 うん、引数の左右の入れ替えは意図的。
left->isCrashed(right);でleftの型に応じた関数を呼び出す。
その中でright->isCrashed(left)を呼び出してrightの型に応じた関数を呼び出す。
この2段階の呼び出しで左右の型両方に対応した関数を呼び出してる。
実際にはisCrashed(Circle*)とかはprotectedにして置けば、
isCrashed(Bounds*)からしか呼び出せないことになるから必ず左右の入れ替えを起こせるようになる。
こうしておけば順序が重要な場合にも使えるようになる。
あ、ごめん。ちょい考えたらC++のprotectedだと無理だ。 色々なOO言語のアクセス権限がごっちゃになって適当な事、書いてしまった。
>>514 interface
isCrashed(RECT*)とisCrashed(POINT*);
を定義して
operator RECT*
operator POINT*
をそれぞれの派生クラスで定義すればいいだけの話じゃね?
俺ならoperatorにもisCrashedの引数にもconst修飾するけど。
542 :
541 :2008/03/22(土) 23:13:23
すまん RECT とPOINTは Rect型とCircle型と解釈してくれ。 検証用に作ったコードで考えてしまった。
>>541 そのやり方だと、これが実現できない
(理由: Boundsには operator RECT* も operator POINT* も定義されてないから)
Bounds* bd1 = new Circle();
Bounds* bd2 = new Rect();
BOOL result = bd1->isCrashed(bd2);
>>541 本人じゃないけど、どういう実装なん?
leftもrightも型分からんはずだから
そのやり方でダブルディスパッチ(相当)の処理を行えるとは思いにくいんだけど。
545 :
514 :2008/03/22(土) 23:32:20
引数の左右を元に戻そうとすると、無限ループになってしまいます。 衝突判定なので、左右逆でも問題ないし、 引数入れ替える方法は天才的だと思いましたが、 ちょっと左右を元に戻す方法が気になる。。。
セキュリティ初心者からの質問です。 strlenにsize_tよりも大きな文字列(へのポインタ)を 突っ込んでもセキュリティ上問題ないですか? *** バッファオーバーフロー対策で、 サイズさえ分かればちゃんと対策すればなんとか なりそうっていう感じはわかってきたのですが、 そのサイズを求めるときに不安になったので。
どっちかといえばsize_tよりも大きな文字列をどうやって用意するのかが気になる
size_tより大きなメモリって確保不可能だろ
549 :
546 :2008/03/23(日) 00:08:53
64bit環境でsize_tが32bitとかならあるいは。
WOW64でVirtualAllocVlmが存在すればあるいは。
DOSのヒュージメモリのことかー
stringstreamでintを二進数表記の文字列に変換はできますか?
ss << std::bitset<sizeof(int)*8>(12345);
templateで 文字列操作関数でcharかwchar_tしか必要ない場合のように 特定の型のみを生成可能にするにはどうしたらよいでしょうか?
他の型が与えられたときはエラーにすればいい
template <typename T> struct HogeCanUse { }; template <> struct HogeCanUse<char > { typedef int Well; }; template <> struct HogeCanUse<wchar_t> { typedef int Well; }; template <typename T> class Hoge { typedef HogeCanUse<T> CanUse; typedef typename HogeCanUse<T>::Well Well; }; int main() { Hoge<char> hoge; Hoge<int> hoge; } とか。 char/wchar_t なら std::char_traits あたりを利用すると 似たようなことができるかもしんない。
mbstowcsは、出力の文字コードってなんですか? UTF8とか16とか? 環境による?決まっている?とか。 ・
560 :
558 :2008/03/23(日) 13:09:53
具体的には?
未定義に具体的もクソもあるか!
boostが使えないので 簡易的なLexical_castを作りたいのですが stringstreamを使うのと特殊化してsprintf系を使うのはどちらが高速に処理できるでしょうか?
実測重要
高速かどうかの話は知らないけど、 iostream系使ってるのはoperator<<のオーバーロードを利用したいからで、 sprintf使うと色々幅が狭まらない?
適材適所
566 :
デフォルトの名無しさん :2008/03/23(日) 14:43:27
整数を2で割るときって、i/2 とするより、
i
>>1 とビットシフトした方が速いのでしょうか?
WindowsXPで動作するアプリで、VC++.NET2003で作ってます。
普通のコンパイラでは勝手に最適化されるから 気にせず i/2 としとけ。
568 :
デフォルトの名無しさん :2008/03/23(日) 14:47:04
変わらないとおもうけど、気になるならシフトにしとく 見にくくなるのと、括弧の位置がかわるが
>>562 sprintf
by Exceptional C++ Style
>>566 符号付整数だとシフトだけで済むぶんi >> 1とかのほうが多くの場合速い。
符号無整数だとよっぽど酷いコンパイラを使わない限り最適化で同じになる。
>>568 意図したことをそのまま書いた方が
最適化が考慮されている可能性は高いので、
シフトにしない方がむしろいいと思う。
573 :
デフォルトの名無しさん :2008/03/24(月) 02:23:38
char ss[80]; で cout << &ss; cout << (void *)ss; の2つの結果が同じなのは、なぜですか? 下の意味がよくわからないです。
>>573 なんで同じであることに納得いかないのか分からん
どうなると思ってたんだ?
575 :
デフォルトの名無しさん :2008/03/24(月) 02:41:16
上がssのアドレスで下がssの値が表示されると思ったんです。
じゃあその考え方が間違っているんだろう。
文字列表示は char* か const char* を渡した時だけだろ。 void* とか他のポインタの場合はアドレス表示。
>>575 上が配列ssのアドレス、下が配列ssの最初の要素へのアドレス。
配列へのポインタ、charへのポインタをvoidに変換しているという点で
型は違うが、アドレスは同じだと思うんだ俺。
>>578 >上が配列ssのアドレス、下が配列ssの最初の要素へのアドレス。
ちょっと違う。前者は配列ssへのポインタがで、後者は配列ssへのポインタと同値の型を伴わないポインタ。
アドレスでなければいけないとは決まっていないし、値を取り出しているかどうかは実装依存。
# printf("%p", ss)で何が出力されるかと同じ問題だね。大抵は、16進でアドレスを出力するのだろうけれど。
>>571 符号付整数の右シフトは環境依存なので、不用意に使うのは如何なものかと。
それに、実際に速いのか? 「多くの場合」とは? 案外処理時間は同じかも知れんぞ。
(不用意に)使うべきとは言ったつもりではない。 単に速度に差があるという指摘のみ。 符号付シフトがコンパイラ依存なのには同意。 速度は実際のところ実測しないと分からないから正直、 適当に推測して書いた。 ただ、符号付除算は最適化前提でもシフトよりは軽くならんだろ。 >>は算術シフト、>>>は論理シフトとすると x/2は大体こういう式に相当する (x >> 1) + (x >>> 31 & x) ・・・ 32bit整数の場合 で、この演算コストがx >> 1より軽い事はまずないだろーって感じの推測。 これがシフト演算1命令より軽いアーキテクチャってあったっけ? ま、正直C/C++の話題からはずれ気味なんでどうでもいいや。
そもそも、x86なんかだと負の値については2で割った結果と右シフトした結果は違うんじゃない? 例えば、-3/2は-1だけど、-3を右シフトしても-2にしかならないと思う。
>>582 結果は異なるのは当然やん?
だから、符号付除算をシフトに置き換える最適化をしても、
結果の補正に演算が必要になる。
その補正の演算分だけ符号付除算が遅いって話だよ。
シフト演算と言えば double型のまま計算するより 有効数字倍(10倍やら100倍やら)のint型に変換してから処理して 最後にまたdoubleに戻してやる方が処理によっては高速になるとかいうテクニックがあるようですが このとき double型を1000倍してから1/1000するより 1024倍して1/1024する方が除算がシフト演算になるからより高速になると聴いたのですが本当ですか?
いちいちdoubleとintを変換するとかえって遅いかもしんない double→int変換は結構遅かったような
>>584 それはシフトじゃなくて、
1000じゃなくて1024にすれば浮動少数の指数部だけ変更すればいいから速いって話じゃないの?
コンパイラが乗除算を指数部への加減算に置き換えてくれるかどうかは疑問。
浮動少数周りの最適化ってコンパイラにはあんまり期待できないし。
>>583 結果が違ってしまうシフトは負の値には使えないって結論でいいの?
それとも、結果が違ってでも速くしたいのならシフトも試してみろってこと?
>>587 いや、符号付の2の除算と(算術or論理)シフトは本質的に異なる演算でシフトのほうが補正がない分速いってだけ。
二つの演算の速度の差以外はなにひとつ主張する気はないし、それ以外の結論も出していない。
そこから先は個々人で判断するべきだと思っている。
>>579 少し書き方が悪かったけど、あげあしはとらないでよ。
揚げ足じゃないだろ
アゲアシだよ
ageashi
うみうしに似てるな
594 :
デフォルトの名無しさん :2008/03/24(月) 15:21:28
vector<int[10]> s[5]; は5*10の配列でしょうか? vector<int[10]> s; として、push_backで追加するにはどうすればいいですか? 何を追加したら増えますか?
int[10]型の何かを追加すればいいだろ
596 :
594 :2008/03/24(月) 15:22:59
質問を変えます 256個の固定配列が、可変個数必要なのですが、どのように定義するのが良いですか?
597 :
デフォルトの名無しさん :2008/03/24(月) 15:24:09
596でなくて?
>>596 struct Array256 {
int array[256];
};
or
#include <boost/array.hpp>
typedef boost::array<int, 256> Array256;
vector<Array256> s;
基底クラスへのポインタの配列に数種類の派生クラスを放り込んでいるのですが、 そのポインタがどの派生クラスを指しているかを直接知る方法はありませんか? メンバ変数にどの派生クラスか印すのが手っ取り早いとは思いますが
そんなことが必要なら設計がおかしい。 なんで派生クラスの種類が知りたいんだ?
>>600 class Base {};
class Derived1 : public Base {};
class Derived2 : public Base {};
...
Base *obj;
Derived1 *derived = dynamic_cast<Derived1 *>(obj);
これでderivedがNULLで無ければ、objはDerived1派生クラス。
RTTI必須なので注意。
typeinfoとか実行時型情報とかで出るやつか?
ファイルとフォルダがツリー状になってる構造とか作るときは必要だろ
必要じゃないよ。
クラスの種類を識別する固有の値を返す関数を埋め込むとか
>>605 それデザパタのコンポジットパターンでいいじゃん。
いちいちdynamic_castとか必要か?
実行時型情報が取得したい場合、たいてい 抽象化ミスってるか、多態で解決できることに気付いていないかのどっちか。
>>608 f = new File;
f.add(new File);
こんなのを静的にエラーにしないといけない場合は、そのパターンとれないっしょ。
class basic_file { }; class directory : public basic_file { public: void add(basic_file* file); }; class file : public basic_file { };
それを使うとき実行時型情報が要るじゃないか。
>>610 静的にエラーというのが何を指しているかいまいち分からん。
コンパイル時に弾きたいならFileクラスでaddのアクセス権限をprivateにしときゃいんじゃね
ダブルディスパッチで解決。
それよりだれも f = new File; f.add(new File); には突っ込まないんだね。 正しく?は f = new File; f->add(new File);
Firefoxのアバウトダイアログにはマウスで反応するコントロールが 環境表示部分のEDITクラスらしきものとBUTTONクラスらしきボタン2つがあるんですが これらのコントロールはspy++でハンドルを取得しようとしてもその親ウィンドウらしきハンドルしか取れないんですが CreateWindow等で作成したコントロールでも親ウィンドウで何らかの処理をするとハンドルを隠す事が出来るのか それともコントロールに見えるけど実は全部描いて作って処理も既存のクラスのように振舞っているのでしょうか? また、前者ならどのような処理をしているのでしょうか 他人のソースコードなんてそんなに見たことないのにあの量のコードじゃ目が点になってしまい挫折してしまいましたorz
>>616 今は別に表記の話題をしてるわけじゃないから、
pseudocodeと思っとけばいいだろ。
# D言語ならそのまま通るし。
Effective C++ 第3版の3項(const)で 「論理的な不変性を保証しない」例が、 載っているのですが、 試しにコードを書いて実験したところ、 確かにコンパイルは通りますが、 実行時エラーとなります。 なにがいけないのか、わかる方、 教えてください。 ・実行時エラーの原因 ・本の意図することを確かめる方法 class CTextBlock{ private: char *pText; public: CTextBlock (char* ini_txt) : pText(ini_txt){}; char& operator[](size_t position) const {return pText[position];} }; int main() { const CTextBlock cctb("Hello"); char* pc = &cctb[0]; *pc = 'J'; // ここで"Jello"になるはず } この最後の部分で、本では"Jello"になると言っていますが このコードでは実行時エラーになってしまいます。。。
文字列リテラルを直接書き換えちゃダメ。
"Hello"などの文字列リテラルはconst char*なので本来は書き換えることが出来ない。 (特例でこの場合はchar*に暗黙にキャストされてるけど) 本来書きかえれないものを書き換えたからエラーが起きたんだろう。
>>620-621 ありがとうございます。
では、本でやっていることは無理ということなのでしょうか。
それとも私のコードが悪いのでしょうか。
上記のmainは本そのまま、operator[]記述も本そのままです。
constなのに書き換えられちゃうよ、ということが証明したいのだと
思うのですが。
>>617 全部自分で描いてると思うよ
でなきゃテーマ切り替えたりできんだろう
>>622 動く環境もあるのは確かなんだけどな。
まあ、組み込みとか MS-DOS とかそういう環境だろうな。
625 :
デフォルトの名無しさん :2008/03/24(月) 18:54:21
HDDを使った配列クラスを作りたいです 既にありませんか? stringを100万行とかはメモリに確保するのは困難ですが HDDなら簡単です
>>624 ありがとうございます。
それでは、ここは気にしないことにします。
>>625 ifstream,ofstreamを使ってちまちまやりましょう。
>>622 よくある実装は文字列リテラルをROM領域に配置するというもの。
寛容に読むことも大事ですよ。メイヤーズが言いたいことはビットレベルの不変性
は保たれていても、この例のように例えばクラス外部で保持しているデータは変更
される危険があることを言っている。この考えは、いろいろな状況で応用できるでしょう。
まあ、気になるならメイヤーズに直接メールして聞いてもいいんじゃないか?
>>623 やっぱりそうですか
自由度の高さから自前で描いてるような気はしてましたけど
あまりの完成度なので…
ありがとうございました。
630 :
デフォルトの名無しさん :2008/03/24(月) 21:01:49
>>625 無いと思うけど、100万行も何のデータに使うの?
631 :
デフォルトの名無しさん :2008/03/24(月) 21:04:15
>>630 100万行に限りませんが、vectorの同等の使い方で
int型配列100メガとか、1ギガとか、メモリ上に確保が難しい場合にメモリが空けられます
巨大行列をディスクを併用して利用するようにしたことはあるな。 数値計算とか画像処理とかやってたら普通に必要になることはあるよね。 そんときゃ自作した。 全部 HDD に置くとパフォーマンスに影響出るから、 一部をメモリに置くとかやった。 そういう形の最適化を個々のケースに対して行うことがあるから 出来合いのものは(多分ないとは思うけど)使わない方がいいかもね。
MMFとかじゃいかんのか
634 :
デフォルトの名無しさん :2008/03/24(月) 21:26:00
メモリマップドファイルは良さそうですね これにバッファを取り付ければ実用的になりそうです サンクス
32bitアプリである以上、仮想メモリ2GBの壁の方が・・・
メモリマップドファイルって、普通、OSが適当にメモリにキャッシュする仕組みだぞ。 処理の都合で、というのならともかく、パフォーマンス目的で自前のバッファを持たすのは無駄である可能性がある。 そのバッファもページングでHDDへ送られる可能性があることをお忘れなく。
637 :
デフォルトの名無しさん :2008/03/24(月) 21:45:36
たとえば500Mのメモリ確保すると、実メモリに何とか入れきれるかもしれないけど 別のデータが出てきて追い出される可能性がある ( メモリを圧迫するという事 ) そしたら初めから最大値を10Mまでと決めておけばメモリの確保が出来る
のぞき窓を物理メモリ上に固定すればいい。
プログラム歴 : 20分 やりたいこと : サンプルプログラムのコンパイル 環境 OS : windowsXP memory : 512MB CPU : Pentium3 1.13GHz ファイル名 test.c 内容 #include <stdio.h> main() { printf("こんにちは"); } やったこと このファイルをborlandとやらのbcc32.exeにD&D 結果 コマンドプロンプトが一瞬出現、消失。 何がなにやらさっぱりです。
>>639 ググれ
詳細に解説してあるサイトがあるから
>>639 プログラムが”正常に”終了したのでプロンプトが閉じられました
printf()のあとにgetchar()でも追加しとけ
>>641 いやいや、それよりずっと以前の問題だからw
>>639 正直なのはいいことだが、20分は短すぎるぞ。もっと悩め
644 :
641 :2008/03/24(月) 22:59:35
初心者っていうか、入門するはずの門に顔ぶつけたくらいの勢いだねw
コマンドプロンプトの使い方を覚えるか素直にIDEを使うか
D&Dでコンパイルにソフト開発の未来を見た
ああ、再起動してなかった。 PATHとやらも設定したんで今日は電源落として寝るよ。
set path=%path%;ほげほげ をして電源落とすところを想像して興奮した
650 :
639 :2008/03/24(月) 23:31:00
待機電力節約のためにいきなりコンセント抜いて電源落としました。
動かないな。 性能低かったのかね。
>>621 >>624 C++だとconst char *なの?
C言語だと、文字列リテラルの書き換えは未定義で、
VC++ではオプションで動作を変えれた気がするんだけど、
ウソ情報かも知れない。
未定義だけどそんなオプションは無かったと思う。
ないよ
ないある・・・ら・・・
かゆ… うま…
「文字列をプールとして扱う」というオプションが
659 :
○ :2008/03/25(火) 07:18:20
>>652 C++ では const char[] だけど char* にも代入できる、という変なもの。
名前ミスったw
663 :
デフォルトの名無しさん :2008/03/25(火) 13:21:29
c++プログラムの特定の関数でメモリアクセスが何回起きてるか調べられるシミュレータってありますか?
抽象クラスの変数を持つ構造体を作ることって可能でしょうか? class Abstract{ virtual void piyo()=0; }; struct Hoge{ Abstract a; }; もちろん実際に使う時にはAbstractの派生クラスの具象クラスしか代入はしませんが、 これに準ずる方法などありますでしょうか?
Abstract *a; じゃダメなの?
std::auto_ptr<Abstract> a; じゃダメなの?
Abstract& a; じゃダメなの?
boost::shared_ptr<Abstract> a; じゃダメなの?
>>665 ,667
実態じゃなきゃダメなんです。
>>666 auto_ptr使ったことないんですが、ちょっと調べます。
用途を書いておくと、あるクラスにAbstractの派生クラスを渡しそれらを一つのvectorで保持するという物なのです。
Javaで言う<T extends Abstract>(だっけ?)みたいなことができれば解決できるかもしれないんですが・・・
>>669 javaでのAbstract a;と
c++でのAbstract* a;は
大雑把に言うと、同じもの。
まずはc++でのポリモーフィズムの書き方について、
サイト見て回った方が良いと思うよ。
>>666 ,668
実体じゃn
今はテンプレートでこんな感じで組んでます。
class Touroku{
struct hina{
template<class T>T data;
template<class T>hina(T& t):data(t){}
その他のデータ
};
std::vector<hina> items;
public:
template<class T>void add(T&);
};
template<class T>
void Touroku::add(T& t){
items.push_back(hina(t));
}
これだと下の関数を呼び出すと外部シンボルが未解決とでてコンパイルできません。
どうすればいいんでしょうか?
>>670 それは分かってるつもりなんですが・・・
でもC++じゃポインタ渡しただけじゃコピー用のメソッドとか作っておかないと
中身同じの実体同士の代入と同じ効果得られなくないですか?
>>672 おまえはJavaもC++も一から勉強しなおしたほうがいいかもな。
まじすか・・・ すいません。ちょっと解説お願いします
とりあえず、Javaで String str1 = "hogehoge"; String str2 = str1; としたとき、str1もstr2も同じ"hogehoge"という文字列のインスタンスを指すって理解してる? してるなら、 const char* str1 = "hogehoge"; const char* str2 = str1; これは?
同じとこ指してますよね
なら
>>672 の意図は?
Javaでも実体同士の代入と同じ効果が欲しけりゃ、
clone書くなりする必要があるわけだが。
あ、そうでしたっけ・・?
しばらく離れてたからってのは言い訳にならないですよね・・・
(そういえば、配列とかも渡した先で変更したら中身変わってますよね。^^;)
でもとにかく、実体でコピーさせたいんですけど、
>>671 のコードどこが間違ってるか
分かりますでしょうか?
もう盛大に違う。構文からして違う。
全部説明してたらキリ無さそうだな
#include <vector> template <class T> class Touroku { struct hina { T data; hina(T& t) : data(t) {} }; std::vector< hina<T> > items; public: void add(T& t); }; template <class T> void Touroku<T>::add(T& t) { items.push_back(hina(t)); } int main() {} とりあえずbcc32で通ったコード
あ、ごめん、これじゃダメだ。
ていうかメンバの方が違う構造体を同一物として扱うことなどできるんでしょうか・・・
今ちょっと距離を置いて考えたら普通に無理ですねこれ・・・ ポインタで何とかするもの考えて見ます。
struct Abstract { virtual void func() = 0; }; class Nanika { std::vector< boost::shared_ptr<Abstract> > items; public: void add(boost::shared_ptr<Abstract> item); }; void Nanika::add(boost::shared_ptr<Abstract> item) { items.push_back(item); } struct Test : public Abstract { void func() {} } int main() { Nanika n; n.add(boost::shared_ptr<Abstract>(new Test)); }
スマートポインタクラス作ってて思ったんだけど単項演算子の*は抽象クラス で具象化するときコンパイルエラーになっちゃうけど、既存のスマポはどうしてるんでしょうね
688 :
デフォルトの名無しさん :2008/03/25(火) 21:38:30
ポインタ配列に書いているアドレスの先を消したいのですが以下でよろしいのでしょうか #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFSIZE (5) void FreeAddress( char **cData , int iLen ){ if( iLen >= 0 ){ for(int i = 0 ; i < iLen ; i++ ){ free( cData[ i ] ); } } } int main( ){ char *cData[BUFSIZE] , *cBuf, cCopy[5]; for(int i = 0; i < BUFSIZE; i++ ){ cBuf = malloc( sizeof( char ) * 5 ); if( cBuf == NULL ){//失敗したら消す FreeAddress( cData , i ); // return 0; } else{ sprintf(cCopy ,"%04d", i ); strcpy( cBuf , cCopy ); cData[i] = cBuf; } } for(int i = 0 ; i < BUFSIZE; i++ ){ printf("%s\n",cData[i]); } return 0; }
>>688 多分、よろしい。
ただ、free(cData[i]) の後に cData[i] = NULL を書くか、
FreeAddress( cData , i ) の後の return 0 を有効にしないと、
エラー後の文字列出力が正しく行えない。
690 :
デフォルトの名無しさん :2008/03/25(火) 22:34:35
ifの条件で、入力されたchar型変数の文字列と、ある文字列が等しいとき というif文はどう作ればいいのでしょうか?
691 :
デフォルトの名無しさん :2008/03/25(火) 22:36:46
>>690 if (strcmp(nyuuryoku, arumojiretu) == 0)
692 :
688 :2008/03/25(火) 22:44:37
お前ら、全角空白でもいいからインデント入れようよ・・・。 ちなみに と書けば半角空白でも連続して入れられる。 ↓をコピペして書くと if(1){ f(); } ↓となる if(1){ f(); }
半角スペースが省略されていても、janeならctrl+レス番号早打ちポップアップ起動で インデントされて見えるから、特別読みにくかったらそうすれば言いだけの話。
むしろnbsp入れるとコピーしたときにひどいことにならね?
IE+壷, oepra+壷では普通に空白になるよ。 janeとかだと、逆に でコピーされる? というか、janeでインデント見れるってことは、 datには情報残ってるんだな。知らなかったよ。 壷の前にローカル串入れていじってみるわ。
>>694 jane使ってたけど知らなかった。ctrlなしならそのスレにジャンプなんだな。thx
698 :
デフォルトの名無しさん :2008/03/26(水) 00:44:49
ウインドウのクラス化について質問です。 Windowsが直接呼び出すウインドウプロシージャから 各インスタンスのウインドウプロシージャ関数を呼び出すとき、 ウインドウプロシージャで得られたウインドウハンドルからそれぞれの インスタンスを特定するコードを書いています。 で、ウインドウハンドルとインスタンスの関連付けは ウインドウハンドルを戻り値として得られるCreateWindowEx()直後で やってるのですが、CreateWindowEx()終了前に呼び出されるWM_CREATEを どうやって捕まえるかで悩んでます。 CreateWindowEx()直前で未登録インスタンスを Windowsが直接呼ぶウインドウプロシージャに予め教えておき、 関連付けのないウインドウハンドル&WM_CREATE時は 予め教えておいたインスタンスを呼び出す方法を考えたのですが、 どうも美しくない。何かの間違いで予期しない動きもしそうですし。 そこで皆さんの知恵を拝借いただければと思った次第です。
699 :
デフォルトの名無しさん :2008/03/26(水) 00:47:20
関数内のstatic変数は、始めに初期化したら次からは初期化は無視されますか?
無視されます
701 :
デフォルトの名無しさん :2008/03/26(水) 00:54:03
サンクス もう一つ質問があります staticな可変個 (動的) 配列は、static int *x;とすればですか? なんども別なのが作られませんよね?
CreateWindowEx の最後の引数に this を渡す。 CREATESTRUCT の lpCreateParams に入ってるので ウィンドウプロシージャでそれを拾って OnCreate を呼べばいい。
>>701 static int *x = new int[100];
と書いた場合、new は最初の1度しか呼ばれない。
static int *x;
x = new int[100];
と書いた場合、毎回 new される。
初期化と代入の違いってやつやね。
まあ、new だとプログラム終了時に delete してもらえないので、
std::vector を使うのを薦める。
704 :
701 :2008/03/26(水) 00:56:35
訂正 関数内で、static vector<int> x; と定義して、xが変更されたとします 次に関数呼び出しがあったときもxは残っていますか?
705 :
デフォルトの名無しさん :2008/03/26(水) 00:57:38
残ってる。
707 :
デフォルトの名無しさん :2008/03/26(水) 00:59:18
ありがとうございます
static はお手軽だけど、自由度が下がる諸刃の剣。 よく考えて使うように。
709 :
デフォルトの名無しさん :2008/03/26(水) 01:13:32
関数 F(n)で、nごとにstatic変数を用意する方法ありますか? たとえば、1のとき、2のときで値を保持します
710 :
デフォルトの名無しさん :2008/03/26(水) 01:16:36
vectorとmap使ったらいいですかね? 異なるnが増えるごとに、vectorの個数を増やして mapでハッシュとして関係づけます ほかの方法ありますか?
>>709 staticなmapを用意すればいいんでね?
でも、それは多分よい設計ではない。
712 :
710=709 :2008/03/26(水) 01:20:41
>>711 static なmapが一番簡単ですか 710は勘違いしてました
static はお手軽だけど、自由度が下がる諸刃の剣。 よく考えて使うように。
714 :
デフォルトの名無しさん :2008/03/26(水) 01:36:37
こんばんは。 構造体配列についてお聞きしたいのですが KATA k[2] = {{1,1}, {2,4}}; という構造体で定義して この関数呼び出しで{1,1}をひとつのprint文で表示する 方法ってありますか? 関数でvoid*baseで受け取った場合 printf("%d",*base1); とすると1だけ表示されます r(k,sizeof(k)/sizeof(k[0],sizeof(KATA); としたとき rの関数内でこの構造体配列の
716 :
714 :2008/03/26(水) 01:56:24
構造体配列の中のメンバをfor文を使わず文字列みたいその構造体配列の先頭アドレスで すべてのメンバを表示することは可能なのでしょうか?
void * じゃなきゃだめなのか? printf( "%d %d", ( KATA * )base1.value1, ( KATA * )base1.value2 ); とかは? となるとかなり環境依存のコードでなきゃ無理だと思う。
718 :
714 :2008/03/26(水) 02:09:04
>>717 さん
はい。そのは仕様でvoid*となっているので変えられません
base1.value1が引数でvoid*型なんで
char*でキャストしてポインタで考えるんですが
どうしても先頭しか表示できないんで困ってます
719 :
デフォルトの名無しさん :2008/03/26(水) 02:51:58
うまくうごきません なぜですか? 2度目の表示はカウントされているはずですが? class cls { public: int n; cls(){ n=10; } }; int F(int n){ static map < int, cls > x; return x[n].n; x[n].n++;} main(){ cout<<F(0)<<endl; cout<<F(0)<<endl; }
720 :
デフォルトの名無しさん :2008/03/26(水) 02:56:33
自己解決しました
呼ぶ側が foo( ( void* )( &k[1] ) ); なら呼ばれる側は void foo( void* p ) { KATA* k = ( KATA* )p; printf( "%d %d", k->value1, k->value2 ); } な感じ。value1とかは適当に置き換えて
>>718 困るのは判るが、先ずは自分の書き込みを読み直す癖をつけろ。
724 :
デフォルトの名無しさん :2008/03/26(水) 03:56:39
質問です Cの勉強を始めようと思い独習Cという本の3版を買ったのですが、時間がとれずにいるあいだ、4版が出てしまいました ご存じの方がいらっしゃれば、 3→4での主な変更点(買い換えを勧められるような変更があったかどうか)を教えていただけないでしょうか googleで検索しても、Vista対応、コンパイラ刷新程度のことしかわかりませんでしたのでここで質問させていただきます 私はほとんど初学で、リファレンスを写しながら数百行程度のプログラムを数個つくったことがあるだけ ということもアドバイスの考慮に入れていただけると幸いです もしすれ違いでしたら申し訳ありません
勉強だけなら10年前の本だって問題ない 気にせず勉強がんばれ
726 :
デフォルトの名無しさん :2008/03/26(水) 05:20:35
map < int, cls > x; とすると、x[n]はクラスですが、 その初期化の時に番号nを使う事は出来ませんか?
727 :
デフォルトの名無しさん :2008/03/26(水) 05:26:15
インクリメントする前にreturnしてるから。
それは自己解決したっつったろうがボケ
729 :
726 :2008/03/26(水) 05:32:09
初期化のあとで、nを使ってデータを書き換える事も出来ますが 毎回書き換えが行われてしまいます 初めの一回だけにしたいんです
730 :
デフォルトの名無しさん :2008/03/26(水) 05:33:53
すみません あまり良い方法ではないですが解決しました 始めにあり得ない値で初期化しておき、そのときだけnで書き換える事にします
731 :
デフォルトの名無しさん :2008/03/26(水) 06:56:32
ID無いんだから自己解決でも安価つけような
>>726 x.insert(std::pair<int, cls>(n, cls(n)));
new が無いC++の環境で、こんな風にグローバルで new オペレータが定義されてました。 void *operator new(size_t size){ return malloc(size); } これで、以下のプログラムが動くんですが、理屈がよくわかりません。 TestClass* pobj = new TestClass(); 関数っぽく書くと、こんな感じのように思うんですが、 TestClass* pobj = new(TestClass()); size_t型を引数にしてるのに、何故引数にTestClass()を入れられるのでしょうか。 それと、malloc()でメモリを確保しているのは分かるんですが、 どこで、そのメモリにオブジェクトのデータがコピーされてるんですか。
>>733 newが無い?
733の定義はnew演算子の定義じゃん。
newを演算子として認識はするんでしょ。
>>733 その定義は、メモリを確保してnewに与えるためのもので、new本体ではない。newはコンパイラがうまく処理してくれる。
newは演算子
vtuneの質問はここでしておk?
おk
template<typename T> class Hoge{ template<typename U>Hoge& operator =(const Hoge<U>&); }; このテンプレート関数を部分特殊化したいんですけど、 一つ目はUがTと等しいタイプで二つ目はTとUがクラスであるタイプ なんですが、いまいち書き方が分かりません。ご教授願います。
>>740 その2つの特殊化があるとして、TとUが等しいクラス型だった場合は
どっちが使われるんだ?
>>740 U と T が等しい場合はコンパイラが生成する oeprator = と同じ引数になるんで
テンプレートが使われることは無い。特殊化として書きたかったバージョンを普通の
代入演算子として書いとけばいいよ。
>>741 その場合はどちらでも良い実装なのですが、コンパイラ的にはどうなのか分かりません。
>>742 実はこれスマートポインタクラスなのでそれではダメなんです。参照カウントのインクリメントが
必要なので、
二つ目のは派生クラスから基底クラスへの代入ができるようにするためのものなんですが、
これで合ってるのかなぁ・・・
>>743 1つ目はテンプレートでないHoge& operator =(const Hoge&);を定義すれば実現できる。
(742の言い直しだけど)
2つ目のスマートポインタでアップキャストは740のやつをそのまま
(部分特殊化せず)使ってできないのか?
boost::shared_ptrはそうしていたはずだが。
あ、一つ目のはそういう意味でしたか・・・戻したらできてるっぽいです。 二つ目を740で定義してるんですが、以下のようなところで変換できないと言われてしまいます。 class Base{}; class Derive:public Base{}; void hoge(my_ptr<Base>); { hoge(my_ptr<Derive>(new Derive())); }
>>745 @my_ptr<Base>とmy_ptr<Derived>は異なる型。
A関数への引数渡しは初期化のセマンティクス(代入演算子は使われない。)
BMore Effective C++ 項目28を読む。
ありがとうございます。 コピーコンストラクタの定義も加えたらコンパイルは通りましたが、 @のルールからパブリックでないポインタ本体やカウント変数へのアクセスが できません。これを解決する手段というのはあるのでしょうか?
横から失礼 初期化のセマンティクスってなんですか?
実引数から仮引数への受け渡しは、 (operator =ではなく)コンストラクタによって 行われているということ。
>>749 なるほど
実引数が元々持ってた変数等の値の代入もコンストラクタで行われるのですか?
>>750 何を言ってるのかわからない
こういうことだろ
void foo(Bar x) {
}
int main() {
Bar y;
foo(y); // Bar のコピーコンストラクタを使って実引数 y から foo の仮引数 x を初期化する
}
ああ、コピーコンストラクタのことかorz となると、めんどくさがらずにちゃんとコピーコンストラクタを用意してあげないと後々面倒になりそうだ
コピーコンストラクタと言えば メンバにFILEやHANDELの様な物を持つ場合これらの扱いはどうしたらいいのでしょうか? ポインタの場合は参照先を共有するか、実体をコピーしてくるかはそれぞれだと思うのですが・・・
>>753 自己レス
HANDELじゃなくてHANDLEだったわorz
>>753 共有するか、コピーコンストラクタと代入演算子をprivateにしてコピー不可とする
コピーできなくてもswapはできればほしいな。
ファイルポインタなんかはNULLにしたり、別のファイルを開いたりしておくのはあり?
>>747 Hoge<T>にキャストしてないと予想
DuplicateHandle
最適化の所に人いない・・・ vtunesで各関数のアクセスメモリ数調べるためにはどこをいじればいいんでしょうか 使ってる人いたら教授願いたいのですが・・・
>>758 それは内部でということでしょうか?関数内では
p=(T*)arg.p;
というようにはしてますが・・・
それ以前の話でしたらもう少し詳しくお願いできますでしょうか?
>>733 new TestClass(); の動作は、
1. operator new(sizeof (TestClass)) を実行してメモリを確保する
2. 返されたメモリ領域を使ってコンストラクタを実行する
この2つ。
void *p = operator new(sizeof (TestClass));
みたいに直接 operator new を呼ぶとコンストラクタは呼ばれないが、
ちゃんと new 演算子を使えばコンストラクタが呼ばれるようになっている。
763 :
733 :2008/03/26(水) 21:06:01
>>734 >>735 >>762 どうもありがとうございます。
new で確保されたメモリでコンストラクタを実行するのは、
定義とか関係なく、コンパイラの特殊機能ということですね。
new の機能が使えなかったわけじゃなく、
operator newにメモリを確保する機能が実装されてなかったから、
自前でmallocしてただけってことでしょうか。
>>763 殆どのC++での実装がmallocを呼ぶようになってたと思うよ。
mallocはCの機能だろ C++はnew
new演算子の話が出てきたので…… char buff[100]とでも宣言してメモリを確保した後、 int *a=new(buff) int[50]; とした場合、int型の配列の後半は、最初に確保したメモリをはみ出します その場所がすでに使用済みだった場合、正常に動作しなくなるのでしょうか
そりゃそうだな。
>>761 ごめん。ちょっとうろ覚えだったw
boost::shared_ptr.hppみたらフレンドになってるじゃん
private:
template<class U> friend class Hoge;
みたいにするらしい
>>767 最近の一般的なPCではcharは1バイトでintは4バイトなんだから当然だろ
>>678 ,770
いや、超えた分は別のところにしっかり確保されるのか、
気にせず確保してない部分に書き込んでバグるのか、
多分後者だろうけど、聞いてみました
thx
placement new は新たにメモリを確保するもんじゃないから 確保し直しなんて起きなくて当然じゃよ。
>>769 おお!できました!
テンプレートって面白いし使えると便利なのに複雑すぎて使いこなせない(´;ω;`)
>>765 newも結局ヒープから領域を取ってくる必要がある。
別に固定配列から切り出したっていいんだぜ?
おν
777 :
デフォルトの名無しさん :2008/03/27(木) 00:04:15
return 777;
return 666;
継承ツリーのなかで ある一つのクラスだけ、メソッドの返り値がintじゃなくてdoubleが必要になってしまいました こういう場合はどうしたらよいのでしょうか?
その説明だけでは何とも言えんが ・そのクラスを継承ツリーから外す ・戻り値がdoubleの仮想関数を継承ツリーの最上位に作る のどっちかかなぁ。
初心者歓迎とか言いつつも、boost薦めてるのって何なの?
初心者歓迎≠住人全て初心者 boostの実装の理解は難しい≠boostの使用は難しい
783 :
デフォルトの名無しさん :2008/03/27(木) 04:39:36
昨日の続きなんですがおねがいします map < HANDLE, クラス > x; と定義して x[fp].read() として使いたいのですが、readの中でファイルハンドルfpを使いたいとします x[fp].read(fp) と2回fpを書くしかありませんか?
784 :
デフォルトの名無しさん :2008/03/27(木) 04:42:24
自己解決しました マクロで定義する事にします
質問です コマンドプロンプトでしかプログラムを動かしたことがないのですが FLASHのようにカーソルがのったときになにかする・・・のようなことをしたいときには どういう機能を使えばいいのでしょうか?GUIというやつでしょうかそれともDirectXとかでしょうか 無知ですみませんがよろしくお願いします。
786 :
デフォルトの名無しさん :2008/03/27(木) 04:43:57
BCBやC#使うと楽と思います C++でGUIやるのは難しいです
>>786 即レスありがとうございます
がんばってC#やってみます
788 :
デフォルトの名無しさん :2008/03/27(木) 09:40:31
>787 とりあえずグラフィカルなプログラムを体験してみるならSDLあたりが簡単
SDLだと公開するとき自分の汚いソースも公開しないといけなくなりませんか?
bitsetについてなんですが 8bitで入ってきたデータを整数型に直して評価した後、bitsetに入れ込んでbitごとのflagを確認したいのですが 例えば 01010000 → 80 → 00001010 とbitsetに入れ込んだときに前後が入れ替わってしまうのをどうにかする方法は無いでしょうか?
>>790 GPLだと思っていたらLGPLでした
スタティックリンクしなければ大丈夫みたいですね
コンストラクタは通常 基底クラスのコンストラクタ→派生クラスのコンストラクタの順で呼び出されるけど コピーコンストラクタも同様でいいのでしょうか?
>>791 Intel CPU(little endian)マシンでも
bitset<8> bs(80);
とすれば01010000となるけど?
何で入れ替わってしまうの?
まあ入れ替わるなら望むビットパターンになるように
0x08にしてbitset作れば?
失礼 0x08 × 0x05 ○
>>779 事後条件を弱化してるならOOPの基本からやりなおせ
>>779 すべてのクラスをdoubleで書き直す
設計がおかしいなら設計から直すべき
800 :
デフォルトの名無しさん :2008/03/27(木) 14:28:55
800
>>779 継承を用いず、templateを用いる
803 :
デフォルトの名無しさん :2008/03/27(木) 16:56:45
windowsのcygwinで小さなC++プログラムをコンパイルすると すべて実行可能ファイルが467キロバイトになります。 なんでこんなにでかくなるんですか??? あとなんで全部同じ大きさなんですか??? ほかの環境でもそうなるんですか???
804 :
デフォルトの名無しさん :2008/03/27(木) 17:00:13
>>803 STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
805 :
デフォルトの名無しさん :2008/03/27(木) 17:04:13
C#は異常にサイズが小さい
>>803 コンパイルするときに -s を付けるか、コンパイルした後に実行ファイ
ルを strip してください。
>>803 VCやbccならそこまで大きくならない。STL使うと少し膨れるけど
どっちにしろダウンロード時間が1秒のびる程度なんだから文句いうな
808 :
デフォルトの名無しさん :2008/03/27(木) 17:42:20
すみません。 教えてください。 VS2005でC++でプログラムを始めたんですが、最初の第1歩でつまずきました。 #include <iostream> using namespace std; int main() { cout << "Hello World." << endl; return 0; } としてビルドしたところ、 「対応する関数ヘッダーがありません(旧形式の仮引数リスト?)」 とエラーがでます。 どこかで、#include <iostream>は古い形式だから新しい形式で書かなければならない、 と読んだような気がするのですが、見つからなくなってしまい、 ここに書き込んだ次第です。 すみませんがエラー解決方法を教えていただけないでしょうか?
古い形式は、 #include <iostream.h> エラーはそのまま貼り付けれ
810 :
808 :2008/03/27(木) 17:49:00
失礼しました。 error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?) C:\Program Files\Microsoft Visual Studio 8\VC\include\cstdio 24 です。
コードは本当に上のと一緒か? int main(); { } とかなってないか?
812 :
808 :2008/03/27(木) 17:53:43
>>811 はい、コードはコピーしましたので、その通りです。
お手数おかけします。
雑談になってしまいますが、今C言語を勉強しています でもいつも途中で挫折してしまいます。 昔のノート見たら日付が5年前だし・・・それでいて全く進んでないし・・・ 皆さん勉強する上で、どうやってモチベーションを維持しいますか?
>>801 テンプレートでどう対応するのですかorz
テンプレート使ったこと無いので見当が付きません
>>813 とりあえず大きな目標を一つ、ちょっとしたソフトを完成させるとか
ベテランから見たらどんなに稚拙で汚いコードでもとりあえず書く(但し、自分で書ける限り最上のコードでねw)
それでそのソフトを書く上で必要な機能は嫌でも身に付く
あと、本とか目を通して使えそうな自分の知らなかった技術は積極的に使ってみる
C言語かぁ
オブジェクト指向言語だと一定の責任を持つグループ群で完結しやすいからツボにはまると上達が早いんだけどねぇ
>>813 作りたいものを見つける
目標を作る
とりあえずマインスイーパーとかテトリスでも作ってみるとか
817 :
デフォルトの名無しさん :2008/03/27(木) 18:18:00
すいません、質問させてください A,Bというクラスがあり、 AにはBのインスタンスへのポインタ(pB)、 BにはAのインスタンスへのポインタ(pA)を持たせて 互いにデータのやり取りができるようにしたいんですが どうやったらできますか? クラスを宣言する際、 Aの宣言には B *pB; という行があるので、先にBを宣言しておく必要があるんですが 逆にBの宣言には A *pA; という行があるので、こちらでは先にAの宣言が必要に… どうしたらいいのかわかりませんorz 誰か方法を教えてください(´・ω・`)
818 :
デフォルトの名無しさん :2008/03/27(木) 18:21:45
関数と同じで宣言だけすればいいのでは?
実体が必要ないなら先行宣言でいいんじゃね? class B class A { /* Aの内容 B* pB; */ }; class B /* Bの内容 A* pA; */ };
>>815 >>816 なるほどありがとうございます。目標か
ゲームプログラム作ってみたいが遠いな・・・
独学で勉強してるが途中で頓挫してしまい、最後に見た
ページが『繰り返し処理 while文』だった。
当然その項目を見ても忘れてるので、最初からやり直し
今printfを勉強中 orz
821 :
デフォルトの名無しさん :2008/03/27(木) 18:33:34
>>818 >>819 クラスって実体なしで宣言できたんですね、、知らなかったでs
ちょっと試したところいけそうな感じでした。ありがとうございました
>>820 初めのうちは関数の機能はこういう物かと頭に入れておくだけで良いと思うよ
全部本でお勉強してたらきりがない
いずれHelloWorldと画面に表示するプログラムが書きたいな、と思ったときに
printf()なんて関数があったなーと思い出せればあとは本で調べればいい
ナイコン時代は授業中ノートに config.sysやN88書いてニヤニヤしてたものだ。
>>823 極限までconfigを切りつめて
UMBとEMSに詰め込んで640kのメインメモリをどれだけこじ開けられるか試した物だなあw
class Hoge { public: int Piyo() { return m_piyo; } void Piyo(int value) { m_piyo = value; } protected: int m_piyo; }; とするとプロパティもどきに見えますか?
827 :
デフォルトの名無しさん :2008/03/27(木) 20:35:45
見えない。
もうマジレスされてしまうくらい廃れたのか。あのコピペは。
RS232cで通信のプログラムなんですが 送信後少し(500mSecぐらい)間をおいた後、返信の受信を行うのですが Sleepをつかうと他の一切の処理を受け付けなくなってしまうようです 他の方法で送信後のディレイをうまく設定することは出来ないでしょうか?
・ タイマー ・ マルチスレッド お好きな方をどうぞ
スレッドでも使えば。
>>825 プログラミングの勉強は計算や漢字の練習みたいなもんだから
キーボード打った分量と時間が全てですよ。
ノートとかとってるようだと何時までたってもダメだお
まあ頑張れ
833 :
デフォルトの名無しさん :2008/03/27(木) 23:36:11
イテレータでp=x.begin()としたとき、これより前にデータが挿入されたとしたら 先頭ではなくなりますか? それともpは先頭のままですか?
>>830 ー831
マルチスレッドですか
マルチスレッドな設計になってないんですよねorz
DOS窓で試験してたときは普通に動いてたんだけどなぁ
>>833 vectorならpush_backやinsertを呼んだ時点でローカルな反復子は全部無効にならなかったっけ?
>>833 コンテナによっては、挿入によりイテレータが無効になるものがある。
「イテレータ 無効化」でぐぐれ。
無効にならないとしても、前に挿入したなら先頭ではなくなる。
837 :
デフォルトの名無しさん :2008/03/27(木) 23:46:21
サンクス
すぐそこ
>>813 >>820 >>825 C/C++自体を勉強する方法だと長続きしないから
Windows ゲームプログラミング 第2版
という書籍を購入して勉強するってのはどう?
>C/C++自体を勉強する方法だと長続きしないから 人間として欠陥があると思う。
842 :
デフォルトの名無しさん :2008/03/28(金) 00:32:36
確かにいまさらC/C++を学ぼうとするのは人間として欠陥があるかもしれない。
血管なら分かるんだがなw
844 :
デフォルトの名無しさん :2008/03/28(金) 00:35:42
やっぱりJavaだよ!Java!
ruby「おっと、俺を忘れてもらっちゃ困るぜ!」 python「お前らばかりに良い思いさせるかよ!」
DarkBASIC、LGP「呼んだ?」
(display "omaira sure chigai desuyo.")
ニホンゴdeオウケイ
>>834 高々2スレッドにするのがそんなにキツイとも思えないけどなぁ
シリアル通信andスレッド で検索すればいっぱいでてくるじゃないか
850 :
デフォルトの名無しさん :2008/03/28(金) 07:15:59
クラスのメンバー関数で、const関数と、処理は同じだけどconst関数でないものがあるとき、 これは関数オーバーロードになるのですか? int operator[](int n) const {...} int& operator[](int n) {...} みたいな感じです。
なる
なるけど上はconst int &を返すべきなんだぜ。
メーテル、頭の悪い人が朝から的外れな罵倒をしてるよ。
>>849 とりあえずマルチスレッドで実装できました
ただ、定期的に通信を監視するクラスとコマンドを送信するクラスが有り
この二つのクラスが通信クラスをsingletonで共有してるのですが
監視クラスが別スレッドで通信クラスを使用してるとき
コマンド送信クラスが通信クラスを使おうとすると問題になりますよね?
856 :
デフォルトの名無しさん :2008/03/28(金) 10:59:31
こうしてみたのですが、constのほうがどうしても呼ばれません。どういうシチュエーションで 呼ばれるのでしょうか? class test { public: int aaa[10]; int &operator[](int n) { return aaa[n]; } const int &operator[](int n) const { return aaa[n]; } }; 853は自分じゃありません。
testがconstのとき const test t; t[0]; とか
858 :
デフォルトの名無しさん :2008/03/28(金) 12:57:47
構造体内の関数へのポインタについての質問です。 以下のように構造体内で足し算を行う関数へのポインタを持っている場合 ----------ここから---------- #include <stdio.h> int sum(int,int); struct calc { int data; int (*sum_op)(int,int); }; int main(void){ struct calc calc0; struct calc *calc1 = &calc0; calc1->data = 0; calc1->sum_op = sum; calc1->data = calc1->sum_op(123,456); printf("123 + 456 = %d\n",calc1->data); } int sum(int a,int b){ return (a+b);} ----------ここまで-----------
859 :
デフォルトの名無しさん :2008/03/28(金) 12:58:37
(858の続きです) このcalc1->data = calc1->sum_op(123,456)なんですが calc1->sum_opは関数へのポインタなので calc1->data = (*calc1->sum_op)(123,456) とすべきだと思うんですが実際はどちらが正しいのでしょう? どちらもコンパイルには成功し実行結果も >123 + 456 = 579 となり困っています。以上よろしくお願いします。
>>855 単純に排他制御したいならMutexとか使って使用中ならreturn;でOK
863 :
デフォルトの名無しさん :2008/03/28(金) 20:06:15
以下の条件に該当するC++ライブラリを探しています。 もしご存知でしたら教えてください。 ○機能 socket、スレッド、ODBC。 (まとめてでも、個別機能のライブラリx3でもかまわない) ○条件 ・CまたはC++で使用可能 ・Linux(Fedora)版とWindows版があり、同一インターフェイスを持っている (Linux(Fedora)とWindowsである程度のソースレベル互換を実現出来る) ・またはラッパー自体にソースレベル互換がある スレ趣旨と若干ずれてるかもしれませんがほかに該当するところがなかったので…… お願いします。
ソケットはAsio、スレッドはBoost.Threadがある。 ODBCはやったことないんでわからない、すまん。
865 :
863 :2008/03/28(金) 20:32:10
>>864 ありがとうございます。早速ぐぐってみます。
>>863 に補足。
最終的にPostgreSQLとやりとりしたいだけなので
最悪ODBCじゃなくてもかまいません。
wxWidgetsなら全部あるな
mono
>>864 Asioって1.35からではないの?
1.34.1が最新みたいだけど。
イナバさんの本に載ってたからもう入ってるものかと思ってた
>>868 Non Boost版を単体で使うのはだめ?
>int main( void ) { > int *n; > *n = 5; /* ポインタ変数nに値5を代入 */ > printf( "%d\n", *n ); /* ポインタ変数nが持つ値(5)の出力 */ > return 0; > } ちょっと待て なんだコレ
凄いな、長文レスの前に記事の訂正しろよと ついでに 2 ページ目にも同様の間違いあり
この大胆さは評価したい
875 :
デフォルトの名無しさん :2008/03/28(金) 23:04:36
DEVMODE構造体はプリンタ一つに対してそれぞれシステムがもっていますか?それともシステムで唯一つしかもってないのでしょうか?
まず一つ目の間違いは、ウォーリーが2人もいる。
>>876 nを初期化せずに*nと書くのは間違い。
記事では
> このときnには代入された値を記憶した場所(アドレス)が自動的に代入されるため
などと大嘘を書いているが、信じちゃいけない。
このサンプルコードなら、
int x;
int *n = &x;
とするのが正しい。
879 :
デフォルトの名無しさん :2008/03/29(土) 00:11:58
コンストラクタ初期化子を使う場合、 コンストラクタの実装はクラス定義の中に書くしかないのでしょうか? class SampleClass { int var; SampleClass():var(0){//ここに実装を書くしかない? } }; SampleClass::SampleClass() {//こんな風に外に書くことはできない? }
>>879 SampleClass::SampleClass() : val(0) {}
class SampleClass { int var; SampleClass(); }; SampleClass::SampleClass() : val(0) { //実装 }
どうもありがとうございます。 クラス定義内ではコンストラクタの宣言だけして、 外に内容を書けばいいってことですか。
>>871 すげえなあ
これでプロの技術物書きなんだから尊敬するわ
NULLが0じゃないというのは無視してもいい程レアか、 もしくはあり得ないのでしょうか? 職場の先輩が、char ch = '\0'; を、 char ch = NULL; と書いてたんですが、 微妙に気持ち悪いです。 気にするほどではないのでしょうか?
885 :
デフォルトの名無しさん :2008/03/29(土) 00:37:48
0で初期化する必要はない
>>884 「先輩、気持ち悪い」って吐き捨ててから帰宅すればおk
int n = NULL;もおかしくないことになる
NULLはポインタであり、charではない。
やっぱやめた方がいいですよね。
>>886 残念ながらたぶんもう一緒に仕事をすることはないです。
自分はC言語初めてまだ3ヶ月なんですが、
その人はCを仕事で20年近くやってる人だったので、
NULLでもいいのかなと迷ってました。
ナル文字とNULLは違うッスよ先輩(ガムを噛みながら)
NULLはnull pointer constant
気持悪いってか恥ずかしくて第三者に見せられないがな
895 :
デフォルトの名無しさん :2008/03/29(土) 01:15:41
sageてしまったorz
896 :
デフォルトの名無しさん :2008/03/29(土) 01:18:09
898 :
デフォルトの名無しさん :2008/03/29(土) 01:25:40
VxWorksのマルチスレッド型のプログラムで taskとpthreadのどちらを使うべきかを検討しています。 現状、他のプラットフォームへの移植性を考慮すると POSIX準拠のpthreadの使用を考えています。 そこで質問となるのですが、 ”taskを使った方が良い点”をご存知であれば、ご教授頂きたく。 今のところ、VxWorks上でタスクを管理する環境が整っているのが利点?と 認識しています。
>>884 ヌルポインタの内部表現のビットパターンが0でなくてもよいが、
その場合でもソースコード上のNULLは0でないといけない(ここ重要)。
だからと言って、NULLを0の代わりに使うのは間違い。
だからCでは近頃#define NULL (void*)0なんて定義が多かったり、
C++だとnullptrキーワードを導入しようとしていたりする。
ポインタに対してZeroMemoryしまくってた・・・どうにでもなれ・・・
901 :
デフォルトの名無しさん :2008/03/29(土) 02:23:22
ポインタもint型も32か64のメモリ食う点は同じだろ
ポインタ先をクリアし忘れてたってことじゃね?
再帰呼び出しの課題がでたのですが n(人数分)の点数分の数値を入力して比較し最大値を表示させるプログラムなんですが 引数はnだけグローバルを使わないという条件なので 点と最大値を初期化してるため 結果がでません どのようにすれば上手く最大値を格納できるのでしょうか? int Amax(int n) { int ten,max = 0; printf("点数?"); scanf("%d",&ten); if (max < ten) max = ten; if (n == 1) return max; else return (Amax(n-1)); }
>>903 static int max = 0;
>>903 int Amax(int n)
{
int ten = 0, kekka = 0;
if(n > 1) kekka = Amax(n-1);
printf("score "); scanf("%d", &ten);
if(kekka < ten) return ten;
return kekka;
}
先に一番奥まで潜ってから戻ってきた値と比較して大きい方を返す
>>871 これは酷いw
>>884 お前が正しい。気にするべき。
セマンティクスの矛盾に気持ち悪さを感じられることは良いことだ。
話題とは全く違う話ですが、C/C++言語の「;」は、付く場合と付かない場合 の区別が論理的に理解できません。何か規則があるのでしょうか? 例えば、 do {ブロック} while(条件式); //付く while {ブロック} //付かない for (;;) {ブロック} //付かない 関数の戻り型 関数名() {実体} //付かない enum {}; class {}; などの最後に ;が付く理由は理解できます。 それは、その列挙型やクラス型の「変数(オブジェクト)」をブロックの 後ろから;の間までにも書くことができるからですね。
>>871 int n[1];
*n = 5;
これなら通るんだっけ
n[0]=*(n+0)だから通るんじゃね?たぶん 素直にn[0]と書いたほうが分かりやすいけど
>>909 多分じゃなく、問題なく通る。
>>908 ブロックの後にはつかない。文の末尾には必要。以上。
つまり、文(...;)かブロック({...})かの違いだけ。
do-whileの場合は、間がどうであろうとwhileが文なので必ず必要になるだけのこと。
do-whileで最後にセミコロンを付けるのは、 単に構文規則がそうなっているからというほうが正確。 (それがわかりやすいかどうかはともかく)
「whileが文」で、「文の末尾には必要」なのに、 > while {ブロック} //付かない のは、「ブロックの後にはつかない」からだけど、ならなぜ > enum {}; class {}; などの最後に ;が付く んだろう。
セミコロンがないと do-while なのか 単独 while なのか一見わかりにくくなるしな
>>914 do-whileでなくても、;が付いていて、勘違いしやすい例もあったりする
かも:
while (条件式);
これは、while文で条件が真のときに実行されるのは「空文」です。
空文は、一般の行にも「;」だけを書く文のことで、何もしない文です。
結局、上のwhile()文は、条件式の副作用以外何もしません。
条件が10回分真なら、条件式の中の10回分の副作用が起きるだけです。
>>913 その{}はブロック(複文)を構成するものではないから。
そうか、それで namespace { } には ; はいらないのか 確かに中身は文の集合(ブロック)だしな
あれ?でも struct {} も、中身は宣言文の集合に見えてきたぞ?。?
>>918 名前空間の{}はブロックではない。
そっちにセミコロンを付けないのは単にそういう構文だからとしか言いようがない。
C/C++で言う文とは、およそ関数の中のものだけ。
式文(空文)、制御文、ラベル付き文、複文。
#ただ、C++だとそれに加えて宣言文 ::= 宣言みたいなことをやっているはずだけど、
#それが通用するのは文を置ける場所(関数内)だけ。
文と(関数・変数・クラス・名前空間などの)宣言は構文上、別物。
名前空間や構造体の中身は、文ではなく宣言の並びと規定されているはず。
式文など一部の文の最後にセミコロンを付けるのと、
変数や関数の宣言の最後にセミコロンを付けるのは、
少なくとも規格に書いてある構文上では独立した事柄。
>>908 struct {..} a;等の場合はstruct {..}の部分がint a;のintのような扱いだから
do〜whileはコンパイラが通常のwhileと間違えないように例外的に;を使うことに
おそらく、;記号がないと複数行に渡って記述するのに
いちいち\で継続したりする必要があって煩わしいし
かといって沢山;打つのも嫌だから必要最小限にしようって折衷案です
>>919 structでも『「変数(オブジェクト)」をブロックの後ろから;の間までにも書くことができるから』;を付けるのである
一方namespaceは型ではないから変数を定義することもできない
923 :
デフォルトの名無しさん :2008/03/29(土) 18:24:21
なんで?と聞かれたらそういう決まりだからとしか答えようがない。
static class X{} obj; こういうことができちゃうからねえ。
while (1);
926 :
デフォルトの名無しさん :2008/03/29(土) 20:55:17
class top{ class down; down* d; }; class top::d {}; と書くと、downクラスはtopクラスのクラス内クラスになって、その場合にdownクラスは topクラスの中以外では使えない、と考えていいですか? こんなクラス内クラスって、どういう場面でつかうのでしょうか?
pimplイディオムとか
C++のconstについてお聞きしたいのですが 以下のようなメンバ関数があるとします。 BClassはBaseClassを派生させたものだとします。 class AClass{ public: static const BClass* const method(){ return new BClass(); } }; これの受けて側で (1)const BaseClass* p = AClass.method(); でも (2)const BaseClass* const p = AClass. method(); でも コンパイルが通りますが クラス宣言・定義で const BClass* const 型の戻り値としているのに (1)でもOKなのは何故でしょうか? また(1)のpと(2)のpでできることに違いは出てくるでしょうか?
>>928 const BaseClass* var :
varの参照先を変更する事ができない。
BaseClass* const var :
varを変更する事ができない
const BaseClass* const var :
varの参照先を変更する事ができない。
varを変更する事もできない。
すいません。 上のはAClass::method(); です。
ということは、 宣言・定義で const BClass* const という戻り値を設定しても 使用する側で const BClass* p = AClass::method() とすれば 宣言・定義側の 2番目の const は無視されるということでしょうか。
「わたしには理解できました。あなたの普通の人ではどうにもならないような性能に私は魅了されました。この気持ちを例えるなら愛という言葉が近いと思うでしょう」 『愛!? 言ってる意味がわかりません』 「好きになりすぎると殺意が芽生えます。キリスト教徒がクルセイドとして他教徒を排除したように!」 『それがわかっていながら、何故戦うのですか?』 「軍人は戦うのが仕事です」 『あなたは歪んでいます!』 「そうしたのはあなたです、ガンダムという存在がわたしを歪めました だから私はあなたを倒します。世界とかはどうでもいいです…わたしの考えで行動しています」 『あなたも世界の一部じゃないですか?』 「まちがえました。これは世界の声でした」 『違います。あなたは自分勝手に行動しているだけです。あなたは歪んでいます。わたしがそれを注意します』 「ガンダムならそういうと思いました」 翻訳してみたけど、なんだかなぁ、この会話
>>931 一般的に、T constをTに代入するのはOKだよな。
この場合、T=const BClass*だ。
>>928 まず、constは左結合、ただし便宜上一番左に書くことも出来る。
なので「const BClass * p」を厳密に書くと「BClass const * p」となる。
同様に「const int n」==「int const n」
次に「BClass const * p」はBClassがconstなので実体が変更出来ない。
「BClass * const p」の場合は*がconstなのでポインタを変更出来ない。
int const n = 10;
int n2 = n; // OK
BClass * const p = ...;
BClass * p2 = p; //OK
>>931 無視されてないって。
a=b;のとき、aが変更されたとは言うけど、bが変更されたとは言わないでしょ。
>>931 const BClass* p = AClass::method()は、
新しい変数pを作る(AClass::method()でコピー初期化)という扱い。
pの初期化には、AClass::method()の値を読み取れるかどうかが重要だが、
値を読み取ってpを作ってしまえば、もはやAClass::method()とは無縁。
だから、AClass::method()がconstかどうかと、
それを受けるpがconstかどうかは無関係。
937 :
934 :2008/03/29(土) 22:48:05
補足。 int n = 10; int * p = &n; int * const * p2 = &p; p2 = NULL; //OK, p2は非const // *p2 = NULL; //NG, *p2(p)はconst **p2 = 0; //OK, **p2(n)は非const
938 :
928 :2008/03/29(土) 22:51:36
ありがとうございました。 ある関数内でポインタを変更したくないときに、実引数ではなく仮引数で制御するのと同様に 関数の戻り値としてポインタを受け取る場合でも、受け手側で制御すればいいわけですね。 上の例だと、宣言・定義では const BClass* を戻り値としといて、 ポインタを変更したくないのであれば、使用側で const BaseClass* const p = ... とすれば、いいわけですね。 宣言・定義で const BClass* const とするのは、文法的には可能だけれど 意味のないことなんですね。
>意味のないことなんですね。 もういちどれすをよみなおそう。
940 :
934 :2008/03/29(土) 22:56:03
const int n = 10; int n2 = n; //OK ↑程度は理解出来ているだろう、という前提で書いたけど、 大丈夫・・・だよな?
941 :
934 :2008/03/29(土) 23:04:01
>>938 >関数の戻り値としてポインタを受け取る場合でも
関数の戻り値をpに入れるのと、
別の変数をpに入れるのは基本的には同じだよ。(※rvalueは今は無視で)
多分、何か勘違いしていると思う。
942 :
928 :2008/03/29(土) 23:04:56
>>940 はい、それは理解しています。
>>939 (1)static const BClass* const method(); は
const BClass* const 型 の値を返すという意味で
(2)static const BClass* method(); は
const BClass* 型の値を返す という意味ですよね・・・
>>938 最初のconstは意味がある。
賢いコンパイラなら
warning: type qualifier on return type is meaningless
static const BClass* const method(){
みたいに警告が出るだろ。
944 :
デフォルトの名無しさん :2008/03/29(土) 23:09:31
自分クラス(仮に名前はtest)があって test a; a++; // test &operator++(int); ++a; // test &operator++(); と定義するじゃないですか。でも、a++だと引数が必要で++aだと引数が不要になっているのは どういう理由によるのでしょうか。 あと、独自クラスでは後者の方がすこし速いと聞いたのですが、本当ですか?手元で実験した限りでは とくに性能差はなかったです。
945 :
928 :2008/03/29(土) 23:11:25
>>943 おお、そうなんですか。
コンパイルが通るとしても、極力戻り値の型は合わせたほうがいいですね。(アップキャストを除いて)
946 :
934 :2008/03/29(土) 23:14:33
>>942 もう一度intで表現するけど、
>(1)static const BClass* const method();
>(2)static const BClass* method();
は、それぞれ、
static const int method();
static int method();
と同じような意味になる。
戻り値をintでなく、const intにして何か利点があるか考えてみて欲しい。
947 :
デフォルトの名無しさん :2008/03/29(土) 23:15:05
>>944 引数をとるとか何かで区別しないと、前置か後置か、コンパイラが区別できないから。
>後者の方がすこし速いと聞いたのですが
普通の前置インクリメントの処理内容は、
1.インクリメントする。
2.thisをreturnする。
普通の後置インクリメントの処理内容は、
1.現在の状態を退避する。
2.インクリメントする。
3.退避しておいた状態をreturnする。
だから前置が速い。
949 :
928 :2008/03/29(土) 23:22:27
>>946 何度もありがとうございます。
よく考えてみます。
>>944 速度は最適化されて結局同じだから気にしない。
operator++(int);のintは偽の引数で実際はvoidです。
static const BClass* const method(); 後のconstは意味ないが初めのconstは意味がある。
>>944 >後者の方がすこし速いと聞いたのですが
>>948 の人の説明の通りだけど、例を挙げてみる。
sizeof(test)==1MBだとして(あえて極端なサイズで説明)
前置だと、インクリメントして自身の参照を返すだけ。
後置だと、1MBの実体をtmpとしてコピーして、
自身をインクメントして、tmpを返す(値渡しになるのでまた1MBコピー)
つまり後置だとコピーコンストラクタが2回追加される。
2回目についてはmove semanticsを使えば緩和出来るけど。
>>952 それどのコンパイラ?
コピーコンストラクタがインラインならほとんどのコンパイラで
確実に最適化されるって思ってるんだけど違うのか?
それに説明するなら一般的な例で頼む。極例はずるいよ。
場合によってはほとんどのコンパイラで確実に最適化される ↓ 場合によっては一部のコンパイラでは最適化されない ↓ 前置インクリメントでいい場合は前置を使っておくと速いかもしれない ↓ (平均すれば)後者の方がすこし速い って流れでしょ。 サイズが極端なだけで例としてはごく一般的だよ。 a++++++++;とかなら極端な例だろうけどさ。
>>953 ずるいとか言われても(;´д`)
最適化出来るコードなら最適化されるだろうし、
出来ないならされないよ・・・
「後置>前置」なコストと言ったつもりは無かったんだけど、
「後置≧前置」と補足しておいた方がよかったかな。
>>955 質問文みるかぎりイテレータだろうし、1Mのデータはポインタで保持だろうし、
参照カウンタ使うなり真っ当に実装してればセフセフだし、ちょっと大袈裟じゃない?
と思ったけど、まあ確かに確認した方がいいのかもしれない。。。
VC2005使ってるんだけど、名前空間stdってどこにあるの? とりあえず<new>とか<memory>などをインクルードしたら使えるようになるんだけど
翻訳単位で検出できればどこにだってあっても良い。 後方参照も可能。
959 :
デフォルトの名無しさん :2008/03/30(日) 00:46:12
違う話題ですが、C++で、deleteに、 1. delete オブジェクトへのポインタ 2. delete [] オブジェクト配列へのポインタ の二種類ある理由が良く分かりません。 配列かどうかは、内部的に分かりそうなもので、1と書いても 自動的に判断してもし、newで配列として確保された物のポインタ であるなら、2の意味と捉える事がどうして出来ないのでしょうか。 そして、もし、間違って逆に記述してしまった場合、どうなるの でしょうか。
配列かどうかは、内部的に分かりそうなものでもないです。
配列をただのdeleteでやるとオブジェクト一つ分しか消してくれなかったはず
>>961 それはたまたま。それを当てにしてはいけない。
963 :
デフォルトの名無しさん :2008/03/30(日) 00:51:49
CObj *pObjs = new CObj[100]; として、 delete [] pObjs; で配列全体を削除出来ると言うことは、100個分であるという情報 は、内部的に分かっているんですよね。 なら、 delete pObjs; としても、100個まとまったメモリブロックだと言う判断は付く と思うんですが。
965 :
944 :2008/03/30(日) 00:52:27
ありがとうございます。 後置よりも前置がよい場合がある理由はわかりました。でも、現実には、実装方法が、 ++i ===> int &operator++(); i++ ===> int &operator++(int); となってますが、 ++i ===> int &operator++(int); i++ ===> int &operator++(); となっていても別に直感に反していないような気がするのですが、 何か、現実の実装方法が、「なるほど、理にかなってる」と思えるような理屈はないでしょうか?
966 :
デフォルトの名無しさん :2008/03/30(日) 00:52:55
>>966 コンパイラ製作会社に問い合わせて独自拡張規格で何とかならないかきいてみたらどう?
>>958 とりあえず<new>とかをインクルードしとけばいいってことですか
>>968 名前空間には使用に先立つ明確な宣言などは特に必要ない。
翻訳単位で後に検出できれば問題ない。
970 :
957 :2008/03/30(日) 01:00:32
後に検出できるためにインクルードしてるってことでいいですか
>>970 何がしたいの?
stdにある<new>の機能を使いたいの?
名前空間自体は別に使用に先立って特に何もしなくてもいいけど、
名前空間にある関数やクラスなどについては当然ながら宣言や定義が必要だぞ?
972 :
957 :2008/03/30(日) 01:04:40
#include<new> しないとstd::bad_allocが使えない状況なんで、それを使いたいんです
すれば良いだろ
>>959 そりゃもちろんdelete1本に絞って、
delete内部で配列かどうか判別するという方法も考えられる。
実装は別に難しくないだろう。全ての単体のnewをnew[1]相当にすればいいだけだ。
だが、そんなオーバーヘッドを許さなかったのが(当時の)C++クォリティ。
D&Eを引いてみてもやっぱりそういう理由のようだ。
>>972 それはstdを使いたいのではなく、std::bad_allocを使いたいと言う。
976 :
957 :2008/03/30(日) 01:08:45
ごめんなさい
977 :
デフォルトの名無しさん :2008/03/30(日) 01:12:12
卓上デバッグの時代だからな。
>>963 最適化のため、そういう保証を課してない。
deleteのときは「何個分か」を見なくて済む。
>>965 D&Eにそれに関する記述がある。
簡単に書くと、
「キーワード使う構文とか考えたけど、
キレる人が結構居たので結局これに落ち着いた。
他の単項演算子は前置形なので、前置インクリメントも同じく引数無し、
(int)は後置のマークとした。
C++の中で異質だけど、十分有効だろう」
とのこと。
>>957 std配下のクラスを使いたいってことだよね?
ヘッダファイルが分かれてるから、必要なものをインクルードすればおk
std:vectorなら<vector>, std:listなら<list>といった感じ。
980 :
誰か965にも答えてくれ〜 :2008/03/30(日) 01:24:59
卓上でデバッグか。卓上でやることといえば徹マン明けの点数計算くらいしかない俺とは大違いだな。
fopenが成功した段階で、メモリ上にファイル内容があるんですか? それともfreadするたびにHDDにアクセスしてコピーするのかどっちなんでしょう
試しにブレイクしながら1GBほどのファイルを読み込んでみればすぐわかることじゃないかな?
>>981 普通はCライブラリとOSでキャッシュするが、
キャッシュサイズとかタイミングは処理系依存。
でも巨大ファイルを全部キャッシュするようなことはしないだろうね。
984 :
981 :2008/03/30(日) 01:34:33
ありがとうございました
次スレ誰か頼むぜ
986 :
誰か965にも答えてくれ〜 :2008/03/30(日) 01:39:03
979の人、ありがとうございます。 なるほど、単項演算子は前置だし、定義するときは引数なしでやるから、という論理か。 ところでD&Eっていいですね。俺もそろそろ読む時期がきたかな。
987 :
デフォルトの名無しさん :2008/03/30(日) 01:52:14
988 :
デフォルトの名無しさん :2008/03/30(日) 02:10:26
59?ずいぶんすっとんでない?
次は52か53くらいじゃなかったっけ?
デバイスコンテキストハンドルについてなんですが BeginPaint()で取得したHDCを 自作描画クラスのメンバ変数HDC*へ代入してクラス内で使用しても大丈夫でしょうか? HDC hDC = BeginPaint( hWnd, &ps ); MyDraw mydraw(&hDC); //HDCのアドレスをコンストラクタで取得してメンバ変数として使いまわしたい /* 色々な処理 */ EndPaint( hWnd, &ps );
992 :
デフォルトの名無しさん :2008/03/30(日) 02:59:12
>>988-990 いや、結構長い間50で停滞してたし、一回51になったこともあったけど、また50に戻ったりしてるから、、、これくらいかな、と。
だいたい、1つのスレの寿命が1〜3ヶ月くらいだとおもうので、50から59の飛躍といっても4〜5ヶ月くらいの飛躍でしょ。
>1つのスレの寿命が1〜3ヶ月くらいだとおもうので、50から59の飛躍といっても4〜5ヶ月くらい (´・ω・`)?
>>992 記憶によると50→51→50→?だから次は53くらいだと思うんだが… 59は飛び過ぎじゃね?
まぁ同じタイトルのスレが乱立してなければ最新なのがわかるからいいよ
>>991 EndPaint以降にそのhDCを使い続けることが無ければ、問題ないよ。
997 :
デフォルトの名無しさん :2008/03/30(日) 10:13:46
おまんこおーぷん(あいつのなまえ)
res997.bokki(); >コンパイルしています... >error: bokkiは実装されていません
猫も杓Cもプログラミング
1000生トイレ!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。