■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part43
251 名前:デフォルトの名無しさん :2005/08/29(月) 19:23:26
>>250
一応現在は保障されているが
Mapがclassでデフォルトコンストラクタが定義されているなら
vector<Map>の構築時に全要素分呼ばれるので
Mapのコンストラクタでゼロ初期化するようにしとけばいい


252 名前:デフォルトの名無しさん :2005/08/29(月) 19:28:49
>>250
Mapがゼロクリアを保証できるならいいが、そうでないならstd::fill()を使うのが無難。

253 名前:デフォルトの名無しさん :2005/08/29(月) 19:35:46
C++はゼロクリアすると危険な場合があるので
(自分または継承元が仮想関数を持つなどでRTTI情報、vTblを持つ場合、
及びそういうオブジェクトをメンバとして一つでも持つ場合)
Mapがそれに該当するならmemsetだろうとfillだろうと危険ですな

254 名前:250 :2005/08/29(月) 19:40:20
>>251-253
とにかくセル数が多くvTblのバイト分も馬鹿にならないので
継承や仮想関数は禁止でやってますが、
おとなしくコンストラクタで0クリアしておきます。
どうもありがとうございました。


255 名前:デフォルトの名無しさん :2005/08/29(月) 19:48:20
>>251
vector<T> a(n);は、T()で一時オブジェクトを作って
それを全要素分コピーコンストラクタで塗るので
通常のコンストラクタが全要素数分呼ばれるわけではないな

256 名前:デフォルトの名無しさん :2005/08/29(月) 19:58:42
mallocやnew char[]でいいやん

257 名前:デフォルトの名無しさん :2005/08/29(月) 20:21:18
>256
それは悪い意味でのCの慣習だ

258 名前:デフォルトの名無しさん :2005/08/29(月) 20:52:08
Win32のメモリ領域確保系関数って一回も使った事ないな

スレ違いですねすいません

259 名前:デフォルトの名無しさん :2005/08/29(月) 22:23:32
スレ違いが続くが。
コンストラクタでHeapCreateしてデストラクタでHeapDestroyするAllocatorを作ってみようかなと思案している。

260 名前:デフォルトの名無しさん :2005/08/29(月) 22:55:11
>コンストラクタでHeapCreateして
うわ!
>デストラクタでHeapDestroyするAllocator
うわわわわ!!

261 名前:デフォルトの名無しさん :2005/08/29(月) 22:56:08
>>253
fill()は代入だよ。

262 名前:259 :2005/08/29(月) 23:03:06
>>260
何か問題でも?

263 名前:デフォルトの名無しさん :2005/08/29(月) 23:07:12
260じゃないけどそんなバカ正直なアロケータ書いても糞重いだけだと思う

264 名前:デフォルトの名無しさん :2005/08/30(火) 01:10:23
>>262
標準のコンテナに渡す場合、 non-static データメンバを持つ allocator は使えない。

265 名前:デフォルトの名無しさん :2005/08/30(火) 12:29:17
>>264
そうですか。
ではHeapCreate〜HeapDestroyはシングルトンにすることにします。

266 名前:デフォルトの名無しさん :2005/08/30(火) 13:24:35
typedef CTypedPtrArray<CObArray,CNode*> NodeArray;
class CNode {
public :
  NodeArray* GetChileNode();
}

このように書くと、「1行目でCNodeが見つからないよ」とコンパイラにはじかれてしまします。

CNode内のメソッドでNodeArray型を使用したいので、CNodeの前にNodeArrayを宣言したい。
しかし、CNodeの前にはNodeArrayが宣言できない。
という状態なのですが、どのようにすればこの状態を解決できるでしょうか?

アドバイスよろしくお願いいたします。

267 名前:デフォルトの名無しさん :2005/08/30(火) 13:27:56
class CNode;
とだけ宣言したらどうだろう。

268 名前:デフォルトの名無しさん :2005/08/30(火) 13:34:07
>>267
ありがとうございます。
先頭行に、「class CNode;」の宣言を入れたら、コンパイルが通りました。

クラス宣言を2回以上しても大丈夫な事を知りませんでした。
勉強になりました。

269 名前:デフォルトの名無しさん :2005/08/30(火) 13:35:43
>>268
一応
クラス宣言
class Hoge;
クラス定義
class Hoge { ... };

宣言と定義は違うってことで

270 名前:デフォルトの名無しさん :2005/08/30(火) 13:40:00
>>269
なるほど。
そういう扱いになる訳ですね。

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

271 名前:デフォルトの名無しさん :2005/08/30(火) 13:42:20
>>269
定義は宣言でもあるってことも忘れてはいけない。

あと、クラス宣言、クラス定義については歴史的に混乱があるようなので、
古くからC/C++を使ってきた人と話すときは明確な区別をあてにしないほうがいい。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#379

272 名前:デフォルトの名無しさん :2005/08/30(火) 13:54:29
>>271
定義は宣言を含むってのは
関数定義がプロトタイプ宣言を含むのと同じだね

273 名前:デフォルトの名無しさん :2005/08/30(火) 14:04:51
質問です。

struct X {};
typedef X * Handle;
typedef const Handle HandleA;
typedef Handle const HandleB;

上記定義において、
HandleA と HandleB の型が同一であることは規格で保障されていますか?


274 名前:デフォルトの名無しさん :2005/08/30(火) 16:24:59
>>273
もちろん。
そこで並べる順番は関係ない。

275 名前:273 :2005/08/30(火) 18:35:28
>>274
ありがとうございます。
const Handle が、const X * に、
Handle const が、 X * const にそれぞれ展開されるんじゃないかと
悩んでいたのですっきりしました。

276 名前:デフォルトの名無しさん :2005/08/30(火) 21:02:21
メンバ関数ポインタを介して、基底クラスの関数を呼び出したいのですが
どうやっても上手くいきません。仮想関数では無理なのでしょうか。VC6使ってます。

#include <iostream>
using namespace std;

class Base
{
public:
  virtual void Foo()
  {
    cout << "Base::Foo" << endl;
  };
};

class Bar : public Base
{
public:
  virtual void Foo()
  {
    cout << "Bar::Foo" << endl;
  };
};

int main()
{
  Bar *pBar = new Bar;
  void (Base::*pFoo)() = pBar->Base::Foo;
  (pBar->*pFoo)(); // pBar->Base::Foo()
  delete pBar;
  return 0;
}

277 名前:デフォルトの名無しさん :2005/08/30(火) 21:16:20
>>276
おまいは、メンバ関数ポインタの定義の仕方をちゃんと調べたのかと(r

278 名前:276 :2005/08/30(火) 21:34:21
>>277
戻り値の型 (クラス名::*)(引数リスト)

こう解釈してますが…何か違うのでしょうか?

279 名前:デフォルトの名無しさん :2005/08/30(火) 21:37:43
>>278
初期化子が変

それから、仮想関数へのポインタはvtblの先頭からのオフセット

280 名前:デフォルトの名無しさん :2005/08/30(火) 21:40:39
>>279
thisどこ?

281 名前:デフォルトの名無しさん :2005/08/30(火) 21:51:48
>>280
何が言いたい

282 名前:276 :2005/08/30(火) 21:57:57
void (Base::*pBaseFoo)() = Base::Foo;
(pBar->*pBaseFoo)();

void (Bar::*pBarFoo)() = Bar::Foo;
(pBar->*pBarFoo)();

デバッガで追ってみましたがどちらも最終的にBar::Fooに。

Baseにキャストしても元がBarなんで、結局Bar::Foo

やっぱり無理なんですかねぇ...

283 名前:デフォルトの名無しさん :2005/08/30(火) 21:58:01
>>276
void (Base::*pFoo)() = &Base::Foo;じゃないとコンパイルが通らないと思うが。
そうしてメンバへのポインタを使ったところであれだ。自分で試してみろ。

284 名前:デフォルトの名無しさん :2005/08/30(火) 21:58:59
>>282
そりゃそうだ。じゃなきゃ仮想関数の意味がない。

285 名前:デフォルトの名無しさん :2005/08/30(火) 22:00:59
アップキャストしたらできないか?

286 名前:276 :2005/08/30(火) 22:17:32
pBar->Base::Foo();
↑のように直接記述したり、virtual外せば問題ないのにな。

融通きかないみたいなんで別の方法考えます。
お騒がせしました。

287 名前:デフォルトの名無しさん :2005/08/30(火) 22:20:10
>>286
メンバへのポインタで仮想関数が適切に呼ばれないほうがよっぽど融通きいていないだろ。

288 名前:デフォルトの名無しさん :2005/08/31(水) 01:13:46
派生クラスが意図的に基底クラスのメソッド呼び出さないようにとかしてたら偉いことが起きそうだな‥

289 名前:デフォルトの名無しさん :2005/08/31(水) 01:47:50
明示的になら呼び出せても良さそうな気はするが。

290 名前:デフォルトの名無しさん :2005/08/31(水) 02:48:02
いや、明示的には呼び出せるけどその記述の仕方が気に入らないらしい

291 名前:デフォルトの名無しさん :2005/08/31(水) 10:51:07
>>282の書いてるプログラムの設計が気になる

292 名前:デフォルトの名無しさん :2005/08/31(水) 11:41:14
C++の例外処理機構って、ifとgotoでやれることのシンタックスシュガーみたいなもん?
もちろん関数を越えてジャンプできるのは凄いけど。

293 名前:デフォルトの名無しさん :2005/08/31(水) 11:42:30
>>292
そのとおりだけど、それを言うとあらゆる制御構造がifとgotoのシンタックスシュガーだな。

294 名前:デフォルトの名無しさん :2005/08/31(水) 11:48:00
>>293
でも他の制御構造は一応条件を判断する要素は残ってるでしょ?
C++の例外処理機構はそういうのすら画しちゃってるから。

295 名前:デフォルトの名無しさん :2005/08/31(水) 11:58:55
>>294
言いたいことがよくわからない。
例外処理の場合はソース中には分岐の条件が明示されないけど、
実際には分岐が行われる。

296 名前:デフォルトの名無しさん :2005/08/31(水) 12:48:16
>>295
例外 or setjmp/longjmpそれ自体は分岐じゃねーだろ。アフォ?

297 名前:デフォルトの名無しさん :2005/08/31(水) 12:50:19
まともに学ぶ気がない奴が言い訳を探してるだけだろ。

298 名前:デフォルトの名無しさん :2005/08/31(水) 12:53:10
話がかみ合わないスレはここですか?

299 名前:デフォルトの名無しさん :2005/08/31(水) 13:21:39
>>296
どのcatchに捕捉されるかの分岐があるだろ。

300 名前:デフォルトの名無しさん :2005/08/31(水) 13:29:13
>>292
更に遡るときローカル変数のデストラクタを呼んでいくのを忘れるな。

301 名前:デフォルトの名無しさん :2005/09/01(木) 04:15:26
>>300
それは例外処理とは別の話

302 名前:デフォルトの名無しさん :2005/09/01(木) 14:30:49
例外処理とstack unwindingは切っても切れない関係にあると思うけど

303 名前:デフォルトの名無しさん :2005/09/01(木) 16:44:30
{}ブロックから抜けるときにスコープの変数解放するってだけの話じゃん。例外とか関係ないし。

304 名前:デフォルトの名無しさん :2005/09/01(木) 17:01:15
>>303
はあ、それをするのが例外処理の重点のひとつじゃないか
何言ってんの

305 名前:デフォルトの名無しさん :2005/09/01(木) 17:16:25
ifだろうがgotoだろうがthrowだろうがブロック抜けるときにやる処理は変わらねーんだよ
例外処理機構だけが特別になにかするわけじゃないっ話だよ
筋読め

306 名前:デフォルトの名無しさん :2005/09/01(木) 17:17:03
つかシンタックスシュガーであるか無いかからどんな価値のある結論が出るというのか

307 名前:デフォルトの名無しさん :2005/09/01(木) 17:38:38
Stack unwinding (wikiの定義)

関数がreturnするときのスタックの調整
(大昔からの用語だと思われる)

stack unwinding (C++の定義)

tryからcatchに移るときにデストラクタが自動で呼ばれるプロセス
(標準文書で、例外が"return"中のときのいろんな制限の説明のために
用意された用語。7ヶ所出てくる)


wikiの定義で語っている多くの本が間違っていると思われる。
wikiの定義で語るならreturnの説明のときにするべきだから。

308 名前:デフォルトの名無しさん :2005/09/01(木) 17:43:50
なんか、言語の機能としての「例外処理」と、広義の「例外処理」とがごっちゃになっているなあ
言語の「例外処理」機能が話の主題のはずだか、
スタックの巻き戻しが無関係とかいってる奴はそこいら変を勘違いしてる



309 名前:デフォルトの名無しさん :2005/09/01(木) 18:38:16
>C++の例外処理機構って、ifとgotoでやれることのシンタックスシュガーみたいなもん?

setjmpとlongjmpのようなものだよ派
 |
 +- stack unwinding について触れる派
 |
 +- 掲示板で難しい話はしない派

catch節にgotoでジャンプするようなものだよ派
 |
 +- 関数を越えてジャンプできるのは凄いよ派
 |
 +- if や goto と全く同じだよ派

310 名前:デフォルトの名無しさん :2005/09/01(木) 19:58:55
>なんか、言語の機能としての「例外処理」と、広義の「例外処理」とがごっちゃになっているなあ

誰もそこはごっちゃにしてないと思うが

311 名前:デフォルトの名無しさん :2005/09/01(木) 20:13:10
一連の流れを読んでいて、「C#で実現してることなんて全部
Cでできることばっかりじゃないか、たいしたことないね」、
と言って何も学ぼうとしない前職の上司(44歳、Cとawkしか
使えないので役に立たない)を思い出した。

312 名前:デフォルトの名無しさん :2005/09/01(木) 20:19:33
>>310
じゃあ、何で例外処理機能の話をしてるのに、「stack unwinding は関係ない」という話が出てくるんだ?
勘違いしてるとしか思えん

313 名前:デフォルトの名無しさん :2005/09/01(木) 21:20:44
すべての言語はチューリング等価だよ。

314 名前:デフォルトの名無しさん :2005/09/01(木) 21:28:17
そもそもシンタックスシュガーって何よ。


315 名前:デフォルトの名無しさん :2005/09/01(木) 21:31:05
糖衣構文:
http://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87


316 名前:デフォルトの名無しさん :2005/09/01(木) 21:36:19
>>305
setjump〜longjumpでデストラクタが呼ばれないのはどうお考えで?

317 名前:デフォルトの名無しさん :2005/09/01(木) 21:46:58
つか>>315の説明から判断すると高級言語全体がそもそもシンタックスシュガーだろ。
重箱の隅つついてどうでもいい話引き伸ばすなっての


318 名前:デフォルトの名無しさん :2005/09/01(木) 22:06:56
>高級言語全体がそもそもシンタックスシュガーだろ
これが元の話と何の関係もないのは言うまでも無いが、どうでもいい話というのは同意

319 名前:デフォルトの名無しさん :2005/09/01(木) 22:10:07
例外機構はifとgoto、それからグローバル変数とか戻り値とかを使えば
「ほとんど同じ」ことは出来るので、シンタックスシュガーと言えるかもね。だから何>>292

となると次に興味が沸くのはなぜC++には例外が導入されたか、
どのように使い分けるのが良いか、といったところかな。


320 名前:デフォルトの名無しさん :2005/09/02(金) 15:31:21
例外といえば、前から気になっていたことがあるので質問します。

access_violation
break_point
derived_by_zero
page_error
stack_overflow

の各種例外を定義するとき、
それぞれどの標準例外クラスから派生するのが妥当でしょうか?

stack_overflow は std::overflow_error、
derived_by_zero は logic_error かなと考えていますが。
皆さんの意見を聞かせてください。

321 名前:デフォルトの名無しさん :2005/09/02(金) 15:40:04
runtime_error

322 名前:デフォルトの名無しさん :2005/09/02(金) 18:37:06
exception

323 名前:デフォルトの名無しさん :2005/09/02(金) 18:59:34
null_pointer

324 名前:320 :2005/09/02(金) 19:01:57
derived_by_zero ってなんだ。素で間違えた
正しくは divide_by_zero です。

access_violation は runtime_error
break_point は domain_error
divide_by_zero は logic_error
page_error は runtime_error
stack_overflow は domain_error

今のところ、上記のような感じで考えてますけど、
厳密に区分けするのは面倒なので、>>322 さんの言うとおり
全部 exception から派生させるのもひとつの手かも。

325 名前:デフォルトの名無しさん :2005/09/02(金) 19:05:31
>>324
OSかエミュレータでも作ってるん?
stack_overflowはruntime_errorっぽい気はするが

326 名前:デフォルトの名無しさん :2005/09/03(土) 13:41:11
C++でコンストラクタから別のコンストラクタを呼ぶにはどうすればいいですか?

class Test
{
private:
int value_;


 public;
 Test()
 {
  //Javaだとここにthis(150)と書けば↓のコンストラクタが呼べる 
 }

 Test(int value) : value_(value)
 {
 }

}

327 名前:デフォルトの名無しさん :2005/09/03(土) 13:46:37
別のコンスラクタは呼べない。


328 名前:326 :2005/09/03(土) 13:50:58
ガーン…

ということは
Test(int a, double b, std::string c, T d, … U w) : a(a), … w(w)
{
 //長ったらしいいろんな初期化処理(数十行)
}
というコンストラクタがあって


Test(int a, double b, std::string c, T d, … U w, V x)
というコンストラクタを作りたくなったら
処理は全部コピペするしかないということですね…

やっぱC++は設計が古いんだな…

329 名前:デフォルトの名無しさん :2005/09/03(土) 13:53:17
>>326
C++オブジェクトモデルでは、オブジェクトのライフタイムが
コンストラクタが完了した時点で始まると定義されている。

コンストラクタからコンストラクタが呼び出せるとすると、
オブジェクトのライフタイムが定まらない。

例えば this(150) のあと、 Test() の続きで例外がスローされた場合に
デストラクタが実行されるかどうかが定まらなくなる。

330 名前:デフォルトの名無しさん :2005/09/03(土) 13:53:36
プライベートメンバ関数に初期化処理を分離すりゃええやん

331 名前:デフォルトの名無しさん :2005/09/03(土) 13:55:15
*this = Test(150);

332 名前:デフォルトの名無しさん :2005/09/03(土) 14:06:09
非コンストラクタなメンバ関数だとメンバ変数の初期化できないけどな。

333 名前:デフォルトの名無しさん :2005/09/03(土) 14:17:21
>>328
初期化メソッド作れ

334 名前:デフォルトの名無しさん :2005/09/03(土) 14:19:18
>>330,333
代入と初期化の違いはわかってて言ってるのか?

335 名前:デフォルトの名無しさん :2005/09/03(土) 14:26:04
どうしても初期化が必要ならポインタで管理すればいいんじゃ
そのあたりは設計の妥協点

336 名前:デフォルトの名無しさん :2005/09/03(土) 15:06:27
コピペするくらいだったらマクロ使えばいいじゃん。


337 名前:デフォルトの名無しさん :2005/09/03(土) 15:59:14
>>326
それができるんだったら、そもそもメンバ初期化リストの意味がないんじゃない?
: value_(value) は value_ = value; とは違う。
初期化はそのオブジェクトの一番最初の構築を意味するわけで、
コンストラクタからコンストラクタを呼べたら二回メンバ変数を初期化する事になってしまう。

そもそもJavaでは : value_(value) とは書けないので、その例でJavaでは呼べると言っても意味がないと思うけど。
コンストラクタの持つ意味自体がC++とJavaでは少し違っているんじゃないのかなぁ。
いつメンバが初期化(最初の構築)されるのかとか。
Javaはメンバとなるオブジェクトを基本型以外は参照型で持つし、
C++ほど定数性にこだわっていないから、その辺の違いから来ているのかもね。


338 名前:デフォルトの名無しさん :2005/09/03(土) 17:22:44
>>328
そのクラスをインターフェイス・クラスと内部実装クラスに分離して、インターフェイスが内部実装を非公開継承もしくはメンバとして持つという手段もある。
インターフェイスの各コンストラクタで共通する部分を内部実装のコンストラクタに落とし込むわけだ。

339 名前:デフォルトの名無しさん :2005/09/03(土) 19:05:59
これだからJava厨は。

340 名前:デフォルトの名無しさん :2005/09/03(土) 19:34:19
何!さっきからどうもJava臭いと思っていたらやっぱりそうか。

341 名前:デフォルトの名無しさん :2005/09/03(土) 20:03:54
総合的に言って、Javaのほうが優れているというのは常識なのでしょうか?

342 名前:デフォルトの名無しさん :2005/09/03(土) 20:09:01
>>341
評価基準による。自分に合った評価基準で言語は選ぶものだ。

っていうか総合的って何だ。っていうか釣りだろ。


343 名前:デフォルトの名無しさん :2005/09/03(土) 20:10:43
つーか釣られんな

344 名前:デフォルトの名無しさん :2005/09/03(土) 20:35:16
つーかJavaに限らずD言語とかでもthis()できるよ

345 名前:C初心者です :2005/09/03(土) 21:18:09
質問です。
NT系のOSってノートパッドに書き込める容量は制限されて無いみたいなんですけど、
Meってノートパッドに書き込みすぎるとメモリ不足って言う表示がでてしまい、それ以上書けなくなってしまいます。
そこで、Meで動作する容量の制限されないノートパッドをC言語で作ってるんですけど、イマイチ作れません。
だれか作り方教えてください。お願いします。

346 名前:デフォルトの名無しさん :2005/09/03(土) 21:21:36
>>345
ここもスレ違い。タイトルを読むってことはできないのか?

347 名前:デフォルトの名無しさん :2005/09/03(土) 21:23:31
まず根本的にだ。
おまいがやりたいのはCでメモ帳もどきを作ることなのか、
容量制限のないメモ帳を使いたいのかということ。

前者なら自分で勉強しろとしか言えん。つかその程度のことを調べられないのなら
根本的にプログラミングは向いていない。
Win32APIとか、Windowsプログラミングでググればいくらでも参考になるページは出てくるから。

後者なら、んなものいちいち自作しないで既存のエディタ使え。
秀丸でもEmEditorでもxyzzyでもTeraPadでも、メモ帳とは比較にならない
レベルのエディタが腐るほどあるから。

348 名前:C初心者です :2005/09/03(土) 21:28:03
>>347
そうですか。回答ありがとうございます。
ちなみに、容量制限のないメモ帳をVCなど使わないで作りたかっただけです。

349 名前:デフォルトの名無しさん :2005/09/03(土) 22:50:18
とりあえずその話題はこっちか?

【初心者歓迎】C/C++室 Ver.21【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1125743714/

ただ、あまりにも質問が漠然としてるからそのままじゃまともなレスは期待できないだろうな。

350 名前:デフォルトの名無しさん :2005/09/03(土) 23:43:15
VCなど使わないで作りたかったとは、BCCを使っているとか、GCCでやっているとかか?

351 名前:デフォルトの名無しさん :2005/09/04(日) 07:55:11
CよりC++やC#やJavaやHSPを使った方がいいんジャマイカ

352 名前:デフォルトの名無しさん :2005/09/04(日) 11:27:31
HSPてなに?

353 名前:デフォルトの名無しさん :2005/09/04(日) 11:29:17
Hなスピード

354 名前:デフォルトの名無しさん :2005/09/04(日) 11:57:42
C++やC#やJavaと同列に置くのが解せん

355 名前:C初心者です :2005/09/04(日) 12:08:12
レス遅れてスイマセン。
>>349
もうちょっとソース組み立ててから相談します。
>>350
BCCでコマンドプロントを使ってコンパイルしてます。
>>351
説明間違えてました、C++で作ってます。

356 名前:デフォルトの名無しさん :2005/09/04(日) 13:17:57
>>354
最近は構造体や関数もあるらしいよ

357 名前:デフォルトの名無しさん :2005/09/04(日) 13:38:18
それだけじゃまだOOPLになってない

358 名前:デフォルトの名無しさん :2005/09/04(日) 13:46:01
>>356
って、昔は構造体も関数もなかったのかよ!
よくそんなもんを使おうと思う人間がいたものだ。

359 名前:デフォルトの名無しさん :2005/09/04(日) 17:35:41
タダで楽ですから。この二つの単語に人間は惹きつけられる

360 名前:デフォルトの名無しさん :2005/09/04(日) 20:05:44
弟子食いの古賀先生w

361 名前:デフォルトの名無しさん :2005/09/04(日) 22:44:38
こんばんわ、質問があります。
環境C++6.0 windowsxp
今、ハードディスクやCDの容量を調べるプログラムを組んでいます。
GetDiskFreeSpaceExをつかって、ハードディスクの使用量と空き容量は入手できたのですが、
焼かれたCDの空き容量が0になってしまうのです。マイコンピュータのCDドライブのところから、
プロパティを開くと空き容量が表示されるのですが、プログラムでそれを入手することが出来ないのです。
基本的な質問ですが、知恵をお貸し願えませんでしょうか?
よろしくお願いします。

362 名前:デフォルトの名無しさん :2005/09/04(日) 22:51:38
>>361
http://pc8.2ch.net/test/read.cgi/tech/1122723009/nの次スレが立ってからそちらへどうぞ。

363 名前:デフォルトの名無しさん :2005/09/04(日) 23:05:51
ありがとうございます >>362

364 名前:デフォルトの名無しさん :2005/09/05(月) 02:22:31
たとえば以下のようなセルからなるマップというクラスがあるとして
class Map {
  struct Cell {
    
  };
  friend class Cell;
  int WorldWidth;   //世界の大きさなどはMapクラスが管理
  int WorldHeight;
  Cell* pCell;     //格CellへのアクセスをMapクラスが抽象化する。
};

ここでCellクラス内のメンバ関数が親のMapクラスの情報が欲しいとなれば
void Hoge(Map* pMap)
{
 pMap->WorldWidth;
}
と、関数の引数にもらってthisポインタのように使う以外に何かいい方法ありますか?
MapクラスへのポインタをCellクラスのメンバ変数に持たせるのはメモリの無駄遣いだと思うし、
静的メンバ変数などにすると複数のMap、(裏の世界とか、夢の世界とか)に対応できないような気もします。
関数の引数でアクセスするのが一番素直なようにも思うんですが、
Cellのメンバ変数が再帰しまくったときにスタックに積みまくるのもなんか無駄なような気がしてます。
なんかこう書くとエレガントだとか、効率的だとかあればご教授お願いします。

365 名前:デフォルトの名無しさん :2005/09/05(月) 03:55:05
>>364
訂正
>Cellのメンバ変数が再帰しまくったときに
Cellのメンバ関数が再帰・・・
です。

366 名前:デフォルトの名無しさん :2005/09/05(月) 04:41:06
>>364
CellがMapを関知しちゃイカンだろ
CellにはMap側で計算済みの値を渡すべき

367 名前:デフォルトの名無しさん :2005/09/05(月) 04:55:46
>>364
基本的に>>366の言うとおりだし、
そもそもスタックが気になるほど再帰しまくるならデータ構造から見直すべき。
しっかりした構造なら大抵は再帰の深さなんてせいぜいlog(セルの個数)程度のオーダーだと思われ。
それを超えるなら簡単に再帰を使うべきではない。
つまり引数にすること自体は問題なし。

368 名前:デフォルトの名無しさん :2005/09/05(月) 17:23:26
VC7.1+STLPortなんですが、
stringstreamのポインタ操作が機能しません。
具体的には下記のコードでp0とp1が共に0を返し
seekpが機能しません。
結果"abcdefgh"と出力されます。
strstreamの場合正常に機能します。
なぜでしょうか?

std::stringstream stream( std::ios::out );
const std::ios::pos_type p0 = stream.tellp();
stream << "abcde";
const std::ios::pos_type p1 = stream.tellp();
stream.seekp( -3, std::ios::cur );
stream << "fgh" << std::endl;


369 名前:320 :2005/09/05(月) 18:19:26
>>325
非常に遅くなりましたけど、
Win32 の構造化例外を、C++ の例外に変換する際のはなしです。
普通は華麗にスルーするところですが、どうしても捕捉しておく必要があったので。




370 名前:デフォルトの名無しさん :2005/09/05(月) 20:48:09
>>368
STLPortのバグ
VC6.0ならともかくVC7.1なら付属のほう(dinkumware)がむしろ安定してるからそっち推奨

371 名前:デフォルトの名無しさん :2005/09/05(月) 21:42:34
>>370
嘘つくなタコ。std::ios::outを指定すると、:ostream iteratorが
指定されるだろ。これはramdom access iteratorではないので、
シークができないし、現在位置も知る事ができない。
従って、tellp()をすると、std::string::nposが返る。

正しく動かすには、std::stringstream stream( std::ios::out | std::ios::in );
としないとだめ。

むしろ、このまま正しく動くような動作をするdinkumwareの方が糞だろ。
少なくとも俺の環境でVC7.1+STLport4.6.2では、上のようにフラグを指定
すれば正しく動作する。


372 名前:デフォルトの名無しさん :2005/09/05(月) 21:44:31
あ、失礼
×std::string::npos
○std::ios::pos_type(-1)

373 名前:370 :2005/09/05(月) 22:11:07
すまん。質問のios::outの指定を完全に見逃してた。
370は撤回させてくれ。371のとおり。

374 名前:368 :2005/09/05(月) 22:40:58
>>372-373
お答えありがとうございました。
勉強になりました。

375 名前:デフォルトの名無しさん :2005/09/05(月) 23:48:48
ポインタの参照先に実体があるかどうかを調べる関数はありますか?

376 名前:デフォルトの名無しさん :2005/09/06(火) 00:03:07
ない。

377 名前:デフォルトの名無しさん :2005/09/06(火) 00:04:26
サンクス

378 名前:デフォルトの名無しさん :2005/09/06(火) 00:24:33
コレじゃ無理かな。
今環境無いから試せないけど。VC++限定で

template< typename T > bool is_valid_pointer( T const volatile * p )
{
 __try{ (void)(*p); }
 __except( EXCEPTION_EXECUTE_HANDLER ) { return false; }
 return true;
}

379 名前:デフォルトの名無しさん :2005/09/06(火) 00:26:15
自分で管理するという方法もある。
俺ならスマートポインタを素直に使ってそんな状況そのものを発生させないが

#include<set>
template<typename T>
struct valid{
    static std::set<const valid*>check;
    valid(){check.insert(this);}
    ~valid(){check.erase(this);}
    static bool isValid(const T*p){return check.count(p)!=0;}
};
template<typename T>
std::set<const valid<T>*> valid<T>::check;

こんな風に定義して

//有効か確認機能付の構造体
struct X:valid<X>{};

X::isValid(p);//pが有効か確認

380 名前:デフォルトの名無しさん :2005/09/06(火) 00:41:02
xをy(≠整数)乗するにはどうしたらいいのでしょうか?

381 名前:デフォルトの名無しさん :2005/09/06(火) 00:51:27
パワー、パワー

382 名前:デフォルトの名無しさん :2005/09/06(火) 00:52:49
#include <math.h>
#include <stdio.h>

void main( void )
{
double x = 2.0, y = 3.0, z;

z = pow( x, y );
printf( "%.1f to the power of %.1f is %.1f\n", x, y, z );
}


383 名前:デフォルトの名無しさん :2005/09/06(火) 00:59:34
>>381-382
お二方ありがとうございました

384 名前:364 :2005/09/06(火) 02:12:33
>>366さんの
おっしゃるとおりだと思いますが、
元々の形はすべてのCellで共通のデータをstaticとして持つでした。
しかしstaticで持ってしまうと、複数のマップ対応に拡張できない。
ということで364の形式、MapクラスはCellクラスからなる、
Cellの共有データはMapクラスが管理ということで
Map Omote_no_sekai;
Map Ura_no_sekai;
というように書けるようにしてみました。
今のところCellがMapを関知することのデメリットはよく分かりません。
静的メンバ変数に比べると関数引数で受け取る必要があるので面倒ですが・・・。

>>367
確かにlogのオーダーなので、それほど問題ないようならこのままいってみます。

蛇足になりますが、静的メンバ変数をあるグループごとに複製したい場合
テンプレートのを使うのは邪道でしょうか?
つまり
template<int WorldSize, int MapType>
class Cell
{
  static int arekore;
};
として
Cell<256, 0> Omoteno_sekai[256*256];
Cell<256, 1> Urano_sekai[128*128];
Cell<128, 2> Yume_no_sekai[128*128];
としてしまう手です・・・。



385 名前:デフォルトの名無しさん :2005/09/06(火) 02:56:05
>>371,373
> std::ios::outを指定すると、:ostream iteratorが指定される

これ、何の話?さっぱりわからない。
「:ostream iterator」って何?
何に「:ostream iterator」が指定されるの?

> std::stringstream stream( std::ios::out | std::ios::in );

これはつまり std::stringstream stream こうしとけばいいってことだな。

386 名前:デフォルトの名無しさん :2005/09/06(火) 03:28:14
>蛇足になりますが、静的メンバ変数をあるグループごとに複製したい場合
テンプレートのを使うのは邪道でしょうか?

その方法はあまりいいものとはいえない。
Cellをテンプレートにすると、当然それを含むMapもテンプレートにしなければならなくなる。
すると、そのMap、Cellを引数にするような関数もテンプレートにせねばならない、などと
際限がなくなってしまう。

struct MapInfo{ int nWorldHeight; int nWorldWidth; };
struct Cell
l
void Hoge(const MapInfo* p)
{....}
.};
class Map
{
MapInfo m_mapInfo;
Cell* m_pCellArray;//Cellのコレクションをメンバに持つ。
};
・CellをMapの外に出す。
・friend class はできるだけ使わない。
って感じで、テンプレートを使わない場合はできるだけMapとCellとの癒着をなくす方がいい。


387 名前:デフォルトの名無しさん :2005/09/06(火) 04:23:52
>>371
自分もちょっとわかりません。
それはC++の仕様なのでしょうか?
それともSTLPortの仕様なのですか?

STLPortのソースを追ってみると
STLPortのstringstreamは、内部にstringとは別の小さいバッファを持っていて
何らかの条件でバッファの中身をstringにフラッシュするみたいです。
tellpが返すポインタはその小さいバッファのものである為
いままで書き込んだ文字列を考慮した位置を返してくれる訳ではないみたいです。

388 名前:デフォルトの名無しさん :2005/09/06(火) 04:24:34
>>385
先頭の ':' は明らかに typo だろ。

>これはつまり std::stringstream stream こうしとけばいいってことだな。

その通り。それがデフォルト・パラメータになっている。わざわざ std::ios::inを
外したオープンフラグを指定したものだから、std::ostringstreamと同じに
なってしまった。それだけの話だ。

389 名前:デフォルトの名無しさん :2005/09/06(火) 04:25:26
>>387
反復子(iterator)について勉強し直せ。自然と理解できる。

390 名前:デフォルトの名無しさん :2005/09/06(火) 04:31:15
>>389
basic_ostringstreamはbasic_ostreamの派生クラスですよね?
そのbasic_ostreamのメンバであるtellpが
basic_istreamを派生することによって使えるようになるなんて
なんか解せないんですが、それが正しい動作なんですか?


391 名前:デフォルトの名無しさん :2005/09/06(火) 04:45:19
いろいろ調べてみましたが
basic_ostringstreamがbasic_ostreamのメンバアクセスに制限があるという
資料は見つけられませんでした。
basic_stringのiteratorはランダムアクセスイテレータですから
実装不可能だとも思えません。
やっぱりSTLPortのせいだと思うんですが・・

392 名前:デフォルトの名無しさん :2005/09/06(火) 04:49:59
>>390
それは勘違い。std::basic_ostreamの反復子は出力反復子(ostream iterator)のため、
tellp()、seekp()メンバ関数の意味を正しくインプリメントできないのだ。

同様にして、std::basic_istreamの反復子は入力反復子(input iterator)のため、
tellg()、seekg()メンバ関数の意味を正しくインプリメントできない。

tellp()、tellg()、seekp()、seekg()は、前方反復子(forward iterator)でのみ、正しい
本来の意味のある値を返す。この前方反復子を備えているクラスは、std::basic_fstreamと
std::basic_stringstreamだけだ。

>>371の、random access iteratorというのは間違い。そこまで厳しい要件を必要と
しない。しかし、おっしゃる通り、std::basic_ostreamとstd::basic_istreamを継承した
クラスでないと、tellp()〜seekg()メンバ関数が使えない。従ってstd::vectorのような
ストリームを継承したのではないくコンテナは、それらの特別なメンバ関数がない。

当然std::listのような双方向反復子(bidirectional iterator)を備えたクラスでも、
seek?()、tell?()が使えない。

393 名前:デフォルトの名無しさん :2005/09/06(火) 04:51:38
あーでもこの時間だしな・・・・誰かISO/IEC調べてもらえませんか?俺はもう
寝なければならないので。

394 名前:デフォルトの名無しさん :2005/09/06(火) 06:32:04
>>388
typo だとは思うが、あまりにも脈略が無いんで何を打とうとしたのか想像できない。
std::ostringstream と同じになったと言われても、 std::ostringstream の
tellp() が 0 を返す理由になるとは思わない。
>371,372 が正しければ -1 が返るらしいが、 >368 では 0 が返ると言われている)

>>389
うーん。 iterator はよく知っているつもりだけど、 >371 の意味は理解できない。

>>392
「std::basic_ostream の反復子」の時点で意味不明なわけだが。
std::basic_ostream::iterator のようなメンバは存在しない。

>>393
今までは何を根拠に言ってたんだ?

395 名前:デフォルトの名無しさん :2005/09/06(火) 06:44:05
cygwin g++ 3.4.4 で試してみた。
以下のコードで 'abfgh' が出力された。
やっぱ STLport のバグじゃないの?
>370,373 は、なんで >371 で納得したんだろう?

#include <sstream>
#include <iostream>

int main()
{
  std::stringstream stream( std::ios::out );
  const std::ios::pos_type p0 = stream.tellp();
  stream << "abcde";
  const std::ios::pos_type p1 = stream.tellp();
  stream.seekp( -3, std::ios::cur );
  stream << "fgh" << std::endl;

  std::cout << stream.str() << std::endl;
  return 0;
};

396 名前:デフォルトの名無しさん :2005/09/06(火) 09:04:37
iostreamはアイオーストリーム

じゃあ、curses ってなんて読むの

397 名前:デフォルトの名無しさん :2005/09/06(火) 09:21:54
>>396 辞書で調べれ

398 名前:デフォルトの名無しさん :2005/09/06(火) 10:08:34
397>>
辞書に載ってないから聞いたんだ〜!!
ちなみに、cygwin も皆さんは何て読んでいるのですか?

399 名前:デフォルトの名無しさん :2005/09/06(火) 10:14:30
こっち行ってくれ
http://pc8.2ch.net/test/read.cgi/tech/1056173956/

400 名前:デフォルトの名無しさん :2005/09/06(火) 11:25:26
basic_ostream の tellp の説明を読むと、以下のように書いてある。

> basic_iosのメンバ関数 fail()がtrueを返すと、tellp() は、
> pos_type(off_type(-1))を返して失敗を伝えます。
> それ以外の場合は、rdbuf()-> pubseekoff(0,cur, out)を呼び出して、
> 出力シーケンスのカレントの位置を返します。

よって tellp の実装は、streambuf の実装に依存する。
basic_stringbuf の seekoff の実装は、

> オープンモードがin | outの場合、
> 入力、出力両方のシーケンスのストリーム ポジションを変更します。
> オープン モードがinのときは、入力シーケンスのストリーム ポジションのみ変更し、
> outのときは出力シーケンスのストリーム ポジションのみ変更します。
> 新しいポジションは、off(ずれ)とway(参照ポイント)の2つのパラメタを組み合わせて計算します。
> 位置変更前にシーケンスのカレントの位置が無効の場合、
> オペレーションは失敗し、pos_type(off_type(-1))が返り値になります。
> それ以外の場合は、カレントの新しい位置を返します。

とあるから、>>368 は STLport 側の問題のような気もする。

401 名前:デフォルトの名無しさん :2005/09/06(火) 17:36:30
あるでかいライブラリを二つ使って一つのプログラムを作りたいんですが、
片方で定義しているrealが他のライブラリでも定義されてしまっているらしく、
error: `typedef double real' redeclared as different
というエラーが出ます。片方の名前をreal2とかに変えれば解決しそうなんですが、
もっと良い解決方法があったらおしえてチョ!

402 名前:デフォルトの名無しさん :2005/09/06(火) 17:42:04
namespaceも使ってないライブラリは糞

403 名前:デフォルトの名無しさん :2005/09/06(火) 17:42:21
>>401
namespace A
{
#include <A.h>
}

namespace B
{
#include <B.h>
}

404 名前:デフォルトの名無しさん :2005/09/06(火) 17:54:21
>>403
そうして、Aのtypedef double realを使いたくて
using namespace A;
とやると、B.hのなかの他の定義ファイルは使えなくなってしまうんですよね?
B.hの他の定義は使いたいんだす。

405 名前:デフォルトの名無しさん :2005/09/06(火) 18:05:08
>>404
A::real って書けばいいじゃん。

406 名前:デフォルトの名無しさん :2005/09/06(火) 18:11:33
>>404
君もC++プログラマなら聞き分けたまえ。

407 名前:デフォルトの名無しさん :2005/09/06(火) 18:23:34
がんばって名前変えるかな。。。

408 名前:401 :2005/09/06(火) 18:24:17
サンクス>all

409 名前:デフォルトの名無しさん :2005/09/06(火) 20:25:51
>>400
いやだからさ、俺のVC7.1+STLportでは、0を返さず、ちゃんと正常に-1を
返すわけよ。>>368と結果が違うというのはどういう事なのかと。

410 名前:デフォルトの名無しさん :2005/09/06(火) 20:52:11
>>409
STLportのインストール方法が違うとか。DLLでビルドしたか、
ビルドせずに使っているかで結果が違うとか。

411 名前:デフォルトの名無しさん :2005/09/06(火) 21:07:10
>>410
知らん。俺はビルドして使ってるけど正常動作した。それを言いたいだけ。
ビルドせずに使ってて不具合起きたんなら、同じビルドせずに使ってる奴に聞け。

412 名前:デフォルトの名無しさん :2005/09/07(水) 00:09:34
すみません、行き詰ってしまって質問します。

現在、ビットマップ画像を読み込んで画像処理をした後に保存するプログラムを作成中なのですが、
ビットマップを表示させるところまでは出来たのですが、再描画ができません。

そこで画像処理をした画像をビットマップに保存して、再描画されるようにしたいのですがどうしたらいいでしょうか?
以下にソースを載せます。(環境はVC++6.0です)

413 名前:デフォルトの名無しさん :2005/09/07(水) 00:11:01
まて

414 名前:デフォルトの名無しさん :2005/09/07(水) 00:12:40
ソースはスレに書かないで別のファイルに書いてアップしたほうがいいんじゃないか?
長くなりそうだし…。

415 名前:デフォルトの名無しさん :2005/09/07(水) 00:13:07
//ビットマップの初期化
void CWallChangerDlg::InitializeBitmap()
{
SaveBitmap.DeleteObject();
CRect ClientRect;
GetClientRect(ClientRect);
m_height = ClientRect.bottom-90;
m_width = ClientRect.right-10;

CClientDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
SaveBitmap.CreateCompatibleBitmap(&dc,m_width,m_height);
MemDC.SelectObject(&SaveBitmap);
MemDC.PatBlt(0,0,m_width,m_height,WHITENESS);
}
初期化したSaveBitmapに読み込んで画像処理したものを保存したいのです。
(その後OnPaintで呼び出します。)

416 名前:デフォルトの名無しさん :2005/09/07(水) 00:15:28
待てと言われたのに…

417 名前:デフォルトの名無しさん :2005/09/07(水) 00:16:29
激しくスレ違い

418 名前:デフォルトの名無しさん :2005/09/07(水) 00:19:22
>>413、414、416
申し訳ない。書き込んでから気づきました。

あと補足。
ダイアログベースで、読み込んだ画像がダイアログ中央に出てきます。
それをSetPixel等を使って2値化 ・・・までは出来ました。
でも再描画されない・・・orz

419 名前:デフォルトの名無しさん :2005/09/07(水) 00:20:35
>>418
イヤマテ勘違いしてる、ソースを貼るのがどうこうじゃなくて、>>417

420 名前:デフォルトの名無しさん :2005/09/07(水) 00:22:40
>>417,419
スレ違いだったのですか・・・。板で質問するの初めてだったのでわからず、スミマセン。


421 名前:デフォルトの名無しさん :2005/09/07(水) 00:24:07
どうやら2chも初めてらしい

422 名前:デフォルトの名無しさん :2005/09/07(水) 01:27:18
C++でWindows上で動くファイアウォールは作れますか?

423 名前:デフォルトの名無しさん :2005/09/07(水) 01:29:30
坊や…良い子だから早く寝な

424 名前:デフォルトの名無しさん :2005/09/07(水) 06:33:09
C++で童貞捨てられますか?

425 名前:デフォルトの名無しさん :2005/09/07(水) 06:56:40
>>424
順番が逆だ。まず童貞を捨ててからC++をやれ。そうすれば立派に禿げる。

426 名前:デフォルトの名無しさん :2005/09/07(水) 08:36:12
>>409,411
名無しで「俺」とか言われても誰だかわからん。
tellp() が -1 を返すのが正しいと言う根拠は何?

427 名前:デフォルトの名無しさん :2005/09/07(水) 10:58:20
it++
http://itpp.sourceforge.net/latest/
をMKLなしで使う方法ないでしょうか?

428 名前:427 :2005/09/07(水) 10:59:24
バージョン3-8-1をwindowsから使いたいのです


429 名前:デフォルトの名無しさん :2005/09/07(水) 21:00:17
インスタンシエートされたオブジェクトの、静的でないメンバ関数ポインタの呼び出しは
出来るのでしょうか?


430 名前:デフォルトの名無しさん :2005/09/07(水) 21:13:18
>>429
分かりにくい表現をしてるが、ごく普通のメンバ関数ポインタのことか
呼べなかったら意味ないね

431 名前:429 :2005/09/07(水) 21:23:48
ごめんなさい。
やりたいことは、クラスのメンバ関数ポインタに、生成されたオブジェクトのメンバ関数を入れたい。

class A;

class B {
public:
void (A::*func)();
};

class A {
public:
void print() {
printf("hoge\n");
}
};

int main() {
A a;
B b;
b.func = a.print;
(b.*func)();
return 0;
}




432 名前:デフォルトの名無しさん :2005/09/07(水) 21:27:34
>>431
C#でいうトコの delegate でそ?
それはただのメンバ関数ポインタでは無理。
boost::function 使えば出来ると思う。

まぁ単に A* と A:*func のペアを保持しといて p->(*func) とするのが、
(格好は良くないが)シンプルだと思うけど。

433 名前:デフォルトの名無しさん :2005/09/07(水) 21:36:56
>>432
× p->(*func)
○ (p->*func)

434 名前:デフォルトの名無しさん :2005/09/07(水) 21:56:50
boost::functionとかを使うとこうなる。
#include <cstdio>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using std::printf;

class A;

class B {
public:
    boost::function<void ()> func;
};

class A {
public:
    void print() {
        printf("hoge\n");
    }
};

int main() {
    A a;
    B b;
    b.func = boost::bind(&A::print, a);
    b.func();
    return 0;
}

435 名前:429 :2005/09/07(水) 22:13:36
>>432~434
ありがとう。なんとか動きました。
うーん、回りくどいことになっているのは、私の設計に問題があるらしいですね。もう一度見直してみます。

436 名前:デフォルトの名無しさん :2005/09/08(木) 11:24:30
>>435
単なる予想として、インタフェースを導入してBはそれを持つのがいいような。

class Func {
public:
 virtual void exec() = 0;
};

class A : public Func {
public:
 virtual void exec() { … }
};

437 名前:デフォルトの名無しさん :2005/09/08(木) 11:53:53

unsigned long field[4];
という、128ビット長の整数配列 field をもとに、
std::bitset<128> を構築する場合、どのようにするのが良策でしょうか?
今のところ、以下のように構築してますが、ほかにいい方法はありませんか?

bitset<128> y =
 ( bitset<128>(field[3]) << 96 ) |
 ( bitset<128>(field[2]) << 64 ) |
 ( bitset<128>(field[1]) << 32 ) |
 ( bitset<128>(field[0]) );


438 名前:デフォルトの名無しさん :2005/09/08(木) 16:24:37
>>437
考えたけど、あまり良い方法が思い浮かばん

#include <bitset>
#include <string>
#include <limits>

template<typename T>
std::string binary(T t)
{
    std::bitset<std::numeric_limits<unsigned char>::digits*sizeof(T)> b(t);
    return b.template to_string<char, std::char_traits<char>, std::allocator<char> >();
}

int main()
{

    unsigned long field[4] = { 1, 1, 1, 1 };


    std::bitset<128> y( binary(field[3]) +
                    binary(field[2]) +
                    binary(field[1]) +
                    binary(field[0]) );


    std::cout << y << std::endl;

}

439 名前:デフォルトの名無しさん :2005/09/08(木) 18:24:57
初心者です。VirtualAllocを使用し、構造体にメモリを割り当てようをしています。割り当ての成功or失敗は戻り値がNULLかどうかで判定できますが、何バイト割り当てられているのか@で知る方法がわかりません。
下記@の(int)sizeof(*pBmp)では、構造体のバイト数40が返ってくるので実際にアロックされたバイト数がしりたいのですが…。
/* 定数・変数定義 */
#define MAP_MAXSIZE (50L*1024L*1024L)
/BITMAPINFOHEADER *pBmp;
map *pMap;
// メモリ獲得処理
if ((pBmp = (BITMAPINFOHEADER*)VirtualAlloc(NULL, MAP_MAXSIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) {
return (-1);
} else {/* ----- @ここで割り当てられたバイト数を知りたい ----- */
sprintf(logMsg, "メモリリソース獲得後: pointer = BITMAPINFOHEADER %x / size = %d", pBmp, (int)sizeof(*pBmp));
pMap = (map *)pBmp;
}
/* 構造体定義 */
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tag_map {
BITMAPINFOHEADER biInfo;// Bitmap Info Header
BYTE bData[1];// 実際には約10MB分
} map;


440 名前:デフォルトの名無しさん :2005/09/08(木) 18:27:13
失礼しました。Aの個所を訂正です。
/* 定数・変数定義 */
#define MAP_MAXSIZE (50L*1024L*1024L)
BITMAPINFOHEADER *pBmp;// ←頭のスラッシュが余分でした。A
map *pMap;
// メモリ獲得処理
if ((pBmp = (BITMAPINFOHEADER*)VirtualAlloc(NULL, MAP_MAXSIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) {
return (-1);
} else {/* ----- @ここで割り当てられたバイト数を知りたい ----- */
sprintf(logMsg, "メモリリソース獲得後: pointer = BITMAPINFOHEADER %x / size = %d", pBmp, (int)sizeof(*pBmp));
pMap = (map *)pBmp;
}
/* 構造体定義 */
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tag_map {
BITMAPINFOHEADER biInfo;// Bitmap Info Header
BYTE bData[1];// 実際には約10MB分
} map;

441 名前:デフォルトの名無しさん :2005/09/08(木) 18:40:06
スレ違い。

442 名前:デフォルトの名無しさん :2005/09/08(木) 18:44:02
>>437
こんなんどうよ

template <int N>
std::bitset<32*N> make_bitset(unsigned long const(&ar)[N])
{
    std::bitset<32*N> result;
    for (int i = 0; i < N; i++)
        (result <<= 32) |= ar[i];
    return result;
}

int main()
{
    unsigned long field[4] = { 1, 3, 7, 15 };

    std::bitset<128> y( make_bitset(field) );
}

443 名前:デフォルトの名無しさん :2005/09/08(木) 19:17:17
437,438,442の中だと442が速いね


444 名前:デフォルトの名無しさん :2005/09/08(木) 19:26:56
>>438
>>442
ありがとうございます。
とりあえず、以下のようにしました。

// VC++7.1 のエラー回避用
template< typename T > struct bsizeof
{
 static size_t const value = sizeof(T) * CHAR_BIT;
};

// inline bitset< sizeof(T) * CHAR_BIT * N > bitset_from_vector( ... )
// と記述するとエラーする。どうして?
template< typename T, size_t N >
inline bitset< bsizeof<T>::value * N > bitset_from_vector( T (&x)[N] )
{
 typedef bitset< bsizeof<T>::value * N > bset_t;

 bset_t b;
 size_t i = N;
 while( i != 0 )
  ( b << bsizeof<T>::value ) |= bset_t( x[--i] );
 return b;
}

いつもオーダーで混乱するので間違ってたら指摘してください。

445 名前:デフォルトの名無しさん :2005/09/08(木) 19:55:50
>>444
まあ typo だとは思うが
× ( b << bsizeof<T>::value )
○ ( b <<= bsizeof<T>::value )

446 名前:デフォルトの名無しさん :2005/09/08(木) 20:09:06
>>439
VirtualQueryでは駄目だった。
VirtualFreeでもサイズは自分で入れなきゃいけないし
システムではサイズの把握までやってないんじゃないの?
だから自分で算出でいいと思うけど。
ページサイズで切り上げ( ページサイズで切り捨て( 開始アドレス ) + サイズ )

447 名前:デフォルトの名無しさん :2005/09/08(木) 22:49:11
質問なのですが、クラス1で、map<string, string> sample を宣言して、 クラス2で、map<string, string>* sampleと
宣言した時、クラス1のsampleのアドレスを、クラス2のsampleに代入して、クラス2で string a = *sample[abc] とするのは
可能でしょうか?  

448 名前:デフォルトの名無しさん :2005/09/08(木) 22:51:36
>>447
可能です


449 名前:デフォルトの名無しさん :2005/09/08(木) 23:04:50
>>447
(*sample)[abc]だな。

450 名前:デフォルトの名無しさん :2005/09/08(木) 23:07:31
>>448
ありがとうございます。
しかし、何度やっても”型変換が間違っています”というメッセージがでてうまくいきません。
mapをポインタとして持つこと自体が間違っているのでしょうか?
それとも、クラス2で、string a = *sample[abc] という書き方が間違っているのでしょうか?



451 名前:デフォルトの名無しさん :2005/09/08(木) 23:11:58
>>450 >>449

452 名前:デフォルトの名無しさん :2005/09/08(木) 23:24:48
>>448 >>449 >>451
みなさんありがとうございました。
ご指摘どおり型変換に問題があったのですね。
早速明日再度試してみたいと思います。
本当にありがとうございます。

453 名前:デフォルトの名無しさん :2005/09/08(木) 23:31:36
型変換じゃなくて演算子の優先順位の問題だろ。

454 名前:デフォルトの名無しさん :2005/09/09(金) 00:19:45
>>440
それってべたcデハ?

455 名前:デフォルトの名無しさん :2005/09/09(金) 01:27:29
累乗を一行で演算子で表せれますか?
10^xを計算したいんだけど

456 名前:デフォルトの名無しさん :2005/09/09(金) 01:28:19
>>455
累乗演算子はC++にはないよ。
代わりにpow関数を使う

457 名前:435 :2005/09/09(金) 01:35:48
>>436
うおーサンクス!

458 名前:デフォルトの名無しさん :2005/09/10(土) 09:03:58
クラスの継承時における、アクセス演算子についてなんですが
例えばある基底クラス内でprotectedなメンバ変数を宣言して、そのクラスを継承した場合
このprotectedなメンバ変数は、派生クラスのメンバ変数としてpublic指定をしたとほぼ同意になりますか?
それとも、privateで宣言したようなものですか?
手持ちの入門書だと継承先で使用できるとしか書いてなくて迷っています。

459 名前:デフォルトの名無しさん :2005/09/10(土) 09:19:57
>>458
試せよ。人に聞くよりそのほうが覚える。

460 名前:デフォルトの名無しさん :2005/09/10(土) 09:23:16
>>458
そのとおり継承先のクラスからでしか使えないから。前者の意味はpublicで十分だろ。
class B
{
public:
  B(int n) : hoge(n) {} //OK
  int get() const {return hoge;}
protected:
  int hoge;
};

class D : public B
{
public:
  void set(int n) {hoge = n;} //OK
};

int main()
{
  D obj(5);
  std::cout << obj.hoge << std::endl; //エラー 
  std::cout << obj.get() << std::endl; //OK 
}

461 名前:デフォルトの名無しさん :2005/09/10(土) 09:25:24
>>458
元々protectedだったメンバは絶対にpublic扱いにならないし、元々privateだったメンバは絶対にprotected扱いやpublic扱いにならない。
「: protected」をしたら継承されたメンバは絶対にpublic扱いにならないし、「: private」をしたら継承されたメンバは絶対にprotectedやpublicにならない。

462 名前:デフォルトの名無しさん :2005/09/10(土) 09:56:44
あっという間に試せることなのに、なんでいちいち質問するんだろうね。
手を動かさないからいつまで経っても成長できないんだよ。

463 名前:デフォルトの名無しさん :2005/09/10(土) 10:06:00
お前らが>>458のしもべなだけ

464 名前:デフォルトの名無しさん :2005/09/10(土) 10:07:53
試してもコンパイラが間違ってるかも知れないって事だろ?

465 名前:デフォルトの名無しさん :2005/09/10(土) 10:24:18
>>461
using

466 名前:461 :2005/09/10(土) 11:18:05
>>465
あぁ、そうか。461の言い方はマズかったな。

467 名前:デフォルトの名無しさん :2005/09/10(土) 15:12:39
char型のポインタをcout文で使うと
文字配列のアドレスじゃなくて文字列を表示するのはなぜなんですか?

468 名前:デフォルトの名無しさん :2005/09/10(土) 15:15:09
>>467
そういうオーバーロードが用意されているから、としか答えようがない。

アドレス値を表示させたければキャストすればいい。
char *p = 〜;
std::cout << static_cast<void *>(p) << std::endl;

469 名前:デフォルトの名無しさん :2005/09/10(土) 15:15:18
そういう仕様だからです

470 名前:デフォルトの名無しさん :2005/09/10(土) 15:20:47
仕様ですかぁー
なるほど

471 名前:デフォルトの名無しさん :2005/09/10(土) 15:28:41
そうしないと文字列を文字列として<<で出力できなくなる。

472 名前:デフォルトの名無しさん :2005/09/10(土) 16:54:58
>>471
馬鹿を晒さなくていいから。

473 名前:名無しさん@そうだ選挙に行こう :2005/09/10(土) 17:18:20
472の馬鹿が逆に晒されてしまいました。

474 名前:名無しさん@そうだ選挙に行こう :2005/09/10(土) 18:31:25
>>466
どうマズいのか教えてくださいー

475 名前:名無しさん@そうだ選挙に行こう :2005/09/10(土) 18:44:24
>>474
アクセス権限なんてusingで自由自在

476 名前:名無しさん@そうだ選挙に行こう :2005/09/10(土) 18:48:38
>>475
いや、usingでは隠すほうに持っていけない。

477 名前:名無しさん@そうだ選挙に行こう :2005/09/10(土) 18:59:37
>>475
あ、どうも。usingってnamespaceの省略以外にも使い道があるんですねぇ。

478 名前:名無しさん@そうだ選挙に行こう :2005/09/11(日) 07:39:56
そこで無名名前空間ですよ

479 名前:デフォルトの名無しさん :2005/09/11(日) 09:08:09
>>478
いや、namespaceの話じゃないから

480 名前:デフォルトの名無しさん :2005/09/12(月) 14:53:28
boostをインテルコンパイラで使用するためにインストールしました。
疑問があるのですが、ここで質問してもいいですか?

481 名前:デフォルトの名無しさん :2005/09/12(月) 14:57:40
>>480
質問していいか質問するなんて行為は辞めれ
いきなり本題でok

482 名前:デフォルトの名無しさん :2005/09/12(月) 14:58:16
BOOSTを語れゴラァ
http://pc8.2ch.net/test/read.cgi/tech/1091198276/l50


483 名前:デフォルトの名無しさん :2005/09/12(月) 15:45:53
ファイルにクラスの状態を保存する為、そのクラス用にoperator<< 関数を作りたいと思います。
しかし同時に、デバック表示用に人が読める形で出力するoperator<<関数も欲しいんですが
どう作り分ければ良いですか?

std::ostream& operator<< ( std::ostream& stream, const ClassA& a ) const;
これでは被ってしまいます。

484 名前:デフォルトの名無しさん :2005/09/12(月) 15:48:54
>>483
マクロで置き換え

485 名前:デフォルトの名無しさん :2005/09/12(月) 15:59:55
インストールに関する質問で恐縮ですが、こちらで質問します。
Visual Studio .NET 2005 + intel C++ compiler ver.9 の環境に下記の様にビルドしました。
bjam -sTOOLS=intel-win32 "--prefix=C:\Program Files\Intel\Compiler\C++\9.0\IA32" "-sINTEL_PATH=C:\Program Files\Intel\Compiler\C++\9.0\IA32" "-sINTEL_BASE_MSVC_TOOLSET=vc-7_1" install
インテルコンパイラ用にビルドしたつもりですが、
vc-C++ bin\boost\libs\wave\build\libboost_wave.lib\intel-win32\release\threading-multi\cpp_re.obj cpp_re.cpp
とvc-C++でコンパイルしていきました。これでよいのでしょうか?
ここでビルドしたライブラリをiclで使用する予定です。


486 名前:デフォルトの名無しさん :2005/09/12(月) 16:10:01
>>483
マニピュレータ

487 名前:デフォルトの名無しさん :2005/09/12(月) 17:00:13
一時オブジェクトの const 参照による束縛の話なんですが、
ちと理解できたか自信ないので質問です。
こんなクラスと関数があったとして…

 struct A {};
 struct X {
  const A* p;
  X(const A& a) : p(&a) {}
 };
 X xget(const A& a) { return X(a); }
 void xtest(const X& x) {
  // ここで *(x.p) を使うとします
 }

以下のようになるという理解であってますか?

これはok
 xtest(xget(A()));
これもok
 const A& a = A(); xtest(xget(a));
これもok
 const A& a = A(); const X& x = xget(a); xtest(x);
これはダメ!
 const X& x = xget(A()); xtest(x);

488 名前:デフォルトの名無しさん :2005/09/13(火) 01:27:54
>>487
挙げている例はあってるけど、「ダメ」の理由を自分で説明できないと、
ちゃんと理解したかどうかは判別できないだろう。

489 名前:デフォルトの名無しさん :2005/09/13(火) 02:10:57
>>487
ややこしいかもしれないが、一番下のはダメともいいきれない。

490 名前:489 :2005/09/13(火) 02:12:32
すまん、よく読んでなかった。忘れてくれ。

491 名前:デフォルトの名無しさん :2005/09/13(火) 02:32:15
>>487をみて思ったんだけど

A* p = &A();

これって、pの参照先はこのスコープが閉じるまで保持されるの?

492 名前:デフォルトの名無しさん :2005/09/13(火) 04:38:33
const A& a = A();

これはダメじゃね?
すぐにデストラクトされるような気が

493 名前:デフォルトの名無しさん :2005/09/13(火) 05:43:23
>>492
それがconst参照の束縛かと

494 名前:デフォルトの名無しさん :2005/09/13(火) 12:51:27
>>491 されない。
>>492 されない。

495 名前:デフォルトの名無しさん :2005/09/13(火) 13:39:25
constわけわかめ

496 名前:デフォルトの名無しさん :2005/09/13(火) 17:05:34
そもそもconst T&をT同然に使える(右辺値で初期化できる)ようにというところからこうなったわけで。

497 名前:デフォルトの名無しさん :2005/09/13(火) 17:35:34
RVOって関係ある?



498 名前:デフォルトの名無しさん :2005/09/13(火) 18:05:19
結果には関係無いんじゃない?

499 名前:デフォルトの名無しさん :2005/09/13(火) 19:21:00
お忙しいところすみませんが教えてください

char s1[80], s2[80];
cout << "Enter two strings : ";
gets( s1 );
gets( s2 );
strcat( s1, s2 );
cout << s1 << "\n";

で、一回目の gets( s1 );
でなぜか入力の状態にならず
勝手に NULL が入ってしまいます。
cin だと問題ないのですが
違いは何なのでしょうか?

500 名前:デフォルトの名無しさん :2005/09/13(火) 20:55:27
>>499
・gets()は過去との互換性が必要な場合を除いて使うべきではない。
・NULLは入るはずがない。NULキャラなら勿論入るが。
>>499に書かれたロジック以前に入力は行なっていないか? その場合空読みするべき。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.