【初心者歓迎】C/C++室 Ver.71【環境依存OK】 at TECH
[2ch|▼Menu]
1:デフォルトの名無しさん
10/01/29 23:15:45
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

【前スレ】
【初心者歓迎】C/C++室 Ver.70【環境依存OK】
スレリンク(tech板)

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

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か に置換すると見栄えだけはよくなります。


2:デフォルトの名無しさん
10/01/30 00:01:59
 codepad
 URLリンク(codepad.org)

長いソースを貼るときはここへ!

3:デフォルトの名無しさん
10/01/30 14:18:17
相談があるので乗ってほしい。

ターゲットは組み込みプロセッサで、メモリマップドレジスタのマクロ宣言で困ってる。

あるレジスタREG_Aがあって、そのレジスタの
- アドレスは 0X12345678、
- レジスタは4バイト長、
- 内部の値は符号無し整数
とする。コンパイラの整数長が4バイトとすると、こういう場合次のようなマクロ定義が定石になってる。

#define REG_A *( volatile unsigned int * ) 0x12345678

こうすると、REG_Aはプログラム中で変数のように使える。当然だけど、この「変数」へのアクセスはレジスタへのアクセスになる。で、困っているのは次のような場合。あるレジスタREG_Bがあって、そのレジスタの
- アドレスは 0XFFFF1234
- レジスタ、整数型、ポインタ型はそれぞれ4バイト長
- 内部の値は関数へのポインタ
- 関数は void ()
つまり、引数も取らず、何も返さない。関数へのポインタ。こういうレジスタは割り込みハンドラのアドレス指定時に使う。

gccを使って試しているんだけど、どうしてもうまくいかない。今はあきらめて*( volatile unsigned int *)としてプログラム中でキャストしているんだけど、気持ちわるい。だれか教えて。試験に使っているプログラムはこんな感じ。

URLリンク(codepad.org)

4:デフォルトの名無しさん
10/01/30 14:30:36
volatileって関数の返却値に使っても有効なの?
規格ではどうなってるんだろ

5:デフォルトの名無しさん
10/01/30 14:37:29
関数ポインタを使うときは、ちょっとでもわかりにくくなったら
必ずtypedefを使うようにするのが鉄則だと思う。
typedef void vfn_t(void);
#define REG_B (*(volatile vfn_t *) 0x11223344)
とか。
いや、これが正常に動くか、そもそも望みのものなのかも知らないけどね。

6:デフォルトの名無しさん
10/01/30 18:40:07
>>5
typedef void (*vfn_t)(void) で正解だな。

7:デフォルトの名無しさん
10/01/30 21:15:46
>>3
>>今はあきらめて*( volatile unsigned int *)としてプログラム中で
>>キャストしているんだけど

それでいいんじゃない?別に気持ち悪くない

8:デフォルトの名無しさん
10/01/30 22:16:06
>>4-7
ありがとう、提案された方法を試したあとに結果を報告する。

>>4
関数の返却値に使いたいんじゃなくて、レジスタの中身がvolatileであることを
宣言したい。だけどそのやり方がわからなくて、貼り付けたコードはめちゃめちゃに
なってる。

>>7
折角だしプログラムの中でいちいちキャストしたくないんだよ。キャストって、
この場合は正しく宣言していれば不要だし、間違った型の代入を防ぐことも
できる。

9:デフォルトの名無しさん
10/01/30 22:26:18
サンキュー、 >>6 の言うとおりにしたら動いたよ。

ソースはこれ。コンパイル結果を読みやすいようにレジスタアドレスを10進に変えてある。
URLリンク(codepad.org)

GCCのコンパイル結果。見事にREG_A、REG_Bへの代入に成功している。
.loc 1 10 0
movl $12345678, %edx
movl $foo, %eax
movl %eax, (%edx)
.loc 1 11 0
movl $12345674, %edx
movl $foo, %eax
movl %eax, (%edx)
.loc 1 12 0
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret

本当にありがとう。

10:デフォルトの名無しさん
10/01/30 23:46:26
敢えて一行で書くならこうかな?
#define REG_B (*(void(*volatile*)()) 0XFFFF1234)

11:デフォルトの名無しさん
10/01/31 01:04:51
>>9
#define の値は括弧で囲っといたほうがいいよ。
それから引数無しの引数リストに void を入れるかどうかはそろえといたほうがいいよ。
C なら必須。

12:デフォルトの名無しさん
10/01/31 09:19:40
任意のクラスのオブジェクトの情報をまるごとバイナリファイルに保存・復元みたいなことはできるんだろうか?

13:デフォルトの名無しさん
10/01/31 09:40:27
>>9
代入がアトミックになってないぞ
mutexか何かでバリアしておいた方が良くないか?

14:デフォルトの名無しさん
10/01/31 09:56:49
>>12
シリアライズで出来るんじゃない?
自分はやったことないけどね

15:デフォルトの名無しさん
10/01/31 10:32:39
>>12
boost::serializationかな

16:デフォルトの名無しさん
10/01/31 11:24:01
>>12
もうまさにboost::serializationだな。


17:デフォルトの名無しさん
10/01/31 17:21:13
>>12
保存中の進捗表示はboost::progress_displayにお任せ!

18:デフォルトの名無しさん
10/01/31 18:06:17
環境ですが、
OSはWindouwsXP
コンパイラ名はMicrosoft VisualC++2008 Express Edition
言語はC
です。

解決できず困っている事があるので、よろしくお願いします。
質問 → URLリンク(kansai2channeler.hp.infoseek.co.jp)

19:デフォルトの名無しさん
10/01/31 18:26:32
WindowsでフリーでVC++ライクの総合環境ってなんか無い?

20:デフォルトの名無しさん
10/01/31 18:42:37
>>19 VC++ EE

21:デフォルトの名無しさん
10/01/31 23:02:34
void (*handle) ();


int address = 0x00000;

handle = (void (*) () )address;


このコードがよくわかりません。
関数ポインタを宣言していることはわかるんですが、3行目のキャストが何を意味しているかが不明です。教えてください

22:デフォルトの名無しさん
10/01/31 23:05:05
代入先を考えろ

23:デフォルトの名無しさん
10/01/31 23:21:49
>>21
関数へのポインタにキャストしているだけです。
void (*x)(); という宣言が理解できるのであれば、それから識別子をとりのぞくと、そのままキャストに使う書き方になるだけです。

24:デフォルトの名無しさん
10/01/31 23:45:44
ちょうど関数ポインタの話題が出てるので聞きたいんだけど、
クラス内でstaticな2次元配列の関数ポインタを扱いたいときってどうすればいいんだろうか。

class ObjectManeger{
public:
 static bool (*Collision[2][2])(const Object &a, const Object &b);

 static bool A(const Object &a, const Object &b){};
 static bool B(const Object &a, const Object &b){};
 static bool C(const Object &a, const Object &b){};
 static bool D(const Object &a, const Object &b){};
};
bool (ObjectManeger::*Collision[2][2])(const Object &a, const Object &b);

って感じの所まではたぶん合ってると思うんだけど・・・。
2×2の配列にABCDの各関数を入れたいんだ。

25:デフォルトの名無しさん
10/01/31 23:48:12
>>21
単に警告でないように強制型合わせしているだけ
違うものを強制挿入する時よくやる



26:デフォルトの名無しさん
10/01/31 23:56:43
>>24
static な関数だと ObjectManeger::* じゃなくてただの * でいいよ。
っていうかコンパイルしてみればいいじゃない。

27:デフォルトの名無しさん
10/02/01 00:02:47
>>26
外部シンボルは未解決だ、って怒られるんだ。
あと、ABCDの各関数を初期化時に入れるのはどうやってやるのか・・・。
色々試したんだけど、コンパイルでエラーの嵐で分からないんだぜ・・・。

28:デフォルトの名無しさん
10/02/01 00:07:11
class Object;

class ObjectManeger
{
public:
  static bool (*Collision[2][2])(const Object &a, const Object &b);

  static bool A(const Object &a, const Object &b) { return true; }
  static bool B(const Object &a, const Object &b) { return true; }
  static bool C(const Object &a, const Object &b) { return true; }
  static bool D(const Object &a, const Object &b) { return true; }
};

bool (*ObjectManeger::Collision[2][2])(const Object &a, const Object &b) = {
  &ObjectManeger::A,
  &ObjectManeger::B,
  &ObjectManeger::C,
  &ObjectManeger::D
};

29:デフォルトの名無しさん
10/02/01 00:08:26
関ポはtypedef
これ、常識ね

30:デフォルトの名無しさん
10/02/01 00:10:17
bool (*ObjectManeger::Collision[2][2])(const Object &a, const Object &b) = {
{ &ObjectManeger::A, &ObjectManeger::B },
{ &ObjectManeger::C, &ObjectManeger::D }
};
ミスった

31:デフォルトの名無しさん
10/02/01 00:18:05
>>30
通った! ありがとう!
そう書けばよかったのか・・・。

>>29
可読性的な意味で、なのかな。
確かに見づらい・・・。

32:デフォルトの名無しさん
10/02/01 00:56:26
>>14-16
virtual 使ってるクラスでもできる?

33:デフォルトの名無しさん
10/02/01 01:20:53
class ObjectManager {
 typedef bool collision_t(const Object& lhs, const Object& rhs);
 static collision_t *Collision[2][2];
 ...
};
ObjectManager::collision_t ObjectManager::Collision[2][2] = {
 &ObjectManager::A,
 ...
};
て感じか。
メンバ関数ポインタじゃないから、そんなに複雑な見た目にはならないかな。

34:デフォルトの名無しさん
10/02/01 08:01:37
関数ポインタって
typedef void (*func_ptr_t)(void);
func_ptr_t fp = &func;
だけじゃなくて
typedef void func_t(void);
func_t * fp = &func;
でも通るんだ
はじめて知ったよ
これって標準?

35:デフォルトの名無しさん
10/02/01 09:09:07
>>34 うん。

36:デフォルトの名無しさん
10/02/01 21:48:30
javaだとIDEの補完機能を使うとimport *を勝手に書いてくれるけど、
C++のIDEはそんな機能がないのかな?

いちいち、#inluce <*>って書くのが面倒くさい
それとも、Qt Creatorは新しいから無いのかな?

37:デフォルトの名無しさん
10/02/01 22:10:21
だから無理してC/C++なんかやらなくていいよ
ずっとJavaで良いじゃん

38:デフォルトの名無しさん
10/02/01 22:10:24
>>36

C++はないよ

C# ならある

39:デフォルトの名無しさん
10/02/01 22:17:59
>>38
わかったよ、ありがとう

40:デフォルトの名無しさん
10/02/02 10:59:32
C++では普通の関数は使わないのですか?
普通の関数の代わりに、staticのメンバ関数を使うのが常識なのですか?

41:デフォルトの名無しさん
10/02/02 11:08:43
>>40
べつにクラスを使わないんだったらバシバシ普通の関数も使うよ

ただクラスを定義しとくとデバッグがめっちゃ楽になんのよ

42:デフォルトの名無しさん
10/02/02 11:15:45
普通の関数ももちろん使うよ
algoritmヘッダなんかには普通の関数もたくさん入ってる(ほとんどテンプレート関数だけど)
もちろん普通の関数を使うところで
staticメンバ関数を使っても問題は起こらないから
すべてstaticメンバ関数で統一したければすればいい
むしろ可視性の操作とかネストクラスとかできることが増えるから
staticメンバのほうが俺はいいと思う

43:デフォルトの名無しさん
10/02/02 16:28:40
template <typename T> class Hoge
と言うクラスがあるとき

実装をcppファイルに記述するには明示的実体化するしかないのでしょうか?
.hファイルに実装を記述するととても見苦しい状態になってしまうのですがどうにかならないでしょうか

44:デフォルトの名無しさん
10/02/02 16:30:30
コンパイラによります

45:デフォルトの名無しさん
10/02/02 16:32:45
使用環境はVS2005standard editionです

46:デフォルトの名無しさん
10/02/02 18:38:51
>>43
仕方がありません
Comeau C++を買いましょう

47:40
10/02/02 19:25:32
>>41-42
ありがとうございます

static関数はクラスに属していますが、それ以外は普通の関数と同じなのですか?

48:デフォルトの名無しさん
10/02/02 20:33:42
クラスの名前空間に属して、そのクラスのprivate/protectedメンバを触れること以外は同じと見て差し支えない
細かい違いはあるけど

49:デフォルトの名無しさん
10/02/02 20:36:50
>>43
いいんじゃね
boostの.hppってっ拡張子は
実装も含んでるヘッダだよ、っていうような意味なんじゃないかね

50:デフォルトの名無しさん
10/02/02 20:39:53
>>48
thx

51:デフォルトの名無しさん
10/02/02 21:45:20
>>49
Boost FAQには以下のようにあるけど。

>なぜ Boost のヘッダファイルはどれもこれも .hpp を使い、 .h や拡張子なしにしないのですか?

>ファイルの拡張子は、人間とコンピュータプログラムの両方にそのファイルの "型" を伝えるものである。
>'.h' という拡張子は C のヘッダファイルで用いられており、 C++ のヘッダファイルに関して間違ったことを伝えてしまう。
>拡張子無しのものを用いると何も伝わらず、型を断定するためにファイルの中身を調べることを強制する。
>'.hpp' を使うことで、そのファイルが C++ のヘッダファイルであることを明確に特定することができ、 また実際に使う際にもきちんと動作する。 (Rainer Deyke)

52:デフォルトの名無しさん
10/02/02 22:00:10
>>51
つまりC++は静的型付け言語だから、
同じように型の発想をしよう、ということか。

・・・それって守らなきゃダメなん?
Boost以外でも守られるのが標準的なC++の文化なの?


53:デフォルトの名無しさん
10/02/02 22:24:15
拡張子なんてただの飾りだから何でもいいよ
.fuckとか.javaとか.exeとか付けるのも自由だ

54:デフォルトの名無しさん
10/02/02 22:30:12
>>53
まあ自由だけど、それをまねした
小学生がぶん殴られたら可哀想じゃないか!


55:デフォルトの名無しさん
10/02/02 22:32:54
The Loki Library
を見てみたら、ふつーに.hだったわ。


56:デフォルトの名無しさん
10/02/02 22:34:27
.exe とか .lnk とか拡張子によってはシステムべったりだから飾りじゃすまないな

57:デフォルトの名無しさん
10/02/02 22:50:13
ゲームのパラメータをファイルに置いておきたいんですが
c++から使えて暗号化もできるシンプルなデータベースってありますか?

58:デフォルトの名無しさん
10/02/02 22:53:42
Linuxにてgprofでプロファイルを見てみたのですが、全関数の処理の合計時間が実測した時間よりも短くなっていました。
この差分は何に起因するものなのでしょうか?

59:デフォルトの名無しさん
10/02/02 22:57:07
>>58
cputime と usertime の差?

60:デフォルトの名無しさん
10/02/02 23:12:30
>>57
URLリンク(www.moongift.jp)
これとかどうだろう

61:デフォルトの名無しさん
10/02/03 05:05:32
gccでAみたいに書くとstrict aliasing rules警告されるんで、
Bみたいに書いたんだけど、これって正しい、というか、
-fno-strict-aliasingを指定した場合と同じ意味になるって保証されてる?

struct Vec { int x, y, z; };
int  data[3][3] = {{0,1,2},{3,4,5},{6,7,8}};
int main() {
  Vec* v0 = (Vec*)data; // A 警告される
  Vec* v1 = (Vec*)(void*)data; // B 警告されない
  return 0;
}


62:デフォルトの名無しさん
10/02/03 06:37:25
警告残した方が後々の為に良い気も

63:デフォルトの名無しさん
10/02/03 06:39:24
>>61
基本的にstrict aliasing ruleに対する違反は
キャストでは解決できないと思った方がいい

じゃあどうすればいいの?ってところでは
GCC3.3.0以上なら__attibute__((may_alias))っていうのがある

けど、そのコードはダーティすぎるからそこから直した方がいい

64:デフォルトの名無しさん
10/02/03 09:35:07
namespaceとはどういうときに使用するのですか?

65:デフォルトの名無しさん
10/02/03 09:42:43
>>64 名前衝突の可能性を最小限にしながら、面倒なプリフィックス付けもしたくないとき。

66:デフォルトの名無しさん
10/02/03 10:13:04
めんどうっていうけど
std_hogeもstd::hogeも変わらねーよ

67:デフォルトの名無しさん
10/02/03 10:24:18
じゃあインテリセンスで一覧表示させたい場合

68:デフォルトの名無しさん
10/02/03 10:34:05
>>66
たとえば関数 hoge の宣言や定義で同じ名前空間にある名前を何度も使うことを考えると
話が違ってくるはず。

std_result std_hoge(std_arg1 a1, std_arg2 a2)
{
  std_detail d;
  std_impl(d, a1, a2);
}

namespace std {
result hoge(arg1 a1, arg2 a2)
{
  detail d;
  impl(d, a1, a2);
}
}

69:デフォルトの名無しさん
10/02/03 10:43:42
DQN的プログラミングにnamespaceは不要

70:デフォルトの名無しさん
10/02/03 11:32:37
DLLとかでエクスポートするときに邪魔なんだよ名前空間
いちいちラップしないといけない

71:デフォルトの名無しさん
10/02/03 11:42:06
クラス内の複数箇所でstd::out_of_range("適当なエラーメッセージ")
このまま文字列リテラルがコード各所に散らばるのは気持ち悪いので

1.あらかじめエラーメッセージをメンバ変数に持たせておく
2.例外を投げるメンバ関数を用意する
3.std::out_of_range("適当なエラーメッセージ")をマクロ定義しておく

どれがスマートな方法でしょうか?

72:デフォルトの名無しさん
10/02/03 11:54:58
俺はマクロかなぁ
const文字列にしてもいいけどマクロのが楽じゃわい

73:デフォルトの名無しさん
10/02/03 12:09:13
void check_range(int min, int max, int value) {
if (value < min || value > max) throw std::out_of_range("〜");
}

74:デフォルトの名無しさん
10/02/03 12:14:27
>>73
それじゃどこからエラー出たか特定できないじゃん

75:デフォルトの名無しさん
10/02/03 12:18:23
どのみち例外に行番号情報は含まれないから、元から特定できないと思うけど

76:デフォルトの名無しさん
10/02/03 12:28:21
__FILE__と__LINE__をパラメータで渡せばいい

77:デフォルトの名無しさん
10/02/03 14:24:53
別に何も対策はしないな
それで問題が出るわけじゃないし

78:デフォルトの名無しさん
10/02/03 15:43:49
C++ で継承不可能なクラスを宣言することはできますか?
C# や Java の static class みたいに。

79:デフォルトの名無しさん
10/02/03 15:49:27
残念なことにできません
(C#やJavaのsealedやfinalのことだよね?)
仮想関数にあたるものにvirtualを付けないことで
これ以上継承しないでね、という意思表示にすることぐらいしか
現状できないと思う
ただ、次期C++だとたぶんあるんじゃないかな

80:デフォルトの名無しさん
10/02/03 15:52:22
例外をマクロ化するのは良いアイデアだなとおもったけど
標準例外のコンストラクタに__LINE__と__FILE__を渡す方法を思いつかなくてガッカリ・・・

どういうマクロにすれば良いでしょうか?

81:デフォルトの名無しさん
10/02/03 16:00:32
class out_of_range_with_line_number : public std::out_of_range {
...........
};

82:デフォルトの名無しさん
10/02/03 16:13:05
行番号とかよりも
どの関数から/どのデータが原因で投げられたのか、といった情報を入れたほうがいいんでないかい
out_of_rangeなら、どの配列からout_of_rangeが出たのかによって
それが分かるような例外クラスを作ってrethrowするとか


83:デフォルトの名無しさん
10/02/03 16:37:42
つ boost::exception

84:デフォルトの名無しさん
10/02/03 17:48:55
>>81>>83
やっぱり継承するなりなんなりするしかないか

85:デフォルトの名無しさん
10/02/03 18:37:02
>>78
デストラクタを private にしてみるとか。

class Hoge {
private:
 ~Hoge() {}
};


86:デフォルトの名無しさん
10/02/03 18:50:11
まともに使えねえよ

87:デフォルトの名無しさん
10/02/03 19:06:09
C++0xの[[final]]も継承禁止じゃないしな

88:デフォルトの名無しさん
10/02/03 19:08:30
iface *create(...) { class local : public iface { ... }; return new local(...); }

制限はあるけどこれでfinalだよ

89:デフォルトの名無しさん
10/02/03 20:52:17
教えて下さい。

今お仕事のデバッグ用にSDカードのセクタをFATではなく
セクタ直接アクセスするコードを今使ってます。

そのソフトでドライブ選択をGetDriveType()でリムーバブルディスクのみを
選択できるようにしておるのですが、これではカードリーダーライターに
刺さったディスク全て選択できてしまいます。(例えばCFとかUSBメモリとか)

自分だけで使う場合は注意すればいいだけなのですが、チームで使ってるんで
できればドライブ選択をSDカードONLYにしたいと思っているのですが、
どのようなコードにすればいいでしょうか?

環境
WindowsXP
Microsoft VisualC++ 6.0 MFC

90:デフォルトの名無しさん
10/02/04 00:22:22
>>71
どの方法にも何のメリットも感じられない。
そのままにしとくのが一番スマートな気がする。

>>80
#define OUT_OF_RANGE(what) (std::out_of_range(std::string(__FILE__":"BOOST_PP_STRINGIZE(__LINE__)": ") + (what)))

91:デフォルトの名無しさん
10/02/04 01:59:50
>>62-63
ありがとう。できるだけ根本的に修正するようにしてみる。
ついでに、このコードについても教えてくれないか。

URLリンク(codepad.org)

これ、仕事で使ってるgcc4.1.1とcodepad(gcc4.1.2)では警告されるのに、cygwinのgcc4.3.2だと、
-fstrict-aliasingと-Wstrict-aliasingを指定しても警告されないんだ(-Wstrict-aliasing=2を加えれば警告される)。
このへんの動作って4.1.2以降で変更されてる?
gccのchangesを見たけど、関係ありそうなのは4.2の
The C++ frontend now also produces strict aliasing warnings when -fstrict-aliasing -Wstrict-aliasing is in effect.
くらいしか見つけられんかった。

92:デフォルトの名無しさん
10/02/04 05:32:31
>>91
どうしてそんな碌でも無いコードばかり書くんだ…

GCCのchangelogに書いてあるのは大きなものだけだから
知らないうちに内部の動作が少々変わることはありうるよ

無印の-Wstrict-aliasingで警告がでないのが正しいかはわからん
そこらへんの加減はgccの中の人にしかわからんだろうから…

93:デフォルトの名無しさん
10/02/04 09:36:50
#include <iostream>
#include <fstream>

#pragma pack(push, 1)

struct POD
{
int a, b;
char str[5];
int x, y, z;
};

#pragma pack(pop)

void test(POD &pod)
{
std::cout << "a: " << pod.a << std::endl;
std::cout << "b: " << pod.b << std::endl;
std::cout << "str: " << pod.str << std::endl;
std::cout << "x: " << pod.x << std::endl;
std::cout << "y: " << pod.y << std::endl;
std::cout << "z: " << pod.z << std::endl;
}

94:デフォルトの名無しさん
10/02/04 09:37:33
void save(POD &pod)
{
std::ofstream out("test.bin", std::ios::binary);
out.write((char*)&pod, sizeof(POD));
}

void load(POD &pod)
{
std::ifstream in("test.bin", std::ios::binary);
POD tmp;
in.read((char*)&tmp, sizeof(POD));
pod = tmp;
}

95:デフォルトの名無しさん
10/02/04 09:39:19
int main(void)
{
POD pod1 = {1, 2, "test", 3, 4, 5};
test(pod1);
save(pod1);

POD pod2 = {0};
load(pod2);
test(pod2);

return 0;
}

上記のコードは自分のマシンだと期待通りに動いてるようなんですが
ほかのマシンに移植しても大丈夫でしょうか?

96:デフォルトの名無しさん
10/02/04 09:44:54
intの奇数番地アクセスに問題ないCPUだったら、大丈夫かも

97:デフォルトの名無しさん
10/02/04 10:01:24
>>96
レスありがとうございます
念のためpack(push, 4)にしてみます

98:デフォルトの名無しさん
10/02/04 10:07:15
移植性考えるなら
stdint.hを読み込んで
int

int32_t
とかに

99:デフォルトの名無しさん
10/02/04 12:44:50
>>98
レスありがとうございます
バイト数も揃えてみます
vc++にstdintが無いのが困りものですがvs2010にはあるようなので・・・

100:デフォルトの名無しさん
10/02/04 13:21:04
>>92
>どうしてそんな碌でも無いコードばかり書くんだ… 
ごめんw
実は>>91は、社内製コードでLoadFileAsync(const char* filename, void** buffer)っていうのがあるんだけど、
これがgcc4.1.1にしたら警告が出たので、調査用に書いたんだわ。
動作は、filenameを非同期にディスクから読み出して、読み出したメモリ領域のアドレスをbufferに返す。
非同期ロード用クラスでも作って、void**を置き換えればいいんだろうが、
既にあちこちで呼ばれてる関数だから手を出しづらいんだよね。

101:デフォルトの名無しさん
10/02/04 16:21:27
>>99
URLリンク(www.kijineko.co.jp)
こういうのがあるよ

102:デフォルトの名無しさん
10/02/04 23:42:27
>>100
それでもその強引なキャストは要らんのでは?

A a;
void* p;
f(&p);
a.str = static_cast<char*>(p);

もしかしてメモリ領域の確保も非同期なの?

103:デフォルトの名無しさん
10/02/05 01:25:07
ヘッダファイルの中で#includeの替わりに,classが使われている時があります
#includeをclassにすると、何かいい事があるのでしょうか?

また、QWidgetは#includeもclassも書かれていませんが
なぜ、使う事ができるのでしょうか?
URLリンク(calmlight.s2.zmx.jp)

104:デフォルトの名無しさん
10/02/05 01:34:59
「#includeの替わりに,classが使われている」わけじゃない
前方宣言でググれ
というかC/C++の#includeはJavaのimport、C#のusingとは違うぞ

105:デフォルトの名無しさん
10/02/05 06:58:32
>>103
もうC言語やC++のプリプロセッサっていう勉強をした方がいいんじゃないか?

106:デフォルトの名無しさん
10/02/05 09:24:40
継承元クラスを引数で受けた時に、そのprotectedメンバにアクセスできないのは
どういう理由でそうなっているのでしょうか?

class A {
protected:
 int x;
};

class B : public A {
public:
 void operator=(const A& a) {
  x = a.x; //a.xはprotectedで操作できない
 };
};

107:デフォルトの名無しさん
10/02/05 09:30:31
>>106
別のクラス class C : public A (略)などが、 B とは違う都合でそいつを使っている
かもしれないから。

めんどくさいから protected なんて最初から使わなけりゃいいんだよ。
private or public でいけないのか、よく考えたほうがいい。

108:デフォルトの名無しさん
10/02/05 09:45:32
>>107
適当なこというな

>>106
自分がAをpublicに継承してアクセス可能になるのは
this->aであって
引数としてAを受けた時は外部からのアクセスになる
つまりAのpublicなメンバにしかアクセスできない
(自分がAを継承してるかなんて全く関係ない)

上のケースでやろうとしてるのはこれと変わらない
void f(const A& a){
int a=a.x;
}

protectedなメンバは
「この機能は継承してから使えな」、っていう意思表示なのに
継承前のAのデータにアクセスできたらおかしいでしょ

109:デフォルトの名無しさん
10/02/05 10:04:23
だったら外からアクセスしてるのに同じクラスのprivateにアクセス出来るのはおかしいはず

110:デフォルトの名無しさん
10/02/05 10:05:47
>>108
あんたのそれは何か根拠があるのかね?

> 自分がAをpublicに継承してアクセス可能になるのは
> this->aであって
> 引数としてAを受けた時は外部からのアクセスになる

protected がそうなってる( private と違う)理由を聞かれてるんだよ。

ちなみに、 A の継承が public であるかどうかは関係ないし、
this->a 以外にも B& b という引数に対してなら b.a でアクセスできる。

> protectedなメンバは
> 「この機能は継承してから使えな」、っていう意思表示なのに
> 継承前のAのデータにアクセスできたらおかしいでしょ

その説明だと、別の派生クラス C の C& c について B のメンバ関数内で
c.a にアクセスできない理由の説明にならないね。

111:デフォルトの名無しさん
10/02/05 10:17:53
>>100
>>92に追記しておくけど
-Wstrict-aliasingは全ての問題があるケースを警告するとは限らない
-Wstrict-aliasingは-Wstrict-aliasing=3と同じで
-Wstrict-aliasing=1が最も「少しでも怪しければ警告にする」けど
それでもit has very few false negativesとしか言われてない
URLリンク(gcc.gnu.org)

製品としてgccの最適化によるバグを絶対回避したいなら
-fno-strict-aliasingにしてこの種の最適化を無効にするしかない

112:デフォルトの名無しさん
10/02/05 10:23:47
>>111
> -Wstrict-aliasing=1が最も「少しでも怪しければ警告にする」けど
> それでもit has very few false negativesとしか言われてない

それ、 "when higher levels do not ... , as it has very few false negatives" の
ところで、 1 より上のレベルについて言ってるところだよ。レベル 1 については
"it has many false positives" ってなってる。

113:112
10/02/05 10:28:46
ん?ごめん、読み違えた。

Level 1 だと false negative が少なくて(でもゼロじゃなくて)、かわりに false positive は多いってことか。

112 は忘れて。

114:デフォルトの名無しさん
10/02/05 15:57:26
ifstream と Win32 ReadFile のメリットとデメリットを教えてください

ReadFileはwindows依存していることは知ってます、ifstreamの内部ではReadFileを使っている(?)とかどってでみた気がする
速度を比較してみたらifstreamの方がはやかったです

115:デフォルトの名無しさん
10/02/05 16:02:59
1バイトずつReadFileを呼び出したりしていないか?
ifstream等は内部にバッファを持って一度の呼び出しで多くのデータを読み込むようにしてAPIの呼び出し回数を抑えているはず

116:114
10/02/05 16:10:02
ReadFile引数のブッファ指定のところでファイルサイズ渡しているので1バイトずつではないはず

117:デフォルトの名無しさん
10/02/05 16:45:56
普通のファイルを普通に読むとOSは勝手にディスクキャッシュするよ

118:デフォルトの名無しさん
10/02/05 17:24:52
それだとReadFileが遅い理由にならんのでは

119:デフォルトの名無しさん
10/02/05 17:28:37
いきなりファイル全体キャッシュするわけじゃないから

120:デフォルトの名無しさん
10/02/05 18:04:54
ディスクアクセスのコストはOSのディスクキャッシュで隠蔽できても
システムコール(カーネルとのモード遷移)のコストは隠蔽できません。
ReadFileを何度も何度も呼び出している限り。

121:デフォルトの名無しさん
10/02/05 19:48:25
ifstreamが速い理由にならんぞ

122:デフォルトの名無しさん
10/02/05 20:15:36
ナニ言ってんだオマエは

123:デフォルトの名無しさん
10/02/05 20:16:50
ちなみに
stdioと比較してifstreamは全然速くない。

124:デフォルトの名無しさん
10/02/05 20:23:02
比較しちゃだめだろ

iostreamの良い所は別にあるんだから。
何かというとそれは次の人どうぞ
↓↓↓


125:デフォルトの名無しさん
10/02/05 20:39:29
継承によって作られている所です

つまり入力元や出力先だけではなくstringstreamのように
根本的な構造が異なっても全く同じイメージで操作できる事です

とでも言って欲しいのか?

126:デフォルトの名無しさん
10/02/05 21:52:34
>>114 どんなコードで比較したのかわかるようにコードを晒さないと答えられないな。


127:デフォルトの名無しさん
10/02/05 22:16:09
>>114
ReadFileの使い方を間違ってるんじゃないか?
ifstreamを書いた人はReadFileの使い方をよく知ってるんだと思うよ。

128:デフォルトの名無しさん
10/02/05 23:44:41
メッセーッジについて教えてくれ
WM_NOTIFYとON_NOTIFY_REFLECTの関係がわからない

調べたところWM_NOTIFYのメッセージが贈られるとるとON__NOTIFY_REFLECTが呼び出されれウ
みたく書いてあったけど
じゃあON_NOTIFY_REFLECTがもってる通知メッセージは何よ?

わかりやすくおしえてね

129:デフォルトの名無しさん
10/02/05 23:49:40
>>128
は?
頭おかしいの?

130:デフォルトの名無しさん
10/02/05 23:50:12
>>128
Win32API質問箱 Build86
スレリンク(tech板)

131:デフォルトの名無しさん
10/02/05 23:52:04
どっちかというとMFCのほうだな

132:デフォルトの名無しさん
10/02/06 02:27:22
PaintDCの描画領域のクリア方法教えて

133:デフォルトの名無しさん
10/02/06 10:22:50
InvalidateRectもしくはValidateRectのことか
それともFillRectのことだろうか

134:デフォルトの名無しさん
10/02/06 13:22:55
template< int Foo >
class CHoge
{
public:
  CHoge(int ini) : m_hoge(ini){}
  int m_hoge;
  char m_foo[Foo];

  static const CHoge<Foo> sc_Zero;
};
//const CHoge<Foo> CHoge<Foo >::sc_Zero = CHoge<Foo>(0); // Foo : 定義されていない識別子です。

 sc_Zero を初期化したいんだけど,どのようにすればいいでしょうか?

135:デフォルトの名無しさん
10/02/06 13:38:26
Fooの値は決まる必要があるんじゃね?

template< int Foo >
class CHoge
{
public:
CHoge(int ini) : m_hoge(ini){}
int m_hoge;
char m_foo[Foo];
static const CHoge<Foo> sc_Zero;
};

CHoge<1> h(10);
const CHoge<1> CHoge<1>::sc_Zero(h);


136:デフォルトの名無しさん
10/02/06 13:41:57
template < int Foo >
const CHoge<Foo> CHoge<Foo >::sc_Zero = CHoge<Foo>(0);

137:134
10/02/06 13:51:57

>>135-136
ありがとうございます.初期化出来ました.

138:デフォルトの名無しさん
10/02/06 17:31:35
前方宣言をすると普通に#includeするよりも、コンパイルが速くなりますか?

139:デフォルトの名無しさん
10/02/06 17:33:57
前方宣言はコンパイル依存性を減らしたりするために
あると思うんだけど

140:デフォルトの名無しさん
10/02/06 17:39:20
>>138
コンパイルが速くなるっていうよりも、コンパイルしなおさなければいけなくなるファイルが
減るっていうのが正しいかと。

141:デフォルトの名無しさん
10/02/06 18:05:26
前方宣言が必要なパターン

class B;

class A {
B b;
};

class B {
A *a;
};

あとはpimplイディオムで少し似た使い方したり。

142:138
10/02/06 18:06:41
>>140
やっぱり、そうだよね
thx

143:デフォルトの名無しさん
10/02/06 22:06:12
newとmallocは似たような動作をしますが、
バックグラウンドではnewがmallocを呼び出しているのですか?

144:デフォルトの名無しさん
10/02/06 22:09:27
>>143
そういう実装も多いけども、そうとは限らない。
それが問題になるようなプログラムを書くべきではないし、書く必要も無い。

145:デフォルトの名無しさん
10/02/06 22:48:57
WinAPIを使わずにマウスをプログラム側から操作するにはどうしたらよいでしょうか?

146:デフォルトの名無しさん
10/02/06 22:50:12
そういうライブラリを探す。

147:デフォルトの名無しさん
10/02/06 22:57:22
>>145
それは不可能だろう。

ラッパライブラリがあれば可能だろうが、
そのラッパもやはりWinAPIは使っているだろうな。

148:デフォルトの名無しさん
10/02/06 23:43:39
VS2005、C/C++でコントローラ(Joystick)の状態を取得するにはどうすれば良いのでしょうか?
調べても中々出てこないみたいなので。助けてください。
プロジェクト設定はWin32コンソールアプリケーションです。
ひどいくらい初心者ですが、よろしくお願いします。

149:デフォルトの名無しさん
10/02/06 23:53:46
GetJoystickState

150:デフォルトの名無しさん
10/02/07 00:13:35
>>148
Windows APIか、DirectXのDirectInputを使う

Joystick Reference (Windows)
URLリンク(msdn.microsoft.com)(VS.85).aspx

DirectInput
URLリンク(msdn.microsoft.com)(VS.85).aspx
URLリンク(msdn.microsoft.com)(VS.85).aspx

151:デフォルトの名無しさん
10/02/07 00:30:49
DirectInputは使っています。

printf("%d\r\n",js.lX);
で一応、初期値の -8 とプリントされているのですが、
動かしても変動がありません。どうも倒しながらキーボードを入力すると数値が変動するようです。

現在はキーボード入力で入力したときだけOpenGLが再描画されるのですが
これをJoystickを倒した時に再描画されるようにするにはどうすればよいのでしょうか?

switch (key) {

case 'd':
{
Point NextPos( PosX+0.2, PosY );
if( !ColCheck( NextPos ) )PosX +=0.2;
glutPostRedisplay();
}
ソースはこんな感じになっています。キーボード入力時のみの再描画ではなく、常に?描画するにはどうすればよいのですか?
初心者ですみません。書き込んでいて何を言ってるのかわからなくなってきました。

152:デフォルトの名無しさん
10/02/07 00:45:10
OpenGLスレで聞いてみれば?

153:デフォルトの名無しさん
10/02/07 00:50:10
はい、そうしてみます。ありがとうございました。

154:デフォルトの名無しさん
10/02/07 02:47:37
void *型から何かの型へのポインタへキャストする時にそれが有効か調べるいい方法はあります?
今のところハッシュにアドレスとtype_infoのペア保存しておくという微妙な方法しか思いつきません

155:デフォルトの名無しさん
10/02/07 07:03:04
>154
dynamic_cast かな。
でもどっちかっていうと型判別しなきゃいけないこと自体がどっかおかしいような気がする。

156:デフォルトの名無しさん
10/02/07 07:19:04
void * にdynamic_castは無理

157:デフォルトの名無しさん
10/02/07 08:14:09
C++にはリフレクションがないから無理だろ

158:デフォルトの名無しさん
10/02/07 10:01:05
>>154
shared_ptr があるよ

159:デフォルトの名無しさん
10/02/07 11:15:33
struct hoge {
int bar1;
char *buf;
int bar2;
};

こんな構造体のbufに文字列入れるなりmallocするなりするとメモリ的にはどうなるの?
bar2がその分後ろにずれたりするの?

160:デフォルトの名無しさん
10/02/07 11:22:14
template<size_t T_size>struct hoge {
int bar1;
char buf[T_size];
int bar2;
};

161:デフォルトの名無しさん
10/02/07 11:22:50
>>155
void*なんか使わないほうがいいと言えばそのとおりなんですが
スクリプトと拡張型のポインタをやり取りするのに一回void*に変換されて型情報がなくなってしまうのです
スクリプト側で変なことしなければ問題はないんですが、間違えるとエラーも出せずに落ちてしまうのでどうにかできないかな、と

>>156,157
やっぱり無理・・・でしょうか

>>158
すいません
詳しくお願いできますか?

162:デフォルトの名無しさん
10/02/07 11:45:30
void*のポインタ先をデータの生ポインタではなく、

struct ptr_holder {
void *ptr;
type_info ty;
};

のポインタとかにはできないの?

163:デフォルトの名無しさん
10/02/07 11:54:49
>>161
void*を何かのクラスに変換するのはプログラマの責任になるんだね。
変換方法はプログラマから決めないといけないけど、1種類のクラスしか扱えないのが実情。
そこで、複数のクラスを扱うには、>>162のように1種類のクラスを挟んでクラスを識別できるようにして変換する。
それをやっているのが>>158の方法。shared_ptr<void>へのポインタshared_ptr<void>*をvoid*として渡し、shared_ptr<void>*に戻す。その後、shared_polymorphic_cast<Hoge>(*Ptr);で変換。型が違えば例外が投げられる。

164:デフォルトの名無しさん
10/02/07 11:56:54
>>159
ずれない
                +------+
0x11111100 | bar1   |
                 |------|
0x11111104 | buf     | ---> NULL
                 |------|
0x11111108 | bar2   |
                +------+
↑こんな感じのが ↓こんな感じになるだけ
                +------+
0x11111100 | bar1   |
                 |------|
0x11111104 | buf     | ----+
                 |------|        |
0x11111108 | bar2   |        |
                +------+        |
                 +------+       |
0x22222200 | 文字列 |  <--+
                 +------+

165:デフォルトの名無しさん
10/02/07 12:13:53
>>163
shared_ptrのその使い方はshared_ptrの本来の使い方の一部にしかすぎない。
shared_ptrの本来の使い方を知った上で使うべき。

166:デフォルトの名無しさん
10/02/07 12:13:58
>>162
残念ながら、ptr_holder*をvoid*にして渡すという形になりますので
結局のところvoid*がptr_holder*に戻せるかという、ほぼ同じ問題に戻ってしまいます

>>163
やはりvoid*がshared_ptr<void>に変換できる保証はないので、完全では無いですね


でも同一プロジェクト内でならshared_ptrに統一することは可能なので試してみたいと思います
みなさんレスありがとうございました

167:デフォルトの名無しさん
10/02/07 12:39:16
>void*がptr_holder*に戻せるか

そこは当然ptr_holderしか使わないという縛りが必要になる

168:デフォルトの名無しさん
10/02/07 12:50:54
void*やshared_ptr<void>ではなく、boost::any(あるいはany*やshared_ptr<any>)にしたらいい。

169:デフォルトの名無しさん
10/02/07 15:23:09
LinuxでC++勉強したいんだけど
ライブラリって何が標準なの?

170:デフォルトの名無しさん
10/02/07 15:25:02
gccとかのこと?

171:デフォルトの名無しさん
10/02/07 15:25:38
>>169
まずは C 標準ライブラリと C++ 標準ライブラリだな。

172:デフォルトの名無しさん
10/02/07 15:29:38
>>171
boostというのが標準ですか?それともSTLというのですか?

173:デフォルトの名無しさん
10/02/07 15:35:08
>>172
boost は標準ではないが、将来の標準に含まれるものを含んでいる。
STL は昔の名前で、今は C++ 標準ライブラリに含まれている。

174:デフォルトの名無しさん
10/02/07 15:38:54
>>172
boostは標準ライブラリではない。
だが信頼性・移植性のある外部ライブラリだと思う。
あとboostのすごいところは最先端をめっちゃ追求しているところかな。



175:デフォルトの名無しさん
10/02/07 15:45:36
boostは盛りだくさんだから、ひとくくりで全部OKとかダメだとは言いにくいな。

176:progress_display
10/02/07 15:49:25
>>175
私のことお呼び?

177:デフォルトの名無しさん
10/02/07 16:40:18
昨日違うスレで質問しましたが、質問させてください

public void setXXX(Foo* f)というメソッドがあった場合、
1.setXXX(f);→fはポインタ
2.setXXX(&f);→fはポインタではなく、fのアドレスを渡している

普通にプログラミングをした場合は、1 or 2のどちらでも大丈夫だと思います
しかし、GUI関係をプログラミングした場合は、2の方法はダメな可能性が高いと思うのですが
結局はGUI Tool Kitに依存するといいうことでしょうか?

178:デフォルトの名無しさん
10/02/07 16:47:07
fがFooのポインタなら1だし、Fooのインスタンスなら2
ツールキットとかそういう問題じゃない
そもそもpublic void setXXXは通常なら構文エラー

179:177
10/02/07 16:51:15
>>178
1はFoo* f = new Foo();
2はFoo f;
で宣言しています

>そもそもpublic void setXXXは通常なら構文エラー
何故?

180:デフォルトの名無しさん
10/02/07 16:58:25
そのGUIオブジェクトがローカルスコープ限りで削除されるような場合は別に2でも問題ないと思うけれど
デバイスコンテキストとかはそういう使い方をしそうだがウィンドウとかはあまりそういう使い方をしないだろう

181:デフォルトの名無しさん
10/02/07 17:06:54
>>179
エラーってのは、publicの後ろにコロンが付いてないだけのことだと思う。

182:デフォルトの名無しさん
10/02/07 17:06:54
>>177
> GUI関係をプログラミングした場合は、2の方法はダメな可能性が高いと思うのですが

なんで?
意味わかんない。

可能性が高いとかグダグダ言ってないで、関数の仕様を確認すればいいのに。

183:デフォルトの名無しさん
10/02/07 17:15:50
スタックやヒープといったメモリ領域はご存じ?

184:177
10/02/07 17:56:51
>>180
それもそうですね

>>181
java出身なもので、うっかりやってしまいました

>>183
yes

185:デフォルトの名無しさん
10/02/07 18:14:18
177がなんでそんな疑問を持ったかのほうが気になる
そもそも実引数fの型がFOOへのポインタだとしたら
上の1と2は全く同じ意味だというのは分かってる?

186:デフォルトの名無しさん
10/02/07 18:17:44
185は忘れてくれ

187:デフォルトの名無しさん
10/02/07 18:21:54
>>185
ドンマイ。たまにうっかりしちゃうよな。

188:デフォルトの名無しさん
10/02/07 18:39:49
>>177は何かを勘違いしてる気がする。

public : void setXXX(Foo* f);

Foo fOrg;
Foo* f = &fOrg;

1.setXXX(f);→fはポインタ
2.setXXX(&fOrg);→fOrgはポインタではなく、fOrgのアドレスを渡している

これでどっちも同じになるんだが。

189:デフォルトの名無しさん
10/02/07 18:47:44
>>188いや、たぶんそれ自体は理解してるんじゃないかな
GUIアプリで、長期間あるオブジェクトを使うような場合に、
ヒープにとるべきか(1)スタックにとるべきか(2)という質問なんじゃないの

190:デフォルトの名無しさん
10/02/07 18:54:41
じゃあ、インスタンスの寿命を気にしてるってことか。
そんなのJavaもC++も一緒じゃないの?
スコープを抜けたらデストラクタが実行されるでしょうよ。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5400日前に更新/160 KB
担当:undef