【初心者歓迎】C/C++室 Ver.50【環境依存OK】at TECH
【初心者歓迎】C/C++室 Ver.50【環境依存OK】 - 暇つぶし2ch175:デフォルトの名無しさん
08/03/02 13:20:54
>>174
じゃあ、一行ずつ読みたいなら、getline()でやるしかないですか?


176:デフォルトの名無しさん
08/03/02 13:25:32
以下のようなとき、
子クラスのオブジェクトから、func(1)を実行すると、
func(const char* ch)を呼んでしまうのですが、
親クラスのfunc(int i)を呼ぶにはどうすればいいのでしょうか?

/*****こんな感じ*****/
class Parent{
public: void func(int i);
};
class Child : public Parent{
public: void func(const char* ch);
};
/*******************/

177:デフォルトの名無しさん
08/03/02 13:29:35
>>175
そうなる。
getline した後 istringstream に渡してやるとか。

178:デフォルトの名無しさん
08/03/02 13:39:57
>>176
Child ch;
ch.Parent::func(1);

179:デフォルトの名無しさん
08/03/02 13:47:37
>176
子クラス Child の func() によって親クラス Parent の func() が隠蔽されている。普通にオーバーロードしたいなら
class Child : public Parent {
public:
  using Parent::func;
  void func(const char* ch);
};
とすることで Parent での func() も見えるようになる。

180:176
08/03/02 14:07:51
>>178
>>179
ありがとうございます。

181:デフォルトの名無しさん
08/03/02 14:27:55
namespace temp
{
class Test
{
private:
std::ostringstream oss;
public :
~Test() {std::cout << oss.str();}

template <typename T>
friend Test &operator <<(Test &, T t);
};
}

template<typename T>
temp::Test &operator<< (temp::Test& test, T t)
{
test.oss << t;
return test;
}

を、temp::Test() << 2;
と使うと、「operator << が曖昧です」というコンパイルエラーになります。
名前空間を使わないとコンパイルできるのですが、何が問題なのでしょうか

Win2k、VC2005です

182:デフォルトの名無しさん
08/03/02 14:32:37
<< の実装部も temp 名前空間に入れないと。
temp::Test 内で宣言してる friend 関数は temp 名前空間内に入る。
だから、今は temp::operator<< と operator<< の2つがある状態。

183:デフォルトの名無しさん
08/03/02 14:37:08
>>182
なるほど、ありがとうございました!

184:デフォルトの名無しさん
08/03/02 14:39:32
あるいは friend のところを ::operator<< にするかだけど、
temp 名前空間内に入れた方がいいと思う。

185:デフォルトの名無しさん
08/03/02 14:50:17
コマンド等文字列処理で2重のループから抜けるときに
goto文使うのって邪道かな?

いつも使ってるんだが。

186:デフォルトの名無しさん
08/03/02 14:50:54
2重ループから抜ける際に goto を使うのは常套手段

187:デフォルトの名無しさん
08/03/02 15:17:28
俺、今まで一度も使ったことが無い。
使いたい衝動に駆られたことはある。

188:デフォルトの名無しさん
08/03/02 15:19:02
小さい関数内なら結構goto使っちゃうなぁ

189:デフォルトの名無しさん
08/03/02 15:23:44
常套手段ではあるけど、
2重ループから抜ける必要があること自体があまりないよね。

190:デフォルトの名無しさん
08/03/02 15:24:49
まあ関数は一目でざっと目通せる程度にするもんだしちゃんと考えて使うならぜんぜんいいと思う

191:デフォルトの名無しさん
08/03/02 15:36:50
ポインタを解放した後、安全のためNULLを入れると書いてたんですが、
NULLを入れると何が安全なのでしょうか?

192:デフォルトの名無しさん
08/03/02 15:38:35
解放されているかどうかを NULL チェックで確認できる。

193:デフォルトの名無しさん
08/03/02 15:39:18
二重にdeleteすることが無くなる(delete(NULL)は安全なことが保障されている)

194:デフォルトの名無しさん
08/03/02 15:40:13
NULL なら間違って解放後にアクセスした際にエラーになってくれる環境が多い。
NULL じゃない場合は偶然アクセスできるかもしれないが、
メモリ領域を壊したり変な値を取得したりしてしまう。

195:デフォルトの名無しさん
08/03/02 15:41:42
無限ループでポインタインクリメントでもしながら片っ端から表示してみれば良いわけない

196:デフォルトの名無しさん
08/03/02 15:49:10
すみません

keybd_eventみたいに
プログラムからキーボードを押したことにするのは
gccだと何か方法がありますか・・・?

197:デフォルトの名無しさん
08/03/02 16:12:32
>196
keybd_event は Windows API。gcc はいろんな環境向けがあるコンパイラ。
例えば Windows 上で gcc を使っているなら keybd_event になるわけだしやりたいことをもっと正確に書こう。

198:デフォルトの名無しさん
08/03/02 17:26:18
初心者です。

デフォルトコンストラクタっていうのは、
1.引数なしで呼ばれるコンストラクタ
2.なにも記述してなくてもデフォルトで呼ばれるコンストラクタ
のいったいどっちのことなのですか?

1と2の違いは、例えば、引数なしのコンストラクタを
自分で定義したときに、それをデフォルトコンストラクタと
いうかどうかという違いになると思うのですが、、、
1と2の説明ともWEB上で見かけますが、
どちらがより正確なのでしょうか?

199:デフォルトの名無しさん
08/03/02 17:29:15
引数無しで呼ばれるコンストラクタ。
自分で定義しようがデフォルトコンストラクタ。

200:デフォルトの名無しさん
08/03/02 17:34:41
>>198
引数なしで呼ばれるというよりは引数なしで呼ぶことが可能なと
いったほうがいいかもな。デフォルト引数もあるから。

class Widget {
public:
Widget(int i = 0) {}
};

      //例えば
Widget w; //このsyntaxがデフォルトコンストラクタを要求する。
      //Widget::Widget(0)が呼ばれる。


201:198
08/03/02 17:35:37
>>199
ありがとうございます。
すっきりしました。


202:198
08/03/02 17:37:25
>>200
おっと行き違いになりました。
そうですか、
それもデフォルトコンストラクタなんですね。
ありがとうございました。

203:196
08/03/02 18:15:40
>197
すみませんでした
OSはDebianでPDFかパワポのようなものを
C言語で操作したいのです

具体的には下キーかEnterキーをC言語で押したことにして
スライドを進めることを行いたいです

204:191
08/03/02 19:36:37
>>192
>>193
>>194
ありがとうございます。
具体的によく分かりました。

205:デフォルトの名無しさん
08/03/02 21:56:29
c言語で聞きたいことが1からたくさんあるので、何方かmsnメッセで教えてくれませんか?
kamisama6@hotmail.co.jp         までお願いします!

206:デフォルトの名無しさん
08/03/02 22:02:14
>>205
C言語の個人講習をして欲しい訳だな?しかも無料で!

そんな奇特な人は少ないが候補として
C言語を覚えたてで自分のために他人に説明する人がいるが
そんな人を探すくらいなら良書を買ったほうがいくぶんかマシ

C言語をマスターしていながら教えてくれる人がいるとしたら
リタイヤした人くらいだろうな

207:デフォルトの名無しさん
08/03/02 22:08:50
string tmp;
cin >> tmp;
としたとき、改行だけが押されたことを知るにはどうすればいいですか?

208:デフォルトの名無しさん
08/03/02 22:16:47
>>207
フォーマット入力はデフォルトでは空白類記号は読み込まれない。

209:デフォルトの名無しさん
08/03/02 23:29:59
gcc をつかった
分割コンパイルの仕方がわからないのですが
わかりやすく解説したページはないでしょうか?

210:デフォルトの名無しさん
08/03/02 23:33:01
gcc -c hoge1.c
gcc -c hoge2.c
gcc -c hoge3.c
gcc -c hoge4.c
gcc -o hoge hoge1.o hoge2.o hoge3.o hoge4.o

211:デフォルトの名無しさん
08/03/02 23:55:20
>>209
Makefileでググれば、良いと思う。

212:デフォルトの名無しさん
08/03/03 00:35:02
namespace Name
{
class Cls;
}

213:デフォルトの名無しさん
08/03/03 00:48:48
丸一日前のレスにレスか

214:デフォルトの名無しさん
08/03/03 00:52:06
Makefileとbjamとどっちがいい?
やっぱ標準であるmakeは一通りやっとくべきかな?

215:デフォルトの名無しさん
08/03/03 01:14:07
>>208
ありがとうございます。一応自分で書いてみましたが、まだうまく動きません。
noskipwsをした後、おかしくなります。
どうかよろしくお願いします。

std::string filename = "default_file.txt";
while (1) {
std::string tmp;
cout << "Input file name : (hit return to default: " << filename << ") ";
cin >> std::noskipws >> tmp; // 下の(1)でY以外で答えたとき、ここで入力を受け付けてくれない。
if (tmp.empty()) {
// リターンキーだけが押された場合に、ここのIF文に入る
tmp = filename;
}
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin >> std::skipws;
cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
cin >> ans; // (1)
if (ans == "Y") {
filename = tmp;
break;
}
}

216:デフォルトの名無しさん
08/03/03 02:22:41
stdlib.hの中で_CRT_DOUBLE_DECと_LDSUPPORTを定義してないとき_CRT_DOUBLE、_CRT_FLOATといった構造体を用意してるようですが、
_CRT_DOUBLE_DECと_LDSUPPORTとこの2つに囲まれた構造体などは何のために用意してるんですか?

217:デフォルトの名無しさん
08/03/03 02:31:37
>>215
改行は読み込まないからgetlineがいい。

std::string filename = "default_file.txt";
while (1) {
std::string tmp;
std::cout << "Input file name : (hit return to default: " << filename << ") ";
std::getline(std::cin, tmp);
if (tmp.empty()) {
tmp = filename;
}
std::cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
std::getline(std::cin, ans);
if (ans == "Y") {
filename = tmp;
break;
}
}

218:デフォルトの名無しさん
08/03/03 02:43:47
C++ってどういう業界の人がつかってるの?
GUIでMFCやVCL、Qtさわるくらいはあるが、
ゲーム以外でフルスクラッチで書き上げる人たちって
どういう人?

219:デフォルトの名無しさん
08/03/03 02:44:13
趣味

220:デフォルトの名無しさん
08/03/03 03:24:20
やっぱそうか。
抽象化なんて考えてる暇あったら別の仕事が
飛んでくるもんね。

221:デフォルトの名無しさん
08/03/03 03:25:01
最近C#なんか使う企業もねえ

222:デフォルトの名無しさん
08/03/03 03:50:36
つまりCωの時代がやってくると。

223:デフォルトの名無しさん
08/03/03 03:57:12
時代はwebアプリか・・・

224:デフォルトの名無しさん
08/03/03 03:58:37
業務ソフトなら実際C#とか.NETでもなんら問題なくなってきてるご時世だもの

225:デフォルトの名無しさん
08/03/03 03:59:03
俺は金融関係だけど、C++使ってるよ。
matlabを使うとこも多いけど。


226:デフォルトの名無しさん
08/03/03 04:00:20
自動車関係企業のシステム部門ってC/C++使うのかなぁ

227:デフォルトの名無しさん
08/03/03 04:01:14
いかにも使いそうじゃないか

228:デフォルトの名無しさん
08/03/03 04:05:58
>>226
COBOLとか使うと思うんだ、経験則

229:デフォルトの名無しさん
08/03/03 04:51:56
昨日から色々質問させてもらっているものです。
色々分かってきたのですが、getlineとcinとの併用のときにどう書くべきかわかりません。

#include <iostream>
using namespace std;
int main()
{
int a;
string s;

cout << "int: ";
cin >> a;
// cin.ignore(numeric_limits<streamsize>::max(), '\n');

cout << "string: ";
getline(cin, s);

cout << "int: ";
cin >> a;
return 0;
}

上記のソースでコメントアウトしている箇所がありますが、コメントアウトしたままだと、
真ん中のstringの入力が、1つめのintの入力の改行を拾ってしまうせいで、とばされてしまいます。
そこで質問なのですが、ここにコメントアウトされている行をいれるのは正しいですか?


230:デフォルトの名無しさん
08/03/03 05:00:45
>>229
コメントアウトした行を入れてもだめ。
cin >> a; で改行文字がバッファに残るため、それが次のgetlineで
読み取られてしまう。Cで言う所のscanf()とgets()を混在させた問題と同じ。

解決策はgetline(cin, s); をもう一つ付け足して改行文字を読み飛ばす。
もしくはgetline()に統一する。

231:デフォルトの名無しさん
08/03/03 05:37:29
今の所COBOL、PL/I、Java、JS、Access、Rubyを見たことがある

232:デフォルトの名無しさん
08/03/03 05:42:58
>>225

金融っていってもmatlab使ってるようなところは
複雑な数値計算やってるだろうからちょっと特殊だな。

車でもカーナビのように限られたリソースでGUI作るようなところは
使ってるだろうが、間違っても制御には使わんと思うんだが。

233:デフォルトの名無しさん
08/03/03 05:53:38
>>230
ありがとうございます。
getline()とcinを混在させないのが一番いいと。でも、cinが便利なので、
基本的にはcinを使いつつ、cinだと改行を扱うのが不便なのでその時だけgetline()を
使う、という風になりそうです。(自分としては)
すると、
(1)getline()する前にバッファに改行が残っているか確認して、残っていれば消す。
(2)cinした後には改行を消しておく。
のどっちかになると思うのですが、今回は(1)の方法が分からなかったので、(2)で実装しました。
どっちにしても、cin関係はなんか使いにくい感じ。



234:デフォルトの名無しさん
08/03/03 06:03:00
linux のmmapのこと調べてて疑問に思ったので質問。
mmap でファイルを仮想メモリにマッピングしたとき、OSがファイル上のデータを
ブロック転送する、アプリがその領域に書き込むとOSがファイルにそれを反映すると
書いてあった。

mmapでマップされた領域に上のあるアドレスに代入したとき、
OSは代入されたことを知っているの?
代入演算子で値を放り込むことと、read write のシステムコールを使うのは
根本的に違いますよね?

235:デフォルトの名無しさん
08/03/03 06:03:27
>>218
GEANTは4からC++だよ!

236:デフォルトの名無しさん
08/03/03 06:09:53
>>234
C/C++の問題じゃないと思う
多分OSがマッピングした領域は書き込み不可の属性が付いており
書き込んだらCPUに割り込みがかかってそれを利用してファイルに反映してるか
そんな所だと思う

237:デフォルトの名無しさん
08/03/03 06:14:44
>>236

失礼しました。
環境に依存する内容は避けたほうがよいですね。

238:デフォルトの名無しさん
08/03/03 06:52:21
>>237
環境依存OKのスレだから問題ないんだけどC/C++よりも
linuxの話になるね

ちなみにWindowsの仮想メモリとメモリマップトファイルも似たような
機構で実現している

239:デフォルトの名無しさん
08/03/03 07:59:34
複数ある単語から文字列中最初にマッチする物を探す用途で、
こんなのを考えてみたのですが、こういう2分木辞書ってなんて
名前になるんでしょうか?
サフィックスツリー?(これよりもっと複雑なようですが)

typedef std::map<char, Node> Tree;
//char に単語の1文字が入る

struct Node {
 Node *pChild; //次の文字ノード
 int No;      //登録番号、兼、非末端(-1)
}

単語がab,ba,ac,abcとあるなら、子ノードの繋がりが下記のようになる。
先頭   <a,-1>       <b,-1>
      / \       /
    <b,0>  <c,3>   <a,1>
    /
  <c,3>

240:デフォルトの名無しさん
08/03/03 08:01:07
訂正
struct Node {
 Tree *pChild;
 int No;
}

241:デフォルトの名無しさん
08/03/03 09:10:06
&ClassName::memberVarName;

って演算はいったい何を行っているのでしょうか?
最初オフセット値を得ているのかと思ったんですが、ためしに出力しても、1が出力
されるだけです。

元ソースでは、これを引数にしてメンバ変数のオフセット値を得ているようですが…

242:デフォルトの名無しさん
08/03/03 09:11:38
>>241
メンバポインタでぐぐれ

243:デフォルトの名無しさん
08/03/03 09:27:45
>>242
ありがとうございます。おかげで理解できました。

メンバポインタからオフセット値を得るには、

&( static_cast<A*>(0)->*memPtr )

で仕様上問題ないでしょうか?

244:デフォルトの名無しさん
08/03/03 09:35:43
単にオフセットが欲しいんなら offsetof を使えばいい

245:デフォルトの名無しさん
08/03/03 11:13:30
>>243
実際には動くだろうけど、仕様上は良くないような
ちゃんとインスタンスを用意した方がいいんじゃない

246:デフォルトの名無しさん
08/03/03 11:30:26
>>243
オフセットは POD 型に対しての offsetof でしか取れないよ。
素直にメンバポインタ通して参照しちゃダメなの?

247:デフォルトの名無しさん
08/03/03 12:07:59
>>229
仕様上正しい。

以下はJosuttis本の記述の要約。

istream& istream::ignore(streamsize count, int delim)
This form ignores up to count characters until delim is extracted and discarded.
(ストリームから改行まで抽出されて捨てられる。)

ちなみにg++ 4.0では無問題だった。

248:デフォルトの名無しさん
08/03/03 12:50:21
>>239
トライ木じゃねえの

249:デフォルトの名無しさん
08/03/03 15:03:37
>>236
割り込みなんかかからない。
ページング機構を備えるどんなプロセッサでも(俺の知る限り)
プロセッサ自体に、書き込まれたかどうかのフラグ
(いわゆる、dirty bit と呼ばれるもの)をセットする機構がある。
例えばx86ならば、ページテーブルの該当ページを示すエントリ内にこれがある。
で、ファイルから読み込んだときにOSがこのフラグをリセットしておき
OSは、ページが不要になった時やsync要求が来たときにこのフラグを確認して
書き戻すか破棄するかを決定する。

250:デフォルトの名無しさん
08/03/03 15:09:16
>>248
それみたいですね。
すっきりしました、感謝。

251:デフォルトの名無しさん
08/03/03 16:48:21
>>245,246
仕様上ダメですか…違う方法を模索することにします。

252:デフォルトの名無しさん
08/03/03 20:58:31
>>249

すみません。

read write のようなシステムコールを実行するとOSデバイスドライバが
あとは処理してくれますよね?
代入演算子を使ってmmapした領域に書き込むとき、
そのフラグもセットするようにgccが実行ファイルを生成してくれるのでしょうか?
でもそれだと操作するアドレスがどこなのかをプログラムソースには書かなくても実行ファイルの中では
毎回見ているということでよろしいのでしょうか?

253:デフォルトの名無しさん
08/03/03 21:15:49
dirty bitを立てるのは249に書いてあるとおりCPUの仕事。
特にコンパイラがすることはない。

254:デフォルトの名無しさん
08/03/03 21:47:57
仮想記憶でぐぐればいいと思うよ。

255:デフォルトの名無しさん
08/03/03 21:51:42
ちなみに、少し前のLinuxカーネルのバグは
この複数からの同一ページへのアクセス時に
このフラグをうまく処理しなかったかららしい。

また、少し違うが
phenomのバグはキャッシュに対するdirty bitの反映が
高負荷時に滞るというものらしい。

256:デフォルトの名無しさん
08/03/03 22:03:13
もう少し補足すると、
普通のページング可能なプロセッサは、
TLBと呼ばれる、ページテーブルのキャッシュを内部に持っている。
(x86以外では呼び方が違うかもしれない)
したがって、該当ページへの書き込みがある度に
毎回物理メモリ上のページテーブルに書き込んだりはしない。
(TLB内の情報と変更があった場合のみ、書き込む)

で、このTLBの内容を書き戻すときにまずキャッシュに書き込むわけだけど
これがうまくいかない場合がある、というのがphenomのバグらしい。
L1とL2の関係もあるとかどっかで読んだが詳しくは覚えてない。

257:デフォルトの名無しさん
08/03/03 22:37:05
enumってプリプロセッサが解釈するのでしょうか??

258:デフォルトの名無しさん
08/03/03 22:41:16
いいえ。コンパイラたんがせっせこお仕事します。

259:デフォルトの名無しさん
08/03/03 22:41:58
>>258
サンクスでちゅ。

260:デフォルトの名無しさん
08/03/03 22:51:12
>>253

ありがとう。
CPUのやるとことまで押さえるのは難しいな。

もちろん仮想記憶で調べたりもしてるんですが、
なかなか自分の知りたいところのたどり着けない。
使い方はソースも含めて載ってたりするんだが。

261:デフォルトの名無しさん
08/03/04 00:31:23
>>260
そういうCPUまわりのことを色々知りたいなら、
URLリンク(www.intel.co.jp)
ここにあるIA-32なんとかなんとか下巻:システム・プログラミング・ガイドが参考になるかも

262:デフォルトの名無しさん
08/03/04 01:00:20
ちょっとお聞きしたいのですが
stringクラスの関数でcompareというのがありますが、参考書によると

int compare(const string& str) const;

のように定義されているとあります。
この定義のconst string& の&ってどういう意味の&なんでしょうか?
最後のconstも、なぜここにconstがあるのか分かりません。

また、上の定義が宣言されている場所を探してみたのですが、そもそもそれが見つかりません。string.hの中にはないのでしょうか??
質問ばかりで申し訳ないのですが、どなたか教えていただけると幸いです。

263:デフォルトの名無しさん
08/03/04 01:15:09
>>262
C++をもちっと勉強するといいよん。
&は参照。C++で導入された機能。参照についてはぐぐるよろし。
constは簡単に言うと「この関数はメンバ変数を変更しません」って宣言。
compare関数を呼ぶことで元の文字列を弄られちゃ話にならんだろ?

264:デフォルトの名無しさん
08/03/04 01:15:17
たぶん、これからも山ほど疑問が出てくるだろうから
入門書を読んだほうが早いと思う。

265:デフォルトの名無しさん
08/03/04 01:16:31
あと定義はstring.hではなくてstringの中だ。
string.hはCのヘッダーだからそりゃないだろうね。

266:デフォルトの名無しさん
08/03/04 01:19:45
>>262
> ちょっとお聞きしたいのですが
> stringクラスの関数でcompareというのがありますが、参考書によると
>
> int compare(const string& str) const;
>
> のように定義されているとあります。
> この定義のconst string& の&ってどういう意味の&なんでしょうか?
> 最後のconstも、なぜここにconstがあるのか分かりません。
>
> また、上の定義が宣言されている場所を探してみたのですが、そもそもそれが見つかりません。string.hの中にはないのでしょうか??
> 質問ばかりで申し訳ないのですが、どなたか教えていただけると幸いです。
例えばcompare(const string str)だとすると引数にstd::string型のオブジェを入れると
std::stringのコピーコンストラクタがstrに働いて無駄なメモリ間のコピーが働く
compare(const string& str) とする理由は引数に参照を取る事となり
コピーが働かないので無駄なメモリの消費がなくなる。
最後のconstはメンバ関数を呼び出したオブジェクトを修正できないようにすることです

267:252
08/03/04 01:45:56
レスくださった方々ありがとうございます。

>std::stringのコピーコンストラクタがstrに働いて無駄なメモリ間のコピーが働く
>compare(const string& str) とする理由は引数に参照を取る事となり
>コピーが働かないので無駄なメモリの消費がなくなる。

なるほど!勉強になります。

あと、compareの宣言ですが、stringやcstringの中も見てみたのですが、みつからないんです。

268:デフォルトの名無しさん
08/03/04 01:54:48
>>267
更にstringからインクルードしている先にあるんじゃないか?
例えばcygwinのgccだと/lib/gcc/i686-cygwin/3.4.4/include/c++/bits/basic_string.hにある。

269:デフォルトの名無しさん
08/03/04 02:19:09
>>262
VSならソースコード中に#include <string>として
stringの所にカーソルあわせて右クリックでstringを開くを選択すれば
中身は見れるよ

270:デフォルトの名無しさん
08/03/04 04:14:40
適当なcompareのとこで右クリック→定義を参照すれば、basic_string::compare()かなにか出ると思うよ

271:デフォルトの名無しさん
08/03/04 04:15:02
あ、VSの話ね

272:デフォルトの名無しさん
08/03/04 04:30:57
たまにはBCBとかのことも思い出してね

273:デフォルトの名無しさん
08/03/04 08:34:19
grepくらい使えよ(´・ω・`)

274:デフォルトの名無しさん
08/03/04 08:37:41
findも使えよと混ぜ返したらDOSのfind.exeと誤解される罠。

275:デフォルトの名無しさん
08/03/04 08:46:55
プリプロセッサだけ通したモノにエディタで検索かけるのはダメですか…?

276:デフォルトの名無しさん
08/03/04 09:40:08
vector型で
vector<int> num;
num[i*j]=a;

見たいなことしたいのですが
どうやるのでしょうか

277:デフォルトの名無しさん
08/03/04 09:48:22
templateで、特定の型以外が渡された場合にエラーなり
分岐なりする方法ってあるんでしょうか?
たとえば
template<class T>
class Hoge {
 void Fuga(T &ref) {
  //ここで渡された型を知りたい
 };
}

C++だと無理?

278:デフォルトの名無しさん
08/03/04 10:01:47
クラスAからそれぞれ派生したクラスB系統とクラスC系統のクラスがあるのですが
Aのポインタ*pがどちらの系統か判別する方法はありますか?

RTTIだとpの中身は分かるけどどういう系統までは追えないようですが良い方法はありますか?


279:デフォルトの名無しさん
08/03/04 10:04:16
意味が良くわからんかったけどメンバに識別子でもいれればいいんじゃない

280:デフォルトの名無しさん
08/03/04 10:07:13
>>277
テンプレートの特殊化の話かな

281:デフォルトの名無しさん
08/03/04 10:08:10
>>278
dynamic_cast

282:デフォルトの名無しさん
08/03/04 10:08:45
>>279
デコレータパターンのConcreteComponentの型を判別する方法はないかな、ということです

283:デフォルトの名無しさん
08/03/04 10:10:30
>>278
dynamic_castはダウンキャストに失敗すると0を返す。

284:デフォルトの名無しさん
08/03/04 10:14:25
>>282
それ、パターンの使い方っていうか、設計ができてないんじゃないの?
URLリンク(ja.wikipedia.org)

285:デフォルトの名無しさん
08/03/04 10:19:42
>>276
operator[](size_type)があるやん

286:デフォルトの名無しさん
08/03/04 10:20:04
>>284
そうなんですけど
出来れば再帰的に
DecoratorA-DecoratorB-DecoratorC-ConcreteComponent
と順番に型情報をたどって行く必要ができてしまって・・・
最悪でも、根元の情報だけでも何とかならないかと

287:デフォルトの名無しさん
08/03/04 10:22:42
じゃあまさに>>279の方法なんじゃないの?

288:デフォルトの名無しさん
08/03/04 10:26:38
>>285
なんですかそれ

289:デフォルトの名無しさん
08/03/04 10:31:02
>>287
Decoratorの方はいくらでもいじれるのですが
ConcreateComponentの方はこちらの一存ではいじれないので識別子を埋め込むのは難しいかと

やはりcastの成否で判別していくのが無難か・・・
castに失敗するとNULLが返る?
bad_castがthrowされるのは参照のキャストの時だっけ・・・


290:デフォルトの名無しさん
08/03/04 10:38:55
>>288
普通にnum[i * j] = aとすればいいということ。勿論、num.size()がi * jより大きいことが条件になるけど。

291:デフォルトの名無しさん
08/03/04 10:40:16
>>277
テンプレートで先ず全ての型で失敗するコードを書いておいて、
特別な型だけ特殊化しておくとか。

292:デフォルトの名無しさん
08/03/04 10:56:49
全く関係ないが
キャストとくにdynamic_castを使用する度に
クラス設計に問題があったんじゃないかと不安な気分になるのは自分だけか?

293:デフォルトの名無しさん
08/03/04 10:58:43
>>292 それが正常。

294:デフォルトの名無しさん
08/03/04 11:03:25
俺なんか気づいたら継承が全部public、メンバもほとんどpublicだったことがあるぜ!


(´・ω・`)

295:デフォルトの名無しさん
08/03/04 11:32:26
でもcast使わざるをえない時ってあるから嫌らしいよな

296:デフォルトの名無しさん
08/03/04 11:36:08
>>280,291
すみません、説明がたりませんでした。
templateでtemplate型を受け取った時にも対応できる方法が
あるかが知りたかったんです。
例えばtempate関数でstd::vector<何でもOK>は受け取れるが
std::list<>はだめな場合など。
こういう場合、特殊化だとvector<int>、vector<float>~という具合に
OKにしたい型を全て記述しないとダメなんじゃないですか?

297:291
08/03/04 11:45:15
>>296
「特定の(少数の)型」だけ有効にしたいのかと思ったから特殊化を提示した。
そうでないんだったらtypeidで動的に型を調べることになるのかな?
templateスレ辺りの方が喰い付きがいいかも知らん。

298:デフォルトの名無しさん
08/03/04 11:52:37
>>296
こんなの?

#include <vector>

template<typename T> void foo(T const& x);

template<typename E> void foo(std::vector<E> const& x) {}

int main()
{
std::vector<int> vi;
std::vector<float> vf;
foo(vi);
foo(vf);
return 0;
}

299:デフォルトの名無しさん
08/03/04 12:00:49
concept check

300:デフォルトの名無しさん
08/03/04 12:07:36
>>296
mplを駆使すればできるだろ

301:267
08/03/04 13:06:56
grepは使ったのですが、なぜかうまく検索できなかったので困ってました。
Eclipse CDT 使ってるんですが同じようなことができました。
ありがとうございました。


302:267
08/03/04 13:07:28
grepは使ったのですが、なぜかうまく検索できなかったので困ってました。
Eclipse CDT 使ってるんですが同じようなことができました。
ありがとうございました。


303:デフォルトの名無しさん
08/03/04 13:18:46
[゚Д゚] castトキイテラグオルカラキマシタ, アイシテ!

304:デフォルトの名無しさん
08/03/04 13:21:32
野郎銃器ロボはお帰りください。
野郎近接ロボとなおんロボはOK。

305:デフォルトの名無しさん
08/03/04 13:34:47
>>298
>template<typename E> void foo(std::vector<E> const& x) {}
あーこういう書き方でいいんですね。助かりました。

いつかさらに複雑な選別が必要になったら、mplやconcept checkも
調べてみます。どうもでした。

306:デフォルトの名無しさん
08/03/04 14:49:30
ちょっとお尋ねした胃のですが

void qsort(void* base, size_t n, size_t size, int(*fnc)(const void*, const void*));

という定義がありますが、const void* ってなんなのでしょうか?
voidってのは「空の型」ってことだと思うのですが、空のものをconst(固定)するってどういうことなのでしょうか?
何もないのだから固定しようがないと思うのですが・・

また、引数がvoid*になっているのもよく分かりません。void(何もない)のポインタを引数にするってどういうことなのでしょうか??


307:デフォルトの名無しさん
08/03/04 14:51:16
void*は汎用ポインタ。voidとは関係ない。

308:デフォルトの名無しさん
08/03/04 14:53:05
>>306
Cでは「何かへのポインタ」をあらわずときに void* を使う。qsort()で
はソート対象の型が決まっていないので、何でも受け取れるように
void*を使っている。

const void* ってのは、「そのポインタが指している先は書き換えしま
せんよ」という意味。



309:デフォルトの名無しさん
08/03/04 14:56:06
ポインタにはアドレスと「そのアドレスから先にどういうデータが入っているか」という情報が含まれる。
void型ポインタってのは「そのアドレスに何が入っているかを指定しないポインタ」という意味。
受け取った関数内で適切な型にキャストしてやって使うことになる。
qsortはintでもcharでも構造体でもソートできる汎用的な関数にするためそういう形になってる。
constってのは「そのポインタの場所に入ってる変数を変更してはいけません」って意味。
constつけた関数内でうっかり書き換えるとコンパイルエラーになるから、ミスを予防できる。

310:デフォルトの名無しさん
08/03/04 16:30:54
下記のソースを
bcc32 test.cpp
でコンパイルすると★の行で
エラー2423 存在しないテンプレート'show_array'の明示的な特化またはインスタンス化
*** 2 errors in Compail ***
が表示されなす。

存在しないって言われても直前に・・・・
テンプレートの定義が間違ってるのでしょうか?


311:310
08/03/04 16:31:43

--- test.cpp ---
#include <iostream.h>

/*-------------------------------------------------------*/
/* 配列の表示テンプレート */
/*-------------------------------------------------------*/
template<class T, class T1, class T2> T show_array( T1 *array, T2 count )
{
T2 index;

if( count == 0 ){ /* 表示しない ? (YES) */
return( 0 ); /* 非表示 */
}

/* 配列を表示 */
for( index = 0; index < count; index++ ){
cout << array[index] << ' ';
}
return( 1 ); /* 表示 */
}

312:310
08/03/04 16:32:59
template char show_array( int *array, int count );      ★
template int show_array( float *array, unsigned char count ); ★

/*-------------------------------------------------------*/
/* main関数 */
/*-------------------------------------------------------*/
void main( void )
{
int pages[] = { 100, 200, 300, 400, 500 };
float price[] = { 10.05, 20.10, 30.15 };

/* int型の配列 */
show_array( pages, 5 );
cout << '\n';

/* float型の配列 */
cout << show_array( price, 3 ) << endl;
cout << show_array( price, 0 ) << endl;
cout << '\n';

return;
}

313:デフォルトの名無しさん
08/03/04 16:53:01
unsigned char String[9] = "S2KTI2G7";
unsigned char KeyTable[11] = "0123456789";
char *id = "0";
int i;

for(i = 0; i < 8; i++)
  String[i] ^= *id;

このプログラムの動作がよくわかりません
たとえばString[0]はSのアスキーコードが83、0のアスキーコードが48なので
String[0] = 83^48になるのかと思ったのですが、実際は99になっているようです。
どうして99になるのでしょうか?

314:デフォルトの名無しさん
08/03/04 16:53:46
>>310
>*** 2 errors in Compail ***
恥ずかしいからちゃんとコピペしようね。

315:デフォルトの名無しさん
08/03/04 16:56:05
>>313
Cではハット(^)はビット毎の排他論理和演算子なので、83^48はちゃんと99になる。

316:デフォルトの名無しさん
08/03/04 16:58:09
>>313
83^48
=1010011^0110000
=1100011
=99

317:デフォルトの名無しさん
08/03/04 17:01:12
>>315-316
なるほど
ここしばらく他の言語しかやってなかったのですっかり忘れてました
すばやい回答ありがとうございます

318:デフォルトの名無しさん
08/03/04 17:01:17
>>310
こんな感じじゃないかなたぶん

return( 1 ); /* 表示 */ 
}; <----- ここテンプレートの最後にセミコロンが必要

template char show_array..... → template<> char show_array.....
template int show_array..... → template<> int show_array.....

show_array( pages, 5 ); → show_array<char>( pages, 5 );
show_array( price, 3 ) → show_array<int>( price, 3 )
show_array( price, 0 ) → show_array<int>( price, 0 )

319:デフォルトの名無しさん
08/03/04 17:02:30
>>310
そのテンプレート関数の目的が意味不明なんだが、取り敢えず「所謂」全角空白が見えるエディタを使おう。

320:デフォルトの名無しさん
08/03/04 17:05:25
>>310
多分、テンプレート関数では配列の一部を出力してその有無を返すだけと判断して勝手に修正してみた。
--
#include <iostream>
using namespace std;

template<class T> bool show_array(T array[], int N)
{
for (unsigned ic = 0; ic < N; ++ic) {
cout << array[ic] << ' ';
}
return N != 0;
}

int main( void )
{
int pages[] = { 100, 200, 300, 400, 500 };
float price[] = { 10.05, 20.10, 30.15 };

/* int型の配列 */
show_array( pages, 5 );
cout << '\n';

/* float型の配列 */
cout << show_array( price, 3 ) << endl;
cout << show_array( price, 0 ) << endl;
cout << '\n';

return 0;
}

321:320
08/03/04 17:09:21
いかん、配列の要素数を勝手に取得するバージョンの名残で引き数Nが大文字だw
ついでなんで、そのバージョンも貼っておこう。
--
template<class T, size_t N> bool show_array(T (& array)[N])
{
for (unsigned ic = 0; ic < N; ++ic) {
cout << array[ic] << ' ';
}
return N != 0;
}
--
これだと、show_array(price)で使える。でも戻り値の意味がないw

322:306
08/03/04 17:33:00
なるほど。
レスくださった方々、わかりやすい説明ありがとうございましたm(_ _)m

323:310
08/03/04 17:34:28
レスありがとうございます!

314 >> あ、aが余分でした (;ω;`)


318 >>
テンプレートの最後にセミコロン付加
templateの後に<>付加
show_arrayの後に<型>付加
をやってみましたが、エラー内容は変わりませんでした・・

319 >>
練習用に色々やってみた感じで作りました。
エディタはさくらエディタ使ってます。

320 >>
> 多分、テンプレート関数では配列の一部を出力してその有無を返すだけと判断して
させたい動作はその通りです。
320さんのソース読んできます。


324:310
08/03/04 17:36:39
アンカーの付け方まちがえたぁぁ~

325:デフォルトの名無しさん
08/03/04 17:47:39
>>324
全角空白を見えるようにしろって言うのは、>320に全角空白が入っているからなんだが。
# 勿論、後から追加したであろう★印のところ以外にね。

326:325
08/03/04 17:48:15
いや、全角空白が入っているのは>320じゃなくて>310だった_/ ̄|○

327:310
08/03/04 17:57:39
>>320さんのソースを元に、自分との違いを考えて
>>311-312
のソースの★の記述を削除し、
>>318さんの変更を加えたら、コンパイル通りました~。

ソースの書き方がコテコテ素人なんで、
>>320さんのソース見て勉強します。

>>318さんの追加が無い場合はエラーが出るのですが、内容読んでも
show_array<char>( pages, 5 ); の<char>が何で必要か
わからんです、ヒントお願いできないでしょうか。
エラー内容は↓です。
エラー2285 show_array<T,T1,t2>(int *, int)に一致するものが見当たらない


328:デフォルトの名無しさん
08/03/04 18:00:40
>>327
template<class T, class T1, class T2> T show_array( T1 *array, T2 count )
というテンプレートがあるので、show_array( pages, 5 ); は
show_array<char, int*, int> かもしれんし
show_array<int, int*, int> かもしれんし
show_array<long, int*, int> かもしれんし
T1とT2は引数見ればわかるけどTの型は決定できないので

329:310
08/03/04 18:03:50
>>326
!? お
template<class T, class T1, class T2>と
T show_array( T1 *array, T2 count )
の間に全角空白が!!!!!!

コピペした後に入れちゃったみたいです。('A`)
ご指摘ありがとうございます。

330:310
08/03/04 18:13:08
>> 328
なるほど!
分かりやすいご説明ありがとうございます。

試しに
<char>show_array( pages, 5 );
してみたら、構文エラーでしまた。
show_array<char>( pages, 5 );
って書き方なんですね。


ご回答下さった皆様、ありがとうございました(。。)゛


331:デフォルトの名無しさん
08/03/04 19:37:21
oprator void *() const
{ if (state&(badbit|failbit)) return 0; return (void *) this; }

のopratorはここではどういう意味で使われているのでしょうか?
この位置にあるのを初めて見まして、よくわからないんです。

332:デフォルトの名無しさん
08/03/04 19:41:08
>>331
型変換の演算子。

333:デフォルトの名無しさん
08/03/04 20:00:13
>>331
例えば
class Foo {
public:
 operator int() { return 42; }
};
main() {
 Foo foo;
 int x = foo; // <-- ここ
 cout << x;
}
というふうに、クラスを別の型に変換するときに呼ばれる。

334:デフォルトの名無しさん
08/03/04 21:54:20
ちなみに、このvoid*への変換演算子は
if (str)のように条件式で用いるために用意されている。

なぜoperator boolでないかというと、boolでは整数へ変換できてしまうから。
int x = str;のような想定外の変換を行わせないためである。

335:デフォルトの名無しさん
08/03/04 23:21:45
C#で開発したプログラムを、事情で一部C++.Netで書き直さないといけなくなったのですが
[C#]
List<int[]> foo;
の書式が、C++.Netではどう直せばいいのかわかりません。
intの配列ではテンプレートを適応できないのでしょうか?

336:デフォルトの名無しさん
08/03/04 23:24:05
>>335
List<array<int>^>^ foo;

337:デフォルトの名無しさん
08/03/04 23:24:19
URLリンク(vene.wankuma.com)
これ?

338:335
08/03/04 23:25:39
>>336
ありがとうございます。私の4時間が返ってきた。
これで作業が続きます。

339:336
08/03/04 23:40:27
>>338
ちなみにあなたが書いてるのはC++/CLIなので
分らないことがあったらC++/CLIスレに行くと幸せになれるかも。

340:デフォルトの名無しさん
08/03/04 23:56:55
List<array<int>^>^ foo;

笑ってるように見えて何かムズムズするw

341:デフォルトの名無しさん
08/03/05 00:36:11
List<List<List<array<int>^>^>^>^ foo = gcnew List<List<List<array<int>^>^>^>();

342:デフォルトの名無しさん
08/03/05 00:37:46
積年の疑問なんですが、スタックサイズはいつどうやって決まるんでしょうか。
1. コンパイル時に
2. リンク時に
3. 実行時に
a. 自動的に(コンパイラとかが自動変数の使用状況などを見て)
b. 固定的に
多分、どれかに当てはまると思うんですが。

343:デフォルトの名無しさん
08/03/05 00:40:00
コンパイルしたら

344:デフォルトの名無しさん
08/03/05 00:48:12
>>342
環境依存。

Windowsはリンク時に実行ファイルのヘッダにサイズが書かれるんだった
かな。子スレッドのスタックは実行時。


345:デフォルトの名無しさん
08/03/05 00:48:49
>>342
Windowsではexeにスタックサイズが書かれるので、リンク時以前
組み込みなんかでリセットベクタもコンパイルする必要がある場合は、コンパイル時
と思う。

346:デフォルトの名無しさん
08/03/05 01:31:09
組み込みで開発してたときはスタックサイズのチェックしてたな
どこまで上ってきてるか心配だったから。
あのときはコンパイル時だな。

347:デフォルトの名無しさん
08/03/05 01:34:24
うちもスタックポインタのチェックやってる。んでも、リンク時だと思う。
リンク時にスタックポインタの開始アドレスとかグローバル変数の確保領域アドレスとかの設定ファイルを使うから。

348:デフォルトの名無しさん
08/03/05 01:52:00
>>347
そうだな。何とか形式のファイルのサマリーを
出してくれるツールがあったな。

349:デフォルトの名無しさん
08/03/05 02:57:13
よく、C++ における class と struct の違いはデフォルトで private か
public かの差しかないって言うけど、本当?
class だと継承やらの情報を管理するための暗黙のメンバが最初にくっつかない?

class C {int a;}
struct S{int a;}
C c;
S s;

を実行してデバッガで c と s の中身見てみるとメンバ違わない?



350:デフォルトの名無しさん
08/03/05 03:10:19
クラスはメンバ関数や、オーバーロードが使えるだろ
構造体の拡張だろう

351:デフォルトの名無しさん
08/03/05 03:14:17
本とかだと、class と struct はデフォルトの可視範囲が異なるだけで、
コンパイラレベルでは全く同一ですと書いてある。

352:デフォルトの名無しさん
08/03/05 03:16:08
>>349
structも継承できるのに何でそこが違うとおもったんだ?

353:デフォルトの名無しさん
08/03/05 03:16:27
細かいことは気にするな 使う側として同じなら構わないだろう

354:デフォルトの名無しさん
08/03/05 03:17:46
>>349
大抵の実装では、仮想関数を持つクラス・構造体は、
仮想関数呼出のためのテーブル (vtbl)へのポインタを隠し持っているが、
これもクラス・構造体どちらでも同じ。

規格でも構造体とクラスは完全に同一視され、
構造体について何か独立した規定は存在しない。
全てクラスとしてまとめられている。

355:デフォルトの名無しさん
08/03/05 04:19:31
full bokko

356:デフォルトの名無しさん
08/03/05 07:17:09
そして大抵の実装では
仮想関数を持たないクラス・構造体は
vtbl へのポインタを持っていない。

357:デフォルトの名無しさん
08/03/05 07:38:19
>>347
H8やSHでは#pragma stacksize XXX というのがあるので、
スタックサイズはコンパイル時、スタックアドレスはリンク時ということかな。

358:デフォルトの名無しさん
08/03/05 08:45:07
struct S{ int m_a; int m_b}

として m_b に代入しようとして

void hoge(void *s){
 int offset = sizeof(int);
 unsgiend char * p = (unsgiend char *)s;
 int * m_b = p[offset];
 *m_b = 1234
}

みたいなコードが書いてあると位置がずれて死ぬ訳か

359:デフォルトの名無しさん
08/03/05 09:23:24
>>358
いいえ、環境依存です。

360:デフォルトの名無しさん
08/03/05 09:30:41
struct S {
 int a;
 int b;

 void clear() {
  ZeroMemory(this, sizeof(*this));
 };
}

こういうのもマズイ?

361:デフォルトの名無しさん
08/03/05 09:32:20
>>360
いつか POD の規則から外れる変更を加えたときに忘れずに修正する覚悟が必要。

362:デフォルトの名無しさん
08/03/05 09:42:56
vectorとか追加した場合ですね。
上のほうで出てた、仮想関数を持つクラスを継承して
vtbl へのポインタを持ってる場合は>360で問題無しですか?

363:デフォルトの名無しさん
08/03/05 10:42:35
>>362
仮想関数を持ったものも POD から外れる。

364:デフォルトの名無しさん
08/03/05 10:45:50
>>357
HEWでそれやってたな。てかconfig入力画面でメモリセクションのカスタマイズできた。

365:デフォルトの名無しさん
08/03/05 10:47:58
struct S {
 std::vector m_v;
} s;



ZeroMemory(&s, sizeof(S));

ってやって死んだ事がある



366:デフォルトの名無しさん
08/03/05 11:46:02
コンパイラBCC55
class PPP{
public:
union{
  struct{
    int n;
    struct{
      enum Hoge hoge;
      int x;
    }aa[32][32];
    LPCWSTR name[256];
  }a;
  struct{
    int p;
    char i;
    float y;
    Hoge *o;
  }b;
  struct{}c;
}data;
};
こんな共用体がクラス変数になってる時に
PPP ppp;
とするとそこでプログラムが例外も吐かずに落ちてしまいます。
しかし、PPPを他のクラスのクラス変数として宣言しておけば落ちません。
class Hoka{
PPP p;
};
分かる人おながいしまつ・・・。

367:デフォルトの名無しさん
08/03/05 11:47:00
ちなみにenum HogeはPPPの中で定義されてます。すいません

368:デフォルトの名無しさん
08/03/05 12:21:18
現象が再現する最小限のソースうp

369:デフォルトの名無しさん
08/03/05 14:39:59
今更ですが>>290のことで

vector<int> num;
num[i*j]=a;

でnum.size()が不定のとき(i*jより小さいときもある)場合
先にnum[i*j]を確保して、num[i*j]=aを入れればよいのでしょうか

確保の仕方を教えてください

370:デフォルトの名無しさん
08/03/05 14:46:08
>>369
num.resize(100) とかで好きなサイズに変更する

371:デフォルトの名無しさん
08/03/05 15:20:53
num.resize(i*j)っていうのも可能ってことでしょうか?


372:デフォルトの名無しさん
08/03/05 15:28:07
>>368最小限が分かりづらいのでエラーの出ないnewで代用しました。

373:デフォルトの名無しさん
08/03/05 15:58:15
>>371
可能だが resize(i*j) ではサイズが足りないと思うぞ

374:デフォルトの名無しさん
08/03/05 16:14:35
もっとも使われていないバッファを解放したいのですがSTLなどで良いライブラリはありますか?

375:デフォルトの名無しさん
08/03/05 16:53:00
>>374
せめてもうちょっと具体的に言わないとどうにもならないと思うよ

376:デフォルトの名無しさん
08/03/05 16:57:59
LRUを実装するのに適したコンテナはどれでしょうかってことだとエスパーしてみる
JavaのLinkedHashMapみたいなやつ?
STLにそれはないから、mapとlistを組み合わせるのかな・・

377:デフォルトの名無しさん
08/03/05 18:39:44
3次元配列(texture)を動的に確保しようと

if( (int)texture.size() < ( temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1] ) )
texture.resize(temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1]);

texture[temp[0] + temp[1]*maxValue[0] + temp[2]*maxValue[0]*maxValue[1]] = num;

こうしたら、格納されません。

現在の3次元配列の幅よりも、大きいのが出てきたら値を取り直して、入るべき所にぶち込む
ってことをやりたいだけなのですが

378:デフォルトの名無しさん
08/03/05 18:58:40
>>377
サイズが 10 だったら、有効なインデックスは 0~9 だ
サイズが temp[0] + .... *maxValue[1] だったら、
有効なインデックスは 0 ~ temp[0] + .... *maxValue[1] - 1 までだ

379:デフォルトの名無しさん
08/03/05 19:07:20
>>378
ありがとうございます、それが抜けていました

ただ 0 0 0 があったときに格納できないというエラーが出てきて
後少しなのに

380:デフォルトの名無しさん
08/03/05 19:20:23
class Aを例外として投げるとき

throw new A;
のようにnewで生成して投げるのと
throw A();
と投げるのはどっちが良いのでしょうか?


381:デフォルトの名無しさん
08/03/05 19:25:04
自プロセスのHWNDを取るにはどうしたらいいのでしょうか?

382:デフォルトの名無しさん
08/03/05 19:25:10
むかーしどっかで見たのですが、3次元以上の配列は使わない方が良いってどういうことでしょうか?
ソースがどこだったか覚えてないのですが、そのときの記憶があり3次元以上はなるたけ使わないようにしてる原状です

383:デフォルトの名無しさん
08/03/05 19:27:31
あんま多いと気づかずやらかす類のバグが増えるかも…しれないけど決定的な理由じゃねえよな

384:デフォルトの名無しさん
08/03/05 19:37:17
>>380
Javaと一緒にすんな

385:デフォルトの名無しさん
08/03/05 19:57:35
>>382
その配列が表すモノが本質的に3次元以上のモノなら3次元配列で良いけど
構造体やクラス等で表すべきモノを配列にしてしまうのは避けるべき

386:デフォルトの名無しさん
08/03/05 20:47:36
数値計算で添字3つ以上の行列とか扱わない限り、
まず必要になることはないと思うけどね。

387:デフォルトの名無しさん
08/03/05 20:52:58
>>380
newするとどこかでdeleteせんといかんよ。

388:デフォルトの名無しさん
08/03/05 21:29:17
>>380
new はしない。

389:デフォルトの名無しさん
08/03/05 22:04:19
#define SAFE_DELETE(p) {delete (p); (p)=NULL;}
を定義して、
SAFE_DELETE(ptr);
とすると「構文エラー : ';' が~の前にありません」のエラーになってしまいます。
delete ptr;なら普通にコンパイルできるのですが、
どこが悪いのでしょうか。

390:デフォルトの名無しさん
08/03/05 22:06:01
ちょっと行き詰まってしまったので質問させて下さい。
VC2005、WinXP64で以下のようなプログラムを作ったのですが、うまく動いてくれません。

DWORD WINAPI ThreadPrc(LPVOID lpParameter)
{
while (!ThreadTerminated){
//要求があるまで待機
WaitForSingleObject(hEventHandle,INFINITE);
if (ThreadTerminated) break;

//共有オブジェクトの排他アクセス
WaitForSingleObject(hMutexHandle,INFINITE);
//適当に処理
ReleaseMutex(hMutexHandle);

//処理が終わると相手に通知
//ここがおかしい
SetEvent(hDoneEventHandle);
}
return 0;
}

普段はDelphiでやってますが、64ビットでビルドする必要があったので、Delphiで作ったものをC++に移植しました。
プロセス間通信でいろいろやってるわけなのですが、同じところでいつもタイムアウトしてしまいます。
もちろんINFINITEにするとそのまま固まってしまいます。
32ビットプロセスでSetEventして、64ビットプロセスでWaitForするのは成功するのですが、その逆がうまくいかないのです。
VC固有の問題なのか、64ビットの問題なのか、関係ありそうなのは調べましたが全く原因が分かりません。
この部分さえうまくいけば完成なのですが・・・。
どなたか分かる方いましたらアドバイスお願いします(o*。_。)o


391:デフォルトの名無しさん
08/03/05 22:09:05
>>389
SAFE_DELETE(ptr);

{delete (p); (p)=NULL;};
に展開される。
} の後に ; があるのがポイント。
これで何か起こってんじゃね?

392:デフォルトの名無しさん
08/03/05 22:12:09
>>389
問題の起こる最小のコードをplz!

393:デフォルトの名無しさん
08/03/05 22:17:54
>>389
うちの環境だと普通に動いてしまったよー。
周りを疑ってみるべき

394:331
08/03/05 22:18:39
なるほど!
分かりやすい説明ありがとうございましたm(_ _)m

395:389
08/03/05 22:20:21
周りを少し抜き出すとこんな感じです。

-----SystemMacro.h----------
#ifndef SYSTEMMACRO_H
#define SYSTEMMACRO_H
#define SAFE_DELETE(p) {delete (p); (p)=NULL;}
#endif

------List.h----------
#include <windows.h>
#include "../system/SystemMacro.h"
template <class T> class List {
public:
virtual ~List(){
if(!_tempFlg) {
WORD i;
for(i=0; i<_ct; i++) {
delete _arr[i];
}
}
SAFE_DELETE(_arr); //←ここをdelete _arr;にするとコンパイル通る
}
};
※Listのメンバ変数は省略してます。

396:デフォルトの名無しさん
08/03/05 22:21:28
template <typename T>
void SafeDelete(T *& p) { delete p; p = NULL; }

397:デフォルトの名無しさん
08/03/05 22:23:00
なんか怪しげなコードだが
_arrの型は?


398:デフォルトの名無しさん
08/03/05 22:24:06
どーでもいいけど _ は変数名の前につける習慣は良くない。
つけるなら後ろに。

399:389
08/03/05 22:25:12
あ、_arrがテンプレートの、T**型なのですが、
それが悪いのでしょうか。

400:デフォルトの名無しさん
08/03/05 22:29:21
fmtflags setf(fmtflags flg, fmtflags mask);
関数の説明で、この関数は

flags((flags() & ~mask) | (flag & mask));

のような処理をしている、と書いてあったのですが、

flags((flags() & ~mask) | flag);

でも同じではないでしょうか?
なぜわざわざ(flag & mask)と書いてあるのでしょうか。

401:389
08/03/05 22:37:45
>>396
ありがとうございます。

>>397
template <class T>のT**型です。

>>398
とあるJavaのソースでクラスのメンバ変数の先頭に_をつけてたのを真似してます。
C言語はまだ初めたばかりな上、グーグルと2chで全て学んだので、
基礎がなってないのですが、先頭_はなんで不味いんでしょうか。

上のListクラスの機能は、たぶんstd::vectorとほぼ同じです。
標準ライブラリというのを知らなくて、作ってしまいました。

402:デフォルトの名無しさん
08/03/05 22:38:32
>>400
> 同じではないでしょうか?

いや、同じじゃないから。

403:デフォルトの名無しさん
08/03/05 22:43:14
だれか>>391に突っ込んでやれよw

>>401
「_」始まりの単語はシステム予約される可能性があるから。



404:デフォルトの名無しさん
08/03/05 22:45:19
pは何処から出てきた?
でいいのかな。

405:389
08/03/05 22:49:40
>>403
ありがとうございます。

}の後ろに;をつけても、うちの環境では動きました。

406:デフォルトの名無しさん
08/03/05 23:06:52
レスありがとうございます。

fmtflags setf(ios::hex, ios::basefield);
で、
ios::hex が 0x0800
ios::bsaefield が0x0e00
とすると、

ios::hex & ios::basefield

で、
0000 1000 0000 0000

0000 1110 0000 0000

の論理積なので、

0000 1000 0000 0000

で、結局
ios::hex(0000 1000 0000 0000)
そのものと変わらないじゃんと思ったのですが、どこかで勘違いしているのでしょうか。

407:デフォルトの名無しさん
08/03/05 23:08:47
>>406
> 論理積なので、

いや、違うから。

408:デフォルトの名無しさん
08/03/05 23:14:46
とりあえず

SAFE_DELETE(_arr);



{delete (_arr); (_arr)=NULL;};

に置き換えてコンパイルが通るかどうか。

あと、コンパイラは何?

409:デフォルトの名無しさん
08/03/05 23:16:54
>>400
flgは立てたいビット、maskはflgの属するフィールドを指定するが、
flgがmaskのフィールドに属さなかった場合に、
余計なフィールドのビットを立ててしまうのを防ぐため。

410:デフォルトの名無しさん
08/03/05 23:24:26
質問させて頂きたいのですが、
このように宣言しましたが、

char a[] = "1234";
char b[] = "4567";

char* abc[2][255]={
a,
b
};

*abc[1]で値が取り出せません。
こういうやり方は無理でしょうか?

411:デフォルトの名無しさん
08/03/05 23:30:23
>>410
abcはポインタが二次元に並んだ配列だが、それでいいのか?
やりたいのは、ポインタの一次元配列のように見えるが。
つまり、こう。
char* abc[2] = {a,b};
そうしたら、
*abc[0]は'1'
になる。

412:デフォルトの名無しさん
08/03/05 23:47:55
>399
>あ、_arrがテンプレートの、T**型なのですが

>395を見ると delete _arr[i]; とあるから、_attrは new[] で確保したアドレスを前提としていないか?
それなら delete ではなく delete[] とすべき。
コンパイルエラーの件とは無関係だが。


413:デフォルトの名無しさん
08/03/05 23:55:17
411>
おっしゃるとおり二次元配列のポインタですね。
全然気がつきませんでした。
ありがとうございます。


414:デフォルトの名無しさん
08/03/06 00:16:05
>389
とりあえず本論とは別だが、その手のマクロは

if(flag)
  SAFE_DELETE(p);
else
  do_something();

みたいにするとエラーになるのでしばしば

#define SAFE_DELETE(p) do { delete (p); (p) = NULL; } while(0)

のように定義されることが多い。

415:デフォルトの名無しさん
08/03/06 00:23:46
この場合なら

#define SAFE_DELETE(p) ((void)(delete (p), (p) = NULL))

でもいいと思うけどね。
まあ、式中に書けるのが嫌だというのであれば、
do-while 使ったのでもいい。

416:デフォルトの名無しさん
08/03/06 00:50:58
SAFE_DELETEを使ってるのを見ると
ああ10年前に学ぶのを止めてしまったんだなと分かる
自分自身がSAFE_DELETEされてしまったんだ

417:デフォルトの名無しさん
08/03/06 03:06:00
>416
ちなみにトレンドは?

418:デフォルトの名無しさん
08/03/06 03:32:56
416じゃないけどshared_ptrとかじゃないの

419:デフォルトの名無しさん
08/03/06 03:44:42
ずっと前から auto_ptr と vector によって delete の出番はほとんど無くなっている。

420:417
08/03/06 04:10:27
ああ、そういう意味でか。勘違いしてた、さんきゅ。

421:デフォルトの名無しさん
08/03/06 06:12:17
ガベージコレクションの緩いやつの理論はありますか?
たとえばファイルに書き出すために複数のバッファを用意したとして
もう書き込みが発生しないだろうと予測されたら書き出してメモリを解放するというやつです

422:デフォルトの名無しさん
08/03/06 06:15:54
100ファイルに書き込みがあって試行するうちに総数の10%のみの書き込みだけになったら
それ以外は書き込みがないだろうと思って解放したいのですが、タイミングをいつにするか具体的に計算する方法は
ありますか

423:デフォルトの名無しさん
08/03/06 06:49:42
LRUでぐぐればいいんじゃない?

424:デフォルトの名無しさん
08/03/06 07:02:10
ちょっと違うんです
たとえばバッファは10個なら、10個前が一番古いですが、11個目の後
1~10番が続くかもしれないじゃないですか
もっとも利用されなかっただけではなく、バッファサイズを増したほうがいいかも調べたいんです

425:デフォルトの名無しさん
08/03/06 09:24:11
最終使用時間を記録しといて、N秒以上使われてなかったら削除
とかでいいんじゃない?

426:デフォルトの名無しさん
08/03/06 14:33:28
>>419
それって大問題なんじゃなかったっけ?

427:デフォルトの名無しさん
08/03/06 16:20:10
質問でございます。
int* A_PTR = new int[5];
として確保した領域の、たとえば、A_PTR[3]のような、
途中の領域だけ解放(delete)することは可能でしょうか?

428:デフォルトの名無しさん
08/03/06 16:45:33
>>427
無理

429:427
08/03/06 16:59:15
>>428
やはり無理なんですね。
別のポインタに入れてからdeleteなど、
いろいろ実験していて気が狂いそうでしたので
大変すっきりしました。
れす、ありがとうございました。

430:デフォルトの名無しさん
08/03/06 17:32:23
CString cstr;
unsigned char uc[sizeof(cstr)] = (unsigned char)(LPCSTR)cstr;

コンパイル通りません。要は、↓を動的にしたいです。
unsigned char uc[10]="0123456789";

よろしくおねがいします

431:デフォルトの名無しさん
08/03/06 17:39:19
配列のサイズを動的に変えるのは無理です。
ヒープで取って良いのなら、
char* uc = new char[文字列の長さ+1];
strcpy(uc, コピーしたい文字列へのポインタ)
でもしてください。


432:デフォルトの名無しさん
08/03/06 17:41:23
これではだめ?
unsigned char* uc = (unsigned char*)(LPCSTR)cstr;

433:430
08/03/06 18:04:24
>>431
やっぱり無理ですか。。

>>432
uc[0],uc[1]みたいに、ポインタではなく配列としてアクセスしたいんですよね。。
なんか根本的に駄目なソース書いてる気がしてきたので、発想を変えてみます。

どうもありがとうございました。

434:デフォルトの名無しさん
08/03/06 18:06:06
動的に大きさを変えたいならstd::vector使えばいいやん。

435:デフォルトの名無しさん
08/03/06 18:06:34
あ、文字列ならstd::stringな。

436:デフォルトの名無しさん
08/03/06 18:09:14
>>433
添え字演算子はポインタでも使えるけど。

437:デフォルトの名無しさん
08/03/06 18:29:09
>>433
E1[E2] は *((E1) + (E2)) の syntax sugar だ。

uc[0] → *(uc + 0)
uc[1] → *(uc + 1)

438:デフォルトの名無しさん
08/03/06 20:40:20
uc[0] → *(uc + 0) → *(0 + uc) → 0[uc]
uc[1] → *(uc + 1) → *(1 + uc) → 1[uc]

439:デフォルトの名無しさん
08/03/06 20:43:02
>>438
さんざん既出
"0123456789ABCDEF"[i]
を大昔はやっていた。

440:デフォルトの名無しさん
08/03/06 20:44:58
それは関係ないだろう・・・。
i["0123456789ABCDEF"] ならともかく。

441:デフォルトの名無しさん
08/03/06 20:48:59
>>440
おんなじやんけ

442:デフォルトの名無しさん
08/03/06 20:49:41
あま~~~い

443:389
08/03/06 22:58:20
みなさん色々とアドバイスありがとうございました。

>>408
通ります。Visual Studio.NET 2003を使ってます。
>>412
_arr = new T*[_max];という感じで確保してます。
delete[] は使ったことないですが、やってみます。
>>414
それは思いつきませんでした。
>>415
その書き方は初めて見ました。
>>416
10年前というか、C言語始めてまだ1ヶ月半なんですが。。。

444:デフォルトの名無しさん
08/03/06 23:05:22
アレだ、「個体進化は系統進化を繰り返す」

445:デフォルトの名無しさん
08/03/06 23:10:44
以下のコードでファイルの2番目のバイトだけを
書き換えようとしたんですが
全く何も代わりません

#include <stdio.h>
int main(void){
FILE *fp;
char cIn;
char cOut = 'X';
int cnt;
fp = fopen("test.txt", "rb+");
fread(&cIn, 1, 1, fp);
printf("%c\n", cIn);
cnt = fwrite(&cOut, 1, 1, fp);
printf("%d\n", cnt);
fclose(fp);
return 0;
}

<test.txtの内容↓>
ABCDEFG

<出力結果↓>
A
1

これはどう理解したらいいんでしょうか?
BCとVCで試してみました

446:デフォルトの名無しさん
08/03/06 23:20:59
freadしてA読んで、表示した(出力1行目)
fwriteして次のBをXで上書きして、(test.txtの中身変化)
要素数の1が戻ってきて表示(出力2行目)
何が不思議なんだ?

447:デフォルトの名無しさん
08/03/06 23:21:31
>>445
readからwriteに切り替える時、もしくはwriteからreadに切り替える時は
必ず間にfseek()を挟む事。

448:デフォルトの名無しさん
08/03/06 23:39:54
>>445
コンパイル君のぼやき
「freadとfwriteに&使わないで下さいよ。あと、辞書ぐらい買ってくださいよ。
何でもかんでも私に聞かないで下さいよ。なんでもかんでもプリントにしないでくさいよ。
宣言するんだったらまともに宣言してくださいよ。main関数の引数ぐらい使ってくださいよ」

449:デフォルトの名無しさん
08/03/06 23:43:29
Visual C++についてなのですが、
分割コンパイルについていまいちよくわかりません。

main.ccp
ClassA.ccp
Def.h
ClassA.h
resource.h
と5つあって、

main.ccpではDef.hがインクルード、
ClassA.hでもDef.hがインクルードされ、Classの宣言と、インラインでのメンバの定義、
ClassA.ccpではClassA.hとDef.hがインクルードされています。
また、Def.hではresource.hがインクルードされているほか、#ifdnefを使って重複しないようにしています。


ビルドをすると、C2143構文エラーなど、ものすごい沢山のエラーが出てきてしまいます。


このようにヘッダとソースファイルを分割する場合、どのようにインクルード等をすればよいのでしょうか。



450:デフォルトの名無しさん
08/03/06 23:48:48
> ClassA.ccpではClassA.hとDef.hがインクルードされています。

とりあえずこのDef.hはインクルードしなくていいいような・・・

451:デフォルトの名無しさん
08/03/06 23:49:48
>>449
その文面だけを見る限り、ファイル分割のしかたもインクルードの仕方
も問題ないよ。エラーが出るのはファイルの内容がどこか間違っている
とか、何かの定義が足りないとか。



452:デフォルトの名無しさん
08/03/06 23:51:02
newを使って確保した領域をポインタとして返す関数を作ったんですけど、開放するにはどうすればいいんですか?
個人的には↓の方法でできるような気がするのですが、できるかどうか心配なので教えてください

char *func(){
char *buf = new char[1024];
//bufにデータを入れる
return buf;
}

int main(){
char *ptr = func()
//ptrであんな処理やこんな処理
delete [] ptr;
}

453:デフォルトの名無しさん
08/03/06 23:51:16
膨大な数のエラーと聞くと、本当に何か書き間違えている気がする。

454:デフォルトの名無しさん
08/03/06 23:55:48
初心者も上級者もnew使うならクラスでつかえよな
解放する方法を間違えたり、しなかったりする
クラスならデストラクタがする

455:デフォルトの名無しさん
08/03/06 23:56:25
>>452
どうでも話にはなるが、
メイン関数のファンクがカマを彫られたって泣いてるが、
わかっててほられたのかほられてないのか気になる。

456:デフォルトの名無しさん
08/03/06 23:56:44
>>452
それで特に問題はないが、

void func(std::vector<char>& buf) {
 buf.resize(1024);
 // buf にデータを入れる
}

int main() {
 std::vector<char> buf;
 func(buf);
 // buf であんな処理やこんな処理
}

とやった方が面倒がないし例外とかあっても確実にメモリが解放されるから安全で便利。

457:デフォルトの名無しさん
08/03/06 23:57:05
>>454
それ・・・なんの冗談?

458:デフォルトの名無しさん
08/03/06 23:57:48
日本語はおかしいが、要するに RAII ってことじゃね?

459:デフォルトの名無しさん
08/03/06 23:58:43
string buf

buf.reserve(1024)

&buf[0]

でも良い

460:デフォルトの名無しさん
08/03/06 23:59:30
それはちょっと・・・。
length 変わらないじゃんか。

461:デフォルトの名無しさん
08/03/06 23:59:47
>>451
あってますか…

1行目初っぱなから
Naive_Grid_Class.cpp(4): error C2143: 構文エラー : ';' が 'NaiveGridCtrl::ChkhCtrl' の前にありません。
などと出てきて(下のようなコード)

#include "DefHeader.h"
#include "Naive_Grid_Class.h"

BOOL NaiveGridCtrl::ChkhCtrl(){
    return (BOOL)hCtrl;
}

もう何が何だかさっぱりなんですが…

462:デフォルトの名無しさん
08/03/07 00:01:05
>>457

class ABC {
char *buf;
ABC(){確保}
~ABC(){解放}
};


main(){
ABC x;
}
とやれば簡単って事

463:デフォルトの名無しさん
08/03/07 00:03:17
呼ばれたタイミングだけでnewしたいとは限らんだろうに

464:デフォルトの名無しさん
08/03/07 00:04:43
>>461
class NaiveGridCtrl の最後の ; を忘れているんじゃないか?

465:デフォルトの名無しさん
08/03/07 00:08:16
質問です。
前から思ってたんだけど、
メモリの解放以外にデストラクタって使い道あるの?

466:デフォルトの名無しさん
08/03/07 00:09:25
データの残りを書き出す

467:デフォルトの名無しさん
08/03/07 00:11:43
リソースの開放

468:デフォルトの名無しさん
08/03/07 00:22:56
質問です。
C++で住所録を作っているのですがソートができません。
構造体に名前、住所、年齢、電話番号・・・など
項目ごとに入れるところまではできたのですが、
名前、住所、年齢、電話番号・・・など項目ごとに分かれているので、
名前なら名前だけがソートされてしまい他のはそのまま。
名前をソートしたらその順序で他の項目が付いてくるようにするには、
どうしたらいいのでしょうか。


469:デフォルトの名無しさん
08/03/07 00:24:16
>>468
まず、どうやってソートしてるんだ?
そこのプログラムみせてみ

470:デフォルトの名無しさん
08/03/07 00:24:24
>>468
え?なんでそうなるのさ?
ソートした順に構造体を並べ替えればいいだけじゃんw

471:デフォルトの名無しさん
08/03/07 00:25:22
名前だけ入れ替えてるんじゃねw

472:デフォルトの名無しさん
08/03/07 00:26:52
構造体にしてる意味がねぇw

473:デフォルトの名無しさん
08/03/07 00:27:37
名前をソートするんじゃなくて、名前のソート順通りに構造体のオブジェクトをソートするんだ。

474:デフォルトの名無しさん
08/03/07 00:33:47
int i = 1;
while(i <= 10){
fout[i].open("dat$i.dat");
fout[i] << i <<'\n';
i++;
}

てな感じでデータファイルを10個作りたいのですが、
""の内のiは変数と見てくれなくて困ってます。

何かいい方法ありませんか??

475:デフォルトの名無しさん
08/03/07 00:36:20
>>474
あたりまえだろw
こうすればいい
char filename[100];
sprintf( filename, "dat$%d.dat", i );
fout[i].open( filename );

476:デフォルトの名無しさん
08/03/07 00:36:50
>>474 stringstream

477:デフォルトの名無しさん
08/03/07 00:37:46
>>468

#include <iostream>
#include <string>
#include <set>
using namespace std;

class memberlist{
public:
string name;
string tel;
string adress;


memberlist(string a, string b,string c){
name=a; tel=b; adress=c;}

bool operator<(const memberlist& a)const{
if(name<a.name)return 1;return 0;}
};

main(){
set<memberlist> x;
x.insert(memberlist("山田太一","030000000","東京都"));
x.insert(memberlist("明石家明","077777777","沖縄県"));
x.insert(memberlist("佐藤一郎","051111111","大阪府"));

set<memberlist>::iterator p;
for(p = x.begin(); p!=x.end(); p++){
cout<< p->name <<" "<< p->tel <<" "<< p->adress <<endl;
}}

478:デフォルトの名無しさん
08/03/07 00:41:10
>>463
どちらにしろ管理クラスに入れとけば
デストラクタが勝手に delete してくれるだろ。

479:445
08/03/07 01:06:00
みなさんドモドモ

>>447
それそれ。それです。
fseek(fp, 0, SEEK_CUR);
が必要みたいなんですが
これがわからない。
カレントポジションから0バイト進めるのは
何もしないのと同じなのではないのでしょうか?

OSのAPIなどの場合
readしてそのままwriteする事でファイル位置が
自然に進む事が多い気がする訳ですが
この仕様はよくわからないです

これはC(ライブラリ)の明示された仕様なのでしょうか?

480:445
08/03/07 01:12:39
そうそう。あと一つ・・・
fwriteで1バイト書き込めたはずなのに
その1バイトはどこへ行ってしまったんでしょうか・・・

481:デフォルトの名無しさん
08/03/07 01:13:18
>>479
APIと違って、バッファリングするのが前提だからfseek()などでバッファを同期を取ることに決められている。

482:デフォルトの名無しさん
08/03/07 01:16:55
>>461
Naive_Grid_Class.h の最後に ; が足りないとか、
BOOLの定義がどこにもないとか。


483:デフォルトの名無しさん
08/03/07 01:17:54
>>480
同期を取っても書き換わらない?

484:デフォルトの名無しさん
08/03/07 01:22:57
>>475
そのようにすれば、できました!
ありがとうございます。
>>476
stringstreamも勉強します。

485:445
08/03/07 01:49:51
>>481
なるほど。仕様ですか・・・
多分FILE構造体の内容とかから必然なのかな?
直感的には把握が難しかったです

>>483
fseekはさめば書き換わりますが、
はさんでなくてもfwriteの結果が1というのが
納得いかず・・・
試しにfread/fwrite/fseek(fp, 0, SEEK_END)
というのもやってはみたけれどやはり書き換わらず・・・

486:デフォルトの名無しさん
08/03/07 02:03:11
int main(){
fin.open("aaa...
fout.open("bbb...
function(....);
}

function(.....){
  fout << "thanks" <<'\n';
}

のようにmain関数でデータファイルを開いて、
function関数の中に開いたファイル持ってきて、書き込みたいんですけど。
どうするのがいいのでしょうか?


487:デフォルトの名無しさん
08/03/07 02:11:36
>>486
ストリームを引数にとればいいんじゃねーの?

488:デフォルトの名無しさん
08/03/07 02:23:55
>>486
ストリームを大域変数にすればいいんじゃねーの?

489:デフォルトの名無しさん
08/03/07 02:48:25
>>486
ストリームを参照で取る
constで取ったらあかんよ

490:デフォルトの名無しさん
08/03/07 03:42:36
>>486
(ofstream& fout[], ifstream& fin[])
ってことですか??
参照型の配列は許されないとかなるんですが。。。
困り果てた。

491:デフォルトの名無しさん
08/03/07 03:47:08
>>490
何故いきなり配列に? >486では一言もそんな話が……

492:デフォルトの名無しさん
08/03/07 03:50:43
>>490
常考参照のポインタだろ

*&fout

493:デフォルトの名無しさん
08/03/07 04:00:42
#include <iostream>
これで通る

#include <fstream>

void sub(std::fstream* f)
{
 f[0];
}

int main()
{
 std::fstream f[10];

 sub(f);
}

494:デフォルトの名無しさん
08/03/07 04:17:54
>>493
すいません、素人目からはさっぱりなんですが。。。
fout,fin???どうなったのでしょうか??

495:デフォルトの名無しさん
08/03/07 04:25:17
>>494
配列だったらリファレンスではなくポインタで渡せばいいだけの話。

496:デフォルトの名無しさん
08/03/07 04:28:51
>>494
あんた>486=>490? >489に答えがあるのに、それをどう曲解したのか>490になって、
>491の質問を無視して>494みたいなこと言われても最早誰も対処できないぞ。

497:デフォルトの名無しさん
08/03/07 07:12:46
もらった回答をすっ飛ばす奴の神経がわからんね。
漢字読むのが面倒臭いからって、上の行↑を「もらったをすっばすのがわからんね」と読んで
「うーん、さっぱりわかりません」とか一人で勝手に困ってるようなものだろ。

498:デフォルトの名無しさん
08/03/07 08:49:37
どっちでもいいといえば どっちでもいいのですが、
現在ゲームを作ってまして、敵の動きを実装するのですが、
C言語で関数のポインタを保持し、タイミングが来たら 保持していた関数を呼び出すのと
C++で、基本のクラスを用意し、それから派生してポリモーフィズムで呼び出すのと どちらが良いでしょうか

開発規模は個人なのでそれほど多くならないです、ですがまだ、仕様が決まってないのでなんともいえないのです。

なにが不満かというと
Cだと 関数だらけになってしまう
C++だと 開発に時間がかかったら保守が大変そうなことです

499:デフォルトの名無しさん
08/03/07 09:01:36
作ったことがないが、C++に一票

500:デフォルトの名無しさん
08/03/07 09:03:21
迷ったらC++。これ鉄則。

501:デフォルトの名無しさん
08/03/07 10:54:41
>>498
Commandパターン or Callback by template

502:デフォルトの名無しさん
08/03/07 11:07:04
くだらない質問で申し訳ありません。

namespace myname{
hogehogehoooge;
}; //←

namespace mymyname{
hagehagehaaage;
} //←

コンパイル自体はどっちでも通ったのですが、どっちが本来の文法的に正しいのでしょうか。

503:デフォルトの名無しさん
08/03/07 11:25:44
コンパイラ的には上のセミコロンは空文があるってだけかと

504:デフォルトの名無しさん
08/03/07 11:43:35
>503
なるほど、納得しました。

505:デフォルトの名無しさん
08/03/07 13:33:34
物凄くくだらない質問なのですが教えてください

double x=1.0; int y = 10000;
int z = y * x;

この場合z=yって成り立つのでしょうか?

506:デフォルトの名無しさん
08/03/07 13:36:02
>>505
成り立つよ
浮動小数点の誤差がどうとか言う観点だよな?

507:デフォルトの名無しさん
08/03/07 13:57:06
はい、そうです
ありがとうございました

508:デフォルトの名無しさん
08/03/07 14:07:28
メンバに変数しかないクラス(ようするに構造体)を継承して、
それらのポインタをdynamic_castしたい場合、親クラスに
virtualな関数を無理やり入れておくしかないのでしょうか?

509:デフォルトの名無しさん
08/03/07 14:09:33
>>508
dynamic_castの意味分かって言ってる?

510:デフォルトの名無しさん
08/03/07 14:10:34
>>508
手っ取り早く済ませたいならそうだね。

手間がかかってもいいなら、たぶん dynamic_cast の必要性を
見直したほうがいいんだろうけど。

511:デフォルトの名無しさん
08/03/07 15:23:55
>>509,510
関数テーブルで引数が違う関数をまとめる場合に、
引数型を全部派生にして親クラスのポインタを
受け取るようにしとくと、キャストミスも無くて便利かなと
思ったんですが。
多分設計見直したほうが良いパターンなんでしょうね。

512:デフォルトの名無しさん
08/03/07 15:49:54
デストラクタを仮想にしておけば良いんじゃないかな

このパターンで自分もはまったな
引数に<list>をとるか可変長引数とか配列とか色々やり用はあるな


513:デフォルトの名無しさん
08/03/07 16:23:58
>>511
つテンプレートの特殊化

514:468
08/03/07 16:44:37
URLリンク(www.borujoa.org)

すみません。ド素人のプログラマですが、質問です。
なるべく上のファイルを利用してファイルソートを行いたいのですが、
これからどうすればいいのかわからず手が止まっております。
ソースではなく文章でいいので答えていただけますか?
filesortがファイルをソートする関数部分です。
つまりVectorとsortを使って何とかしたいわけですが、
この書き方であると要素ごとでしかソートできません。
もちろん要素だけのソートはできました。
なんかあとちょっと弄ればできそうな気がするんですが、
僕の脳ではどうしようもありません。
どなたかご指導ください。

私的にはsetさえ使えば100人力じゃぁみたいな感じになるので、
setを使いたくありません。その点も含めてよろしくお願いいたします。

あとこのソース見て「ここをこうした方がいいのでは?」と思う人はご指摘ください。
よろしくお願いいたします。勉強になります。

開発環境:CentOS 5
コンパイラ:g++
コンパイルエラー:無し

515:デフォルトの名無しさん
08/03/07 16:49:15
クラスについてさっぱりわかってないからこんなこと思うのかも知れませんが、
クラスの公開メンバ関数のアドレスを外部に教えてあげて、
そこから直接クラスの関数にアクセスすることってできますか?

具体的に言うと、Wik32APIでの、ウィンドウプロシージャに、クラスのメンバ関数を使いたいのですが…

516:デフォルトの名無しさん
08/03/07 17:06:28
>514
filesortの中身をちらっと読んだだけ。

・カンマ区切りを取り出す常套手段は
 1:スペース記号、タブ記号をすべて別の文字列で一旦置換
 2:カンマ記号をすべてスペースに置換
 3:stringstreamに流し込んで >> を使って読み込む
 4:1:で入れ替えてたのを元にもどす
 です。こうした方がいいです。

・名前を入れ替えたいだけじゃないんですよね?
 今のあなたのファイルは「名前データを取り出して、それをベクターに格納。そのベクターをソート」
 している「だけ」ですよ。
 あきらめてsetを使うか、set相当のものを自分で書くか、
 そうでなければsort相当のものを自分で書いてください。

・fin>>temp
 この部分は、もし入力ファイル中にスペースがあると困るのではないかと。
 nameに「Richard Feynman」って入ったら、Richardで切れますけど、いいんですか?
 一行取り出したいならgetlineを使いましょう。


517:デフォルトの名無しさん
08/03/07 17:07:45
>>511
普通の関数は仮想にするなよ
つEffective C++ 第38項

ダウンキャストはやめよう
つEffective C++ 第39項

というかEffective C++を購入して一読する事を強く勧める。

518:デフォルトの名無しさん
08/03/07 17:12:53
>>515
メンバ関数の実装は、クラスのポインタを引き渡していることが多い。
(thisポインタが引数としてわたっている)。
よって、関数ポインタを取ってきたところで、メンバ以外からマトモに使えません。

519:デフォルトの名無しさん
08/03/07 17:31:14
>>513
511じゃないが参考までにどういう形で実装するのか教えてくれませんか?
テンプレートを使った経験がないのでどういう風に使うのか見当がつきません

520:452
08/03/07 18:21:57
>>455-456
亀ですがレスthx
Winsockと同時に使うから文字列をstd::stringじゃなくてchar*で使ってたんですが、
例外処理さえつければ>>452のコードで大丈夫ですよね
あと、>>455のカマを掘られたって言うのがどうことかちょっと気になるんですが・・・

521:デフォルトの名無しさん
08/03/07 19:07:56
>>518
やっぱ駄目なんですか。
共通プロシージャ用意してmapしたのを検索する方向で考えてみます。

522:デフォルトの名無しさん
08/03/07 19:31:55
>>515
URLリンク(web.archive.org)

523:デフォルトの名無しさん
08/03/07 19:42:31
>>521
staticなメンバ関数なら問題ない

524:デフォルトの名無しさん
08/03/07 19:48:12
>>523
staticメンバ関数はstaticなメンバしかイジれないじゃん。

525:デフォルトの名無しさん
08/03/07 20:31:15
>>524
そうだよ。単にクラスという名前空間に閉じ込め、
protected/privateにできるという程度の意味しかない。

どっかからインスタンスへのポインタを得て、非静的なメンバ関数を呼ぶのが
静的メンバ関数のウィンドウプロシージャの仕事。
>>522

526:デフォルトの名無しさん
08/03/07 20:34:15
>>524
オブジェクトを作らずに呼び出そうとしてるんだからメンバなんていじる必要ない気が

527:デフォルトの名無しさん
08/03/07 20:42:15
>>515
サンクという手法でウィンドウプロシージャを書き換えて、ウィンドウハンドルの代わりにthisをスタックに積んでメンバ関数にジャンプさせれば?

528:デフォルトの名無しさん
08/03/07 20:47:14
boost::function

529:デフォルトの名無しさん
08/03/07 21:35:51
>>528
どうやってやるのさ

530:デフォルトの名無しさん
08/03/07 21:38:29
>>523-527
あ、オブジェクトではなく、クラスにひも付けすればよいのですね。

有り難うございました!

531:デフォルトの名無しさん
08/03/08 01:39:03
とあるクラスの派生クラス郡の中で一つの派生クラスだけ
関数の引数が異なることになってしまいました

こういう場合はどうしたらよいでしょうかorz

532:デフォルトの名無しさん
08/03/08 01:51:31
設計しなおす

533:デフォルトの名無しさん
08/03/08 01:52:10
>>531
全クラスに引数増やすとか(そしてデフォルト引数をつけておくとか)、
その派生クラスだけ別のメンバ関数で余分の引数を設定しておくとか、
引数の集合を何かクラスにまとめて、上位の概念に置き換えることで引数を共通にするとか。

534:デフォルトの名無しさん
08/03/08 01:53:54
dynamic_castしろと悪魔が囁いているぜ

535:デフォルトの名無しさん
08/03/08 01:56:46
>531
1. きっとやりたいことが間違ってるから考え直す。
2. boost::any とか boost::variant とかでぶちかます。

まぁもう少しやりたいことを詳細に説明するべきだろうね。

536:531
08/03/08 02:14:02
とある計測器と連携して、とあるプロセスを監視してそのデータをモニタに表示するのですが
今回のプロセスだけ表示させたいパラメータの数が増えてしまいました

監視プロセスが複数同時に走っていて、そのうち3つを同時に表示するようにするため
表示対象をユーザーが切り替えられるようにするため
表示クラスに監視クラスのポインタをつかって保持させています
監視クラスに
GetData(int OutputA, int dataB,int dataC)
という関数をよういしていたのですが
最新の計器が監視できるパラメータが増えてしまって・・・orz

537:デフォルトの名無しさん
08/03/08 02:22:28
>>536
そのシグニチャでGetだと言うのなら、参照かポインタ渡しじゃないの?
まあそれはいいとして。
パラメータの種類を指定して、データを1種類だけGetする関数を作ったら?

538:デフォルトの名無しさん
08/03/08 02:38:59
void calc(int& m, fstream* fio);

int main(void)
{
fstream fio[10];
char filename[10];
int m, steps;
steps = 7;
fio[0].open("calc0.dat");
m = 1;
while(m <= steps){
sprintf(filename, "calc%d.dat", m);
fio[m].open(filename, ios::in | ios::out);
m++;
}
m = 1;
while(m <= steps){
calc(m, fio);
m++;
}
return 0;
}

539:デフォルトの名無しさん
08/03/08 02:43:13
void calc(int& m, fstream* fio)
{
int i, j;
int a, d[100];
j = 1;
while(j <= 3){
fio[m-1] >> a;
d[j] = a;
j++;
}
j = 1;
while(j <= 3){
fio[m] << d[j] <<' '<< j <<'\n';
j++;
}
}
calc0.datの中身
5
16
77

基本的にすべてのデータファイルが同じになるようにプログラムを書いたのですが。
うまくいかないです。どこか間違っていますか?

540:デフォルトの名無しさん
08/03/08 02:43:52
void calc(int& m, fstream* fio)
{
int i, j;
int a, d[100];
j = 1;
while(j <= 3){
fio[m-1] >> a;
d[j] = a;
j++;
}
j = 1;
while(j <= 3){
fio[m] << d[j] <<' '<< j <<'\n';
j++;
}
}
calc0.datの中身
5
16
77
基本的にすべてのデータファイルが同じになるようにプログラムを書いたのですが。
うまくいかないです。どこか間違っていますか?

541:デフォルトの名無しさん
08/03/08 09:11:50
>>540
>どこか間違っていますか?
あんたの説明。
結果がどうなったのか、どうなるつもりだったのか(これは全てcalc0.datと同じになるということか)、
実行した環境と処理系は何か、位のことは書いても罰は当たらんよ。

542:511
08/03/08 11:33:07
昨日の続きなんですが、引数のの違う関数を
まとめた関数テーブルって、どう実装するのが
良いでしょうか?
>512のようにlistや可変長引数だと、個数が
違う場合には有効ですが、構造体を渡す場合には
無理があると思えます。
(構造体の要素をPOD型に分解してlist化するとか?)

>513で書かれた特殊化では、どう実装するのかが
全く閃きませんorz
キャストを使う以外で違った構造体やクラスを
スムーズに(できれば低コストで)渡す方法ってあるのでしょうか?

543:デフォルトの名無しさん
08/03/08 11:41:16
>>542
昨日の続きと言われても状況を把握するために過去に遡って読むのは面倒なので目的を詳しく。
まぁ、よくあるGUIライブラリの実装などでは構造体を丸ごと渡すのではなく汎用ポインタを渡す形が多いけどね。

544:511
08/03/08 11:42:33
なお今自分が使ってた方法だとこんな感じです。

class ArgBase { //引数親
public:
 virtual ~ArgBase(){};
}

class Arg1 : public ArgBase {
public:
 int arg;
}
//以下必要なだけArgBaseを引き継いだ構造体を作る

//関数テーブル
typedef bool(*pFunc)(ArgBase*) FUNCPTR;
FUNCPTR fuctable[10];
fnctable[0] = Func1;

//関数例
bool Func1(ArgBase *pArg) {
 //これがArg1が必要な関数なら
 Arg1 *ptr = dynamic_cast<Arg1*>(pArg);
 if(ptr == NULL) return FALSE;
 //処理
 return TRUE;
}

545:デフォルトの名無しさん
08/03/08 15:49:36
久しぶりにプログラムを組むのですが、初歩的なことが分からないので
教えてください。昔


float a;
a=1.0

と1ではなく1.0にしなさいと教わったのですが、その詳しい理由を
忘れました。
どうしてなのでしょうか?


546:デフォルトの名無しさん
08/03/08 15:56:19
>>545
1.0も中途半端だな。1.0fと書け。
1と書くとそれはint型になる。
1.0と書くとdouble型になる。
1.0fと書くとfloat型になる。
intやdoubleからfloatへの変換は警告が出る可能性があるので、
代入先と同じ型にしておけということ。生成される機械語は同じだろうけど。

547:デフォルトの名無しさん
08/03/08 16:23:22
>>543
やはり間違わないように気をつけてvoid*で渡してキャストするのが
常套手段なんですかね。

548:デフォルトの名無しさん
08/03/08 16:25:25
あと、
typedef bool(*pFunc)(ArgBase*) FUNCPTR;
じゃなくて
typedef bool(*FUNCPTR)(ArgBase*);
でしたorz

549:デフォルトの名無しさん
08/03/08 17:09:29
現在、勉強がてらに、Windows用のクラスライブラリを無意味に作ってるのですが
dynamic_castって良い機能ですねぇ
基本クラスに無意味に仮想関数を突っ込まなくても、派生クラスの機能が使えるなんて嬉しすぎる


550:デフォルトの名無しさん
08/03/08 17:12:08
dynamic_cast禁止

551:デフォルトの名無しさん
08/03/08 17:12:19
は?

552:デフォルトの名無しさん
08/03/08 17:12:46
すげークラスライブラリきた

553:デフォルトの名無しさん
08/03/08 17:24:08
俺も今無意味にgtkのラッパークラスライブラリ作ってるよ!

Window wnd("sample",MAIN_WINDOW);
vBox box(MAIN_WINODW);
Label sample_label("sample",MAIN_WINDOW);
Button ok_button("OK",MAIN_WINDOW);

CREATE(MAIN_WINDOW);

ok_button.clicked(func);

box << sample_label << ok_button;
wnd << box;

CONSTRUCT(MAIN_WINDOW);

みたいにmain関数の中で書いたらコンパイルが通るようになるやつ。
今マニピュレーター実装中。


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