C++相談室 part56
..
44:デフォルトの名無しさん
07/07/28 10:54:42
>>42-43
そうだったんですか。。勉強不足でした。ありがとうございます。
45:デフォルトの名無しさん
07/07/28 11:04:36
>>37 assign()
46:デフォルトの名無しさん
07/07/28 11:16:34
>>45
vectorにassign()というのも用意されてたんですね、、
ありがとうございます。
47:デフォルトの名無しさん
07/07/28 11:27:52
こうやって参照渡しにNULLが渡せるのは規格として正しい動作なんですか?
gcc4.1とvc8sp1両方ともこれが通って
&str is NULLが出力されます。
#include <iostream>
#include <string>
void func(std::string& str)
{
if(&str == NULL)
{
std::cout << "&str is NULL" << std::endl;
}
}
main()
{
std::string *str = NULL;
func(*str);
}
48:デフォルトの名無しさん
07/07/28 11:28:13
>>47
未定義動作。
49:デフォルトの名無しさん
07/07/28 11:37:28
>>48
ありがとうございます。
具体的にどの部分が未定義動作になりますか?
1, *str (NULLの参照外し)
2, 参照型にNULLアドレスの実体が渡る事
3, funcのif条件で&strとして参照型のアドレスを見に行った事
1と2で合ってますか?
そもそも1が未定義なので2は起こる事はあり得ないはずという認識の方がいいんでしょうか?
50:デフォルトの名無しさん
07/07/28 11:44:59
1 は、参照先にアクセスしたり参照の初期化に使ったりしない限りは未定義じゃない。
例えば main 内で &*str がヌルポインタになるのは well-defined 。
だから、未定義なのは 2 と 3 。
51:デフォルトの名無しさん
07/07/28 11:45:49
良く分かりました。ありがとうございました。
52:デフォルトの名無しさん
07/07/28 12:16:54
>>50
それって↓ここにある話だよね?
URLリンク(www.open-std.org)
現行の規格では 1 も未定義動作と読めるから、ダメだと考えておいた
ほうがいいんじゃない?
53:デフォルトの名無しさん
07/07/28 12:22:51
DirectX SDKに以下のクラスがあって
D3DVECTOR(Cバージョン。float x,y,zのみ)
D3DXVECTOR3(C++バージョン。上記にメンバ関数が付いた)
後者を引数として受け取る関数
func( D3DXVECTOR3 &v )
に前者D3DVECTORを渡そうとしているのですが、型が違うという
エラーがでるので、func( (D3DXVECTOR3)v )とキャストしています。
問題なく動いているのですが、こういうキャストって文法的に問題無い
のでしょうか?なんとなく違和感があって
func( *((D3DXVECTOR3*)&v) )
こっちに直そうかと思っているのですが…
54:デフォルトの名無しさん
07/07/28 12:32:14
ちょっと試してみたのですが、メンバ変数が異なるクラスを
func( (D3DXVECTOR3)hoge );
とするとちゃんとエラーが出ますね。ということはコンパイラが
ちゃんとそこまで判断して通してくれているのでやはり合法
なのかな?
55:デフォルトの名無しさん
07/07/28 12:32:50
>>52
あら、そうだったんだ。すまん。
56:デフォルトの名無しさん
07/07/28 12:38:55
>>53
URLリンク(msdn2.microsoft.com)
D3DXVECTOR3 は D3DVECTOR からの変換コンストラクタを持っているので
(D3DXVECTOR3)v が static_cast 相当の働きになり、一時オブジェクトが作られる。
ただし標準では一時オブジェクトを非 const 参照には渡せないので、
func() の呼び出しがエラーになるはず。 VC 系は最新でも通るんだっけ?
>>54
メンバ変数が同じかどうかは関係ない。
57:デフォルトの名無しさん
07/07/28 13:06:23
>>53
>>56
とりあえずVC7.1で試してみた感じだと、
「組み込み型では通らないけどユーザー定義型なら通る」っぽい。
58:デフォルトの名無しさん
07/07/28 13:55:59
>>56>>57
なるほど、やぱり駄目な書き方なのですね。私も最初エラーになると
思ったのですが、動いてしまったのでむしろ驚きました。
ちなみにこちらは.NET2003です。
>メンバ変数が異なるクラスは駄目
ここら辺はVCの独自拡張なのかな?
とりあえず以下の書き方に直します。
func( *((D3DXVECTOR3*)&v) );
59:デフォルトの名無しさん
07/07/28 16:40:05
どこをどうすればそこまで誤読できるんだ?
60:デフォルトの名無しさん
07/07/28 16:44:32
>>59
それが説明できるくらいなら誤読しないだろ。
61:デフォルトの名無しさん
07/07/28 17:33:43
あれ?誤読してます?
文法的に問題ないということでしょうか?
func()の引数にconst付ければ問題ないということです?
62:デフォルトの名無しさん
07/07/28 20:54:10
無名構造体のコンストラクタ、デストラクタはどうすればじっそうできるの
63:デフォルトの名無しさん
07/07/28 21:19:58
無名をやめればいい
64:デフォルトの名無しさん
07/07/28 22:00:17
無名でなければならない時は?
65:デフォルトの名無しさん
07/07/28 22:03:48
適当な名前を付けろ。
66:デフォルトの名無しさん
07/07/28 22:17:25
>>64
どんなとき?
67:デフォルトの名無しさん
07/07/28 22:19:42
\ / ヽ l | / \_人从__
ヘ、 ヽ _..≧=ヽ|Y〃/∠._ / }
\ ,′ \ >ヘ´ | / '⌒≦ / ノ
ヽ. /// `X < く V
!. \ / , / / | j{ /ヽ ) だ I
!. /〃/ / / , 〃|l U \ ヽ `) さ P
/ {/ / / / / || |l } lヽ 丶 < い で
‐- . / { / 〃,′{ { |l jl | |ハ ヽ} ヽ ! や
_ ヽ、 { ハ{ { {/´≧x x≦ヽハ\ ヽ〈 ノ、 っ
 ̄ ≧‐-{;;;\ヽ{ {:::{.j {.j::} }|lヽ \ ハヽ=≦ヽ て
/ `八;;;;;;;;....|xx`~ _'_ `~xxjハヽ;;;;;;;;;;}ハ }
-‐ァ'//´ ヽ:;;;;...{ヘ、 ( j ノ ハl|;;;;;;;ハ  ̄ ノ /
-/ // , \/⌒≧ーr---ァ≦'⌒ヽノ}|};;;/ハ /⌒Y⌒ヽ{
7/ / / 〉\ }ノ'⌒ヽ // | リノ \
{ / ノ厂 {{ }'⌒ヽ⌒ヽL_ \ \!
j/ / f´/ ノ>ァ‐1 j| l ) \ j
ハ / W 〃/ `ーく{ |{ \ \,'
ハ / / l{ / イ ー==- \\ Y ヽ \ /\
× / ノ // | \ヽ \ ヽ \ イ
68:デフォルトの名無しさん
07/07/28 22:27:57
何故だ
69:デフォルトの名無しさん
07/07/28 22:29:49
>>66
好きなものは好きと言える気持ち抱きしめてたいとき
70:デフォルトの名無しさん
07/07/28 22:37:43
>>69
俺の胸に飛び込んで来い
71:デフォルトの名無しさん
07/07/28 23:01:58
まんゆうき懐かしいな
72:名無しさん@そうだ選挙に行こう
07/07/29 14:36:28
perlだと1行でできた・・・
73:名無しさん@そうだ選挙に行こう
07/07/29 16:18:36
C++始めたばかり何でちょっと分からないことがあります。
class C {
public:
int hoge;
};
class B {
C *c;
public:
B() : c(NULL) {}
virtual ~B() { if (c != NULL) { delete c; c = NULL; } }
void init() { c = new C; c->hoge = 4545; }
int Get() { return c->hoge; }
};
class A {
B b;
public:
B Get() { return b; }
void init() { b.init(); }
void print() { printf("%d\n", b.Get()); }
};
int main() {
A *a = new A;
a->init();
B b = a->Get();
printf("%d\n", b.Get());
a->print();
delete a;
return 0; }
このソースなんですが、Bクラスのデストラクタが2回呼ばれてエラーを吐きます。
私的には、delete a;した時に1回だけ呼ばれてほしいのですが、どうすればいいのでしょうか?
分かる方お願いします。
74:名無しさん@そうだ選挙に行こう
07/07/29 16:35:39
代入演算かコピーコンストラクタか…その辺でググレば幸せかもしれない?
75:名無しさん@そうだ選挙に行こう
07/07/29 16:43:15
>>73
エラーも吐かずに普通に実行できてしまった。
再現方法は?
76:名無しさん@そうだ選挙に行こう
07/07/29 16:46:38
B b = a->Get();
↑これをポインタで受け取れば?
77:名無しさん@そうだ選挙に行こう
07/07/29 16:48:41
返事ありがとうございます。
>>74
ちょっと調べてみます。
>>75
試しに、Releaseビルドで実行したら普通に実行できました・・・。
Debugビルドだとエラー吐きます・・・
一応環境は、VS2005 pro です。
>>76
ポインタで受け取ってみたらエラー吐かずに実行できました。
どういう事なんでしょうか??
78:名無しさん@そうだ選挙に行こう
07/07/29 16:51:32
C++の初心者はnew/deleteを使わないほうがいいと思うんだ。
79:名無しさん@そうだ選挙に行こう
07/07/29 16:53:22
問題はそっちじゃなくて、class BのCポインタが2回削除されていること。
#delete aと、B bがdeleteされるとき
メンバーポインタはけっこう難しいので、最初は使わないほうがよろしいかと。
boost::shared_ptrがお勧め
80:79
07/07/29 16:57:41
あと、C++の場合は「このインスタンスの所有者は誰?」というのを常に意識すると良いよ。
あと、RAIIを調べると幸せになれるかも。
81:名無しさん@そうだ選挙に行こう
07/07/29 17:01:31
ここで返したいのはprivateのBだよね?
B Get() {return b;}
これだとここでコピーが行われて新しくメモリ作られるよ
ポインタで返すようにして
B* Get() { return &b; }
こうやってポインタで受け取るべき
B* b = a->Get();
82:名無しさん@そうだ選挙に行こう
07/07/29 17:01:59
>>78-80
返事ありがとうございます。
boost::shared_ptrですか、、聞いたこと無いな、、
ググってきます。
アドバイスなどありがとうございます。
参考にさせていただきます。
83:名無しさん@そうだ選挙に行こう
07/07/29 17:03:58
>>81
>B Get() {return b;}
>これだとここでコピーが行われて新しくメモリ作られるよ
あっ、そういうことですか。
難しいですね、、
ありがとうございます。
84:名無しさん@そうだ選挙に行こう
07/07/29 17:11:24
>>83
>難しいですね、、
だから、>78。
そもそも、なんでnew/deleteを使うのか理解している?
#Javaじゃあるまいし、new/delete[]と違ってnew/deleteの必然性なんてそんなにないだろうに。
85:名無しさん@そうだ選挙に行こう
07/07/29 17:14:37
そんなにnew/delete使わせたくないならnew/deleteについて語れよ。
86:名無しさん@そうだ選挙に行こう
07/07/29 17:22:24
こういうノウハウを覚え続けないとまともに使えないのがC++
87:えいいち ◆GRGSIBERIA
07/07/29 17:22:56
MS-DOSのようなコマンド入力を受け付けるようなプログラムを組んでいるのですが、
char name[20];
char *p;
int j = 0;
cin >> name;
p = name;
if(*p == 'a'){
j = 1;
}
p++;
if(*p == 'b'){
j = 1;
}
if(j == 1){
cout << "成功\n";
}else{
cout << "失敗\n";
}
return 0;
のように書くと、コマンドの文字数や種類が増えるにつれて何行もif文に費やされることになってしまいます。
簡略化できる方法を教えてください。
88:名無しさん@そうだ選挙に行こう
07/07/29 17:24:33
>>73
コピーされては困るクラスでは代入演算子やコピーコンストラクタをprivateにしよう。
class B {
C *c;
public:
略
private:
B(const B&);//禁止
const B&operator=(const B&);//禁止
};
詳しくはEffective C++でも読んでくれ。
89:名無しさん@そうだ選挙に行こう
07/07/29 17:26:53
new/delete使う使わないは好き嫌いの問題でおk?
90:名無しさん@そうだ選挙に行こう
07/07/29 17:27:26
>>87
多重分岐→データテーブル→データファイル化
91:えいいち ◆GRGSIBERIA
07/07/29 17:28:17
修正
if(*p == 'b'){
j = 1;
}
↓
if(*p != 'b'){
j = 0;
}
92:79
07/07/29 17:29:45
new/deleteも便利だから、まったく使わないのはもったいない。
new/deleteで問題なのは所有者がはっきりしないことなので、そこに注意していればいい。
何だかんだ言って、boost::shared_ptr使うのが良いけどね。
93:名無しさん@そうだ選挙に行こう
07/07/29 17:31:47
>87
つ Commandパターン
94:名無しさん@そうだ選挙に行こう
07/07/29 17:41:24
shared_ptr便利そうだけど
STLだけでやりたい漏れはいらないや。。
95:えいいち ◆GRGSIBERIA
07/07/29 17:44:12
>>90,93
ありがとうございます。
96:名無しさん@そうだ選挙に行こう
07/07/29 17:50:08
>>94 auto_ptr 使え。
97:名無しさん@そうだ選挙に行こう
07/07/29 17:56:30
>>94
std::tr1::shared_ptr
98:名無しさん@そうだ選挙に行こう
07/07/29 18:04:17
>94 そうすると、auto_ptr + 生ポインタかね。
ライセンス制限ないんだから素直にboost使えばいいんじゃね?とは思うけど。
99:名無しさん@そうだ選挙に行こう
07/07/29 18:05:02
boostインスコめんどいよめんどいよ
100:名無しさん@そうだ選挙に行こう
07/07/29 18:48:13
shared_ptrぐらいならビルドする必要ないだろ。
インクルードパスを通しておくだけ。
101:デフォルトの名無しさん
07/07/29 18:57:05
このプログラムのエラーがわからなくて困っています
hash_set<string> h;
string s = "Hoge";
h.insert(s);
stringじゃないものを指定した場合にはinsertではエラーが出ないんですが、stringだと出てしまいます。
コンパイラはg++を使っています。
原因は何でしょうか?また、対応策はあるのでしょうか?わかる方がお願いします。
102:名無しさん@そうだ選挙に行こう
07/07/29 19:20:21
>>101
エラーメッセージは?
103:名無しさん@そうだ選挙に行こう
07/07/29 19:31:22
boostってライブラリとソース落としてこないと使えないでしょ?
104:名無しさん@そうだ選挙に行こう
07/07/29 19:39:55
一部を除いてヘッダをインクルードするだけで使える
105:名無しさん@そうだ選挙に行こう
07/07/29 19:41:45
>>101
>原因は何でしょうか?
ext/hash_fun.hに template <> struct hash<std::string> が定義されてないから
>対応策はあるのでしょうか?
たぶんこんなんで良いと思う
#include <string>
#include <ext/hash_set>
struct string_hash
{
size_t operator () (const std::string &p) const
{
return __gnu_cxx::hash <const char *> () (p.c_str ());
}
};
int main ()
{
__gnu_cxx::hash_set <std::string, string_hash> h;
std::string s = "Hoge";
h.insert(s);
}
106:名無しさん@そうだ選挙に行こう
07/07/29 19:46:06
>>103
じゃ今後ともどんなプログラムも頑張って標準関数だけで書いていって下さい
107:105
07/07/29 19:49:47
あぁ105では動くけど速くないかも知れんよ
108:名無しさん@そうだ選挙に行こう
07/07/29 19:59:10
vs2008がboostのライブラリを2,3個破壊しないか心配
109:名無しさん@そうだ選挙に行こう
07/07/29 20:09:15
ヘッダファイルのみ(ソースファイルは無し)で
唯一の静的汎用クラスを作ろうとしてこうしたんだけど、
こういう書き方普通?一応うまくいってますが
//test.h
#include <windows.h>
class CTest{
friend CTest* test();
CTest(){}
char *c; //実質静的メンバ変数(ソースで初期化する必要なし!)
public:
void f1(){c="f1";MessageBox(0,c,0,0);}
void f2(){c="f2";MessageBox(0,c,0,0);}
void f3(){c="f3";MessageBox(0,c,0,0);}
};
static CTest* test(){ //ここからのみアクセスできる
static CTest inst;
return &inst;
}
//main.cpp
#include "test.h"
int main(){
test()->f1();
test()->f2();
test()->f3();
}
110:名無しさん@そうだ選挙に行こう
07/07/29 20:13:23
ポインタは遅いしいろいろ駄目だから
なるべく参照を使っているのですが、
戻り値に参照を使っているときに関数が失敗したときに
NULLは返せません。この場合どうすればいい?
exit(0)で強制終了するとか駄目だし・・・
111:名無しさん@そうだ選挙に行こう
07/07/29 20:13:45
シングルスレッドならいいんじゃね
112:名無しさん@そうだ選挙に行こう
07/07/29 20:14:28
>>109
2つのソースから include して使ってみろ。うまくいかない。
113:名無しさん@そうだ選挙に行こう
07/07/29 20:16:26
>>109
> static CTest* test(){
このstaticは余計なんじゃねーの
114:名無しさん@そうだ選挙に行こう
07/07/29 20:16:37
>>110
ポインタが遅いから参照ってのが大間違い。そんなの信じてるようじゃ
「いろいろ駄目」ってのも疑わしい。ヌル返したいなら素直にポインタ使え。
本当に参照が適切なら、失敗を例外で伝えるという手もある。
115:名無しさん@そうだ選挙に行こう
07/07/29 20:19:56
ポインタって参照に比べて遅いの?
一番早い書き方は?
116:名無しさん@そうだ選挙に行こう
07/07/29 20:20:38
>>103
Boost Consultingにインストーラあったと思ったが
117:名無しさん@そうだ選挙に行こう
07/07/29 20:21:47
ポインタが遅いってなんだ?
エイリアスが無いと判断しにくいから最適化しにくいとかそういう話?
118:デフォルトの名無しさん
07/07/29 20:26:48
>>113
コンストラクタがprivateなのにどうやってインスタンス化しろっての。
119:デフォルトの名無しさん
07/07/29 20:38:07
>109
一昔前ならLoki::Singletonをお勧めしていたところだけど……
boostにSingletonあったっけ?
120:デフォルトの名無しさん
07/07/29 20:40:12
つーかそもそもシングルトン、要るか?
121:デフォルトの名無しさん
07/07/29 20:41:02
いらねーよ。今でも要らないシングルトンが量産されてるってのに。
122:デフォルトの名無しさん
07/07/29 20:41:20
__ .__
/| \ / |\
/ | / | \ Nentansoft
| /\/ ^o^ /\/|
|/\/ /\/ | J i n s e i O w a t a o 2 0 0 5
\ | / | /
\|__/ \__|/
123:デフォルトの名無しさん
07/07/29 20:42:09
>>118
それ static 関係ない。 friend が指定してある。
あれ? friend に内部リンケージの関数って不味くないか?
124:デフォルトの名無しさん
07/07/29 20:47:46
それ、翻訳単位毎にtest関数とその中の
CTestのinstが存在することにならね?
125:デフォルトの名無しさん
07/07/29 20:52:14
>>119
URLリンク(boost.cppll.jp)
126:デフォルトの名無しさん
07/07/29 21:27:24
>>109
テンプレートクラスなら普通にstaticなメンバ変数をヘッダ内に書ける(ODRに違反せずに「定義」できる)んじゃ無かったっけ?
それなら前にやったことがあるけど。
っていうかこれってどうやってるんだろう。やっぱリンカががんばってるんだろうか。
テンプレートじゃなきゃ、別にヘッダだけで収めようとしたことはないなぁ。
127:デフォルトの名無しさん
07/07/29 22:16:17
>>109 コピーコンストラクタを禁止しないのはまずいと思う
128:デフォルトの名無しさん
07/07/30 00:34:51
>>116
いや、便利ライブラリが嫌いなんじゃなくって
STL以外だと会社にもってって使えないいんよね。
便利なパーツは単体で、尚且つインクルード/コピペするだけで
リンカの設定弄らなくてもさくっとコンパイルできるのがいい。
ソース管理されてる環境だとプロジェクトファイルすら弄れないしね。。
129:デフォルトの名無しさん
07/07/30 00:39:49
>>128
同意
130:デフォルトの名無しさん
07/07/30 00:45:12
質問です
「あいうえお」と書いた外部ファイルを読み込んで1文字画面に出力するという操作を実装しようとしたら文字化けしてしまいました。
理由は文字コードが0x82A0なのに対し0x82までしか読み込んでなかったからみたいなのですが、
FILE* fp;
wint_t ch;
TCHAR s;
if( fopen_s(&fp, "word.dat", "r") )
{
MessageBox(NULL, TEXT("ファイルオープンに失敗"), NULL, MB_OK | MB_ICONSTOP);
exit(-1);
}
for(ch=fgetwc(fp); ch!=EOF; ch=fgetc(fp))
{
wsprintf(&s, TEXT("%d"), ch);
MessageBox(NULL, &s, NULL, MB_OK);
}
fclose(fp);
これだと1バイト分しか読み込まないのでしょうか?
また、2バイト読み込むにはどうしたらいいのでしょうか?
使ってる環境は、
WindowsXP Home Edition
VC++2005 Express Edition
です。
131:デフォルトの名無しさん
07/07/30 00:45:53
BSTRかwchar_t使えば?
132:デフォルトの名無しさん
07/07/30 00:50:28
>便利なパーツは単体で、尚且つインクルード/コピペするだけで
>リンカの設定弄らなくてもさくっとコンパイルできるのがいい。
Boostは大概インクルードだけで使えるけど……
133:デフォルトの名無しさん
07/07/30 00:53:04
インスコで環境を変えないなら使う
134:130
07/07/30 00:56:53
>>131
できませんでした。
wint_tも2バイト変数なのでfgetwcで2バイト読み込んでないということだと思うのですが、
fgetwcでは2バイト読み込むことは出来ないのでしょうか?
135:デフォルトの名無しさん
07/07/30 01:00:43
>>130
C言語の上にバグ持ちのVC++8.0か
環境依存スレ向きの話題じゃないのか
136:デフォルトの名無しさん
07/07/30 01:08:11
TCHAR s; //<--1バイト?2バイト?
wsprintf(&s, TEXT("%d"), ch);
TCHARってコンパイルの環境によって定義かわらない?
137:デフォルトの名無しさん
07/07/30 01:11:05
TCHARの定義はUNICODEが定義されているかどうかで変わるし
fgetwc()とfgetc()を混ぜこぜにしてるし
> TCHAR s;
> wsprintf(&s, ...
って何だそら
ムチャクチャだ
138:デフォルトの名無しさん
07/07/30 01:14:30
Cのwchar_tがらみの関数はsetlocale()を実行しておかないと
まともに動かん
VC++8.0の場合はバグのせいで、どっちみちw系のコンソール入出力が
腐るので諦めろ
139:デフォルトの名無しさん
07/07/30 01:17:31
VC++8ってそうなのかw
TCHAR WCHARとかじゃなく
明示的にchar wchar_tとか書いてもだめなん?
140:デフォルトの名無しさん
07/07/30 01:19:18
imbue
141:デフォルトの名無しさん
07/07/30 01:20:09
>>139
有名な話だよ。SP1でも直ってない。
URLリンク(forums.microsoft.com)
参照。
142:デフォルトの名無しさん
07/07/30 01:23:53
>>140
Cにはimbueも糞も無いんだが。
以下のコードがVC8.0では期待したように動かない。
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(void)
{
wint_t c;
setlocale(LC_CTYPE, "");
while ((c = getwchar()) != WEOF)
putwchar(c);
return 0;
}
143:デフォルトの名無しさん
07/07/30 01:25:08
ほんまやw
MSだせーな
BCC32マンセーしててしらんかったわw
144:130
07/07/30 01:38:26
みなさんアドバイスありがとうございました。
VC++8.0にはバグがあったんですね…
bccでコンパイルしてみることにします。
145:デフォルトの名無しさん
07/07/30 01:39:52
>>130
ざっくり見直してみたけどこれでどうよ?
FILE* fp;
wint_t ch;
wchar_t s[32]; //10進数の文字表現を格納する?
if( fopen(&fp, "word.dat", "r") )
{
MessageBoxW(NULL, L"ファイルオープンに失敗", NULL, MB_OK | MB_ICONSTOP);
exit(-1);
}
for(ch=fgetwc(fp); ch!=EOF; ch=fgetwc(fp))
{
wsprintf(s, L"%d", ch);
MessageBoxW(NULL, s, NULL, MB_OK);
}
fclose(fp);
146:デフォルトの名無しさん
07/07/30 01:41:26
>>145
WEOFにしないと無限ループ
147:145
07/07/30 01:42:18
ああスマン
148:130
07/07/30 02:07:48
>>147
このソースでも文字コードが0x82と0xA0いうふうに分かれて表示されてしまいました
やはりBCCを使ったほうがいいということなのでしょうか…
149:デフォルトの名無しさん
07/07/30 02:09:19
ん?もしかして
fopen/fcloseじゃなくて、wfopen/wfcloseじゃないとだめとかある?
150:デフォルトの名無しさん
07/07/30 02:09:55
>>148
setlocale(LC_CTYPE, "");
をプログラムのドアタマで実行汁。
151:デフォルトの名無しさん
07/07/30 02:10:37
>>149
関係ねー
それらはUTF-16なパス名でストリームを開く、というだけだ
152:130
07/07/30 02:30:11
>>150
出来ました!
ロケールというものを設定しないといけなかったんですね!
ロケールについて調べてみたらよくわからなかったんですが、
ロケールとはパソコンの情報の表示形式みたいなものと考えていいのでしょうか?
153:デフォルトの名無しさん
07/07/30 02:37:35
>>152
ロケールは貨幣や数値、時刻の形式なども扱うが、この場合は
LC_CTYPEというカテゴリを指定してやることで、
文字エンコーディング(SJISだのEUC-JPだの)をCランタイムに
教えてやっている。「""」は、「実行環境に応じて良きにはからえ」という
意味だ。Cランタイムはそれに応じてワイド文字とマルチバイト文字の
変換を行う。
154:130
07/07/30 03:02:24
>>153
なるほど、だからロケールを設定してないときの読み込み方がおかしかったんですね
わかりやすく教えていただきありがとうございました!
155:デフォルトの名無しさん
07/07/30 08:17:11
型Tから型Uへの変換が存在するかどうかを調べるtemplateの手法ってありますか?
具体的には次のようなことをやりたいのですが…
template<typename T>
struct PtrWrapper { T* p; };
class A {...};
class B : public A {...};
PtrWrapper<A> a;
PtrWrapper<B> b;
a = b; // 可能
b = a; // 不可能
156:デフォルトの名無しさん
07/07/30 11:44:19
template <typename T, typename U>
class Conversion
{
typedef char Small;
class Big { char dummy[2]; };
static Small Test(U);
static Big Test(...);
static T MakeT();
public:
enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
};
int main() {
using namespace std;
cout
<< Conversion<double, int>::exists << endl
<< Conversion<char, char*>::exists << endl
<< Conversion<size_t, vector<int> >::exists << endl
<< Conversion<A*, B*>::exists << endl
<< Conversion<B*, A*>::exists << endl;
}
詳しくは Modern C++ Design 参照。
157:デフォルトの名無しさん
07/07/30 16:10:51
iGoogleで複数のコンテンツを追加してみると、
追加したコンテンツをドラッグ&ドロップで移動できるのですが、
そのUIを、WinXPSP2上のVS2005 C++ Windowsフォームにて実装してみたくて調査中なのですが、
技術的に停滞中です。
フォームにPanelを配置し、そのパネルをドラッグ&ドロップすればよいのかと思うのですが、
パネルのドラッグ&ドロップが出来ません。。
何かサンプルありませんか?
158:デフォルトの名無しさん
07/07/30 16:26:33
MFCのCOleDropTargetクラスあたりかなぁ?
159:デフォルトの名無しさん
07/07/30 17:46:58
ありがとうございます。
COleDropTargetですか。ちょっとみてみましたが、
楽チンポンとは行かないみたいですね。
ちょっと勉強にいそしみます。
160:デフォルトの名無しさん
07/07/31 00:30:10
>>156
ありがとう!
ていうか解説読んで感動しました…
161:デフォルトの名無しさん
07/07/31 09:22:22
>160
どうせ中では同じようなことをやってるはずだけど、使えるなら Boost TypeTraits を使うのが楽。この場合は is_convertible
162:デフォルトの名無しさん
07/08/01 05:03:00
placement delete は
対応する placement new の実行中に例外が発生した場合に呼ばれるからという
ただそれだけのために存在する、という認識で問題ありませんか?
163:デフォルトの名無しさん
07/08/01 06:18:29
え
164:デフォルトの名無しさん
07/08/01 06:24:12
struct s{ s(){puts("s");} };
と定義して
struct s s_obj();
としてもコンストラクタが呼ばれないんですが、
俺何か間違ってるんでしょうか?
165:デフォルトの名無しさん
07/08/01 06:31:42
それは「struct sを返す関数」の宣言
166:デフォルトの名無しさん
07/08/01 11:23:21
struct s s_obj; としないといけない。
もっとも、s s_obj; で十分だが。
167:デフォルトの名無しさん
07/08/01 12:24:54
>>162
どうせ君は使わないだろうから問題ないよ。
人と話すときにはその話題避けてればいいんだし。
168:デフォルトの名無しさん
07/08/01 12:32:58
>>162
違う。正しくは
対応する placement new が成功した後のコンストラクタで例外が発生した場合に以下同文。
169:デフォルトの名無しさん
07/08/01 13:11:18
placement new というと、規格を見ると new の構文は
new-expression:
::(opt) new new-placement(opt) new-type-id new-initializer(opt)
new-placement:
( expression-list )
と書いてあって、new-placement ってのはあらゆる引数リストを指す要素のようだけど、
引数つきの new は何でも placement new と呼ぶのか?
170:デフォルトの名無しさん
07/08/01 13:13:10
そういうこと。
最初に想定されたのが配置に関する制御だったので、
placement newと名付けられたが、
使ってみたら色々使い道があったというわけ。
171:デフォルトの名無しさん
07/08/01 13:17:43
Ruby のイテレータみたいなもんか。繰り返さなくてもイテレータ。
っつーことは、「いつもの placement delete」 には特に呼ぶ価値ないけど、
それ以外の placement delete には十分価値があるかもしれんっつーことか。
172:デフォルトの名無しさん
07/08/01 21:46:24
RUBYYYYYYYYYYYYYYYYYYYYYYYY
173:デフォルトの名無しさん
07/08/01 21:53:00
pythonでおk
174:デフォルトの名無しさん
07/08/01 22:31:34
AnsiString GetReg(AnsiString Key, AnsiString Name, HKEY RootKey)
{
AnsiString Value;
TRegistry *Reg = new TRegistry();
Reg->RootKey = RootKey;
if(Reg->OpenKey(Key,false)){
if(Reg->ValueExists(Name))
Value = Reg->ReadString(Name);
Reg->CloseKey();
}
Reg->Free();
return Value;
}
175:デフォルトの名無しさん
07/08/02 00:53:06
テラBCB
176:174
07/08/02 00:57:40
書き込みが途中までしか出来てませんでした。
↓続き
関連する項目をググって、上記ソースを見つけたのは良いのですが、
得た値"Value"をstrcpy(a,b)のbで使おうとすると、
AnsiString型からキャストできず、エラーとなります。
AnsiString型をキャストすること自体がよろしくないようなのですが、
キャストか、他に良い方法がありましたら教えてください。
長文すみません。よろしくお願いします
177:デフォルトの名無しさん
07/08/02 01:01:43
strcpy(dst, AnsiString("あひゃ").c_str());
178:デフォルトの名無しさん
07/08/02 01:13:55
>>177は
Value.c_str()でやれということ
179:174
07/08/02 07:30:49
>>177=>>178さん
どうもありがとうございます。
助かります。
180:デフォルトの名無しさん
07/08/02 22:26:11
プログラム中から現在のCPUのクロック数を測定したいのですが
どうすればいいでしょうか?
181:デフォルトの名無しさん
07/08/02 22:29:12
>>180
Win32APIのQueryPerformanceFrequencyは?
182:デフォルトの名無しさん
07/08/02 22:32:00
あれはかなりいい
しかしモバイル用CPUとか動的にクロックが変化するCPUだとちょっと困る
183:デフォルトの名無しさん
07/08/02 22:42:28
すいません>>182の理由により別の方法をおねがします
もしかして不可能?
184:デフォルトの名無しさん
07/08/02 22:45:00
条件があったのなら初めに言えよ
185:デフォルトの名無しさん
07/08/02 22:46:46
cpuid命令を呼ぶ
レジスタに信用なら無いモデルナンバーが返って来る
メーカーの資料と照らし合わせる
周波数を知る
186:デフォルトの名無しさん
07/08/02 22:51:17
CPUとは違う固定周波もってるハードに割り込みかけてもらうぐらいしか思いつかん……
187:デフォルトの名無しさん
07/08/02 22:56:08
>現在のCPUのクロック数を測定
だから>>181でFA
188:デフォルトの名無しさん
07/08/02 23:08:53
>>185
ああ、その方法もありますね。しんどいけど。
どこかに cpuid --> cpu clock 変換表みたいなのありませんか?
クロック自体はrdtscで読めるんですが、
最近のCPUは省電力モードとかで
クロック自体が落ちてることもあって
正確なクロックが取得できないんです
189:デフォルトの名無しさん
07/08/02 23:15:32
CPU毎の定格周波数が知りたかったのか?
190:デフォルトの名無しさん
07/08/02 23:24:10
CPU に意図的に負荷かけてから測定するとか。
191:デフォルトの名無しさん
07/08/02 23:40:09
asmでおk
192:デフォルトの名無しさん
07/08/03 16:33:06
可変長のメンバ配列変数は C99 で規格合致になったけど、
C++ だと 9.2p8 を見る限り対応されてなさそうな雰囲気を感じる。
これは、非静的メンバ配列変数のサイズは必ず指定する必要があるという記述だから
ここだけじゃ実際のところはっきりとは分からんけど。
でも、次期 C++ ドラフトを見るとこの記述が削られてる。
これは C99 と同様に可変長のメンバ配列変数に対応された現れだと見ているけど、
そのことが書いてある箇所が見つからない。
C++ での可変長のメンバ配列変数への対応具合の状況はどんな感じなんじゃろか。
193:デフォルトの名無しさん
07/08/03 20:55:47
可変長配列がないならvector使えばいいじゃない(マリー
194:デフォルトの名無しさん
07/08/03 21:23:30
それなら C でも malloc 使えるしー。
でも、本気でそれでも問題ないと思うんだよな。
正直可変長メンバってどのくらい意味があるのか分かんないな。
Windows API とか可変長メンバを要求するところがあるから
しゃーなしで使わんといかんこともあるんだが。
195:デフォルトの名無しさん
07/08/03 21:33:07
ポインタ使うかわりに可変長メンバ使うとメモリ上のレイアウトがフラットに
なるから、そのままファイルに読み書きしたりできて便利な場合もあるでそ
196:デフォルトの名無しさん
07/08/03 22:04:00
stlのアロケータってrealloc操作がないのな。
vectorやstringのサイズ増加時にコピーが走りまくって参った。
197:デフォルトの名無しさん
07/08/03 22:16:19
reserveとかあるだろ
そういうハナシじゃない?
198:デフォルトの名無しさん
07/08/03 22:19:34
ふつうdeque
199:デフォルトの名無しさん
07/08/03 22:25:23
>>195
書き込みは一発だけど、
読み込む時は一旦サイズを読み出さないといかんのだよな。
状況によってサイズが分かる場合もあるけどさ。
そこまでの利点には思えんのよなあ。
昔だとその僅かな差も重要だったんだろうか。
200:デフォルトの名無しさん
07/08/03 22:27:52
>>196
<cstdlib>のreallocも、その場で拡張できなければ、
新しい領域を確保して、そこへ元の記憶域の内容をコピーすることになっている。
クラスインスタンス相手にコピーコンストラクタを使わず複写なんて
やるわけには行かないから、アロケータにrealloc相当の操作がないのも妥当な判断。
仮にやるとしたら、その場で拡張できるときだけ成功するrealloc操作
なんてことになるんだろうな。
201:デフォルトの名無しさん
07/08/03 22:33:47
>>199
malloc()/free()一発で確保・解放できるのも「Cでは」便利
で、特にデメリットも無いわけで
まあ可変長に出来るのは最後のメンバだけ、という制限があるけどな
ま、基本的に言語サポートが貧弱なCで特に生きるテクニックという気がする
202:デフォルトの名無しさん
07/08/03 22:35:49
記憶域の内容がコピーされても、
その後にちゃんとコピーコンストラクタを placement new で呼べば一応正常に動作する。
問題は二度手間になることと、
realloc による管理は C++ っぽくないってところだな。
203:デフォルトの名無しさん
07/08/03 22:36:31
PODのときはrealloc or memcpyするぐらいの配慮が欲しかったなあ
パフォーマンスに関わるんで結局手書きしちゃったよ
無駄にT()でfillするし・・・
204:デフォルトの名無しさん
07/08/03 22:37:30
>>201
どっちゃにしろ動的に確保する場合は
確かに一発で済むから便利か。なるほど。
205:デフォルトの名無しさん
07/08/03 22:40:24
でもまあバッファを拡大するときも、必要な量ぎりぎりではなく、
例えば倍々に増やしていったりする実装の存在なんかを考えれば、
やっぱりコンテナがrealloc相当のことをやっているんだよなと思う。
206:デフォルトの名無しさん
07/08/03 22:42:15
なんでC++にnew/deleteがあってrealloc()相当物が無いのかってのは
Stroustrupが説明してた気がするが、忘れた
207:デフォルトの名無しさん
07/08/03 22:45:50
placement new でコピーコンストラクタ使ってオブジェクト作ってるよ。
208:デフォルトの名無しさん
07/08/03 22:49:31
Win32 APIのVirtual Allocみたいなの使ってアドレス空間だけ予約しとけ
209:デフォルトの名無しさん
07/08/05 02:02:59
シグナルって何に使えばいいの?
中で特別な関数以外の関数呼んだら未定義とか規格に書いてるんだけど。
210:デフォルトの名無しさん
07/08/05 02:04:27
ぶっちゃけsignalがCの標準に含まれているのはどうかと思う
211:デフォルトの名無しさん
07/08/05 02:04:59
マジ?あの欠陥品が?
212:デフォルトの名無しさん
07/08/05 02:05:32
>>209 Unixの規格を読むんだ
213:デフォルトの名無しさん
07/08/05 02:09:07
Posix的にはsignal()は推奨されないでしょ
sigaction()を使うべき
Windowsのコンパイラが提供するsignal()は、規格を満たすためだけの紛い物で
何の役にも立たない
つまりsignal()なんて要らない子
214:デフォルトの名無しさん
07/08/05 02:10:34
いやシグナルという仕組み自体が正直勘弁だ
215:デフォルトの名無しさん
07/08/05 02:11:28
まあスレッド登場前の化石だよな
216:デフォルトの名無しさん
07/08/05 02:14:57
signal handlerからlongjmpがunixの作法ですが何か?
217:デフォルトの名無しさん
07/08/05 02:15:53
おk。大体分かった。
218:デフォルトの名無しさん
07/08/05 02:17:24
それが今となっては最悪の作法だよねって話でしょ
スレッドと相性が非常に悪いし
それでなくとも
シグナルハンドラが再インストールされるかどうかとか
システムコールが再送されるかどうかとか
シグナルハンドラ内であれをやってよいこれはよくないとか
バッドノウハウのすくつやん
219:デフォルトの名無しさん
07/08/05 02:23:03
write一つとっても、linux/*bsd/solaris/hp(dec)でそれぞれ挙動が違うからねえ
posixもM$がサーバ戦略に本腰いれて慌てて始めたもんだしなあ
220:デフォルトの名無しさん
07/08/05 03:22:10
set_terminate ってどういう場合に使う?
main で全ての例外補足してから異常終了した方が
ローカル変数のデストラクタが呼ばれていいと思うんだけど。
221:デフォルトの名無しさん
07/08/05 03:24:59
そういうまともな例外処理が出来ないときのためにあるのでは
例外処理中に例外が出たとか
222:デフォルトの名無しさん
07/08/05 03:27:03
>>220
2行目以降の意味がわからん。 set_terminate() 関係ないだろ。
223:デフォルトの名無しさん
07/08/05 03:36:23
>>221
ああ、二重例外に対応する場合か。なるほど。
224:デフォルトの名無しさん
07/08/05 12:41:24
VS2005 MFCなんだけど、アクセスバイオレーションの例外処理を
捕らえたいんだけど、
try{}
catch( ... ){}
この構文では捕えられないんだけど、どうしたらいい?
225:デフォルトの名無しさん
07/08/05 12:44:09
アクセスバイオレーションて単純にソフトウェアのバグじゃないか?w
226:デフォルトの名無しさん
07/08/05 12:54:51
/EHaとか/EHcがらみじゃないの?
でもデフォルトから変更した場合、
ミドルウェアとか依存するライブラリ絡みの整合性が心配だな。
227:デフォルトの名無しさん
07/08/05 15:14:37
URLリンク(msdn.microsoft.com)
まあC++の範疇じゃないな。
228:デフォルトの名無しさん
07/08/06 06:55:48
構造化例外で捕まえた方が良いと思うヨ。
229:デフォルトの名無しさん
07/08/06 18:19:11
_set_se_translatorという手もある。
いずれにせよVC++くらいしか使えるものがないというのに変わりはないけどな。
230:デフォルトの名無しさん
07/08/06 21:25:46
スレ違いだったらすいません。
アプリ開発の依頼スレが見つからなかったのでこちらに書かせて頂きました。
当方所有のウェブアプリケーションソフト
(以前プログラマに依頼して作ってもらったものですが今は連絡が取れません)
がURL先の変更?で突然使えなくなってしまいました。
そこで、緊急で本日中に改変が出来そうな方是非お願いできないでしょうか?
当方、全くの知識不足で言語が C++ということ以外分かりません。
ソースファイルは持っております。料金は2万円でお願いします!
seishinkeiki@hotmail.co.jp
231:デフォルトの名無しさん
07/08/06 21:29:58
マルチはよくないな
232:デフォルトの名無しさん
07/08/06 21:47:57
やすっ
233:デフォルトの名無しさん
07/08/06 23:11:47
>>230
ソースがあるならソースを晒せよ。ロハでできるぞ。
ソースを晒せないから有料でということなら、2万円なんて人を見下したようなことをするもんじゃない。
234:デフォルトの名無しさん
07/08/07 06:33:04
void foo(char *p, size_t len)
{
}
235:デフォルトの名無しさん
07/08/07 06:34:28
すみません途中で送信してしまいました。
void foo(char *p, size_t len)
{
// ここでpとlenからistreamを作りたい
}
実際には、basic_istreamの派生クラスを作るしかないのでしょうか?
236:235
07/08/07 06:44:00
最初は、std::istringstreamを使って実装していたのですが、バイナリを扱う必要があるので、見送りました。
237:デフォルトの名無しさん
07/08/07 07:39:56
俺判定
↓エスパー1級
238:デフォルトの名無しさん
07/08/07 07:48:18
>>236
ファイルストリーム以外でバイナリとテキストの問題なんて起こらないだろ?
istringstream でいいと思うよ。
239:デフォルトの名無しさん
07/08/07 07:50:42
>>236
なんでバイナリを扱う必要があったら istringstream を見送るの?
240:デフォルトの名無しさん
07/08/07 09:01:36
stringという名前が付いてるからバイナリは扱えないと思っているんだろうな
241:デフォルトの名無しさん
07/08/08 20:13:23
義務教育もしっかり受けてるのに
x = x +1
が疑問でもなんでもない俺は負け組
242:デフォルトの名無しさん
07/08/08 20:15:25
柔軟な思考は大事
固定観念はよくない
243:デフォルトの名無しさん
07/08/08 21:16:13
もう疑問を持ったかどうかすら覚えてないわ
244:デフォルトの名無しさん
07/08/08 21:57:28
>>241
x = x * x + Cならマンデルブロ集合なんだけどね。
245:デフォルトの名無しさん
07/08/09 10:46:54
>>241
むしろそのへんの切り替えが高速にできない子は算数のできない子
246:デフォルトの名無しさん
07/08/09 19:51:16
リアル演算子オーバーロードだよな。
247:デフォルトの名無しさん
07/08/09 19:59:43
要は「今まで習った常識・ルール」に囚われてしまっていて、
新しいルール、新しい前提の上でのゲームには一歩も踏み出せないってことだからな
その程度の頭の柔軟性が無いのでは算数やプログラミングに限らず
何やってもだめ
248:デフォルトの名無しさん
07/08/10 09:40:31
何でも受け入れるのもあれだけどな。
そこに疑問を持ち、考察し、納得する、というプロセスをだな・・・
249:身の程知らず
07/08/10 12:01:33
C++の文法に疑問を持つのは、よほどの天才か身の程知らずのどちらかだろ。
もちろんもっと人間にもコンパイラにも分かりやすくて、すばらしい文法は作れただろうが、
今のような位置を占めているかどうかは疑問だ。
以下、俺様演算子を定義できる機能とか、
Cのプリプロセッサなんかより、もっとプログラマブルで、文法を考慮するマクロとか、
↓禿のお気に入りだったマルチメソッドなどについて語ろう↓
250:デフォルトの名無しさん
07/08/10 12:04:48
>以下、俺様演算子を定義できる機能とか、
演算子オーバロードではお気に召しませんか?
>Cのプリプロセッサなんかより、もっとプログラマブルで、文法を考慮するマクロとか、
C99のプリプロセッサではお気に召しませんか?
それならDをどうぞ。
251:デフォルトの名無しさん
07/08/10 12:06:05
Lispじゃねぇの
252:デフォルトの名無しさん
07/08/10 12:10:18
開発当時はのんびり言語仕様考えるヒマなかったんだろう。
シェア争いを制するために時間を惜しんだんだろ
結局当時は高級言語に負けたが。
253:デフォルトの名無しさん
07/08/10 12:11:29
俺様演算子っていうと、Prolog みたいなやつか。
254:デフォルトの名無しさん
07/08/10 14:42:56
俺様演算子っていうと、Haskell みたいなやつか。
255:デフォルトの名無しさん
07/08/10 14:58:06
Forth なら何でもありだな
256:デフォルトの名無しさん
07/08/10 15:05:03
禿は演算子オーバーロードは必要最小限に抑えたほうが良いと言ってなかったか
257:デフォルトの名無しさん
07/08/10 15:54:28
おまいは禿が死ねって言ったら死ぬのか?
258:デフォルトの名無しさん
07/08/10 16:32:06
詭弁のガイドライン
259:デフォルトの名無しさん
07/08/10 17:05:23
おまいは「おまいは禿が死ねって言ったら死ぬのか?」ってレスを見たら詭弁だと短絡的に思うのか?
260:デフォルトの名無しさん
07/08/10 17:07:20
次の相談者の方、どうぞ↓
261:デフォルトの名無しさん
07/08/10 17:10:30
禿はC++に関しての第一人者だけど、死に関しての第一人者じゃない。
詭弁じゃないと言うなら、何をもって
「禿は演算子オーバーロードは必要最小限に抑えたほうが良いと言ってなかったか」
「おまいは禿が死ねって言ったら死ぬのか?」
というのが同じ重みがあるとするのかを明確化しろ。
262:デフォルトの名無しさん
07/08/10 17:44:52
物事の良し悪しは他人任せにせずに自分で考えましょう、
と注意する場合の定型句だと思うが。
263:デフォルトの名無しさん
07/08/10 18:16:58
ならそう書けばいいんじゃないかなw
264:デフォルトの名無しさん
07/08/10 18:21:40
なんでも平たく書き下すんじゃなく、
慣用句等あれば使うのが文化って奴だろ
その点APLなんかすごいぞ
265:デフォルトの名無しさん
07/08/10 18:26:07
論点ずらしの天才
266:デフォルトの名無しさん
07/08/10 18:34:21
演算子と人の生死を結びつけるところが正直よく分からん
267:身の程知らず
07/08/10 18:45:10
禿があれほどD&Eで多くのページを割いて、規格に入らなかったことを悔しがっているのに、
一言も突っ込まれないマルチメソッド哀れ。
まあ、正直言ってまず使わないと思うけど。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5391日前に更新/205 KB
担当:undef