【初心者歓迎】C/C++室 Ver.43【環境依存OK】
1 :
デフォルトの名無しさん :
2007/09/27(木) 11:39:04
2 :
デフォルトの名無しさん :2007/09/27(木) 12:05:39
_,rr-―''''¨゙゙゙ ̄ ̄ ̄ ̄ ̄`゙゙゙゙゙゙゙゙''ヘi、、 ,,,,-―---、 ,r‐'″ ._,,,, `'lri,!'''″ ゙l .,,,″ ,,r'"` ゙゙l, ゙ヘ, | !アr, .l°.ェ'ニ,コ .| ゚ヘ、 | `'i、 .く_,、vr''″ ., ゙'i、 .,,/ ゙X、 ト ゙!,゛ .,,r‐--、 ,、_,、 .,,,,r‐'″ | } .,,r‐'^’ .|゜ め゙゚“゙゙~゛ |  ̄` .,l゙ | ,i´ ,l゙ ゙!、 ,i´ ,ノ .'┐ ,,-° '=,, /` .゚!, ,,,,r'″ ゙┐ ,l゙ ゚'r, .''''"` │ .,,-''i、 / `''x, .| | .,,r'" .゙┐ ,i´ ~'ヘi,,, | |_,r・″ 'ヘ,、 l゙ `¬--|i,,,,,,,,,,,,,,,,v、r',广 ゙ヘ〟 ,l゙ `゙'ーぃ--r'″ `'―、,,,,/
3 :
デフォルトの名無しさん :2007/09/27(木) 13:00:37
前スレ
>>999 'CFuncHolder::SetFunc' : 1 番目の引数を 'boost::_bi::bind_t<R,F,L>' から 'void (__cdecl *)(char *)' に変換できません。
って怒られました。
4 :
他板37 :2007/09/27(木) 13:03:35
>>前007 とりあえずこんな感じにすると動いた #include <boost/function.hpp> #include <boost/bind.hpp> #include <windows.h> void g_func(const char* str) { MessageBoxA(NULL, str, "", NULL); } class Cfunc { public: void func(const char* str) { MessageBoxA(NULL, str, "", NULL); } void (Cfunc::* GetFuncPtr()) (const char*) { return &Cfunc::func; } }; class CHolder { public: template <typename T> void set(const T& f) { func = f; } boost::function<void(const char*)> func; }; int main() { CHolder hold; Cfunc cf; hold.set( boost::bind(&Cfunc::func, &cf, _1) ); hold.func("text"); }
6 :
5 :2007/09/27(木) 13:15:03
007→997 typo typo
7 :
デフォルトの名無しさん :2007/09/27(木) 13:20:30
セットするところを↓にしたら
>>998 でいけたよ!
void SetFunc(boost::function1<void, char*> func){m_func = func;}
unsigned longの値を入れる配列無いでしょうか? CStringListみたいなやつで
std::vector<unsigned long>
好きなコンテナに入れな
ところで↓って何やってるのか意味が分からないんだが、 誰か噛み砕いて教えてくれないだろうか。 boost::bind(&Cfunc::func, &cf, _1)
boost::bind(&Cfunc::func, &cf, _1)(hogr)⇔cf.func(hoge)
14 :
デフォルトの名無しさん :2007/09/27(木) 17:29:12
boost::functionはグローバル関数へのポインタや関数オブジェクトなどを統一的に保持できるってのは分かった。
で、boost::bindはなにやら拘束とかいうのをして2引数の関数を1引数の関数として扱える?のだとかなんとか・・・
>>5 でいうところの、
普通のグローバル関数g_funcへのポインタというかアドレスはg_funcで、
メンバ関数CFunc::funcのアドレスは&Cfunc::func?
でもそれだけだとどのインスタンスのfuncかわからんから、
Cfunc cfっていうインスタンスの情報もどうにか渡す必要があるってのはわかる。
が、それらを拘束するっていうのの意味が分からない。拘束ってなんですか?
リファレンスの日本語訳読んでも全然分からない・・・
ポインタうんぬん、インスタンスうんぬんという実装よりも、 まず概念を理解せんことにはな。 Haskellあたりで勉強してきたら?
>>14 STL の bind1st と bind2nd を調べてくればわかるんじゃない
17 :
デフォルトの名無しさん :2007/09/27(木) 18:11:30
例えば↓みたいな場合、gfunc2のiかjを なにかしら定数として固定して、引数が1変数の関数としてCFuncHolderのm_funcにしまえる? ってことですか? class CFuncHolder{ private: boost::function1<void, int> m_func; public: CFuncHolder(){}; void SetFunc(boost::function1<void, int> func){m_func = func;} void RunFunc(int i){m_func(i);} }; void gfunc1(int i){ printf("%d\n",i); } void gfunc2(int i, int j){ printf("%d\n", i+j); } void main(){ CFuncHolder fh; fh.SetFunc(gfunc); fh.RunFunc(1); }
>>14 拘束じゃなくて束縛だと思うが
関数型言語の束縛とも意味が違うので紛らわしい
どっちかっつーと「部分適用」だわな
19 :
17 :2007/09/27(木) 18:57:49
bindの最初の引数がメンバ関数へのポインタのとき、第二引数はインスタンスのアドレスを渡すのが そういう場合の決まった書き方ってことでとりあえず解決した。
_beginthread() でスレッドを生成し、そのスレッドが無限ループしている場合、 プログラム終了時にそのスレッドも終了してくれるのでしょうか?
はい
Σ(・ω・ノ)ノエッ
終了しなかったら欠陥OSだろw
main() { char *buf = new char[1024]; } 上のコードでbufはプログラム終了時に解放されますってのと同レベルだな
んー・・・「終了される」と言われると違和感あるなぁ。 「破壊される」? まぁ言葉遊びか
よくclassではなくstructで表現されたものを見ますが 何か違いがあるのでしょうか? メリット、デメリットを教えてください
( ゚д゚)ポカーン
classはデフォルトでprivate structはデフォルトでpublic class A : X { // <-- private 継承 int x; // <-- private メンバ }; struct B : Y { // <-- public 継承 int x; // <-- public メンバ }; それだけ
>>26 C++においては特に無いんじゃね?
メンバ関数を持たずある用途のためにまとめた”変数のセット”
って言う意味を強調したいときに
俺はあえてstructを使うけど。
>>11 >>19 boost::bind(&Cfunc::func, &cf, _1)は、
boost::bind(boost::mem_fn(&Cfunc::func), &cf, _1)相当。
mf = boost::mem_fn(&Cfunc::func)とすると、
mf(a, b)は、a.func(b)と同じ。
つまり、mem_fnはメンバ関数を通常の関数呼出の構文で
呼び出せるようにするアダプタと言える。
>>12 へ続く。
std::string str switch( str ) { case "あいうえお" funcA(); break; case "かきこくけこ" funcB(); break; (同様に続く・・・) } のように処理させたいけど文字列な為に出来ません この様な場合どういうやり方が一般的ですか? if文でゴリゴリ書くしかない?
一般的じゃないかもしれないけどこういう手が楽っぽい #include <map> #include <string> #include <iostream> void funcA() { std::cout << "invoke func A\n" ; } void funcB() { std::cout << "invoke func B\n" ; } int main(void) { std::map< std::string, void(*)(void) > funcs ; funcs[ "あいうえお" ] = funcA ; funcs[ "かきこくけこ" ] = funcB ; std::string str = "あいうえお" ; void(*f)(void) = 0; f = funcs[str]; if ( !f ) // default: の処理 else f(); return 0; } 要は条件をキー、呼び出す関数を値にするmapだな 値をboost::functionへの参照とかにしてやれば、動的なオブジェクトのメソッドを呼び出すことも可能
35 :
デフォルトの名無しさん :2007/09/28(金) 16:53:01
C++初学者です。 std::fstream等を使い、テキストファイルの中身をstd::stringのオブジェクトに格納したいと思います。 テキストファイルtext.txtはShift_JISで書かれ、空白や改行、マルチバイトの文字を含みます。サイズは不明です。 この改行などは、可能な限り保持するとします。 自分は、以下のようなコードを記述しました。 std::string str; std::ifstream ifs; ifs.open("text.txt",std::ios::in); if(!ifs.is_open()) return; //オープン失敗 while(!ifs.eof()) { std::string line; std::getline(ifs,line); str += line + "\n"; } 1.getlineや>>を使って、少しずつ読み込むという方法で良いのか分かりません。一括読み込みの方法はあるのでしょうか。 2.getlineを使う場合、一時的にlineを用意し、それからstrに格納する方法を採っています。何となく冗長な気もしますが、こんなもんなのでしょうか。 3.最後に改行コードを付加する時、+"\n" という書き方をしていますが、std::endlを使う方法、もしくはそれに似たような方法はあるのでしょうか。
ファイルの中身を全部読み取りたかったら、istreambuf_iterator使えばいい。 typedef std::istreambuf_iterator<char> isb_it; str.assign(isb_it(ifs), isb_it());
C++ってキモk
>>35 > 2.
大体皆そういうコードを書く
> 3.
stringstreamを使えばよい
39 :
デフォルトの名無しさん :2007/09/28(金) 17:27:12
プログラムからMSXMLを使用してローカル(C:\.....\foo.xml)のXMLファイルを読み込みたいのですが
どうもload関数で失敗してしまいます。
#import "msxml.dll" named_guids raw_interfaces_only
using namespace MSXML;
MSXML::IXMLDOMDocumentPtr pDoc;
HRESULT hr = pDoc.CreateInstance(MSXML::CLSID_DOMDocument);
pDoc->put_async(VARIANT_FALSE);
VARIANT_BOOL f;
hr = pDoc->load(_variant_t(L"C:\\Documents and Settings\\.........\\foo.xml"), &f);
このXMLファイルのパスに実際Web上に存在するファイルを指定したらloadは正常にXMLを取得出来ました。(
http://....../foo.xml )
ローカルにあるXMLファイルを読み込むには何か特殊な事をしなければいけないのでしょうか?
環境はWinXPでVisual Studio 2005 Pro Editionです。
40 :
35 :2007/09/28(金) 17:32:10
>36>38 ありがとうございます、助かりました
>>35 2.についてだが、普通はこう書く。
std::string line;
while (std::getline(ifs, line)) {
:
}
しかし、
>>35 のコードでは結局行読みすることに何の意味もないコードに
なっている。
そもそもそういう場合はstd::getline()を使うべきではないだろう。
>>39 load()でローカルファイルを普通によめたと思うが。
MSXMLのバージョンにもよるのかも知れんが。
それとそのパスはなにやら胡散臭いな。
argvでも渡して、カレントのパスや相対パス、絶対パス、漢字を含むもの
含まないもの、色々実験汁。
43 :
デフォルトの名無しさん :2007/09/28(金) 18:09:05
マジWindowsアプリとか詳しい奴尊敬するぜ あんな分かりにくいもん C++の難しさよりも ライブラリ覚えるだけで大変そう
44 :
デフォルトの名無しさん :2007/09/28(金) 18:13:44
>>42 "C:\\foo.xml"で試してみましたが無理でした。
SetCurrentDirectory()でxmlのあるディレクトリに移動して相対パスでの指定も試してみました。
バージョンによる違いも一応調べてみます。
>>43 あんなに膨大にあるAPIを全部暗記してる奴はいないだろう
関数の名前覚えてたって、引数の並び順だの何だの覚えきれねえよ
それに良く使いまわす処理は俺ライブラリ化するなりコピペするなり
いちいち一から書かんだろ
file:// とかは?
>>43 今はほとんどどの世界に行っても、言語仕様よりライブラリ覚える方が大変だよ
48 :
デフォルトの名無しさん :2007/09/28(金) 18:25:17
>>46 file://の書き方は
file:///C:/foo.xmlであってるでしょうか?あまり詳しくないもので・・・。
フォルダのアドレスバーにfile://と入力して出てきたやつをそのまま使ってみました。
でも、やはりロードで失敗してしまいます。xmlファイル自体に問題があるか、MSXMLのバージョンの問題なのか・・・
>>48 ファイルに問題があるかどうか切り分けたければ、URL越しでロードできた
ファイルをローカルに落として試せばいいだろ。
50 :
デフォルトの名無しさん :2007/09/28(金) 18:33:30
>>49 Webからxmlファイル落としてローカルで試したところloadすることが出来ました。
どうやら自分のxmlファイルに問題があったようです。
xmlファイルの中身を見比べてみて原因を探ってみます。
51 :
デフォルトの名無しさん :2007/09/28(金) 18:33:49
>>47 オープン系はそうですね
組み込みはそうでもなくて、純粋にC++に集中できそう
IXMLDOMDocument::loadは、IStreamなんぞも受け付けるらしいから、 SHCreateStreamOnFileでも使ってストリーム化したらどうだろう?
53 :
デフォルトの名無しさん :2007/09/28(金) 18:35:42
どうやら文字コードが原因だったみたいです。 自作のxmlはShift_JISで、正常に読み込める方のxmlはUTF-8で保存されたものでした。 なんでShift_JISでダメなのかはよく分かりませんが、とりあえずUTF-8で書くことでやっていきたいと思います。 ありがとうございました。
XML宣言でエンコーディングを指定すれば、 Shift_JISは受け付けてくれると思う、MSXMLなら。
>>53 既にC/C++の話題でも何でもないが
XMLファイルで↓のようにちゃんとエンコーディングは指定してるか?
<?xml version="1.0" encoding="Shift_JIS"?>
環境依存とかマジわかんねえ XMLなんて言葉しか知らん
>>53 HRESULTの判定をしてないのがいかんのだな。
その辺が出来ないなら raw_interfaces_onlyは使うなよ。
58 :
デフォルトの名無しさん :2007/09/28(金) 19:17:04
>>54-55 対象のXMLファイルにはちゃんと
<?xml version="1.0" encoding="Shitf_JIS" ?>
と先頭に記述はしていました。ますます分からないですけど、
もしかしたら俺の環境がどこか特殊なのかもしれないので(または全然関係ないところのエラー)、
あまり悩まれない方がいいかもしれませんw
>>58 MSXMLがちゃんとエラーメッセージが返してるからそれみりゃわかるって。
エラーメッセージの取り出し方わかってる?
爆弾クラスのデストラクタに壁を壊す処理を入れてるんですが こういう使い方は良くないと聞きました どうしてですか? だとしたら自分を壊して壁を壊すような処理はどこに書けばいいんですか? よくわからなくなったので教えて下さい
いやいやいや ゲームのアイテムの話ですよ?
>>62 理由:クラスの柔軟性が損なわれる
「インスタンスの破壊時に必ず呼ばれる」
→爆発させずに爆弾を消去するときも破壊判定させる気?
「デストラクタは引数とれない」
→わざわざ破壊対象の壁の情報を他のクラスに問い合わせるわけ?
それなら自分が爆発(explodeメソッド)するって情報だけ他のクラスに送って
それ以外の処理は他に任せるようにした方が責任の所在が明確になって
まだ良い設計になると思わない?
俺が思いつくのはとりあえずこんな所
66 :
682 :2007/09/29(土) 00:47:46
001.ppm 002.ppm ・ ・ xyz.ppm という内容のファイルリストからgetlineで画像名を読み込み、 それぞれの画像のカラーヒストグラムを書き出していくという プログラムを作成しています。 一度に処理する画像枚数が約200枚までならば正常に動作するのですが、 一度に処理する画像が300枚前後になると、OSが急に固まりコンソールに 強制終了と表示されて、プログラムが終了してしまいます。 以下、メインのソースの一部 ifstream filelist While(!filelist.getline(filename, sizeof(filename)).eof()) { Image24 test_image; ここらへんで様々な処理 } この例の場合、ループでtest_imageが宣言される度に デストラクタは呼び出されるのでしょうか?(デストラクタでメモリを解放する処理は書いてます) 長文ですがよろしくお願いします。
>>66 デストラクタは呼ばれます。
実験してみりゃ一発なのに・・・
>>66 とりあえずアップしてるソースの範囲は問題なし。
デストラクタの開放処理に漏れや誤りがあるか、
「ここらへんで様々な処理」 に問題があると思う。
LoadImageしてDeleteObjectしてないとか、LD_SHAREDしてるとか。
69 :
66 :2007/09/29(土) 01:54:27
>>67 ,
>>68 ありがとうございます。
メモリ周りの処理をもう一度徹底的に見直してみます。
int型を文字列の型に変換する関数ってありますか?
Cならsprintf, snprintf C++なら(関数ではないが)std::ostringstream. boost::lexical_cast
ありがとうございます
class string_ex : public std::string { funcA(); funcB(); } のようにstd::stringを拡張してstd::stringの機能をそのままに 文字列操作を行う関数を新たに追加したクラスを作りました string_ex ex; std::string str; ex = str; という操作を期待したのですがコンパイルエラーが出てしまいます 何か良い方法はありませんか?
代入演算がないだけでは?
確かstd::stringは継承される事を前提に作られてないはず やめといた方がいいんじゃね デストラクタも仮想じゃないし
>>74-75 ありがとうございます
そうですか、スッキリして良いと思ったのですが残念です
コンストラクタがないからstd::stringからstring_exに変換できない。
ただし、
>>75 の指摘通り使用に際しては注意が必要。
コピー代入演算子とコピーコンストラクタが無いのが原因だな #include <string> struct A : public std::string { A(){} A(const A&){} A& operator=(const A&) { return *this; } A& operator=(const std::string&) { return *this; } }; int main() { A a; std::string b; a = b; } とりあえずこんな感じでそれらを用意してやれば通る、けどやっちゃいけないよこんな事 basic_stringのカオスさ加減をどうにかしたい気持はわからんでもないけど
どうやらstd::stringを弄るのは禁じ手のようですね 無理にメンバ関数にしないでフリーの文字操作関数にします いろいろとありがとうございました
俺も同じことやってる。 コンストラクタ、代入演算子、あたりを全部作らないといけない上に、const / 非constの制御がかなり面倒。 でもやりたいよね…。ヘルパー作ってばっかだと、なんのためのオブジェクト指向か分からないし。
>>73 仮想デストラクタを持たないstringやコンテナなどから
派生クラスを作る誘惑に負けるな by スコット・メイヤーズ
#include <stdio.h> main() { int i; int b; int c; int d; printf("最初の数字を入れてください(半角)=>"); scanf("%d", &i); printf("なに算をするか入れてください( / * - + )=>"); scanf("%s", &b); if(b = /){ printf("割る数を入れてください=>"); scanf("%s", &c); d = i / c; }else if(b = *){ printf("賭ける数を入れてください=>"); scanf("%s", &c); d = i * c; }else if(b = +){ printf("足す数を入れてください=>"); scanf("%s", &c); d = i + c;}else{ printf("引く数を入れてください=>"); scanf("%s", &c); d = i - c;} printf("%d\n",d);} これでものすごい勢いでコンパイラエラー吐かれます>< 初心者といううか見様見真似でつくったのでどこがだめかエラー見ただけじゃわからない のでどこがおかしか教えてくださるとうれしいです
何算するかというところで、 +-/*という数値でないものを入力しようと言うのに intという数値を扱う型で読み込もうとしているのがいけない。 bはchar型にし、%cで読み込めばいい。 そして、if (b == '/') {のようにする。
>>83 intは数値だったんですか;
いろいろがんばってみます
intはintegerの略。
>>82 ・コンパイルエラーがたくさん出ても焦るな。先頭の1つから順に消していけばいい。
・見よう見まねで作ったならエラー出て当然。まずはもう少し自分で理解する努力をしてから人に聞け。
・人に聞くなら、どんなエラーが出たのかぐらいは書くべき。
>84まず入門書か入門サイト嫁www
_typeof, __typeof みたいに前にアンダーバーを1つ2つ付けるのは 予約キーワードと衝突するおそれがあるので避けるべきらしいですが、 typeof_, typeof__ みたいに後ろに付けるならおkでしょうか?
アンダースコアが2個続くのは先頭でも途中でも最後でもだめ
90 :
デフォルトの名無しさん :2007/09/30(日) 12:49:51
template<typenamt t, typename sig> class test; template<typenamt t, typename result, typename arg> class test<t, result (t::*)(arg)>{ result r; };//resultがvoidだとエラーになるので template<typenamt t, typename arg> class test<t, void (t::*)(arg)>{};//特殊化したい んですが、コンパイラからは「特殊化できない」とエラーになります。 引数の数が被ってるのがダメなのかと思い、 template<typenamt t, typename sig, typename dammy1, typename dammy2> class test; template<typenamt t, typename result, typename arg> class test<t, result (t::*)(arg), void, void>{ result r; }; template<typenamt t, typename arg> class test<t, void (t::*)(arg), void, void>{}; としてもやはりダメでした。
91 :
(90) :2007/09/30(日) 12:50:52
ちなみに上下共に同じエラーで弾かれます。
92 :
(90) :2007/09/30(日) 13:03:41
後者にしたうえで、 template<typenamt t, typename arg> class test<t, void (t::*)(arg), void, void>{}; を template<typenamt t, typename arg> class test<t, void, arg>{}; としtemplate<typenamt t, typename result, typename arg> class testの特殊化を狙っても 「テンプレート引数の数が少なすぎます」とダメでした。
ちょっと質問。 ヘッダをインクルードする時、ファイル名だけ指定してインクルードパスで検索する方法と、 インクルードパスを限定して、相対パスでファイルを指定する方法とではどちらが一般的でしょうか? ヘッダが100近いフォルダに散在していると前者と後者のどちらを適用すべきか判断がつきません。 他のプロジェクトで類似するケースではどのようにしているのか聞いてみたいんですが。 ちなみにヘッダファイルの移動はないことを前提としています。
int main(){ (処理) return 0; } 何で0を返すんですか? 1ではダメなのですか?
>>94 いいよ~
終了コードの使い方は処理系依存だけど、一般的には
0が正常終了、エラーや警告があれば1以上の数字を返すのが慣例。
>>90 gcc 3.4.4 だと通った。 詳しいことは解らんけど、それだけ報告。
#include <stdio.h>
template<typename t, typename sig> class test {
public: static void foo(){ printf("foo\n"); }
};
template<typename t, typename arg> class test<t, void (t::*)(arg)> {
public: static void foo() { printf("bar\n"); }
};
class X{};
int main()
{
test<int,int>::foo();
test<X, void(X::*)(int)>::foo();
}
>>93 適材適所。
そのたくさんのディレクトリが相互に無関係ならそれぞれパス指定するしかないと思う。
そうではなく、ある程度共通のディレクトリの中に分散しているのなら、共通部をパス指定して
残りはファイル名で記述すればいいだろう。
例えば、こんな感じ。
--
/home/who/someProject/include/catA/inc1.h
/home/who/someProject/include/catA/inc2.h
/home/who/someProject/include/catA/inc3.h
/home/who/someProject/include/catB/inc4.h
/home/who/someProject/include/catC/inc5.h
こんなインクルードファイルがあるなら、
#include "catA/inc1.h"
#include "catA/inc2.h"
#include "catA/inc3.h"
#include "catB/inc4.h"
#include "catC/inc5.h"
と記述してパス指定に$HOME/someProject/includeを追加。
>>90 コンパイラは何を使っている。
また、そもそも何をしたい?それ次第では別の手段があるかもしれない。
>>90 #include <stdio.h>
#include <boost/type_traits.hpp>
class test1 {
public: static void foo() {printf("test1\n"); }
};
template<typename t, typename result, typename arg>
class test2 {
public: static void foo() {printf("test2\n"); }
};
template<typename t, typename arg>
class test3 {
public: static void foo() {printf("test3\n"); }
};
namespace detail {
template<typename t, typename sig> struct selector {
typedef test1 type;
};
template<typename t, typename result, typename arg> struct selector<t, result (t::*)(arg)> {
typedef typename boost::mpl::if_<boost::is_void<result>, test3<t,arg>, test2<t,result,arg> >::type type;
};
}
int main(int argc, char *argv[]) {
detail::selector<test1,void>::type::foo();
detail::selector<test1,int(test1::*)(int)>::type::foo();
detail::selector<test1,void(test1::*)(int)>::type::foo();
return 0;
}
そもそも
>>90 のresult r;って、
コンパイラさえ問題なく、しかもrがvoid型なら、
<t, void (t::*)(arg)>なんて特殊化は
不要だと思ったのだが違うのか?
>>93 インクルードパスにはあまりごちゃごちゃ含ませないことが望ましい。
インクルードパスに含まれるヘッダの名前は実質システムグローバルだからな。
行儀のいいやりかたは、
>>97 のように、インクルードパス直下にヘッダを
置かず、モジュールだのライブラリだの用のディレクトリを掘り、その下に
ヘッダを入れることだ。
そうすることで、汚染する名前をディレクトリ名だけに限定でき、
名前の衝突を回避しやすくなる。
勿論、これにはインクルードパスの下をあまりとっちらからせずに、整理整頓できる
というメリットもある。
boostみたいに実装詳細のヘッダをhoge/datail に入れておくと 外部公開するヘッダとプライベートなヘッダを分けられてうれしい
svnのboost::function_typesなら関数の型から、戻り値や引数を取りだせるから それとenable_ifで特殊化してやる方法もある #include <iostream> #include <boost/function_types/result_type.hpp> #include <boost/type_traits.hpp> #include <boost/typeof/typeof.hpp> #include <boost/utility.hpp> void func_v() {} int func() { return 0; } template < typename sig , class Enable = void > struct C { void f() { std::cout << "func\n"; } }; template <typename sig> struct C< sig , typename boost::enable_if< typename boost::is_same< typename boost::function_types::result_type<sig>::type , void>::type>::type > { void f() { std::cout << "void func\n";} }; int main() { C< BOOST_TYPEOF(func_v) >().f(); C< BOOST_TYPEOF(func) >().f(); }
うへ 仕事では出会いたくないタイプのコードだな…… だからC++は(ry
boost厨多過ぎ
boostは順調に使えてる時点ではいいんだけど、 バグったりするともうお手上げ
そのバグを自力で直して公式に反映できたり、 そこから新しい使い方を発見できる程になりたひ
>>97 >>101 レスありがとうございます。
自分も正直ごちゃごちゃしたインクルードパスを書くよりは
プロジェクトのルートパスを一つ指定するような書き方が望ましいと思っているので、
その方向で調整して行きたいと思います。
ただ、好みの問題程度にあしらわれないか不安ではありますが。
使っているコンパイラはvisual C++ 2005です。 メンバ関数を特殊化で返り値、クラス、引数をそれぞれ特殊化した後に 内部に作っておいたクラスを使い間接的に返り値を特殊化したらコンパイルが可能になり解決しました。
オーバーロードについて質問 int Func(int a=NULL); string Func(string a=""); こんな感じで引数が無い場合に戻り値の型によって 関数がオーバーロードされるのを期待してみましたが コンパイルエラーが出てしまいました このような場合関数名を変えるしか無いのでしょうか?
>>110 戻り値の型でオーバーロードはできません。
ポインタじゃないものに NULL を使っちゃだめです。
113 :
94 :2007/09/30(日) 18:43:55
int x = 4896; int y = 1406; double z = y/x; でzが0になってしまうのですが、 これを0.28.... とやるにはどうすれば良いのでしょうか?
z = (double)y / x;
わぁ、ありがとうございます。 ところで、double>intなのに なんで代入変換されないのでしょうか?
z=y/xという式は、まずy/xが実行される。 int/intなので結果はint、この時点で結果が0になる。 int型の0をdouble型に代入しても当然0になる。 (double)y/xとすることで、yがdoubleになりこの式の結果もdoubleになる。
118 :
デフォルトの名無しさん :2007/10/01(月) 02:51:59
int同士の/演算はint -> int -> intだから、代入する時点ですでに(intの)0なんだよ。 それをdoubleに変換したところで、0.0になるだけさ。
なるほど、ありがとうございました!
演算子の優先順位って奴だな = よりも / の方が優先順位が高い
121 :
デフォルトの名無しさん :2007/10/01(月) 03:54:49
=の優先度がたかかったら使いにくくてしょーがねー。 (z=y)/x は欲しい結果じゃないだろ?除算結果捨ててるしなw
メンバ変数をpublicメンバにして公開せずに入出力関数を用意すべきと言いますが その際に入力用と出力用と2種類作った方が良いのでしょうか? class Choge { private: std::string memo_; public: std::string memo(const std::string& data = "") { return (data.empty() ? memo_ : memo_ = data); } } 上のように入出力をまとめちゃった方がスッキリしそうな気がするのですが 少しトリッキーなようで、こんな事をしても良いのか迷ってます
>>122 そのメンバを空にしたいときにはどうするんだ?
そんな癖のある仕様にするくらいなら、別々に作った方がいいことは自明だ。
>>122 そもそも、メンバを参照するだけのmemo()がconstメンバ関数じゃないから使い難い。
設定用に非constメンバ関数、取得用にconstメンバ関数を用意するなら、最初から別々に作ればいい。
# 例えば、void func(Choge const & hoge)なんて関数からhoge.memo()を呼べないのは面倒だぞ。
127 :
デフォルトの名無しさん :2007/10/02(火) 07:38:20
はじめまして、すいませんが質問させてください。 Linux(Turnolinux Fuji)でsys/systeminfo.hを includeしてSI_HOSTNAMEを使用したい< sysinfo(SI_HOSTNAME~を対処したい >のですが、 コンパイル時にsys/systeminfo.hがないとエラーが出力されてしまいます。 どうすればよいのでしょうか?ご教授ください。
探す。includeする。
>>126 ちゃんとmakefileまでついてるじゃないか
gccみたいだけど別にほかのコンパイラでも大丈夫だろ
>>126 cygwinを入れて、makeではどうでしょう。
>>127 systeminfo.hを探してみたらどうでしょう。
132 :
デフォルトの名無しさん :2007/10/02(火) 12:48:32
質問です。 INT_MIN~INT_MAXの範囲を超える整数の計算をしたいんですけど どうしたらよいのでしょうか?
133 :
デフォルトの名無しさん :2007/10/02(火) 13:02:56
>>132 intよりも大きい値を扱える型を使いなさい。
135 :
デフォルトの名無しさん :2007/10/02(火) 13:34:03
ありがとうございます
>>133 多倍長っていうんですね。
ググってみます。なるべく自作したいので。
>>134 ちょっと思いつかないんですが、例えばどんな型がありますか?
符号付の値が扱えるのがいいです。
こちらの環境はVC6です。
>INT_MIN~INT_MAXの範囲を超える整数の計算をしたいんですけど 大きく超えないのなら vc6 なら __int64 が使えないこともない。 (なんか加算でバグった経験あって個人的には嫌だけど)
>>135 C99ならlong longも使えるし、そうでなくてもint64_tなどの型があるかもしれない。
それに、doubleでもlong doubleでもいいかもしれない。
要は、INT_MAXを超えると言われても大きさも必要精度も判らなければなんともしようがない。
>>135 Windowsだと__int64 / unsigned __int64
139 :
132 :2007/10/02(火) 16:13:46
>>136 そういえばそんなものがありましたね。試してみます。どうもです。
(バグってどんなバグだろう)
>>137 VC6なのでC99なんて対応してません。
精度は64ビットも要らないけど32ビットじゃ足りません。
__int64で試してみます。
140 :
132 :2007/10/02(火) 16:14:33
>>139 32<必要ビット数<64なら、doubleが丁度手頃じゃないか。
非標準の型を使わなくて済むし。
hoge.h hoge.cpp とわざわざ2つのファイルに分けるのはどうしてですか? 後でヘッダファイル見て理解しやすいようにしてるだけ? ヘッダに実装部も含めてclassを記述しちゃった方が楽だと思うのですが
そう思うのなら、そうすればよろしいでしょう。 実際私も、クラスの実装はインクルードファイルに書くことが多くなっています。
>142に提示された条件だけでは問題があるともないともいえません。
ヘッダに実装コードを書くのはおかしい
単にprivateなメンバ変数の値返すだけとかならヘッダに書いちゃう。
全てを宣言内に書いてしまうというのは、分割コンパイルの利点の放棄に等しい。 まぁマシン速くなったから、それもいいんじゃない?
>>147 そうゆうのはインライン何とかの範囲だからいいと思う
インラインは早いけどたくさん使うと実行ファイルが大きくなるみたい
どうせ今のコンパイラはオブジェクト間最適化で無理矢理インライン展開したりもするんだから、気にするほどのことじゃないだろ。 ついでに言えば、テンプレートクラスだとどうせ実装はインクルードファイルに書かないといけなくなるわけで。
switch - case と do - while について質問 下記のコードで処理がどのような順番で行われるのか教えてください。 よろしくお願いします。 int width = 15; int n = (width + 3) / 4; switch(width & 0x03) { case 0: do { *buffer++ = 0 case 3: *buffer++ = 0; case 2: *buffer++ = 0; case 1: *buffer++ = 0; } while(--n > 0); }
>>154 ざっくり言うと、widthを4で割った回数だけループする作りになっている。
実際には、4で割った余りも処理しないといけないのでその分を最初の
switchからのcaseへの飛び込みで賄っている。
つまり、その例では15でスタートするから初回はcase 3に飛び込むわけだ。
各行にprintfでも挟んでみれば?
157 :
154 :2007/10/02(火) 18:51:37
>> 155 どうもありがとうございます。 初回に case 3 に飛び込むのは理解しました。 2回目以降はどうして case 0 ~ case 1 まですべての処理を通るのでしょうか。 すいませんが、もう少し詳しく解説してください。 >> 156 printf を挟んで動作は確認しました。 ただ、どうして >> 155 さんのような挙動になるのか理解できません。
最初に switch でどれかの case ラベルに飛んだ後、 while で条件が偽だった場合 do に戻る
もしかして、break が無いとそのまま次の case が実行されるってことを知らない?
ちなみにこれはDuff's deviceという名で有名。
まあただの興味で聞いてるだけだと思うが一応 caseの後には必ずbreak付けろ 使わなくてもdefaultは書け caseはswitchスコープの直下に置け、ループの途中に挟むなんて言語道断 以上
162 :
155 :2007/10/02(火) 19:08:41
>>154 ヒントを一つ。caseラベルはswitch以外からは只のラベルにしか見えない。
つまり、switchから飛び込んだ後は存在しないも同然。
各caseラベルを渡り歩く理由については>159にも書かれている通り、breakしないとスルーするわけだ。
アルゴリズムの質問なんですが カオリ、165cm、24歳、年収500万 サキ、150cm、21歳、年収1000万 タカシ、180cm、18歳、年収200万 グレイ、100cm、120歳、年収0etc というデータがあってa*身長+b*年齢+c*年収の値が一番大きい順にソートしたとき 最もあいうえお順に近い並び方になるa,b,cの値を探すプログラムを書きたいのだが 如何組めばいいか見当がつきません。 教えてください。
全通りの並べ方試してみてそれぞれあいうえお順に近いかどうか調べりゃいいじゃん ところであいうえお順に対する近さって何?
165 :
154 :2007/10/02(火) 19:20:26
>>159 それは理解してます。
>>160 ありがとう。色々調べてほぼ理解できました。
>>161 自分で書く場合はそうしています。
なので、逆に今回のコードが理解できませんでした。
>>162 最初の case 0: do { ...; case 1: ... の時点で理解不能でした。
switchが単なるcaseラベルへのジャンプだと理解すれば
それ以降は do{ } while() だけに注目すればよく、その中ではcaseラベルに意味はないのですね。
あうかえお ○××○○ 3/5=60% という感じでこの値を100に近づけたいんです。 パラメータの全通りとはどのような感じですか?
さらにgotoを加えて混乱させればいいのに…
>>163 Nx3行列A
165 24 500
150 21 1000
180 18 200
100 120 0
3x1行列B
a
b
c
Nx1行列C
6 ← 50音順で何番目か
11
16
8
とするとき
A・B=C
を満たす行列Bを決定すればよい
このとき行列Aの逆行列をPとするとき(上付き文字が使えないので^^;)
両辺に左からPを掛けると
P・A・B=P・C
B=P・C
となり求めることが出来る
逆行列の求め方は本(Numerical Recepies in C/C++ みたいなやつ)に
書いてあるのでそれを見ればおk
171 :
163 :2007/10/02(火) 19:28:46
>>168 本来その位置は「い」だからです。
>>169 どうもありがとうございました。
さっそくやってみます。
本来って何だ 「あ」「う」「か」「え」「お」のソートに何で「い」が出てくるんだ? じゃあデータが「さ」「し」「す」「せ」「そ」ならこうなるのか? さ し す せ そ ×(本来あ) ×(本来い) ×(本来う) ×(本来え) ×(本来お) 0% 変なの
173 :
168 :2007/10/02(火) 19:35:26
174 :
172 :2007/10/02(火) 19:37:07
いや、168を騙るつもりはないが なんか致命的な勘違いをしてる予感がしたから聞いてみたんだがもう見てないかな
175 :
169 :2007/10/02(火) 19:38:07
>>171 >>169 をちょっと訂正
要素数Nが4以上の時は
Nx4行列A (4列目の要素は常に1)
165 24 500 1
150 21 1000 1
180 18 200 1
100 120 0 1
4x1行列B
a
b
c
d
にしないといけない
176 :
163 :2007/10/02(火) 20:36:22
>>169 追加どうもです。
例が悪かったですね。
あうかえおいきくけこさしすせそ以下順番どおりだとすると
47/50=94%となります。
例が悪いというか、希望する順列との差異を表したいわけでしょ? そこで「あいうえお」を例にするから悪いわけじゃね? 普通の人が聞けば「あ」はあるかも知れんが「い」はないかもしれないと思う。
てことは「んあいうえおかきくけこ…を」だったら0%なわけね そういう定義ならそれでいいけど目的としてはそれで大丈夫なの?
179 :
163 :2007/10/02(火) 22:10:54
180 :
デフォルトの名無しさん :2007/10/02(火) 22:21:34
C++でnewで生成した配列の要素数って求められないんでしょうか? char* a = new char[5]; char b[5]; sizeof(a) は4(ポインタのサイズ) sizeof(b)は5になるのですが... お願いします
181 :
デフォルトの名無しさん :2007/10/02(火) 22:23:10
>>163 って、結果が必ず50音順になるわけじゃ無いよな。
効率よくやるのは結構ムズい気がする。
あいうえお順に近い並び方から順に、解があるかどうかを
1つずつ調べていくプログラムが作るの楽なんじゃないかなぁ。
>>180 char a[] = new char[5];
にすればおk
コンテナ使えやヴォケェ
スマソ
>>182 じゃ無理かも
C++ならvectorでもつかっておけば?
風邪なのに2chやってると判断力が鈍るな
コンテナなんてクソ
int hoge = 5; char* a = new char[hoge]; でhoge見りゃいいじゃん
要素数とポインタをタプルにしよう☆
サイズは定数で無いと受け付けないから
じゃあboost::arrayもしくはそれに似たものを自作すればおk
190 :
182 :2007/10/02(火) 23:05:56
レスありがとうございました. Vector使います. もひとつ関連質問ですが、Cで関数に配列渡す場合同じことが起きるんですが 関数内で渡された配列の要素数が必要な場合、要素数も別に渡さないと いけないということですか? void hoge(char a[], int numOfFactor)みたいに
もちろんそうよ ループの終了条件にしか使わないなら番兵置く手もあるけど
>>190 そうだよ。静的な配列ならsizeofで要素数を取得できるけど、そうでない場合は別に値を管理する必要がある
193 :
190 :2007/10/02(火) 23:14:31
了解しました。重ね重ねありがとうございました。 要素はfactorじゃなくてelementでした。おまいらサンクス!!
どっちかと言うと、C++では先頭及び最後の1つ後を指すイテレータ という2つの引数を取るほうが一般的だと思う。 template<typename Iterator> void hoge(Iterator first, Iterator last); 要素数はポインタ的にfirst - lastと言いたいとこだが、 std::distance(first, last)で求める。 もうちょっと先進的なのが好みならBoost.Range。 template<typename Range> void hoge(Range& r); boost::size(r)で要素数が求まる。 boost::begin(r), boost::end(r)でイテレータ取得。 vectorその他コンテナ一般や配列などを引数に渡せる。
DWORD dwSize = GetFileSize(...); LPBYTE lpBuffer = (LPBYTE)malloc(dwSize)); これをNewを使って書き換えるとするとどんな風になりますか?
Happy New Year
んー。 std::vector<BYTE> buffer(GetFileSize(...));
DWORD New = GetFileSize(...); LPBYTE lpBuffer = (LPBYTE)malloc(New));
DWORD dwSize = GetFileSize(...); //1 LPBYTE lpBuffer = new BYTE[(dwSize + sizeof(BYTE) - 1) / sizeof(BYTE)]; //2 LPBYTE lpBuffer = (LPBYTE)new char[dwSize] //3 LPBYTE lpBuffer = new BYTE[dwSize]
//4 LPBYTE lpBuffer = new(nothrow) BYTE[dwSize]; malloc差し替えなら挙動が同じ(bad_alloc投げずにNULL返す)new(nothrow)最強
んなコードは窓から投げ捨ててFileMapping使え
WindowsServer2003x64上で、64ビットプロセスと32ビットプロセスのメモリ共有を行いたいと思っています。 調べてみるとメモリマップドファイルがあるのですが、これで実現可能でしょうか?単純な方法がありましたら教えていただきたいです。 また、64ビットプロセスでメモリ確保したものを32ビットプロセスでデータ参照するにはどうすればいいでしょうか?
独学で勉強中です。 ClassA a; ClassA b = a; ClassA c(a); とした場合 bはメンバ変数が初期化され、 cは未初期化状態になります。 これは言語仕様でしょうか?環境依存でしょうか? WinXP + Cygwin + gcc3.4.4
やってみたが #include <iostream> class ClassA { public: int x; }; int main() { ClassA a; a.x = 42; ClassA b = a; ClassA c(a); std::cout << b.x << std::endl; std::cout << c.x << std::endl; } 実行結果 42 42 どのへんが未初期化?
>>205 >ClassA c(a)
これは、どういうことをしてるの?
コピーコンストラクタによる初期化
>>207 コピーコンストラクタってどこに宣言・定義されてるの?
#include <iostream> <----ここの中?
>>208 >コピーコンストラクタってどこに宣言・定義されてるの?
あなたの心の中。
冗談さておき、特に自前で宣言しなかった場合は暗黙のコピーコンストラクタが用意される。
# なーに、メンバを全部(浅い)コピーに出すだけさ。
>>209 >暗黙のコピーコンストラクタ
ってこうしなさいとC++の仕様で決まってるんの?
そう。
浅いコピーっていうのは、単なるビットコピーってこと?
浅いコピーなんだから深く考えちゃだめ
そのメンバがコピーコンストラクタを持っていればそれを使うが、ない場合はそういうことになる。
>>205 すみません、説明不足でした。
> ClassA a;
> a.x = 42;
> ClassA b = a;
> ClassA c(a);
の
> a.x = 42;
を取ると
0
17~~~(-1のunsinged表記?)
のように表示されてます。
両方ともコピーコンストラクタによりインスタンスが生成されていますが
結果が異なっていたため気になった次第です。
そもそも元のメンバ変数を初期化していない時点で まともな動作を期待するなよ
int x; printf("%d\n", x);
>>216 int x;
int y;
x = y;
この場合, x, yは異なる可能性があるの?
221 :
デフォルトの名無しさん :2007/10/03(水) 21:20:08
C++で使用対象のクラスが参照カウンタを実装している可能性があるので ZeroMemoryなどでデータを初期化するのはご法度 と何処かで目にしか記憶があるのですが、同様の理由で構造体に対しても ZeroMemoryを使うことはあまり好ましくないのでしょうか? C言語では常套手段だったので。
#include <tr1/memory.hpp> #include <cassert> struct Base { virtual char f(void) =0; }; struct A : public Base { char f(void) { return 'A'; } }; struct B : public Base { char f(void) { return 'B'; } }; int main() { std::tr1::shared_ptr<Base> p; p.reset(new A); assert( p->f() == 'A' ); p.reset(new B); assert( p->f() == 'B' ); } こういう実行時バインディングをCRTPを使って書きたいんですがどう書けばいいんでしょうか?
>>215 ローカル変数として定義したオブジェクトはデフォルト初期化される
組み込み型の場合のデフォルト初期化は不定値
どんな実装でどんな結果になろうが、考えること自体意味がない
>>221 その構造体・クラスがPODならZeroMemoryしても構わない。
PODになるには色々条件(コンストラクタ・デストラクタ、仮想関数禁止など)があるが、
概ねCでそのまま使えるような単純な構造体なら大丈夫と思っていい。
それでも、ZeroMemoryよりは初期化子などでゼロ初期化を促すほうが一般的だと思うけど。
225 :
221 :2007/10/03(水) 21:29:51
そもそもコンストラクタで初期化させるように設計するものなのでは?
でも外部のライブラリなんかで、 そういうCと共通のヘッダを使うなんて機会もあるし。 #そういうのはラップしろというのは同意。
>219
>>215 の報告を信じるなら、クラスのメンバ変数の場合には異なることが
ありうるってことだねぇ。最適化の関係かな。
229 :
222 :2007/10/03(水) 22:19:01
#include <cassert> template <typename Derived> struct base { char interface() { return reinterpret_cast<Derived*>(this)->implementation(); } static char static_func() { return Derived::static_sub_func(); } }; struct derived : base<derived> { char implementation() { return 'A'; } static char static_func() { return 'B'; } }; template <typename T> char f(base<T>& t) { return t.interface(); } int main() { derived d; assert( f(d) == 'A' ); } 英語版wikipediaを参考に書いてみましたがまだしっくりきません というかあきらかに違うような気がします
230 :
202 :2007/10/03(水) 22:46:03
>>203 ありがとうございます。メモリマップ先をファイルでなくメモリで可能ですよね?ただ、やはりメモリ幅の違いが気になります。実装は困難なのでしょうね・・・
>>229 reinterpret_castではなく、static_castにすべきだが、ほかは合っている。
>>230 自分でメモリマップを実装するのは困難だろうけど使うだけなら簡単
#include<windows.h>
#include<stdio.h>
#define IS_PARENT // ←この行の有りと無しでコンパイルする
#define MEMMAP_ID "maptest"
int main(void){
HANDLE hmap;
char *ptr;
#ifdef IS_PARENT
hmap=CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 256, MEMMAP_ID);
if(hmap!=NULL && GetLastError()==ERROR_ALREADY_EXISTS){
CloseHandle(hmap);
return 1;
}
ptr=MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0, 256);
ptr[0]='\0';
while(scanf("%255s", ptr)==1) ;
#else
hmap=OpenFileMapping(FILE_MAP_WRITE, FALSE, MEMMAP_ID);
if(hmap==NULL) return 1;
ptr=MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0, 256);
while(getchar()!=EOF) printf("%s", ptr);
#endif
UnmapViewOfFile(ptr);
CloseHandle(hmap);
return 0;
}
>>230 size_tのような64ビットと32ビットで大きさの違うデータ型を読み書きしようとしない限り問題ない。
32ビットプロセス同士でやるのと同じ。
234 :
202 :2007/10/04(木) 00:24:19
>>232 , 233
ご返信ありがとうございます。
今メモリ共有を行いたいのは、unsigned char型の配列です。
この場合も普通に232さんの教えくださったサンプルで問題ない
という認識でよろしいでしょうか?
>>234 なぜ、やってみないのでしょうか?
>>232 はただの動作確認のためだけのサンプルです
サンプルで問題がないかどうかは使い方によります
使用しているAPIについて*自分で*調べて下さい
236 :
202 :2007/10/04(木) 00:35:11
>>235 ご返信ありがとうございます。おっしゃるとおりです。
自分で調べずにすぐに質問してしまいました。
実装にトライします。
ありがとうございました。
237 :
デフォルトの名無しさん :2007/10/04(木) 01:12:29
そんなこと言われても、mplなんて使いこなせないんで…
stdのcoutやcinはヘッダを見るとextern宣言されてますが、定義はどこで行われているんでしょうか?
C++はヘッダファイルではなくヘッダをインクルードしますが ヘッダファイルとヘッダの違いって何ですか? ヘッダの中でヘッダファイルがインクルードされてる?
>>241 ほとんどのコンパイラの実装ではヘッダといえばそれに対応するファイルが
用意されているので、ほとんど同義。ただしコンパイラは <stdio.h> というヘッダを
ファイルとして実装する必要はなく、規定された動作さえすればいい。これは
C でも C++ でも同じ。
で、一般的にヘッダファイルといえばヘッダのように動作するユーザー作成の
ファイルも含む。
<iostream>ってヘッダファイルぢゃないの?
>>244 C++ の標準ヘッダではあるけど、ファイルであるかどうかはコンパイラの実装しだい。
>>242 なるほど。ということはユーザー定義のヘッダファイルを
#include "hoge.h" とした場合でも、規格上はhoge.hの実装
がファイルでなくてもよいということですか?
>>245 例えばファイルではないヘッダを使っているシステムってあるのですか?
LinuxとかWindowsのコンパイラの場合、OSがファイルシステムを持っているから
事実上はファイルとして実装されてるということになるのですかね?
>>246 いいんじゃねーの。
実際プリコンパイルドヘッダが用いられるときなんかはhoge.h以外の
とこから情報取ってきてるわけだし
privateな仮想関数って意味ありますか? 派生クラスで上書きしても呼び出せないのに。
>>248 プリコンパイルドヘッダというのはコンパイル済みヘッダということだと
思うので、バイナリファイルを覗きに行くのですかね?
delphiのinterface節/impliments節ってよくできてると思う
>>249 Non virtual interface と呼ばれる手法で使われる。
似たような話でデザインパターンの Template method とか。
>>250 ただのファイルにするかDBにするかインターネットからとってくるかは、
コンパイラ作成者の自由なんじゃないの?規格も神も制限してないんだから。
そんなの俺に聞いてどう答えて欲しいの?
>>249 派生クラスから呼び出せなくても、基本クラスから上書きバージョンを呼び出すことは出来る。
>>252 >>254 class B
{
public:
void mf(){ privmf(); }
private:
virtual void privmf();
};
class D : public B
{
private:
void privmf();
}
int main()
{
D objd;
objd.mf();
return 0;
}
このプログラムでobjd.mf() 内で呼び出される関数がB::privmf()ではなく、
D::privmf()になるのですがなぜですか?
ポインタか参照に対して呼び出されたときにポリモルフィズム機構
が働くと思うのですが。
void mf(){ privmf(); }はvoid mf(){ this->privmf(); }と同じことですが、
このthisポインタが指している実際のオブジェクトの型がクラスDの
場合(上のプログラムの場合)はD::privmf()が呼ばれるということで
しょうか?
そのとおり
>>256 ポインタthisに対する多態性ということですか。
objd.mf() を実質 mf(&objd)と考えて this と &objd
が等しいものを表すため、クラスDの仮想関数
テーブルが参照され、そこに登録されている
D::privmf()が呼ばれるということで納得できました。
258 :
BOLT :2007/10/04(木) 18:19:42
クソショボイブログだなw 誰も見ないしとっとと閉鎖しろよ
誰も見てくれないからこそ続けるんだ 最低1年くらいは毎週更新できるように努力しる
C++が全角なのが気にくわない
「全角ってなんですか?」 「"いわゆる全角"のことではないでしょうか」
いいえ、焼き肉屋のことです。
おまえら向上心のある奴はやさしくしてやれよ
どこぞのかわいがりよりはずっとやさしい。
可愛がってやらないと強くならないぞ!
267 :
デフォルトの名無しさん :2007/10/04(木) 22:37:51
C++でCSVからデータを読み込もうとしています。 普通は1文字ずつ変数に入れていくと思うのですが、 プログラム側で #define FILENAME "a.txt" と定義しておき、 CSVに記述された FILENAME を "a.txt" として読むことはできるのでしょうか。 よろしければお力添えをお願いいたします。
"FILENAME"があったら適当に置換でもしとけばいいじゃん
269 :
267 :2007/10/04(木) 23:04:23
返信ありがとうございます。説明が不足していました。 defineが他にも多数あり、今後外部ファイルに定義を移して defineの名前も変更できるようにするため、いい方法がないかと思っています。 FILENAME 1個だけなら置換で問題ないですね。
CreateProcessでWindows Services for UNIXのunzipコマンドを使うのは可能ですか?
>>269 よくわからんけど、私的なツールなら cppでプリプロセスすればいいんじゃない?
>>270 createprocess 外部コマンド
で検索するぐらいしてから来れば?
273 :
267 :2007/10/04(木) 23:28:39
>>271 すみません、cppでプリプロセスの理解ができませんでした。
私的ではなく会社で使います。今日はこれ以上つなげないので調べてからまた来ます。
クラスのメンバ変数に参照型を追加した場合の初期化の 方法はこれが正しい書き方でしょうか? class Hoge{ private: int &Test; public: Hoge(int &T):Test(T){} ~Hoge(){} }
いえす 一番最後にセミコロン無いけど
>>267 その程度のこと会社で聞けよ
きみの会社の客はかわいそうだな
277 :
275 :2007/10/04(木) 23:38:58
>>275 どうも。
参考書にもググっても全く見つからなかったので不安が解消できました。
278 :
274 :2007/10/04(木) 23:39:49
質問です。 pure virtual な関数て、基底クラスで class ClassA { public: virtual void Test(void) = 0; }; こんな感じに定義するのは普通なのですが、さっき間違って class ClassA { public: virtual void Test(void) = 0 { } }; と、中身を定義したら、コンパイルが通りました。気になったので、派生させてみて、 派生先の Test 関数で、ClassA::Test を呼んだら、呼べました。 pure virtual な関数は、実体を作れないと思いこんでいたのですが、それは間違いなのでしょうか? vc++8.0 sp1 xp sp2
>>279 それは間違いです。
でもその書き方ってできないんじゃなかったっけ。
class ClassA{
public: virtual void Test(void) = 0;
};
void ClassA::Test(void) { }
って書く必要があったような・・・
記憶違いかね。
281 :
デフォルトの名無しさん :2007/10/05(金) 12:29:52
>>280 VC++はそういう書き方ができるんじゃなかったか。
pure virtualなデストラクタの定義を書くのを楽にするための、MSの配慮というか
お節介だったと思うが。
まあ勘違いしやすい所だよな ×pure virtual な関数は、実体を作れない ○pure virtual な関数を持つクラスは、実体を作れない
printf 系で "%10s" と指定している箇所が全て 12 に変更されることになって 数値を定数化してフォーマットに埋め込めないものかと思っているんですが、 #define した定数がそのまま表示されたりと期待した動作が得られません。 どなたか知恵を貸して頂けませんか。 (そもそも文字列終端を付けられたらこんな苦労もなかったんですけど・・・)
#define FMT "%12s" printf(FMT,"hogehoge"); じゃダメなの?
こんな書き方も出来るかもー!! printf("%*s", 10, "hogehoge"); printf("%*s", 12, "hogehoge");
#define FMT "12" printf("%" FMT "s", "hogehoge"); とか
std::mapでキーワードを予め指定しておいた予約語以外は受け付けないように出来ますか? "hoge""hage""hoji""haji" // 何らかの方法で指定した予約語 std::map<std::string , std::string> strmap strmap["hoge"] = "これは成功する"; strmap["miss"] = "これは失敗する"; こんな感じで
C++で下みたいな方法ってよろしくないですかね・・・ 配列に入れた座標データを,オペレータオーバーライドを使って計算したいんですが 要素毎にコンストラクタ呼び出しは冗長になるので 問題点が判らないので指摘をお願いします #include <stdio.h> float data[] = {1., 2., 3., 4., 5., 6.}; class Data { public: // use default ctor float x, y, z; Data& operator+=(const Data &right) ....省略... }; int main() { Data *ptr; ptr = reinterpret_cast<Data*>(data); printf("%f %f %f\n", ptr[0].x, ptr[0].y, ptr[0].z); printf("%f %f %f\n", ptr[1].x, ptr[1].y, ptr[1].z); return 0; }
>>287 勝手に追加されちゃうから無理じゃね?
std::mapを包含したクラス作ってインデクサの中で例外投げるとかしか思いつかない
>>289 stringの方をラッピングするのもアリじゃね?
書く量としてはその方が少なくなりそう。
>>289 そうですか、残念
ありがとうございました
>>288 >コンストラクタ呼び出しは冗長
といってもinlineであれば実質気にするほど変わらない気がする。
Dataがfloatピッタリ3つ分で収まるという保証があるのだろうか?データメンバーが後から追加されたりする可能性は?
virtualな関数をもつとサイズが変わったりする様だし、危険を伴う気がします。
assert(sizeof(Data) == sizeof(float[3])); を書いとくとか
>>292 ,293
Thx
対象がRAWなベタデータなので簡素に出来ないかと思ったのですが
素直な書き方をした方がよさげですね
>>284-286 フォーマットって普通に文字列なんだな。
>>285 の方法は知らなかった。参考にさせて貰います。
色々試してみたけど、やりたいこともこれで出来そう。 ありがとね。
>>288 × オーバーライド
○ オーバーロード
297 :
デフォルトの名無しさん :2007/10/06(土) 16:19:13
wcout はバグがありますか? wcout を使うのは避けてますか? WindowsXP Home + BCC
char *hogehoge(){ return "hogehoge"; } 文字列リテラルの場合、変数と違って関数を抜けても有効なままなんでしょうか?
有効なままです
リテラル返すならconst char*にした方がいいかも
inline const char *&
302 :
デフォルトの名無しさん :2007/10/06(土) 18:45:41
&はイラネーだろ なんか違うのか?
inline const const char *&
304 :
デフォルトの名無しさん :2007/10/06(土) 18:52:50
C++超初心者です。 今まで動いていたのに、今日コンパイルすると、 (1029) invalid format string conversion と表示されてしまいます。 原因が分からず、どのように変えたらよいのかも分かりません。 ご教授宜しくお願いいたします。 すごく長いプログラムなので、関係してそうなところだけ書き込んでます。 FILE *ottq; ottq = fopen("ottq.dat", "w"); double chir,l l=20.05e-3; chir=0.0e-5; fprintf(ottq, "l(m)=\t%le\t\n",l); fprintf(ottq, "chir(%)=\t%le\t\n",chir*100.0); ←1029行目ここです。 fclose(ottq);
%→%%
こえぇ お前みたいなのが扱うもんじゃねぇだろ
変数名きめぇwwwww
309 :
304 :2007/10/06(土) 19:30:54
なんてことだ・・・%% 自分がいやになる 皆さんありがとうございました・・・
>>310 この人にメールしたら50万円振り込んでくれたよ
すいませんホントにくだらない質問なので申し訳ないのですが マクロについて聞かせてください。 #define GET_FRAGMENT_PARAM(name) \ myCgFragmentParam_##name = \ cgGetNamedParameter(myCgFragmentProgram, #name); \ checkForCgError("could not get " #name " parameter"); このようなマクロがあったときに \ で複数行にすることはわかったのですが その後の##nameと#nameの違いと意味について教えてください。
例えば #define A(x, y) x##y #define B(x) #x というのがあったとき、 A(foo, bar) → foobar B(foo) → "foo" に展開される
へぇ~
>>314-315 さん
ありがとうございます。
わかりやすい例で理解できました。ほんとに助かりました
318 :
デフォルトの名無しさん :2007/10/06(土) 21:32:59
std::vector<int> hoge; 略 for(i=0; i <hoge.size(); i++) { 略 } 例えばforに入る段階でhoge.size()が5だったとして、 forの中でもなにもhogeに対して操作をしてないのに 出てきた段階でiが5を指してるんですが、いったいどういうことですか? 01234で出てくるはずですよね?
i=4だったら、まだ i<hoge.size() が成立するから、もっかいループするだろ。 i=5になって、ようやく i<hoge.size() が成立しなくなって、ループから抜けれる。 つまり出るときは i=5
i == 5のときはi < 5は?
321 :
デフォルトの名無しさん :2007/10/06(土) 21:37:09
vector使う前にC言語のfor文を学びなおしとけ。
std::string func() { std::sting buf; buf = "hogehoge"; return buf; } こんなんもアリですか?
うん
ありだが、そりゃねぇよ・・・
アリだが、return "hogehoge"; で十分だろう
それがstd::string& func()になったらアウト
いや、簡略化しただけでもちろん引数に文字列取って bufに対して何らかの処理を加えたものを格納してると仮定した上で・・・
329 :
デフォルトの名無しさん :2007/10/06(土) 21:44:19
>>319 そっか。そうでした。
forの{}の中でとりうるiの値は01234ってことですね。
int *********************************************************************p; これ通ってビックリしたんですけど *っていくつまで行けるんですか?
int *******************************p; p[0]; p[0][1]; p[0][1][2]; p[0][1][2][3]; p[0][1][2][3][4]; p[0][1][2][3][4][5]; p[0][1][2][3][4][5][6]; p[0][1][2][3][4][5][6][7]; p[0][1][2][3][4][5][6][7][8]; p[0][1][2][3][4][5][6][7][8][9]; p[0][1][2][3][4][5][6][7][8][9][10]; p[0][1][2][3][4][5][6][7][8][9][10][11]; p[0][1][2][3][4][5][6][7][8][9][10][11][12]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29]; p[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30];
これは綺麗だなw
>>330 いちおう規格で最低限の数値が示されている。
ISO C 5.2.4.1 Translation limits より
"12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or incomplete type in a declaration"
ISO C++ Annex B Implementation quantities より
"Pointer, array, and function declarators (in any combination) modifying an arithmetic, structure, union,
or incomplete type in a declaration [256]."
C なら 12 まで、 C++ なら 256 までがポータブルってことね。
ふーん。
336 :
332 :2007/10/06(土) 23:18:18
んなわけない
まちがいさがし
ただしいさがし
ひょっとして
>>332 は全部 sizeof(p)==0 ?
sizeofで0が出ることってあるの?
342 :
デフォルトの名無しさん :2007/10/07(日) 00:11:19
ないよ。
g++ 3.4.4 cygming special だと C/C++ とも要素数 0 の配列が定義可能で sizeof とると 0 になったけど 規格上は要素数は 0 より大きくないと駄目って書いてある。 空の構造体の場合、C では 0、C++ だと 1 になった。C++ では complete な class type のサイズが 0 に ならないことは規格上明記されてるけど、C では軽く見た限り記述はなかった。
344 :
デフォルトの名無しさん :2007/10/07(日) 01:55:19
Cの規格にも、異なるオブジェクトのアドレスは異なる みたいな記述なかったっけ?
>規格上は要素数は 0 より大きくないと駄目 new する時に値が 0 かどうかチェックしないとダメってこと?
#define stroustrup struct しているのは俺だけでいい
うん あほのお前だけでいい
あほだなw
>345 普通に配列の宣言/定義をするときに、という意味。 new するときは要素数 0 を渡すことができて(確保が成功すれば)他の(有効な=deleteされていない) new の戻り値と かぶらないポインタが返ってくることが保証されている。(14882:2003 3.7.3.1/2) なお、C99(9899:1999) だと要素なしの struct が認められてなかった。 > 6.7.2.1/7 >If the struct-declaration-list contains no named members, the behavior is undefined. > 6.2.6.1/2 >Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, とも書いてあるし、sizeof が 0 返すのはなさそげ。 C89/C90 がどうなってるかは分からないけど、gcc の -Wall -std=c89 -pedantic の結果からすると C99 と同じだと思われる。
なさそげ?
なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。 なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。なさそげ。
>>343 仮に空の構造体の大きさが0でよければ、
空メンバ最適化 (EMO)なんて言葉も出来なかったよね。
EBOでなくEMO?
どうせeffective読んだんだろ
std::string から std::wstring またその逆の変換はどうしたらいいですか?
stringの中に入れる文字エンコーディング次第じゃね?
shift-jis から ユニコード です
>>357 Windows なら MultiByteToWideChar() が使えそうだけど、ほかの環境もあるなら
やっぱり iconv か?
mbstowcs
>>358-359 一発では出来そうもありませんね
自作するしかない?
レスありがとうございました
361 :
デフォルトの名無しさん :2007/10/08(月) 12:25:39
ハンガリアンって賛否両論あるのか何なのか知りませんが 私としては分かりやすいので使ってます。 で、静的メンバって頭になんてつけるのが通例? 普通のメンバにはm_ってつけてたのですが、 これってホントは静的メンバにつけるもの?
>>361 >普通のメンバにはm_ってつけてたのですが、
それはハンガリアンではない。
363 :
デフォルトの名無しさん :2007/10/08(月) 12:44:56
>>362 そうなの?じゃあ別になんでもいいけど、
よくメンバってm_ってつけるじゃないですか。
分かりやすいし。グローバルにはg_とか。
で、静的メンバはなんて付けとくのが通例?
感覚的にはsm_とかでいいのかな。
でも見たこと無い。
sm_ってwww
366 :
デフォルトの名無しさん :2007/10/08(月) 13:00:45
staticMember_
368 :
デフォルトの名無しさん :2007/10/08(月) 13:09:21
なんだここ、役立たずのアホしかいねーのか。
と役立たずが申しております。
370 :
デフォルトの名無しさん :2007/10/08(月) 13:18:39
と役立たずが申しております。
g_ m_ s_ 見たことあるのはこの3つくらいだな
372 :
デフォルトの名無しさん :2007/10/08(月) 13:29:05
冬だねえ。
374 :
デフォルトの名無しさん :2007/10/08(月) 13:38:47
冬は来月からです。
仕事…社内規約・既存のソースに準拠 趣味…わが道を行く でいいんじゃね 仕事で変数名を順にa,b,c,d,e,...と付けてあるソースを見たときはブチ切れた
>>376 スマンそれ漏れだわ
当時彼女とうまくいってなくて怒りを仕事にぶつけちまった
私事を仕事に持ち込むなんてプロ失格だぞ
だって・・だって・・ウッウッ・(´;ω;`)ブワッ
>>360 どれもこれも直接string<->wstringの変換はできんが、ラッパーを書くのは
大した手間でもないだろう。問題は、どれもこれも何がしかの問題があるように
見えることだ。
mbtowc(): リエントラントでないんで多分非推奨。
mbrtowc(): 上のリエントラント版で、しかも標準だが
使えない環境もあるかも?どっちみちグローバルロケール依存なので用途が
限られるかも?
codecvt<>: C++標準で、wstreamの変換に使われているが、
実装が貧弱(バグもち、遅い)であることも多いかも?
iconv: Unixでは標準的でWindowsにもGNUのが移植されているが、
エラーケースの実装がまちまちだったり色々変種があったりパッチが
あったり無かったり、罠も多いかも?
ICU: Unicode絡みでは決定版とも言えるライブラリだが、巨大すぎるかも?
MultibyteToWideChar(), MLang: Windows専用。
_bstr_t, A2W, CA2W: VC++専用。
>>379 誰が上手いことを言えと(ry
と、いってほしかったんでしょ
俺は前任者のソースのコメントに はにゃ~ん て書いてあった事がある
>>382 へ?
もしかして 私事 を しごと と読んでるのか?
狙って書いたんじゃないのか
し・・・私事
>>384 もちろん違う。
並べると、そう読ませるシャレになってんのかなと思っただけだよ。
class aaaaとかaだけで構成されたソースなら見たことある
brainf*ckかよ
#define __pascal brain class f;
>>381 レスが遅れました
これは丁寧な解説ありがとうございました
参考にさせて貰います
393 :
デフォルトの名無しさん :2007/10/08(月) 22:41:52
何にも知らない俺がC始めてみようと思ってとりあえず超簡単なのをコンパイルしようとしたら sample.c: can't open: stdio.h: No such file or directory とか言われてどうしたらいいかわかんなくなった
コンパイラ入れなおせ てかstdio.h入れてないとかどんな設定で環境入れたんだ 何か走らんが
>>393 始めたばかりでもそのレベルじゃやめといた方がいい
399 :
デフォルトの名無しさん :2007/10/08(月) 23:20:40
class A{ public: int mA; virtual FuncA(); }; があったとします。このクラスをBというクラスが継承した場合、 クラスAのメンバにアクセスするには普通にmA、FuncA()でアクセスできます。 これを、”この変数はクラスAのだよー”と、明示的に示したい場合、A::mAとすべきでしょうか?this->mAとすべきでしょうか?
this->A::mA
うほっ
402 :
399 :2007/10/08(月) 23:57:59
イテレーターって何で継承関係ではないんですか? たとえば前方反復子は入力反復子の操作を全て持ってるわけだから 継承すればいいと思います。 イテレータータグ(iterator_category)で型の区別はできますが。
ただのポインタがクラスじゃないから。 int a[10]; std::fill(a, a+10, 42); とかできなくなる。
>>403 仮想関数はC++の標準ライブラリに
遅いか、あるいは必要ないか、の理由で拒否されている
ソースからvirtualを検索すれば分かる
だからC++はオブジェクト指向言語ではない
C++はHaskellとLispをまぜた何か。だ
>>404 つまり、それがiterator_traits<Iter>の組み込みポインタ(ランダムアクセス反復子)
用の特殊化バージョンを定義してることと関係してるのですか?
>>405 仮に継承したとしても各演算子をオーバーライドしたり仮想にする必要は
ないと思いますがいかがでしょう?
>>406 ポインタをランダムアクセス反復子として扱いたいので、そうできるようにしている。
構造体(クラス)同士の = は、 Cだと「ただのビットのコピー」で、C++だと「メンバ変数ごとに operator= を呼び出す(もしくはコピーコンストラクタ?)」で合ってますか? (C++は、構造体にoperator=を自分で実装してない場合です
>>409 はい。
同じような質問を、何か最近見たような気がする。
質問です。 hoge[25]とhuga[25]みたいな感じで、 25個の配列を比較しなければならなくなりました。 hoge[25]のほうは値が固定なのですが、配列宣言で const double hoge[] = {0,1,2,…24}; とやるのはなんかダサイ気がします。 なにか、うまい解決方法は無いでしょうか? それと、もし宣言する場合はconst double hoge[] = {0,1,2,…24};を グローバル変数として宣言した方が処理が早いでしょうか? それともmainのローカル変数で宣言して、参照渡し(const付けた意味なし) した方が早いでしょうか? それとも配列の比較をする関数の中で宣言した方が処理が早いでしょうか?
412 :
デフォルトの名無しさん :2007/10/10(水) 04:01:22
先が見えない
後からfor文で代入すればいいじゃん C++ならstd::generate_n()も使える。
>>412 書き捨てなので
>>413 for文で代入とは?配列に代入される値は固定ですが、線形ではないです。
ちなみにCです。
やりたい事は簡単に言えば、統計処理で
X Y X*Y X^2
1 5 5
3 9 27
4 6 24
5 8 40
6 3 18
みたいな感じで(この場合Xの値は固定でYを引数)。
んでXの配列をべた書きでも良いんですが(ファイルで読み込みだと遅いし)、
ダサイなと。
固定のXは入れるしかないだろ。 Yを引数に他の値が決まるなら、それをfor文で代入すればいい。 何がダサいのかはしらんが。
逆に、どんな風にできたらカッコいいと思うんだろうか?
そうかなぁ。 ソースの中に配列が、 hoge[] = {1,4,65,7,....} みたいな感じでダラダラ書いてあったら、イラッとしません? ところで、 「それと、もし宣言する場合はconst double hoge[] = {0,1,2,…24};を グローバル変数として宣言した方が処理が早いでしょうか? それともmainのローカル変数で宣言して、参照渡し(const付けた意味なし) した方が早いでしょうか? それとも配列の比較をする関数の中で宣言した方が処理が早いでしょうか?」 はどうなんですか?
なんかムカツク。以上。
そのくらい自分で計ってみなよ
頻繁に呼ばれるコード内でいちいち初期化するような 書き方さえしてなければどれでもいいだろ。 グローバルだろうと参照渡しだろうと速度は変わらん。 プログラムの規模と関数の汎用性をどうしたいのか考えてから あとで保守するときに一番楽が出来そうなやり方でやればよろし。
定数配列はstatic constだろ。常考
常考なんてお前あほだろ。
>>418 「なんかダサイ」「イラッとしません?」なんて主観でしか語らないやつには
どんな方法で答えても後付けで文句が返ってきそうだから、答えたくない。
あと、速度は実測が基本。
>>424 >「なんかダサイ」「イラッとしません?」なんて主観でしか語らないやつには
>どんな方法で答えても後付けで文句が返ってきそうだから、答えたくない。
プゲラッチョ
じゃ、お前さんはインデントがむちゃくちゃなソースの読みにくさを
どうやって数値(客観的な方法)で表すんだい?
後学のために教えて頂戴。
このソースコードの奇麗さや汚さを数値で表してみせてよ。
日本語でおk
もう触らないほうがいいな。
>>418 >イラッとしません?
個人的な話でよければ、hoge[25] = {1,4,65,7,....} な書き方で、
5個ずつなり10個ずつなりで改行してあれば気にならない。
25個全部が1行で書いてあるとイラっとする
プリプロセッサとテンプレートを使えばコンパイル時に計算される生成関数もC++ならできそう
>>425 読みにくさを客観的に表すのは簡単。
何故イラっとするのか、何故ダサイと思うのかを正確に記述すればいいだけ。
何か大きな勘違いをしているみたいだけど、「主観的な考え方」と「主観的な表し方」はまるで別物。
>>418 が言われているのは、
「お前の感覚の原因を客観的に表せ。原因がわからなければ、原因を取り除いた書き方も提供できない」
ということだと理解しよう。
究極的には主観で好みが分かれる、というのをいくら興奮しながらまくしたてたところで、
その詳細を表現するのに「なんかダサイ」「イラッとしません?」といったレベルの低い主観的表現しか
出てこなかったから回答しようがない、という間抜けな状況の言い訳にはならない。
Cスレですよ
いえ、CとC++のスレです。
いえ、トムはペンです。
「可読性が低い」でいいじゃないですか
プゲラッチョ とか久しぶりに見たわwww
bcc5.5を使ってコンソールプログラムを勉強中の初心者です。 CUIメニューでカーソルキーが押されたら何らかのアクションをしたいのですが、 カーソルキーの押下を拾う方法がわかりません。何か参考になるサイトとかありますか?
pdcurses
カーソルキーって何?
>>436 kbhit + getch
WaitForSingleObject + ReadConsoleInput
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define NULLPO NULL #define WALL 0 #define FLOOR 1 #define WIDTH 15 #define HEIGHT 13 #define S_WALL "■" #define S_FLOOR " " int main(int argc, char **argv){ char maze[HEIGHT][WIDTH]; int y, x; memset(maze, WALL, HEIGHT * WIDTH); for (y = 0; y < HEIGHT; ++y) { for (x = 0; y < WIDTH; ++x) { printf("%s", (maze[y][x] == WALL) ? S_WALL : S_FLOOR); } printf("\n"); } return 0; } ニコニコ動画のプログラムを真似てみたのですが■が大量発生して強制終了してしまいます
>>440 >for (x = 0; y < WIDTH; ++x) {
この行!
a[0]=2 a[1]=0 a[2]=1 のとき、これの逆関数というか f(2) = 0, f(0) = 1, f(1) = 2 って感じで、2を与えられたら「a[?] = 2となる?は"0"なので0を返却する」ようなことって簡単にできますかね? やっぱりfor文で要素を一個々々調べるしかない?
>>443 ほう、mapってのを使えばできそうですか。調べてみます。どうもです
一般にそれは止めた方が良い巨大な配列というと どれ位の事を言うものでしょうか? int hoge[1000][1000] とかやっても良い?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define NULLPO NULL #define WALL 0 #define FLOOR 1 #define WIDTH 15 #define HEIGHT 13 #define S_WALL "■" #define S_FLOOR " " void dig(char maze[HEIGHT][WIDTH], int x, int y); int main(int argc, char **argv){ char maze[HEIGHT][WIDTH]; int y, x; memset(maze, WALL, HEIGHT * WIDTH); srand(time(NULLPO)); dig(maze,1,1); for (y = 0; y < HEIGHT; ++y) { for (x = 0; x < WIDTH; ++x) { printf("%s", (maze[y][x] == WALL) ? S_WALL : S_FLOOR); } printf("\n"); } return 0; } すいません又ご指導いただきます
void dig(char maze[][HEIGHT][WIDTH], int x, int y) { static const int vector_x[] = {0, 0, -1, 1}; static const int vector_y[] = {1, -1, 0, 0}; int directions[] = {0, 1, 2, 3}; int direction_count; maze[y][x] = FLOOR; for (direction_count = 4; direction_count > 0; --direction_count) { int direction_index = (int) ((double) direction_count) * rand() / (RAND_MAX + 1.0); int direction = directions[direction_index]; int moved_x = x + vector_x[direction] * 2; int moved_y = y + vector_y[direction] * 2; if (moved_x > 0 && moved_x < WIDTH && moved_y > 0 && moved_y < HEIGHT && maze[moved_y][moved_x] == WALL){ maze[y + vector_y[direction]][x - vector_x[direction]] dig(maze, moved_x, moved_y); } directions[direction_index] = directions[direction_count - 1]; } return; }
>>446 それが自動変数ならスタックサイズを指定してコンパイルすればいい。
そうでないなら、今時MiBオーダ位で気にすることはないだろ。
寧ろ問題は、本当に固定長でいいのかってことだ。
>>446 int hoge[0x8000000]とかは辞めた方がいい
>>447 何を指導して欲しいんだ?
>>448 のソースはひどいね。何をしたいのか分からん。
(二次元に配置したWALLをランダムで掘ってFLOORの道を作りたいんだろうけど。)
とりあえずソース貼り付けてから質問文を作ってるなら、先にテキストエディタにでもまとめてから貼り付けたほうがいい。
インラインアセンブラでファイルオープンしてデータ書き込みってできますか? OSはLINUXでCです。
>>452 できるっちゃぁできるけど、どうせシステムコールするだけなのになんでインラインアセンブラを使うの?
どうしてもアセンブラでやりたいならわざわざCのインラインにする必要もないだろうし。
>>446 環境によっては、1KBでも止めた方がよい
一般にとか言うのは難しい
>>447 #ifdef NULLPO
#undef NULLPO
#define GA
#endif
>>452 できるかといえばできるんでしょうけど、何のために、って感じる
あと、最近のコンパイラの最適化は結構優秀なので、
思いのほかインラインアセンブラに近い出力を、Cで出せることもある
C++では無理ですか?><
よく注意すれば可。でも、それができる頃には、そんな質問には自分の答えを持ってるはず
>>460 あちこち写し間違えてるだけ。
動画に正解が書いてるんだから、めんどくさがらずに一時停止しながら一字一句見直せ。
そのソースはコンパイルすればエラーメッセージが出てるはず。
何を間違えたか自分で考えたり調べたりした?
自分ではプログラムを理解しようともせずに、見よう見まねで打ち込んだら間違ってて分からない。
それを誰かに調べて欲しいというの? そんなのはここでは誰も助けてくれないと思うよ。
C言語です。 配列同士の引き算って出来ないのでしょうか? array1[] = {1,2,3,4,5}; array2[] = {5.4.3.2.1}; hoge = array1[2] - array2[2]; とやりたかったのですが、 invalid operands to binary - と出でしまいます。
>>462 array1, array2 の要素型は何?
勝手に省略せずに、問題の発生するひととおりのソースを貼ったほうがいいよ。
5,4,3,2,1だろw
>>462 構造体同士の引き算は出来ません
構造体の要素毎に計算しませう
>>463 >>464 >>465 すいません。
int i;
double hoge;
double array1[] = {1,2,3,4,5};
double array2[] = {5,4,3,2,1};
for(i = 0;i < 5;i++){
hoge = array1[i] - array2[i];
}
と言うことをやりたいと思います。
double tmp1;
double tmp2;
for(i = 0;i < 5;i++){
tmp1 = array1[i];
tmp2 = array2[i];
hoge = tmp1 - tmp2;
}
とやるしかないのでしょうか?
>>466 >と言うことをやりたいと思います。
それで動くはずだよ
std::vector<int> v1 = oven::initial_values(1,2,3,4,5); std::vector<int> v2 = oven::initial_values(5,4,3,2,1); assert( boost::size(v1) == boost::size(v2) ); std::vector<int> vo( boost::size(v1) ); foreach (e, boost::tie(v1,v2,vo) | oven::zipped) e.get<2>() = e.get<0>() - e.get<1>(); C++なら意図したものと同じような構文でできるよ^^
hoge意味ねぇ
mjd? 原因追及したいけれど、学校に行かなければならなくなりました。 帰ってきてから、デバッガで調べます。 どうもありがとうございました。
デバッガなんてたいそうなもん持ち出さなくても…
これからTR1とboostの勉強を始めるのですが、 良い参考書ってありますか?
boostのドキュメントとml
>>468 oven使いとかお前はなにもんだよw
あれ使ってるのまだpstadeさんくらいじゃなかったの
He is pstade.
No, I can't speak Engrish. hehehe:)
479 :
466 :2007/10/11(木) 13:02:43
解決しました。 グローバル変数の配列と構造体の名前が同じで、 構造体-配列という状態になっていました。 お恥ずかしい。
No Probrem.You can write English. ufifififi:)
クラスのメンバ変数?にdequeを持たせたのですが 初期化と破棄はどのように書くものでしょうか? 一応動くのですが、これでいいのかがいまいち理解できないです。 class hoge:public age { : char* mMagicCookie; std::deque<uint_t> packetSize; }; hoge::hoge() : mMagicCookie(NULL), packetSize() { : } hoge::~hoge() { }
どういう意味で初期化したいのか分からんけど、 メモリの確保と解放という意味で言ってるなら、それは考えなくていいです。 そういうのを自動でやらせるためのコンテナなんだから。 hogeのインスタンスが出来た時点でdequeの中に必要な値が入っている必要があって、 その意味で初期化と言っているのならば hogeのコンストラクタの初期化リストで値を入れてやるか コンストラクタの中でassignしてやればよろしいかと。
>>482 なるほど、道理で何も指示しなくてもエラーにならないのですね。
初期割当サイズを変えるにはコンストラクタのなかでreserve()をよべば、
・・・と思ったら、vectorと違ってdequeではreserveがないのか・・・
K&R 第二版228Pにあるmallocのコードについて質問なんですが nunits = (nbytes + sizeof(Header) - 1) /sizeof(Header) + 1; の-1や+1はどういう意味なんでしょうか?
>>484 最後の +1 は分けて考える。
(nbytes + sizeof(Header) - 1) /sizeof(Header) は、
nbytes を収めることができる最小の sizeof(Header) バイトの個数(用語難しいな)。
類例: n 円をm円玉で支払う場合に必要な最小の枚数は (n + m - 1) / m 枚。
ここまで説明されてもここの -1 の意味がわからないとこの先かなりつらい。
最後の +1 はヘッダそのものを収めるための sizeof(Header) 1コ分の領域。
>>485 とてもよくわかりました。ありがとうございます
int a[5]; a[0] = 0; a[1] = 0; for (int i=0; i<5 ;i++) { if( a[i] == NULL ) // 値が入っていなければ・・・ a[i] = 1; } こんな感じで配列に値が入っていなければ値を入れるように出来ますか?
488 :
デフォルトの名無しさん :2007/10/12(金) 17:17:44
>>487 正直、質問の意図がよくわからないけどw
整数のゼロを先に入れていて、
ゼロのままだったら、ということをしたければ、
せめてif (a[i] == 0) のほうが素直では。
できません。
>>488 配列に値が入っていれば何もせずに飛ばして
値が入っていなければ値を入れるようにしたいのですが・・・
>>487 場合によってできます。
配列の要素の型において、「絶対に代入されない値」が決められる場合は
その値のどれかを「配列の空値」として、配列作成時にかならず
その値で初期化しておくことにより可能です。
例えば、配列にはかならず1以上の整数を入れると決めているならば、
0や-1などを空値として定義して、その値で配列を初期化すれば良いです。
もし配列の要素が全域を取りうる場合(例えば、signed int で
INT_MIN~INTMAX の値をとりうる場合)「絶対に代入されない値」は
ありませんので「配列の空値」は定義できませんので上記のような
処理は無理です。
その場合、同じサイズの配列を用意したり、ビットマップを用意したりして、
空かどうかを別途管理する必要があります。
適切&丁寧すぎてワロタw
>>491 詳しい説明ありがとうございます
前者の方法で試してみます
>その場合、同じサイズの配列を用意したり、ビットマップを用意したりして、 ビットマップ?
この場合、各要素とその要素の初期化状態を紐付けたMapのこと
boost optional
497 :
491 :2007/10/12(金) 17:49:00
>>494 適当な型の配列を用意して、それが連続したビット列とみなします。
そして、そのビット位置と管理したいもののIDを対応付けて、
ビットのオン/オフで状態管理する方法をビットマップっていいます。
通常は、最初の要素の最下位ビットをID:0とします。
こうすると、char ひとつで8要素の未初期化状態を管理できます。
例えば、以下のビットマップでは 32bit x4 で 128要素の状態を管理できます。
int32_t bitmap[4];
サンプルに要素数5の配列を書くような香具師に、ビット単位で管理させるなんて阿呆だろう。常考 同要素数のunsigned charの配列で充分だって。
初心者でも使えるようにマクロ書いてみた #include<stdio.h> #include<limits.h> #define BITMAP_BIT(bitmap) (sizeof(bitmap[0])*CHAR_BIT) #define BIT_GET(bitmap, idx) ((bitmap[idx/BITMAP_BIT(bitmap)]>>(idx%BITMAP_BIT(bitmap)))&1) #define BIT_SET(bitmap, idx) (bitmap[idx/BITMAP_BIT(bitmap)]|=1<<(idx%BITMAP_BIT(bitmap))) #define BIT_RESET(bitmap, idx) (bitmap[idx/BITMAP_BIT(bitmap)]&=~(1<<(idx%BITMAP_BIT(bitmap)))) // 注意! int main(void){ unsigned char map[10]={0}; int number[30]; int i; number[5]=123; BIT_SET(map, 5); number[25]=1234; BIT_SET(map, 25); for(i=0;i<sizeof(number)/sizeof(number[0]);i++) if(!BIT_GET(map, i)) number[i]=i, BIT_SET(map, i); for(i=0;i<sizeof(number)/sizeof(number[0]);i++) printf("%3d : %d\n", i, number[i]); return 0; }
idxを括弧で括り忘れた
C++向けライブラリboostにあるboost::optionalは、 値がない状態(初期化すらされていない状態)を表現できる仕組みです。
てst
new演算子関数について教えてください T *p = new T; などでの一般のnew演算子は void* operator new(size_t) throw (bad_alloc) の呼び出しとなりますが、この引数が一つのoperator new関数は 必ずヒープに領域を確保するということでしょうか? 一方、配置構文newで使用される void* operator new(size_t, void* p) throw ( ) { return p; } では、ヒープの領域の確保はしないということでしょうか? よろしくお願いします。
504 :
503 :2007/10/12(金) 22:14:07
後半の配置構文newは定義を見れば確保してないのが 明らかでした。要は定義内容によるということですね。 前半の void* operator new(size_t) throw (bad_alloc) については言語仕様として関数定義内でメモリ確保 が行われているということですよね?
505 :
503 :2007/10/12(金) 22:19:04
しつこくてすみませんが、 前半の void* operator new(size_t) throw (bad_alloc) についてもクラス内でオーバーロードして隠蔽してしまえば ヒープに領域を確保しないような定義も可能になるんですよね? (要はやろうと思えばどんな定義でもできる) そんなことをする意味があるかないかは別としてですが。
>503 14882:2003 ではデータ構造としてのヒープしか出てこなくて、場所としてのヒープは出てこない。 適切にアラインメントされたメモリが返されることだけ規定されていてどこに確保されるかは規定されていない。 >についてもクラス内でオーバーロードして隠蔽してしまえば クラス内どころかグローバルの operator new も置き換え可能と規格で明言されている。 ただし、上記のように適切にアラインメントされたメモリを返す必要がある。
507 :
503 :2007/10/12(金) 23:35:07
>>506 規格ではヒープかどうかは別として、必ずどこかに領域が
確保されるということは間違いないということですね。
ありがとうございました。
>>501 これは凄い便利だな
デバッグ時に値が解らなくて不便な点も
autoexp.datを書き換えることで解決するみたいだし
class A { public: A( ) { } ~A( ) { } } ; A *p = new A ; delete p ; とした場合、Aのデストラクタが呼ばれオブジェクトが解体された後に動的記憶 領域の開放が行われると思いますが、以下のように明示的にデストラクタを呼び 出した場合はどのような動作になるのでしょうか? オブジェクトは解体されると思うのですが、newで確保された動的記憶領域は 正しく開放されるのでしょうか? A *p = new A ; p->~A( ) ;
class Widget { public: Widget( ) : { std::cout << "Widget::Widget()" << std::endl; } ~Widget( ) { std::cout << "Widget::~Widget()" << std::endl; } }; int main() { using namespace std; Widget *p = new Widget(3); operator delete(p); return 0; } のように delete p ; ではなく delete p ; で呼び出される operator delete (void*) を直接呼び出したところ、Widgetオブジェクトのデストラクタが呼び出されません でした。以下の理解で正しいでしょうか? 1. デストラクタの明示的呼び出しのみ p->=Widget( ) ; pの指す型のデストラクタが呼ばれるが、領域は開放されない。 2. operator delete ( p ) ; の明示的呼び出し デストラクタは呼ばれずに、領域が開放される。 3. delete p ; デストラクタが呼ばれた後、operator delete ( p ) が呼ばれる(領域が 開放される)。 つまり、delete p ; と operator delete ( p ) ; は動作が違い、後者では 領域の開放のみが行われる。
続きです。 結局、 delete p ; は p->~Widget( ) ; operator delete ( p ) ; と同じと考えてよいのでしょうか?
関係ないけど、publicだけならclassじゃなくstructの方がいいと思う。 たまにメンバも派生もpublicだけなのにclass使ってるソース見るけど違和感がある。
拡張考慮じゃね?
俺は用途に応じて使い分けてるなぁ。 ちょっと便利な構造体程度の使い方ならstruct、 後々隠したいメンバを追加する可能性があるならclassに、とか。
それはC++が、classはprivateで、structはpublicになっている OO言語の実装論からだろ? 意味論から見れば、 クラスではないはずの単なる構造体が どうしてクラスの概念を持っているのかが不思議。
fopenで開いているファイルの大きさを切り詰める方法を教えてください。 一時ファイルとして使ってるんですが、自前のデフラグで前に積めた時、 後ろのゴミを消したいので。
>>512 p の指すクラスが、クラス独自の operator delete () を提供している場合は違いが出てくる。
>>520 正確に書くと
p->~Widget( ) ;
::Widget::operator delete ( p ) ; //グローバルスコープのもの
で
Widget クラスで operator delete(void*) が定義
されていた場合は
delete p ;
は
p->~Widget( ) ;
Widget::operator delete ( p ) ; //クラス独自のもの
となるということですよね?
>>521 >511 の例で言えばそうだけど、デストラクタが virtual になってるクラスを
指してるときは動的な型の operator delete () が適用される。
>>519 ISOにはない。POSIX準拠でよければftruncate()が使えると思う。
>>522 なるほど。そこまで想定してませんでした。
class Widget
{
public:
~virtual Widget( );
} ;
class Derived : public Widget
{
public:
~Derived( ) ;
static void operator delete ( void* ) ;
}
Widget *p = new Derived ;
省略して書きましたが、上のような場合
delete p ;
は
D::~D( ) ;
Widget::~Widget( ) ;
Derived::operator delete ( p ) ;
ということですね。
サンプルプログラムとはいえ、class使ったりdeleteにstatic付けたり面倒じゃないか?
>>525 effective C++ではそのようになっていたのでそうしてます。
>>524 > D::~D( ) ;
> Widget::~Widget( ) ;
> Derived::operator delete ( p ) ;
おかしいだろ。
↓このほうが正解に近いかな。
p->~Widget( ) ; // virtual だから実際は ~Derived() が実行される。
Derived::operator delete ( static_cast<Derived*>( p ) ) ;
>>527 D::~D( ) ;
Widget::~Widget( ) ;
は
p->~Widget( ) ; // virtual だから実際は ~Derived() が実行される。
のつもりでした。派生クラスDerivedのデストラクタの実行による
派生クラス固有部分と基底クラス部分の解体。いずれにしてもD
はDerivedの間違いです。
Derived::operator delete ( static_cast<Derived*>( p ) ) ;
ここまで注意してませんでした。pの動的な型という
ことですね。
A *ap = new A; で、(デフォルト)コンストラクタAが例外を投げた場合、newで確保されたメモリ が開放されることは保障されていますか?
531 :
デフォルトの名無しさん :2007/10/13(土) 22:10:05
class Mutex{ (略) void Lock() throw(MutexException); void Unlock() throw(MutexException); }; こんなクラスがあらかじめ用意されてて、 こいつをラップするクラスを自作しています。 class ScopedLock{ private: Mutex* _m; public: ScopedLock(Mutex* m): _m(m){ _m->Lock(); } ~ScopedLock(){ _m->Unlock(); } } さて、デストラクタから例外を送出してはいけないらしいですが そうなると、ScopedLockみたいなRAIIパターンを使う場合は Unlock失敗は無視するほかないですか?
>>531 基本的にはそう。
後処理の失敗で分岐が発生するような場合は、明示的な呼び出しも
使えるようにしとくといいかもね。 std::ofstream の close() とか。
Mutexのアンロックに失敗されても、放っておくかabortするくらいしか対処のしようが無い気がするけどな
534 :
デフォルトの名無しさん :2007/10/15(月) 00:11:38
ReadFileをつかって、テキストファイル全部CStringに読み込む方法ってありますかね?
はい。
typedef double (*phi_x)( double ); /* ψ(x)関数 */ typedef double (*f_x)( double ); /* f(x)関数 */ ↑上のような記述があるサンプルソースを見ていたのですが コレまで構造体やtypedef int SIZEといった使いか確かしておらず このような記述は初めてでした。 すいませんが、これはどういうことをやっているのか教えていただけませんか?
double(*)(double) 型の phi_x を定義している よくわからないなら関数ポインタでぐぐってみれ
Linuxを使ってるならsignal(3)のmanページとかな。
>>536 使い方としてはこんな感じ
typedef BOOL (WINAPI *ENUMPROCESSMODULES)(HANDLE, HMODULE*, DWORD, LPDWORD);
ENUMPROCESSMODULES pEnumProcessModules;
hPsapi = LoadLibrary("psapi.dll");
pEnumProcessModules = (ENUMPROCESSMODULES)GetProcAddress(hPsapi, "EnumProcessModules");
pEnumProcessModules(hProcess, &hModule, sizeof(hModule), NULL);
typeofの修飾対象はstaticなどと同じ
>>536 phi_xとf_xは引数としてdoubleを一つ持ち、doubleを戻す関数へのポインタ型
}
>>537-541 みなさんありがとうございます
関数ポインタについて、なんとなくでしか理解していなかったので
この機会にちゃんと理解をします。
ありがとうございました
Linuxで、プロセスのリストを取得するには、どの関数を使うのですか? WindowsのEnumProcessのようなものですが、Linuxの構造に関しての知識はほとんどないため、相当のAPIを探しています。
544 :
デフォルトの名無しさん :2007/10/15(月) 21:58:13
関数ときたか。 Linux板に逝ったほうがいいとおもうが、ヒント。 - psコマンドをstraceしてみる - psコマンドをltraceしてみる - psコマンドのソースを読む
545 :
デフォルトの名無しさん :2007/10/15(月) 23:03:01
//ヘッダーファイル x.h class X { public: //省略 private: struct XImpl *pimpl ; } ; //ソースファイル x.cpp #include x.h struct X::XImpl { //省略(いろいろな定義) }; ソースファイルx.cppのコンパイルができません。 X::での修飾が悪いみたいなエラーが出ますが 原因はなんでしょうか?
>>547 structはヘッダーファイルに入れたら?
それじゃpimlイディオムの意味が
>>547 エラーメッセージをなるべくそのまま貼れ。
PImplイディオムか ググってでてきたところコピペしてみれば?
>>547 ,548
より詳しく言うならヘッダファイルのstruct XImpl *pimpl;
よりも前でXImplを宣言する必要がある。
それにインナークラス(クラス内でのクラス)なら親クラスであるクラスXの中に書かないといけない
//ヘッダーファイル x.h
class X {
public:
class XImpl {
//省略(いろいろな定義)
};
//省略
private:
struct XImpl *pimpl ;
};
//ソースファイル x.cpp
#include x.h
// メンバ関数の実装
// 例…クローン関数(似非)
X::XImpl X::XImpl::operator() (void)
{ return X::XImpl(*this); };
ヘッダで前方宣言すればいいだけじゃね
インナークラスとpimplを混同していると思われ。
たくさんのレスありがとうございます。
>>552 private部をコンパイル依存から切り離したいので
publicなインナークラス定義はおきたくないです。
struct XImplは別ファイルに定義したいです。
ちなみに以下のようにしたらコンパイルは通りますが
理由がわかりません。コンパイラはg++です。
//ヘッダーファイル x.h
class X {
public:
//省略
private:
struct XImpl ; //これを追加(前方宣言?)
struct XImpl *pimpl ;
} ;
//ソースファイル x.cpp
#include x.h
struct X::XImpl {
//省略(いろいろな定義)
};
struct XImpl *pimpl ; はstruct XImplの宣言も兼ねてるのではないんでしょうか?
>>555-556 struct XImpl *pimple; のように他の宣言の一部として現れた場合は、その宣言を
囲む名前空間スコープに宣言される。クラスや関数のスコープはすっとばされるわけね。
単品で struct XImpl; とした場合は、クラスでも関数でもそのスコープに宣言される。
規格の 3.3.1p5 参照。
たぶん C との互換性のためなんじゃないかな、と。
C++のenumで質問なのですが、 enum Fruit { Apple, Orange, .... } とあるとき、これらの列挙子をそのままC++の文字列として出力する方法はないでしょうか。 標準出力にそのまま"Apple"とやりたいのですが。
>>558 できません。
プリプロセッサを駆使して変換テーブルや変換関数を enum と同期させる手段が
ないこともない。
Fruit.tbl --------------- AAA(Apple) AAA(Orange) .... --------------- #define AAA(aaa) aaa, enum Fruit { #include "Fruit.tbl" } #undef AAA #define AAA(aaa) #aaa, const char *FruitString[] = { #include "Fruit.tbl" };
>>560 面白い方法だ
sed などを前提にしなくていいのがイイ!
>>560 × const char *FruitString[] = {
○ const char * const FruitString[] = {
興味深いけどundefとか気持ち悪いから実際には勘弁
>>563 このconstが2こついてるのがイマイチ意味が解らない
解りやすく教えてくれませんか?
>>566 const char *p; // ポインタの指す先がconst
char *const q; // ポインタ自体がconst
const char *const r; // 両方const
*p = x; // NG
p = x; // OK
*q = x; // OK
q = x; // NG
*r = x; // NG
r = x; // NG
>>567 なるほど。
簡潔な回答ありがとうございました
>>567 配列になってる
>>563 のときはどうなるの?
配列の要素のポインタ全てがconstってことかな?
FruitString[0]
FruitString[1]
・
・
・
が指す先を変えられないってこと?
FruitString[1] = x; //NG ?
C++でリスト構造のプログラムをするときは、 Cと同じように構造体を準備してするものですか? 構造体の代わりにクラスを準備しておいて 作るものですか?
>>571 標準ライブラリの std::list を使います。
>>572 早速のレスありがとうございます。
確認してみます。
Effective C++ 52項の動作確認をするために以下のサンプルを作りました。 しかしコンストラクタが例外を投げても、配置構文deleteが呼ばれず いきなりアボートしてしまいます。これは実装がC++標準に準拠してい ないからでしょうか?Fedora Core4のg++とBorland bcc32です。 class Widget { public: //コンストラクタ(故意に例外を投げている) Widget(int i = 0):mi(i){ cout << "Widget::Widget(int)" << endl; throw "reigai"; } ~Widget(){ cout << "Widget::~Widget()" << endl; } //配置構文new void* operator new(size_t s, int) throw(bad_alloc) { cout << "Widget::operator new(size_t, int)" << endl; return ::operator new(s); } //対応する配置構文delete void operator delete(void *p, int) throw() { cout << "Widget::operator delete(void *p, int)" << endl; ::operator delete(p); } }; int main() { Widget *p = new (1) Widget(3); return 0; }
575 :
574 :2007/10/17(水) 15:55:56
自己解決しました。 try catch構文で例外をキャッチしたら正しく呼ばれて いました。表示のタイミングの問題だったようです。 VCとg++はOKでしたが、bccはやはりNGでした。
あまり技術的な質問ではないのですが、以下の関数について bool F(bool b) { if(b){ return true; }else{ return false; } //★ } もれなくどちらかのreturn文が実行されることが確実な場合に、 ★の位置にreturn文は書く必要はありますか? (機能的に考えれば普通は書く必要は全く無いが、全ての処理系に対して 言語仕様の作法としてはどうあるべきかってことです)
>>576 ない
むしろコンパイラの警告が出て鬱陶しくなる
寧ろそのケースは -- bool F(bool b) { if(b){ return true; } return false; } -- こうとか -- bool F(bool b) { return b; } -- こう書かないか?
ですね
580 :
576 :2007/10/18(木) 20:16:32
>>577 なるほど。確かに優れたコンパイラであれば実行されないことに関して
ワーニングが出るかもしれないですね。
>>578 一番単純なサンプルコードを示しただけで戻り値がbool以外も考えてます。
前者の例でいくならelseでつなぐ方がコードの統一性が保たれるが良い気もしますが、
特に問題が無いということなので、あとはその辺りは個人次第ということですかね。
ありがとうございました。
581 :
576 :2007/10/18(木) 20:17:30
>が良い 編集ミス。
C言語ではコンソール画面にて入力した変数を使わないで入力があるまで 一時停止するのにgetchar()を使ってましたが、同様のことをC++でも したいのですが、 int buf; cin >> buf; 以外に良い方法はありますか?
#include<stdio.h> getchar();
#include <new> class CBase { public: /** new */ void* operator new(std::size_t aSize) throw(std::bad_alloc); /** delete */ void operator delete(void* aMemory) throw(); /** placement new */ void* operator new(std::size_t aSize, void* aPtr) throw(); /** placement delete */ void operator delete(void* aMemory, void* aPtr) throw(); }; Effective C++にあった配置newを試そうと上のクラスを作ってみたのですが、 BCBでコンパイルすると下記のエラーが出てしまいます E2238 'CBase::operator delete(void *) throw()' の宣言が複数見つかった ボス助けて
みっちゃん と入力しても みっちゃん が見つかりません。比較関数の書き方を教えて下さい。 #include <iostream> #include <map> #include <string> class human{ private: std::string name; int age; public: human(std::string name, int age){ this->name=name; this->age=age; } int getAge(void){ return age; } std::string getName(void){ return name; } }; typedef std::map< char* , human > clsmap_t; int main(void){ clsmap_t clsmap; human yosida("吉田", 21), mitui("三井", 20); char buf[100]; clsmap.insert(clsmap_t::value_type("よっちゃん", yosida)); clsmap.insert(clsmap_t::value_type("みっちゃん", mitui)); std::cout << "あだ名を入力して下さい : "; std::cin.getline(buf, sizeof(buf)); clsmap_t::iterator n = clsmap.find(buf); if( n == clsmap.end() ) std::cout << buf << " not found." << std::endl; else std::cout << n->second.getName() << " " << n->second.getAge() << std::endl; return 0; }
× typedef std::map< char* , human > clsmap_t; ○ typedef std::map< std::string , human > clsmap_t;
マルチかよ、糞が。
590 :
586 :2007/10/19(金) 08:26:50
>>587 ありがとうございます
どうにか char* のままでできる方法を探しています
すみません。解決したかもしれません
下のように変更したら動作はしました
typedef std::map< char* , human > clsmap_t;
↓
typedef std::map< char* , human , bool (*)(const char *a, const char *b) > clsmap_t;
bool cmp(const char *a, const char *b){
return strcmp(a, b)<0;
}
clsmap_t clsmap;
↓
clsmap_t clsmap(cmp);
>>588 >>589 それは自分がしたものではないです
mapのキーをchar*にしておきたいだけなら std::string buf; std::getline(std::cin, buf); のほうが簡潔じゃね?
あ、すまん。ビルド通らんわ。
>それは自分がしたものではないです 出たw
イマジンの和訳を自分のブログに張って 「オリジナルです」 「ジョンレノンという人は知りません。たまたま同じことを書いたのなら仕方ありませんね」 とか言い張る中学生を思い出した。
親切な人がコピペしてくれたんだよ なんでそんなことしたのか知らんけど
親切な人じゃないからだろうなw
陰謀だな
598 :
デフォルトの名無しさん :2007/10/20(土) 21:01:17
可変長引数に関する質問です(bcc32 and vs2005) void mprintf(const char*str,...) { char tmp[256]; va_list ap; static int i=0; va_start(ap,str); vsprintf(tmp,str,ap); sprintf(tmp,"%d,%s",i++,tmp); printf("%s",tmp); va_end(ap); } 上記の関数を定義しmprintf()を任意の引数で呼び出すと、printfで出力する ところの%s部分、tmpが表示されないです。若しくはバグってしまいます。 デバッガでtmpの内容を確認してみると、ゴミが混入しているらしいのですが、 どこか使い方間違っていますでしょうか?
>>598 間違っています
tmp の指す領域を書き換えながら読み込んではいけません
600 :
598 :2007/10/20(土) 21:15:25
なんという初歩的なミス。。 こんなことで一夜考えてました。 ありがとうございます。
catchのデフォルトや可変長引数の宣言に使う「...」って何者なんですか? 演算子でも予約語でもないですよね?
602 :
574 :2007/10/20(土) 22:25:43
単にそういう構文なだけ ; とか { } とかも別に演算子でも予約語でもないが普通に使ってるだろう
>>... 可変個引数を使うための書式 catchやオーバーロード関数時は他の場合のどれにも当てはめていく場合 これを用いた物が最後になる。 Cにもあるんだけどな...
前にstdarg.hを覗いたら、 ...がdefineされてたような気がする
>>605 #defineで?
マクロとして定義できるのって通常の識別子とおなじ形式だけじゃなかったっけ?
あれ、じゃあ見間違いかも
608 :
デフォルトの名無しさん :2007/10/21(日) 00:49:38
基本的な質問 void funcA(a&); void funcB() { ... func(a(100)); ... } このaのインスタンスの生存範囲はfuncBを抜けるまでという理解で正しいですか?
正しくない func(a(100)); が終わるまで
存在しない関数を呼び出してるけど、それはfuncAの間違いだとして aのインスタンスはfuncAの呼び出しが終了すると同時に解体されます。
funcを抜けるまで
612 :
574 :2007/10/21(日) 00:58:52
てか、非const参照に一時オブジェクトを渡せるんですか?
ほら、呼び出してるのは func であって、funcA じゃないから、きっとどこか見えないところで定義されてる別の関数なんだよきっと
614 :
574 :2007/10/21(日) 01:08:00
C++って奥が深いし難しい言語ですね JAVAの本見ると凄く簡単に見える
最近C++を覚え始めたのですが、オブジェクト指向の考え方について質問があります。 class foo{ ... }; class bar{ foo f; ... }; このような場合、barのfooに対する依存性が強いと考えられますが、OOP的には望ましくないのでしょうか? 特にfooがbarでしか用いられないような場合、fooをbarのインナークラスとして定義するべきなのでしょうか? もしくは、この設計は全くもって適当でない、と判断すべきなのでしょうか。
>>615 has a で is implemented in terms of 関係を実装するなら
普通にある形だと思いますけど。
>>615 それだけの情報で何か判断できると思ってるのが間違い。
>>616 ありがとうございます
特にfooがbarでしか用いられないような場合でも、わざわざインナークラス化する必要はないのでしょうか?
それと、答えてもらってなんなのですが、よく見直したら私の悩んでいることと先程の質問が少しずれていました……
すみませんが質問を訂正させていただきます
class bar;
class foo{
...
public:
void function(bar &b);
};
class bar{
foo f;
...
pubilc:
void dosome(){f.function(*this);}
};
このような場合、foo、barともに互いの存在を前提にしているわけですが、
やはり問題無いのでしょうか?
619 :
618 :2007/10/21(日) 02:09:47
>>617 曖昧な質問ですみません……
悩んでいるのは
>>618 の例で、
barがfooを持つことを前提とし、
fooがbarに持たれること(少なくともbarを関数の引数として受け取ること)を前提としている場合、
これは果たしていいのかどうか、ということです。
自分としてはそれぞれの独立性が損なわれるような気がして気持ち悪かったので、以下のような方法を考えました。
1.単純に、それぞれのクラス設計を適切に変更して独立性を確保する
2.fooクラスを分解してbarの実装として取り入れる
3.fooクラスをbarのインナークラスとする
1については適切な設計が思い浮かびませんでした
2については、クラスの分解ということでむしろOOPに逆行しているのでは、という躊躇いがありまして、
3はインナークラスを安易に用いるべきではないのでは、と考えて、やはり躊躇しています。
ここまで考えて、そもそもこれは直す必要があるのか、と考えて質問させていただいた次第です。
少なくとも
>>618 のような関係性だけでは、やはり「何とも言えない」程度なのでしょうか?
あれだけで不味いということは、ないのでしょうか。
もう面倒だからクラスをいっこはさむ foo <-> hage <-> bar
>>619 何とも言えない。そういう関連が必要になる実際の仕様があまり
思い浮かばないんだけど、仕様を見ずに否定もできない。
具体的な情報が出せないんなら相談は無理だと思われ。
622 :
618 :2007/10/21(日) 02:46:17
>>620 あ、その方法でちょっと関係性を練り直せば、何とかなるかもしれません
そんな方法すら思いつかなかった自分が恥ずかしい……
ありがとうございます。
>>621 イメージとしては、bar has a foo.で、
持ち物(メンバ)としてのfooが持ち主のbarに対して何らかの効果を及ぼす、って感じなんですが、あんまりないんですかね。
とりあえずなんとかなりそうなんで、質問を打ち切らせていただきます。
そこらへん思ったときにリファクタリングできるように書けばいい 言うは易し(ryだが、これに尽きるかと
>>619 何かマジで仕事で書いてるプログラムじゃないか?
こんなとこで相談するんじゃなくて経験ある先輩に
聞けよ
そんな先輩がいないというよくあるパターンじゃねw
独りぼっちなんだろ
劣悪な環境なんていくらでもある。 改善によってムダがなくなることが工数削減となり、金銭面で不利になることを嫌い改善を認めないのもよくある話。 そういう環境下では相談できる相手なんていないので独りぼっちになる。
628 :
618 :2007/10/21(日) 13:30:28
いえ、工房の趣味グラマです
絶対に外で使われる事はないならインナーしかもprivateにしちゃえばいいよ
tr1::shared_ptrについてですが、 class B { public: ~B( ); }; class D : public B { public: ~D( ); }; のように基底クラスのデストラクタを仮想にしなくても tr1::shared_ptr<B> にDクラスの動的オブジェクトを 格納すると、オブジェクトの解放時に正しくDのデストラクタが 呼ばれるのですがそういうものなんでしょうか? コンパイラはg++です。
型Tに対して、 T obj; const T& ref = obj; となっている場合、&refの型は const T* なのか、T* なのか どちらでしょうか?
>>631 参照はポインタではない。参照の挙動は実体と同じ。よってconst T
#include <stdlib.h> int main() { int *p = malloc(sizeof(int)); return 0; } Cだとコンパイルできますが、C++だと型変換エラーで コンパイルできませんでした。 mallocはvoidのポインタを返し、voidポインタは任意のポインタ に代入可能なはずですが、何が違うのでしょうか?
>>632 &refとすると、refが参照しているオブジェクトのアドレスを取得できる
と記憶してたのですが違いますか?
&refの型は少なくともポインタであるはずなのですが。
>>633 voidポインタが暗黙のうちに型変換されて代入できてただけ
>>634 ごめん、631の「 &ref 」を 「 T&ref 」と間違えて読んでいた。
ref の型は const T と同じ挙動だから const T*
>630 驚くべき事に shared_ptr<void> にしても正しいデストラクタが呼ばれる。 キーワードは deleter。 shared_ptr 生成時に正しいデストラクタを呼ぶ deleter も作成して shared_ptr の中で保持し、破棄時に呼び出している。
>>636 なるほど。refの型に依存するわけですね。
ありがとうございました。
operator=とかがtemplateになっていて、代入時に右辺の型を判別できるようにし、 そのデストラクタを記憶してるって事?
>>635 CでもC++でも、仕様ではvoidポインタから任意のオブジェクトポインタへの
暗黙の型変換が可能だと思っていたのですが、Cでは認められていて
C++では認められていないということでしょうか?
(ANSI CとC++では仕様が異なる?)
641 :
630 :2007/10/21(日) 17:20:42
>>637 便利にできてるんですね。
後日deleterについて調べて見ます。
>>639 さんは自分ではありません。
642 :
デフォルトの名無しさん :2007/10/21(日) 17:28:12
boost::anyの実装でも読んどけ。簡単だから。
>>643 仕様が違うんですか。勉強になりました。
EffectiveのとおりだとするとC++ではstatic_castを使うわけですね。
int *p = static_cast<int*>(malloc(sizeof(int))
645 :
デフォルトの名無しさん :2007/10/21(日) 18:34:42
日本語を使うときc++のstringをつかうより、安定している型ってありますか
646 :
デフォルトの名無しさん :2007/10/21(日) 18:37:47
お前の「安定」の定義を述べよ。話はそれからだ。
wstringでいいんじゃない?
648 :
デフォルトの名無しさん :2007/10/21(日) 18:56:14
文字を読む込んだときに統一的にあつかること
「統一的」の(ry
「あつかる」n(ry
「読む込んd(ry
652 :
デフォルトの名無しさん :2007/10/21(日) 19:18:20
wstring w = L"テストです。"; wstring w = _T("青野晃です"); L Tの意味わかりますかか?
653 :
デフォルトの名無しさん :2007/10/21(日) 19:19:39
L"" はワイド文字列のリテラルであることを示すためのC++の標準機能。 _T() はVC++のマクロ。どう展開されるかは設定による。
分からない方が珍しい
青野晃って誰?
657 :
デフォルトの名無しさん :2007/10/21(日) 19:26:12
サンクス
みなさん2ちゃんねらーなのにかなり詳しいですが、 やはり業務でC++を使いまくっているんですか?
はい
2ちゃんねらーなんかじゃないですよ
>>658 > 2ちゃんねらーなのに
麻生元幹事長も2ちゃんねらーだそうだよ。
>>645 wchar_tは実装依存なので、今のところはstd::string+UTF-8は
案外悪くないかもしれない。
UTF-16ベースのWindowsワールドでは微妙だけどな。
662 :
デフォルトの名無しさん :2007/10/21(日) 19:38:26
うごきません 文字出ません #include <string> #include <iostream> using namespace std; main(){ wstring w = L"青野晃です"; wcout << w << endl; }
665 :
デフォルトの名無しさん :2007/10/21(日) 19:46:43
666 :
デフォルトの名無しさん :2007/10/21(日) 19:46:53
どうすれば wstring w = L"青野晃です"; がでますか?
礼儀知らずだし、いい加減人の名前使うのやめたら?
msvc なら std::wcout.imbue( std::locale("japanese") ); gccなら ::setlocale( LC_ALL, "ja_JP.utf-8" ); をoperator<<を使う前に実行すればできたようなできなかったような
669 :
デフォルトの名無しさん :2007/10/21(日) 19:54:00
すみません wstring w = L"テストです。"; の出し方教えて下さい
素直にstringかprintfで。
>>662 ワイド文字、文字セット、ロケールの関係?
僕もこのあたりよくわかりませんね。
>>668 プログラムで別のものを指定すれば、環境変数LANGがja_JP.eucでも
問題ないのですか?
673 :
664 :2007/10/21(日) 19:59:01
>>665 wchar使ってないからwcoutあるなんて知りませんでした…。
>>672 環境変数LANGやLC_CTYPEに応じて設定して欲しい(WinならACPを見て欲しい)
んなら、単に空文字列を指定すればよいよ。
それが一番普通の使い方。
675 :
デフォルトの名無しさん :2007/10/21(日) 20:01:51
stringがいちばん安定してるって事?
だから安定って何なんだyo
>>672 もちろんシェルで表示できるロケールじゃないと当然のように文字化けはするがね
678 :
デフォルトの名無しさん :2007/10/21(日) 20:05:24
>>676 読み込む文字種に依存しない、不都合がおこりにくい
>>675 素直にそう思ってくれた方がここが安定する
一応標準なんだから素直に受け入れてみては如何?
wstringも標準だけどね。
681 :
デフォルトの名無しさん :2007/10/21(日) 20:15:07
stringに文字を渡すときは、どんなコードがいいんですか? unicode?
682 :
671 :2007/10/21(日) 20:25:29
>>668 >>674 >>677 ::setlocale(LC_ALL, "ja_JP.UTF-8");
wstring str = L"こんにちは";
wcout << str << endl;
これでうまく表示されました。よくわかってないですが感動しました。
setlocaleはCにもある関数らしく C++の標準に従うと、 locale loc("ja_JP.UTF-8"); locale::global(loc); wstring str = L"こんにちは"; wcout << str << endl; とするらしいですが(プログラミング言語C++)、 Linux環境(LANG=ja_JP.UTF-8)では正しく表示されました。 ソフトのローカライズ作業などでは、このようなこともするのでしょうか?
684 :
デフォルトの名無しさん :2007/10/21(日) 20:45:47
BCC5.5.1だと682も 683も駄目
>>683 ま、それなりにマルチプラットフォームに対応したければ、
バグだらけの実装の地雷を踏みまくることを覚悟汁。
cygwinのようにあまりにロケールまわりがヘボくて、
wstringは使えないという環境もあるよ。
そういうgochaを避けたければ、残念ながら現状ではstd::stringを
使ったほうがいい気もする。
gocha?? gotchaか?だとしても意味がよくわからないけど。
>>685 ローカライズは難しい問題があるようですね
stringだけを使う場合はbasic_string<char>だから日本語は諦める
しかないですね。
>>687 文字の区切りを自分で判定しないとダメだが、日本語を格納してはだめってことにはならんだろ。
多言語対応するならwstringの方が便利だろうけど 日本語のみならstringでもいいんじゃない?
690 :
デフォルトの名無しさん :2007/10/21(日) 21:09:13
すみません MSDOSで上位ディレクトリや自分のディレクトリを 点や点点で表現すると思うのですが、これを点「.」で比較すると一致しません どんな文字と比較したら点と一致しますか
>>690 一致しないプログラム貼りつけるとすぐ答えが返ってくると思う
>>690 ==ではなく、!strcmp()で比較しましょう。
とエスパー。
693 :
690 :2007/10/21(日) 21:19:18
おねがいします #include <iostream> #include <windows.h> #include <stdlib.h> using namespace std; main(){ HANDLE hd; WIN32_FIND_DATA fd; system("mkdir test"); hd = FindFirstFile(".\\test\\*", &fd); char ch[]="."; do { if(fd.cFileName!=ch){ printf("ファイル名: %s", fd.cFileName); if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) printf("(ディレクトリ)"); printf("ファイルサイズ: %d\n", fd.nFileSizeLow); }} while(FindNextFile(hd, &fd)); FindClose(hd);}
お前等凄いな プログラムなんて覚えようと思って始めた次の日には理解出来ずに止めてしまうのに
>>694 お前には向いてなかったんだ。他のものを頑張れ
697 :
690 :2007/10/21(日) 21:24:05
サンクス
>>696 そう言う時は嘘でも良いから励ませよ
それが心意気ってもんだろ、あばよ
>>698 人間のリソースなんて限られてるんだから無駄遣いしちゃダメだってことさ
>>694 「プログラムなんて」に微妙な上から目線を感じる。
>>698 励ましたつもりだが?アホだから覚えられないんだよが本音
おまえらは自分より下とわかるとすぐに調子に乗って・・・
703 :
デフォルトの名無しさん :2007/10/21(日) 22:16:15
char ch[2000]; をstring型に変換する必要があるとます chの文字列長を計るには、ループか、標準関数か、size()のどれが速いですか?
あるとます
706 :
デフォルトの名無しさん :2007/10/21(日) 22:18:54
>>706 まずはstd::stringにどういうコンストラクタがあるか調べて来い。
708 :
デフォルトの名無しさん :2007/10/21(日) 22:27:19
MFCで、SetModifiedFlag();を使うときなのですが、 シリアライズを使わない方法をやっているのですが、SetModifiedFlag();をしたときだけなぜかシリアライズのほうが実行されるのですが 回避する方法はありますか?
>>703 sizeof(ch)/sizeof(char)
ってそういう話じゃないか……
strlenでも使えば?
710 :
デフォルトの名無しさん :2007/10/21(日) 22:31:33
計ってみました size()が最速でした
>>707 やり方わからないですがコンストラクタk速いですか?
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
#define N 10000
#define M 300000000
main(){
char c[N];
int n,x,k,cl;
for(n=0;n<N-1;n++)c[n];c[N]='\0';
string s=(string)c;
x=0;cl=clock();for(n=0;n<M;n++)x+=strlen(c);cl=clock()-cl;cout<<cl<<endl;
x=0;cl=clock();for(n=0;n<M;n++)x+=s.size();cl=clock()-cl;cout<<cl<<endl;
x=0;cl=clock();for(n=0;n<M;n++){for(k=0;c[k]!='\0';k++);x+=k;}cl=clock()-cl;cout<<cl<<endl;
}
711 :
デフォルトの名無しさん :2007/10/21(日) 22:31:38
>>703 strcmpとかってつかえないんだっけ?
あとは.Formatとかは?
712 :
710 :2007/10/21(日) 22:32:42
まちがえました
713 :
デフォルトの名無しさん :2007/10/21(日) 22:47:34
MFCでViewの背景を青色にしたのですが、 スタティックテキストの背景だけデフォルトの色のままです。 スタティックテキストの背景も同じ色になってほしいのですが、 透明にする方法はないでしょうか??
714 :
デフォルトの名無しさん :2007/10/21(日) 22:59:58
なんとなく解決しそうです。 OnCtlColor関数をオーバーライドしたら、できそうです。
仕事や勉強しているけど 実はプログラミングがあまり好きではない人いる?
そんな人いるのかな~ 好きなのじゃなけりゃ、勉強でも仕事でも そう長続きはしないだろうけど
>>716 時間忘れて勉強できますか?自分は30分くらいで休憩
してしまいます。
コンパイラ作れるくらいだったら尊敬されるけど
>>717 自分は30分単位で休憩をはさむと覚えられない
本読んで、書いてみて、動作させて、弄って、また動作させてだから
始めると 1 時間は続ける
コンパイラなんかもC++で作ってるの?
>>717 年齢にもよるだろうけど、若いうちはうっかり20時間くらい
飲まず食わずで続けちゃったりしない?
>>717 集中の仕方は人それぞれだと思うんだが、30分はちと短いな。
ふつうは集中してフロー状態に入るまでにそれなりの暖気運転=時間を要する
ものなので、それだと効率が悪すぎる。
多分君は、そこまで行っていないんだろうね。
夢中になれるほど好きでなければやっていけない、というものでも無いとは
思うが、好きなほうが有利なことは確かだねえ……。
>>721 さすがにトイレには行ったけど、学生時代にそんな感じでやってたことあるよ。
三十路を過ぎた今ではもう無理だorz
というか働くようになると、趣味としてのプログラミングに避ける時間が少ない。
すまん。避ける→割ける
マ板でやれ
だったら誘導しろカス
逆ギレか。なさけな。
プ
>>716 嫌いでも楽に理解出来るから仕方なくやってる奴だって居るけどな
好きな事をやってる奴なんてこんな世界には殆ど居ないよ
人間というものの要件定義書 まず自分にとって心地よいかどうか。 次に心地悪くても、論理的に自分にとっての利益となるなら我慢する。 心地よいことも続けてるとそうではなくなる。 我慢できてることも続けてるとそうではなくなる。 バランスが変わると行動の代わり時。
>>702 自分より下だと思った奴を見下したい
自分と同レベルのキモオタと馴れ合って現実逃避したいから2chやってるんだろ
上を見る奴は2chなんか来ないし
>>735 それは君の信念であって、他の人間がどういう風に2chと接しているかはわからないよ。
君もプログラマの端くれなら、データも取らずに「大きな結論」に走っちゃいけないよ。
ちょっと必要だったんで、intの上位バイトへのアクセス速度を測ってみた。 長いからソースほとんど省くけど、 #define BYTE_SLIDE(a,n) *((char*)(a)+(n)) int x[100];for(i=0; i<M; i++) x[i]=0x01010101;c = clock(); for(i=0,y=0; i<10000; i++) //Test1 for(j=0; j<100*sizeof(int); j++) y+=BYTE_SLIDE(x,sizeof(char)*j); c = clock() - c; printf("Test1-A:%d*%d*%d=%u,time=%.4f\n",10000,100,sizeof(int),y,(double)c/CLOCKS_PER_SEC); y=0x01010101;c = clock(); //Test2 for(i=0,z=0; i<1000000*sizeof(int); i++) z+=BYTE_SLIDE(&y,sizeof(char)*(j%sizeof(int))); c = clock() - c; printf("Test2-A:%d*%d=%u,time=%.4f\n",1000000,sizeof(int),z,(double)c/CLOCKS_PER_SEC); こんな感じのをそれぞれの方法について。以下結果。むらがあったんで1000回平均。 Test1-A:Average is 0.012961. //上記 Test1-B:Average is 0.012788. //((char*)x)[j] Test1-C:Average is 0.025887. //ビットシフト Test2-A:Average is 0.016863. Test2-B:Average is 0.020827. Test2-C:Average is 0.024504. Test2-D:Average is 0.015565. //剰余でなく繰り返しで。方法はBと一緒。 当たり前なのかもしれないけど、わざわざビットシフトするよりポインタアクセスのが速いんだね。 (Test1-Cは添字アクセス経由してるから当たり前としても) それと剰余よりも単純繰り返しのが速い。もしかして常識?
質問です。 scanfで数値を読み込む動作を他の入力関数で置き換えようと思っているのですが stdinからfgetsで読み込んでから数値等に変換しようと思っています。 もっと良い方法はありますでしょうか?
>>738 どんな入力なのか内容について詳しく
1行について一つの数値だけなのか、複数あるのか
数値ではないものが来た時に読み飛ばして続けるのか、終了するのか
などなど
No! Always , "getchar()" is the best way!! いいえ! 常に、"getchar()"が最良の方法です!!
文字列リテラル中のシングルクォーテーションや 文字リテラル中のダブルクォーテーションも\でエスケープすべきなのでしょうか?
しなくてもいいよ。試せばわかる。
>>743 了解です。
レスありがとうございました。
745 :
デフォルトの名無しさん :2007/10/26(金) 13:48:04
DirectX9のIDirect3D9のCreateDeviceを実行環境にあわせてパラメータを変えながら使うときに、 変化しないパラメータをbindを使って固定しようとしました IDirect3D9 *pD3D = /**/; // 固定するパラメータ HWND hwnd = /**/; D3DPRESENT_PARAMETERS* param = /**/; IDirect3DDevice9** dev = /**/; // bind boost::bind/*<UINT>*/ (&IDirect3D9::CreateDevice, pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, param, dev)(); これだとなんかうまくいかないので上のコメント部分を外して戻り値の型を明示的に指定してやると >error C2064: 7 引数を取り込む関数には評価されません。 どうにかうまくできませんかね?
746 :
745 :2007/10/26(金) 14:01:46
= /**/は省略で実際はなんらかの値を取得してます。 またD3DVTYPE_REFやD3DCREATE_SOFTWARE_VERTEXPROCESSINGは boost::lambdaのプレースホルダにする予定です。 「このようにパラメータを与えたbindから生成される関数オブジェクトに、 D3DTYPE_やD3DCREATE_等の定数を放り込んで、 環境に合わせて適切なDirect3Dデバイスを生成するルーチンを簡単に書きたい」 というのが目的です。
748 :
745 :2007/10/26(金) 14:28:33
750 :
デフォルトの名無しさん :2007/10/27(土) 10:02:47
Visual Studio6.0使ってCの勉強してるんですが Visual C++ 2008のβを入れてみました。 APIをやりつつMFCも触ってます。 そこで、6.0はMFCプロジェクトを 新規作成→MFC APP(exe) で作れたのですが2008では windowsコンソールアプリ API32コンソールアプリ どちらにすればいいのか・・・・ 二つの違いがサッパリ分かりません!! こんな初心者に違いを教えて下さい
作ってみてもまだ違いが分からないような初心者がOrcusに手を出すな。
752 :
デフォルトの名無しさん :2007/10/27(土) 10:59:03
確かに。手に余るのでアンインスコします
public static int[] invoke(int[] input){ //WARNING: This will destroy the contents of the input array //This function assumes input.length=2^n, n>1 int[] output = new int[input.length]; for(int length = input.length >> 1; ; length >>= 1){ //length=2^n, WITH DECREASING n for(int i = 0; i < length; i++) { int sum = input[i*2]+input[i*2+1]; int difference = input[i*2]-input[i*2+1]; output[i] = sum; output[length+i] = difference; } if (length == 1) return output; //Swap arrays to do next iteration System.arraycopy(output, 0, input, 0, length<<1); } } ここで聴いていいのかアレなのですが このJAVAのソースをCに直したいのです、、、俺に力を!!!!!!!!11
何が問題でCにできないと言ってるのかがわからんと。 int[] をCではどう書けばいいのかわかりません、って話ならmalloc使えって話だし、 arraycopy の代わりは?って話ならmemcpyでも使ってみたら、とかかな。 Cってなんですか?ポインタってなんですか?なら無理すんなとしか言えない。
宿題なら宿題スレにいってやってもらうべきだし、 そうじゃないなら具体的にどこがわからないのか書くべきだな
>int[] をCではどう書けばいいのかわかりません、って話ならmalloc使えって話だし、 >arraycopy の代わりは?って話ならmemcpyでも使ってみたら、とかかな。 まさしくそのとおりです!!!! int[]って何よ?おいしいの?JAVAシネやって感じでした!!! > for(int length = input.length >> 1; ; length >>= 1){ このfor文もなにやってんだかさっぱりです! C最高!!!わかりやすいのに!JAVAしねやJAVAくそまんこ!!!
わかりました!宿題スレ行ってきます! でもこっちでも回答ください!!!!みんな大好き!
リアル厨房か
759 :
デフォルトの名無しさん :2007/10/27(土) 17:35:19
お前が死ねや マルチ野郎
厨房っぽく振舞いたかっただけで。。。ほんとすみません
っぽくも何も…
762 :
デフォルトの名無しさん :2007/10/27(土) 18:18:18
C++から、Cの共有ライブラリを実行したいのだけど。環境はLinuxで GCC4です。コンパイラ、リンカはg++を使っています。 そのままCの共有ライブラリをリンクしようとしてもうまくいかないの ですが、なにか手順が必要なのでしょうか?
764 :
デフォルトの名無しさん :2007/10/27(土) 18:24:07
>>763 C++の共有ライブラリにあるシンボルが、未定義であるっていう
エラーメッセージです。例えば、libmy.soがCのライブラリで、
myfuncという関数があるとして、nmでlibmy.soのシンボルを
表示させても、きちんとmyfuncというのがあります。
libmy.soはgccでコンパイル、アーカイブしています。
で、c++のソースコードをg++でコンパイル、リンカ指定で
-lmyすると、リンクするときに
"undefined reference to symbol myfunc"となります
>>762 どうせ extern "C" が抜けてるんだろ。
>>764 エラーメッセージもコンパイル時のコマンドラインもコピペしろ。
手で書くと余計な解釈や思い込みが混ざる。
767 :
デフォルトの名無しさん :2007/10/27(土) 18:30:13
>>765 おっしゃるとおりでした!
ありがとうございました。
myfuncの宣言にextern "C" がないとmyfuncとは違う名前で オブジェクトファイルが作成されるんではなかったっけ? ライブラリなら#ifdef __cplusplus マクロの指定が必要とか
やっぱりエラーメッセージの手写しは駄目だな。 extern "C" が原因なら undefined reference で表示されるシンボルは myfunc じゃなくてもっとキモイやつだったはずだ。
770 :
769 :2007/10/27(土) 18:38:57
あ、 C から参照してるのか。じゃぁ嘘は nm で「きちんとmyfuncというのがあります」のほうだな。
c++のほうのオブジェクトファイルのmyfuncのシンボルがキモイ名前に なってるはず
obj「ママ、みんなが僕の名前気持ち悪いっていじめるんだ。」 gcc「ごめんよ。母さん、お前のためを思って、頑張っていい名前を考えたんだけど…。ゴメンね。」 ln「お前の名前には、ちゃんと立派な意味があるんだ。『人』には理解されにくいかもしれないが、いつかきっと分かってもらえる。 父さんたちを信じて、もっと自信を持て。」
組み込みシステムでC++を使ってる人いる? 例外処理外してコンパイルしないとパフォーマンス落ちないか?
そりゃそうだろ 巻き戻しの処理入るんだから
組み込みってバリバリTMPとかプリプロセッサメタプログラミングさせてくれるんでしょ? いいよなぁ羨しいよ
コードサイズが予想しにくいのでダメです
例外処理外してコンパイルした場合 newは失敗してもbad_alloc投げなくなりますか?
>>774 速度は実測が基本。
例外を実際に投げない限りは速度にペナルティの無い実装もある。
>>778 標準の動作じゃないから、コンパイラのマニュアル嫁。
>>779 第三者が横から質問ですが、vc2005の場合はその速度に影響のない実装なんでしょうか?
憶測しましたw
>>778 gccの場合、-fno-exceptionsでコンパイルしてもnewは例外投げるよ。
例外が投げられると即死する実行ファイルができるだけ。
bool型配列で bool b[1000]={false}; で、要素0以外の値がfalseで初期化されることは保障されていますでしょうか?
0で補完されるんじゃなかったっけ? false==0だろうから問題無いと思うけど
>>785 心配ならBOOST_STATIC_ASSERT(false == 0); でも入れておけば。
>>786 配列の要素の指定されていない部分が0で補完される仕様と、
bool型のfalseがint型の0と互換性がある仕様二つから保障されているということですね。
>>787 BOOSTライブラリですか。検討してみます。
ありがとうございました。
Trieの練習で文字列の出現頻度を計算するプログラムを書きたいのです。 それで、各ノードにポインタ配列を用意して、各文字列別の遷移先を作りました。 しかし、そこの遷移先のチェックのif(prevNode->next[c]==NULL)で実行時にエラーが出てしまいます。 NULLかどうかのチェックも確認出来ないのでしょうか?ポインタ配列として宣言してるので、ポインタそのものの領域はあるはずなのですが…。 ソースはこんな感じです。 typedef struct NODE{ char c; int *p_freqList; NODE *next[MAX_CHAR]; }NODE; typedef struct{ NODE *root; int freqList[MAX_WORD]; }GLOBAL_DATA; GLOBAL_DATA g_data; void initFreq(){ memset(g_data.freqList, -1, sizeof(int)*MAX_WORD); g_data.root=(NODE *)malloc(sizeof(NODE)); } NODE *addNode(unsigned char c, NODE *prevNode){ if(prevNode->next[c]==NULL){ ←ここで問題発生 prevNode->next[c]=(NODE *)malloc(sizeof(NODE)); memset(g_data.root->next,NULL,sizeof(NODE*)*MAX_CHAR); } return prevNode->next[c]; }
790 :
789 :2007/10/28(日) 14:05:54
NODE *addLeaf(NODE *prevNode){ if(prevNode->next[0]==NULL){ prevNode->next[0]=(NODE *)malloc(sizeof(NODE)); prevNode->next[0]->c='\0'; for(int i=0; i<MAX_WORD; i++){ if(g_data.freqList[i]==-1){ prevNode->next[0]->p_freqList = &g_data.freqList[i]; break; } } } *(prevNode->next[0]->p_freqList)++; return prevNode->next[0]; } void addStr(char *str){ int i=0; NODE *node=g_data.root; while(*(str+i)!='\0'){ node=addNode(*(str+i), node); i++; } addLeaf(node); } Cは、久しぶりに触ったので、色々忘れてる部分も多く、問題が多いと思いますが どうぞ、よろしくお願いします。
791 :
デフォルトの名無しさん :2007/10/28(日) 14:54:33
読み込むインクルードファイルなど全文おしえろ
792 :
789 :2007/10/28(日) 15:01:43
>>791 レスありがとうございます。
とりあえず、
>>789-790 は、trie.hと言うファイルに記述されていて
main.cppに
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "trie.h"
int main(void){
char str[1024];
initFreq();
while(1){
scanf("%s", str);
if(str[0]=='q')
break;
addStr(str);
}
}
と言う形でTrieへの追加の実験コードを書きました。
例えば、"abc"と入力した所
bの追加の処理中に、NULLとの比較でエラーが出ます。
よろしくお願いします。
>>789 #define MAX_CAHR 255?
#define MAX_WORD ???
この辺りが不明だけど、
ま、いいでしょう。
で、問題の箇所だが、2文字目ってのがわからん。
普通に1文字目からエラーが出るはずだが・・・
1.今のノード=ルート
2.今のノードの次のノードを参照し、入力文字を辿る←この時点で、次のノードの領域確保なんてしてるの?
よくヘッダ初めに class Foo; struct Bar; あとこれとか void function(class FooClass *ptr); とあるけど,これなんと呼ぶのでしょう? ある名前が,こいつはクラス・構造体だぜって宣言してるのは判るんですが
795 :
デフォルトの名無しさん :2007/10/28(日) 18:32:04
forward declaration
>>794 class Foo;
は前方宣言。
class FooClass だけだと elaborated-class-name とかいうんだけど、
日本語での呼び方はしらない。
前方宣言
更新すればよかった恥ずかしい
>>795-797 うほ早!サンクス
呼び方が判らなくて正しい使い方が調べられなかったのです.
enum Foo_{ A,B,C }; struct Bar{ typedef Foo_ Foo; }; こういうことは出来ないのでしょうか? enumじゃなくてstructならできるんですが…
802 :
801 :2007/10/29(月) 00:24:50
すいません思いっきり勘違いでした、できました
803 :
801 :2007/10/29(月) 00:52:38
すいません、質問したいのはこういうことでした。 namespace NA{ enum Foo{A,B,C}; struct Inner{ Foo_ foo; }; } namespace NB{ struct Bar{ typedef NA::Foo Foo; typedef NA::Inner Inner; void test(){ Inner f; f.foo = NA::A;//←本当は、Aと書きたい } }; } この願いは、無理でしょうか? Visual C++ 2005 で試しました。
>>803 using namespace NA;
805 :
801 :2007/10/29(月) 01:19:47
struct Bar{ using namespace NA; (略) }; だとエラーになってしまいます。 namespace NB{ using namespace NA; struct Bar{ (略) }; } だとOKですがこれでは名前空間を分けた意味がありません。 無理ってことですかね…
>>805 using NA::Foo;
using NA::A;
using NA::B;
using NA::C;
using NA::Inner;
char型同士の演算は、char型で帰ってきますか
>>805 usingディレクティブをクラス定義のなかに入れることは違反。
クラス定義のなかのusing宣言は基底クラスの識別子に対してのみ使用可能
namespace NB{
//ここに
>>806 のusing宣言
struct Bar{
(略)
};
}
で可能。
int* a, b, c[4]; としたときに、 なんで int*じゃなく、intのみが全ての変数名a,b,cに係るのですか?
>>810 int* は一つの予約語じゃなくてintと*の二つからなるから。
int *a, b, c[4]; です
流れとまったく関係ないけど、 auto signed int* って書くと無駄に長いな
0xになればautoも日の目を見る日が来るだろう
typedef int* intp; intp a,b,c;
817 :
810 :2007/10/30(火) 03:06:39
XXX *a, b, c[4]; のときに 全てに係るXXXってどんなの? 組み込み型は該当するのは知っています。
>>817 >>811 が言うように「2つからなる」のがこの場合の原因だから、
「1つからなる」ものは何であれすべてにかかるよ。
const type_info *info_ptr = &typeid(object); とするとtype_infoのポインタが取れますが、 そのアドレスが一意であるかは処理系依存でしょうか?
恐れながらBeckyのPluginをVisual C++ Express 2005で作っています。 メールのcharsetがISO-2022-JP(つまりはJISなのかな)のようで、 strstrで文字列検索を行いたいのですが、うまくマッチしません。 Visual C++ 2005の標準charsetはShift_JISなのでしょうか。 #define MOJI "マッチさせたい文字" void Myfunction(~){ char c_text[MAX_TEXT]; bka.GetText(c_text, 65536); //メール本文のテキストを得る LPSTR sjtext; sjtext = bka.ISO_2022_JP(c_text, FALSE); //メール本文のテキストをShift_JISに変換 if (strstr(sjtext, MOJI) != NULL){ //マッチしたときの処理 }else{ //マッチしないときの処理 } } MOJIを含むメール本文の場合にも、マッチしないときの処理になってしまいます。 どうかお力をお貸し下さい。
>>820 ソースコードのエンコーディングは?
日本語版のVC++なら、デフォはシフトJIS(CP932)だよ。
BOMつきならUnicode(UTF-8, UTF-16)のソースも食える。
それ以外は駄目だ。
VC++にはgccのexec-charsetオプションのようなものは無いので、
非ワイド文字リテラルは、ソースのエンコーディングそのままに
メモリに格納される。
よって、文字列をリテラルと直接比較したいのなら、リテラルの
エンコーディング=ソースコードのエンコーディングに合わせなければ駄目だ。
823 :
820 :2007/10/30(火) 13:31:20
>>821-822 ほんとにごめん。
bka.GetTextにおいて、メールが選択されてなかった…。
きちんと選択してShift_JIS1に統一したらマッチしました。
ほんとにごめん。
初心者で申し訳ないのですが、分からないところがあるので教えて下さい #include <stdio.h> struct data{ int a[25]; }d; int main(void) { struct data *ptr; int i; ptr=&d.a[0]; //ptr にa[0]のアドレスを格納 for(i=0;i<=25;i++) { scanf("%d",ptr); ptr++; } for(i=25;i>=0;i--) { printf("%d \n",ptr->a[i]); } return 0; } 上記のソースをコンパイルしようとすると一応コンパイルできるのですが、警告がでます。 出来上がった実行ファイルを実行すると途中でエラーが出てしまいます (;´Д`) 自分ではどこがおかしいのか分かりません。というか、構造体やポインターがイマイチよく分かってません;; お手数かとは思いますが、エラーがでる原因や誤り等を教えて下さい。よろしくお願いします。 OS: WindowsXP HomeEdition , コンパイラー: bcc32
× ptr=&d.a[0]; //ptr にa[0]のアドレスを格納 ○ ptr=&d; //ptr にdのアドレスを格納 × for(i=0;i<=25;i++) ○ for(i=0;i<25;i++) × scanf("%d",ptr); × ptr++; ○ scanf("%d",&ptr->a[i]); × for(i=25;i>=0;i--) ○ for(i=24;i>=0;i--)
>>824 struct data *ptr;
↓
int *ptr;
&と.ってどっちが優先順位高かったっけ?
即答で.だろ。カンだけどw ->と同じだと思うんで。
プログラム自身のあるディレクトリが欲しいです。 GetCurrentDirectoryだと、現在作業しているディレクトリを返してしまい、 自身のディレクトリが返ってきません。 なにか取得する方法はないものでしょうか?
GetCurrentDirectoryが使えるなら、GetApplicationFileDirectoryが使えると思うんだ。 少なくともおいらのライブラリにはあるぞw
>>831 つまり貴方はこう仰りたいのですね。
--
自分の環境も書かずに質問するんじゃねぇよこの馬鹿!
GetApplicationFileDirectory に一致するページは見つかりませんでした。
>>834 >少なくともおいらのライブラリにはあるぞw
#include <脳内.h>
GetModuleFileName でよかろう
838 :
デフォルトの名無しさん :2007/10/31(水) 02:50:14
VC2005EEなのですが、以下のコードでビルドエラーになってしまします #include <string> #include <iostream> struct { std::string operator()() { return "aaa"; } } aaa; struct { std::string operator()() { return "bbb"; } } bbb; int main(int ac, char** av) { std::cout << aaa() << bbb() << std::endl; return 0; } main.obj : fatal error LNK1179: ファイルが無効か、または壊れています: COMDAT '??R<unnamed-tag>@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ' を複製します。
839 :
デフォルトの名無しさん :2007/10/31(水) 02:52:18
BCCは動く
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)でもいけた VC m9(^Д^)プギャーーーッ
>>838 VC8.0でも同様のエラーになった。
C++の規格書を読まないと詳しい事は分からないけど、無名の
構造体(この場合はクラス)を2つ以上作ると出るリンカエラーみたいだね。
gcc3.4.5(MinGW)でも正しくコンパイル出来て動作した。
VC8.0Proではエラーにならなかった。
VC9.0 Beta2ではいけた
846 :
デフォルトの名無しさん :2007/10/31(水) 04:21:56
1行が16000文字あったとして、初めの20文字読んだら次の行へ移動したいとき 1行目を全部読み込まないと出来ませんか?
847 :
デフォルトの名無しさん :2007/10/31(水) 04:25:27
可変長でおねがいします 1行が16000文字以下あったとして、初めの20文字読んだら次の行へ移動したいとき 1行目を全部読み込まないと出来ませんか?
Cならfseek C++ならseekg
あ、可変長か そりゃ無理だ 次の行へのオフセットでも記録してあれば別だけど
850 :
デフォルトの名無しさん :2007/10/31(水) 05:14:53
>>849 となると高速で読み込んで、\nを探すしかないですかね
\nとは限らんよ、自分で用意するの?
>>838 aaa, bbb に static つけたらどうなる?
固定サイズの普通の配列が欲しいとき、 通常の配列の代わりにvector使うとアクセスにオーバーヘッドかかるもんでしょうか? malloc時間は無視するとして。 関数に配列を渡すときはvectorでスッキリさせたいとこですが、 効率を最優先する場合はCプログラミング的なコーディングが結局は最良ですかね?
あっても微々たるもんだと思うけど、 ところどころでチェック入れられる可能性が怖いんなら 吐かれたコードを比較して検討すればよろし。
配列かvectorかを悩むより、他のところを気にした方が良い場合がほとんどだよな
856 :
デフォルトの名無しさん :2007/10/31(水) 07:24:46
vectorは初めにサイズがわからないときに使えよ 確保する時点でサイズが判明しているならnewで あまりに確保するサイズ小さいときは配列でもvectorでもnewでもいい
857 :
デフォルトの名無しさん :2007/10/31(水) 07:26:15
たとえばファイルから1行ずつ読み込んでいくつか不明ならvector かなりでかいサイズ、たとえば200M程度とかなら210Mほどnewで確保する
858 :
853 :2007/10/31(水) 08:02:20
みなさんレスありがとうございます。 ちょっと簡単に比較用のプログラム書いてみたんですが、 うーん、はっきり差はわかりませんねぇ。 必要な配列サイズはたかだか30kbくらいなんですが、 頻繁にアクセスが必要で処理速度も重要になる部分でしたので、 効率がどんなものか気になってました。 ソースの他の部分は基本的にvectorで渡しているので、 できるだけ統一させたいというのもあって、さて、どうしようか・・・という感じです。。 まぁ、ほとんど変わらないならvectorにしとこかな。
パフォーマンスは 実測が 基本
↑ どうでもいいですけど、30kBと書くべきでしたね
861 :
STLは時間かかる :2007/10/31(水) 08:09:10
#include <iostream> #include <string> #include <time.h> using namespace std; string qq="bfhbtfbhfgbhfww\nqqqq"; char pp[]="bfhbtfbhfgbhfww\nqqqq"; inline int f(){ return qq.find("\n");} int g(){ return qq.find("\n");} int h(){ int i; for(i=0;pp[i]!='\0';i++)if(pp[i]=='\n')break;return i;} main(){ int n,N,c; N=0;c=clock();for(n=0;n<70000000;n++)N+=f(); c=clock()-c;cout<<"STL+インライン関数call "<<c<<"m秒\nsum= "<<N<<endl; N=0;c=clock();for(n=0;n<70000000;n++)N+=qq.find("\n"); c=clock()-c;cout<<"STL+埋め込み "<<c<<"m秒\nsum= "<<N<<endl; N=0;c=clock();for(n=0;n<70000000;n++)N+=h(); c=clock()-c;cout<<"char型自作関数call "<<c<<"m秒\nsum= "<<N<<endl; N=0;c=clock();for(n=0;n<70000000;n++){ int i; for(i=0;pp[i]!='\0';i++)if(pp[i]=='\n')break;N+=i;} c=clock()-c;cout<<"char型自作埋め込み "<<c<<"m秒\nsum= "<<N<<endl;}
862 :
デフォルトの名無しさん :2007/10/31(水) 08:37:36
STLは生産性は高いけど、何度も繰り返し速度が必要なところは、C言語のみで書いた方が良いね
で、その場所はプロファイラによる実測で決めると あーmsvc用のコマンドラインプロファイラが欲しいなぁ。。。
プロファイラって効率を測定するソフト?ですか? プログラムの実行速度を計ってみたいのですが Linux環境でのプロファイラってありますか?
865 :
864 :2007/10/31(水) 09:16:07
プロファイラが何するものかはわかったのですが、 Linuxでフリーのプロファイラってありますか?
gprof
867 :
デフォルトの名無しさん :2007/10/31(水) 10:03:30
FILE_FLAG_NO_BUFFERINGっていうオプション付けると書き込めるサイズが決まってしまうのですが、 書き込む配列が余分に取ってあったらその部分も書き込まれてしまうと思うのですが、バイナリデータの終端ってわかるものなんですか? HANDLE fq = CreateFile("D:\\datafile", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING , NULL);
868 :
デフォルトの名無しさん :2007/10/31(水) 10:06:01
char buf[4096]; 中に入っているデータは先頭の100個だとします このとき4096バイト出力したら未定義の部分も書き込まれてしまいますよね? FILE_FLAG_NO_BUFFERING付けると書き込みが速くて良いんですけど、解決方法ありますか?
>>852 同じエラーがでました
vc8.0のコンパイラでobj作ってvc9.0betaのリンカでリンクしたらいけるかと思ったのですが
同じエラーでました たぶんvc8.0はコンパイラの段階でだめなんだと思います
それってODR違反にはならないのー?
>>868 パフォーマンスを取って仕様変更をするか、仕様を厳守してパフォーマンスを犠牲にするか。
>>865 gprofがgccとセットでインストールされていると思う。
尚、>861みたいに小さいデータで較べることは余り意味がないと思う。
当然ながら、自分が扱うデータサイズに近いものでテストすること。
# つーか、それだけでなくそれ以外の点でも>861はカスだが。
>>868 4096バイトのNO_BUFFERINGでの書き込み10回より
40960バイトの書き込み1回の方が10倍近く速いんだけど
その辺をわかった上で「速くて良い」と言ってるのかね?
で、確かに4096バイトを1回書き込むだけならその方が速いんだけど
その1回の書き込みはそれほど重要なのかね?
つまり、4096バイトだけ書き込む(それ以上同時に書き込んではいけない)タスクが多数あるとか
どうしても4096バイトのファイルを数百個作る必要があるとかで
かつ、メモリマップドI/Oや非同期処理等の、他のもっと有効な手段すらとれないと。
873 :
デフォルトの名無しさん :2007/10/31(水) 10:24:10
>>872 べつに4096に限定されているわけではなくて、40960でもいいんですけど・・・
ボリュームのセクタサイズの整数倍という制約があります すると余分な領域も書き込んでしまいますよね?
874 :
デフォルトの名無しさん :2007/10/31(水) 10:25:42
データの入っている領域だけ指定して書き込むって言うことが出来ないのが不便なんです
あー確かに。find("\n")をfind('\n')にしたら自作と称する駄関数より速いや。 そもそも、この程度をインライン展開できないコンパイラを前提としている段階で速度を語られてもなぁ。
find('\n')にしても同じだぞ bcc
>>875 あと埋め込み版とたいして速度変わらないよ charの関数呼び出し埋め込みも変わらない
charはstringの倍の早さ
埋め込み版ってぇのを比較している辺りがインライン展開能力のないコンパイラ前提って感じ? そもそもSTLといいつつstringを出されてもなぁ。元質はvectorなんだし。
>>873 で、NO_BUFFERINGの方が速いというのは、ちゃんと速度計測した上でのこと?
もちろん、普通は遅延書き込みだからディスクにかかれる前に戻ってくるけど
NTFSだとジャーナルに一度書き込むまで戻らないから、
メモリ上でのコピーに要する時間の影響はかなり小さくなると思うんだけど。
で、俺が提示した他の手段は使えないと。
そもそも、どういうデータ形式で、データ数の保存をどうしているのか激しく疑問なんだけど。
非固定長だとデータ数が取得できて固定長だと取得できないってのは
もしかしてデータ長をファイルサイズで得ようとしてるのかな。
そんなベタなデータ形式って、テキストファイル以外には見当たらないけど
そういう用途で、ディスクアクセスの時間がそれほど重要なわけ?
それこそ、stdioとsetvbufで大容量バッファを用意する方が、よっぽど有効だと思うんだけど。
ではvectorとnewとintを比較するやつを作ってやるよ
vectorは、普通内部でnewしてるからアクセス速度自体は、まず変わらんよ。 だから、「メンバとして」vectorを持つのとポインタを持つのなら、まったく同じ。 ただ、メンバとして配列を持つのと比較すると 間接参照一回分増えるケースが多いかもしれない。 ローカル変数の場合も基本的には同じ。 (内部で持ってる)ポインタ変数の値を取得するのに thisをベースにするかフレームポインタをベースにするかが違うだけ。 ただ、ローカル変数でポインタを持つ場合、レジスタ割付される可能性が高い。 その分、(何回もポインタの値を読み出す必要があるなら)差がつくかもしれない。 ローカル配列の場合は、フレームポインタ経由で直接アクセスするので レジスタ割付された場合と同等の速度になる。 クラスメンバの場合は、100%レジスタ割付されないから、必ず間接参照を含むわけだけど 気になるようなら、頻繁に利用される部分(ループ内とか関数全体とか)で 先頭を一度ポインタ変数に取得して、それをベースにアクセスすればいい。 そうすればレジスタに割り付けられる場合が出てくる。 当然オーバーフローの危険はあるが、それはvectorに[]でも同じだし 生存(new/delete)を気にせずにすむだけでもメリットはある。 ただ、増減する可能性がある場合は使えないけど。
882 :
デフォルトの名無しさん :2007/10/31(水) 11:17:17
これどこが間違えていますか? pとqの値が同じです #include <iostream> #include <vector> #define N 32000000 using namespace std; vector<int> a; main(){ int n,k,c; a.reserve(N); for(n=0;n<N;n++)a[n]=rand(); vector<int>::iterator p=a.begin(),q=a.end(); cout<<p<<" "<<q; }
883 :
デフォルトの名無しさん :2007/10/31(水) 11:23:49
わかりました reserve();は領域の確保できるけどsize()は変わらないみたいです 謎です
取り敢えずstaticなint配列を用意して、次の3つの関数の所要時間を実測した。 -- static int fvf(std::vector<int> const & foo, int bar) { return std::find(foo.begin(), foo.end(), bar) - foo.begin(); } static int fvl(std::vector<int> const & foo, int bar) { for (std::vector<int>::const_iterator it = foo.begin(); it != foo.end(); ++it) { if (* it == bar) return it - foo.begin(); } return foo.end() - foo.begin(); } static int fl(int const * foo, unsigned size, int bar) { for (unsigned ic = 0; ic < size; ++ic) { if (foo[ic] == bar) return ic; } return size; } -- icc(10.0) -xP -O3 -ip -funroll-loops 2.46sec 3.53sec 2.31sec gcc(3.4.6) -msse2 -O3 -funroll-loops 2.22sec 3.69sec 3.04sec -- 約3000件のデータを10M回回してこの所要時間だからどれも大差ないっちゃ大差ないけどね。
reserveが変えるのはcapacity sizeを変えるのはresize
>>883 reserve()は領域を確保するだけ。要素数を変更するにはresize()かassign()が必要。
つーか、reserve()しているんだから素直にfor (int n = 0; n < N; ++n) a.push_back(rand())すればいいだけ。
# それはさておき、グローバル変数にしてはいけないと思うのだが。
887 :
vector は差がない :2007/10/31(水) 11:47:18
#include <iostream> #include <vector> #include <time.h> #define N 8000000 #define M 80 using namespace std; vector<int> a; int *b; static int e[N]; inline int f(){vector<int>::iterator p=a.begin(),q=a.end(); int k=0;while(1){p=find(p,q,0);if(p==q)break;;k++;p++;}return k;} inline int g(){int n,k=0;for(n=0;n<N;n++)if(a[n]==0)k++;return k;} inline int h(){int n,k=0;for(n=0;n<N;n++)if(b[n]==0)k++;return k;} main(){ int n,k,c,i; a.resize(N);b=new int [N]; for(n=0;n<N;n++)a[n]=b[n]=e[n]=rand(); k=0;c=clock();for(n=0;n<M;n++)k+=f(); c=clock()-c;cout<<"vector + iterator call "<<c<<"m秒 sum= "<<k<<endl; k=0;c=clock();for(n=0;n<M;n++)k+=g(); c=clock()-c;cout<<"vector + []アクセス call "<<c<<"m秒 sum= "<<k<<endl; k=0;c=clock();for(n=0;n<M;n++){for(i=0;i<N;i++)if(a[i]==0)k++;} c=clock()-c;cout<<"vector埋め込み "<<c<<"m秒 sum= "<<k<<endl; k=0;c=clock();for(n=0;n<M;n++)k+=h(); c=clock()-c;cout<<"new call "<<c<<"m秒 sum= "<<k<<endl; k=0;c=clock();for(n=0;n<M;n++){for(i=0;i<N;i++)if(b[i]==0)k++;} c=clock()-c;cout<<"new埋め込み "<<c<<"m秒 sum= "<<k<<endl; k=0;c=clock();for(n=0;n<M;n++){for(i=0;i<N;i++)if(e[i]==0)k++;} c=clock()-c;cout<<"配列埋め込み "<<c<<"m秒 sum= "<<k<<endl;}
888 :
デフォルトの名無しさん :2007/10/31(水) 11:50:02
ほんのわずかだけどterator が毎回トップ これが一番手がかかっている気がするが・・
堂々とマルチ来た
未初期化変数をそのまま突っ込む
>>889 が地獄に落ちますように。
892 :
889 :2007/10/31(水) 12:52:26
2ch外ならマルチにならないと思ってました。 すみません。 書き忘れました、m,nは初期値として-1を代入しています。 マルチすみませんでした、あちらで気長に待ちます。
>>887 のソースで
lambdaとstd::count_ifを使ったら少し遅くなった(120%)
が一行で済むからそのコストも安いもの…なのかな?
即席の比較コードで速度比較をした結果を、実際のコードを書くときの根拠に してはいけない。「実測が基本」とは実際のコードで計測した値に基づいて最適化を 施すべきということ。 オーダーの変わらない範囲の比較用コードをいくら並べたところであまり意味は 無いんだよ。
じゃあ「実測」できる条件が整うまでは簡単な記述でとりあえずおkですか?
vc++ 2005使い始めてまだ日が浅いのですが、文字化けで困っています。 HTMLのファイルからタグを取ったファイルを作りたいのですが日本語がうまくコピーできません。 StreamReaderのReadLine()で読み込んでStreamWriterのWriteLine()でファイルに 出力しようとしているんですが、ReadLine()で読み込んだ時点でうまくいってません。 こんなやり方ではできないんでしょうか?
>>896 StreamReaderやStreamWriterのコンストラクタでちゃんとエンコーディング
を指定汁。
それと、C++/CLIはさすがに専用スレに行ったほうがいいぞ。
指定汁って何でしょうか?プログラミング用語?
899 :
896 :2007/10/31(水) 15:26:23
>>897 ありがとうございます。
ついでなんですが、HTMLの文字コードが決まっていなくいろいろあります。
やはり、HTMLのファイルのコードを統一してから文字の読み込みとするしかないのでしょうか?
901 :
デフォルトの名無しさん :2007/10/31(水) 15:57:14
オーストラリア訛りはちょっと聞き難い
>>899 MSHTMLあたりでDOMとして読み込めば、
自分は文字コードの問題を考えずに済むと思う。
904 :
デフォルトの名無しさん :2007/11/01(木) 04:30:23
MinGWとBCCってどっちのほうがいいんですか?
>>904 方向性が違うので、較べる方向によって異なるかと。
906 :
904 :2007/11/01(木) 04:49:40
まずは実行速度が速くて、つぎにコンパイル速度がはやいのがいいです あと開発環境も軽いのが良いです
それならicc一択だろ。
コンパイル速いか?w
速いぞ、gccより。尤も、オブジェクト間最適化を掛けると死ぬほど遅いけど。
910 :
デフォルトの名無しさん :2007/11/01(木) 10:54:29
初心者です。 VisualC++2005 win32なんですが 拡大鏡のプログラムを作っています。 マウスカーソルの座標を読み込んで その周囲の100*100くらいのピクセル値をGetPixelで読み込んで配列に格納。 そのピクセル値の中央のあたりをを拡大した値をまた配列に入れて、 それをSetPixelで現在のマウスカーソルの位置の周りに表示させてます。 それで拡大はできてるんですが、動作が遅いのか カクカクと点滅するようにしか表示されません。 フリーソフトとかである拡大鏡みたいに スムーズに表示させるにはどうしたらいいんでしょうか? そもそもこのやり方より別の方法使ったほうがいいでしょうか?
>>910 Win32APIスレのほうがふさわしいと思うが。
GetPixelは遅かった気がする。
よく知らんけどDCとかDIB弄ると良いのでは?
912 :
デフォルトの名無しさん :2007/11/01(木) 11:41:52
ファイルの書き込み方法教えて下さい Nはデータ長、dataはデータです これらより良い方法ありますか? 4Mずつ転送します while(n<N){ m=N-n;if(m>4194304)m=4194304; WriteFile(fq ,&( data[n] ) ,m, &sz , NULL); n+=sz; if(n >= N)break;} 可能な限り転送します while(n<N){ WriteFile(fq ,&( data[n] ) ,N-n, &sz , NULL); n+=sz; if(n >= N)break;}
913 :
デフォルトの名無しさん :2007/11/01(木) 11:46:42
あと、メモリにデータが蓄えてあったら、OSのキャッシュを経由させずにディスクへ書き込んだ方が良いですよね? 一度に200Mとか書き込み要求したときは、WriteFileは書き込み成功まで固まるんでしょうか? 細かく転送すると、ディスクのシーク時間等がかかって鈍くなると思いますけど・・・ 4Mくらいがちょうど良いですか?
DCのDC作るとか
915 :
910 :2007/11/01(木) 11:50:01
>>911 わかりました。とりあえずそっちで聞いてみます。
ありがとうございます。
>>913 まぁ、大差ないから気にするな。気になるなら実測しろ。
# 私なら 4194304 と書くより 4 * 1024 * 1024 って書いちゃうなぁ。
917 :
デフォルトの名無しさん :2007/11/01(木) 12:07:00
>>916 ありがとうございます
読み込みも書き込みもですけど、200Mとかメモリに貯まる前に
例えば5Mとか貯まったら書き出した方が良いですよね?
バッファ1と2があって1が貯まったら書き出してその間に2へ蓄えておくっていうのがいいと思うんですけど・・
バッファサイズと個数の最適地を実測してみます あと定番のアルゴリズムってあるんでしょうか?
>>917 そもそも前提条件がわからない。
200Mメモリが貯まるって何?
環境やどういう作業をしたいのか(ファイルコピーでもしたいの?)、
求めるパフォーマンスはどこに重点を置くのか(速度、メモリ?)等はっきりさせたほうがいいよ。
まぁ、先ずは実直に標準関数で組んでみて、それを動かして問題点を洗い出す方がいいね。
920 :
デフォルトの名無しさん :2007/11/01(木) 12:27:24
前提は、でかいサイズのファイルのコピーや読み取りを高速にしたいってことなんです
そういうことは、(WriteFile()からWindowsだと思うので)エクスプローラに任せるのが一番。
922 :
デフォルトの名無しさん :2007/11/01(木) 12:36:17
system( "copy ・・・")が最速って事ですか
ffc呼び出せばいいじゃない。
924 :
デフォルトの名無しさん :2007/11/01(木) 16:50:10
FFCの速いんだったらwindowsのほうが鈍いって事だろが どっちかが嘘教えてるな
日本語でおk
直接ハードを叩けばいいよ
見る前から予測できたw
>>913 とりあえず、以前から「NO_BUFFERING」と叫んでる初心者君だと思うが、
続けるなら捨てハンつけろよ。
で、「書き込みをバッファリングしない」というのは、
確かに「処理が完全に終了する時間(=ディスクに書き込み終わる時間)」は短くなるが
「WriteFileから戻って次の処理を続けられるようになるまでの時間」は長くなるんだよ。
当然だろ?OSのバッファまでコピーするだけで戻れるんだから。
(コピーしない場合、メモリ上のデータが書き換えられるのを防ぐため、カーネルから戻れない)
バッファリングを無効にすることにより処理が速くなるのは、読み込みのときだけだから。
それも、メモリマップドファイルを使う方がずっと一般的で
わざわざOSのキャッシュシステムを無効にして書き込みするのは
DB等の確実性が求められる用途など、極一部でしかない。
もちろん、こういう場合は、自前でキャッシュ管理している。
捨てハン付けるな死ね
>>929 よくわからんが、
巨大なファイルを高速に&キャッシュを汚さずに転送したいとか
考えてるんじゃないのかねえ。要するにFireFileCopyみたいな。
とりあえずSDKのサンプルにunbufcpyというのがあったような。
IOCP&マルチスレッドで、バッファリング無しコピーをやっていたと思う。
>>913 はまずその辺を見てみたら。
932 :
931 :2007/11/01(木) 23:07:32
あーそれと、
>>913 にだが、
・速いか遅いかなんてのは自分で実測しろ
・自分の環境でたまたま有効なチューニングが、どんな環境でも有効だとは思うな
と言っとく。
933 :
デフォルトの名無しさん :2007/11/02(金) 00:33:11
ファイルをよめません どうしたらいいですか? #include <iostream> #include <string> #include <fstream> using namespace std; main(){ locale::global(locale("japanese")); setlocale(LC_ALL, "japanese"); wstring a=L"ハローワールド" ; wcout <<a<<endl; wfstream fp("file",ios::in); if(!fp){wcout<<"file err\n";return 0;} for(;;){ getline(fp, a);wcout<<a<<"\n"; if(fp.eof()){wcout<<"end\n";break;} }}
935 :
933 :2007/11/02(金) 00:53:37
やりかたわからないので*charで読み込んで変換したいのですが やり方わかりますか?
936 :
933 :2007/11/02(金) 03:36:54
wstring wchar_tのファイルの入出力教えて下さい おねがいします
wcout.imbue
938 :
933 :2007/11/02(金) 03:57:57
wcout.imbueはやりましたが、ファイルの関係にないようです いま一番確実だと思うのは、NKFでシフトJISに変換してchar配列で読み込んで MultiByteToWideCharでwchar_tに変換するという方法です
940 :
933 日本語のwchar_tへの読み込みできたよ :2007/11/02(金) 06:53:29
#include <windows.h> #include <iostream> #include <string> #include <fstream> using namespace std; typedef int (__stdcall *FNC)(LPCSTR); typedef void (__stdcall *FND)(LPCTSTR ,LPCTSTR ); main(){ locale::global(locale("japanese")); setlocale(LC_ALL, "japanese"); HINSTANCE hd = LoadLibrary("nkf32.DLL"); FNC SetNkfOption = (FNC)GetProcAddress(hd,"SetNkfOption"); FND NkfFileConvert = (FND)GetProcAddress(hd,"NkfFileConvert2"); SetNkfOption("-w -X -Lu -d");NkfFileConvert("file","templary"); fstream fp("templary",ios::in); char buf[4100];wchar_t* wbuf; fp.getline(buf, 4096);int n; n=MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0); wbuf=(wchar_t *)LocalAlloc(LPTR, (n+1)*sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, n); wcout<<wbuf<<endl; n=WideCharToMultiByte(CP_ACP, 0, wbuf, -1, NULL, 0, NULL,NULL ); char* putf = new char[n+1]; n = WideCharToMultiByte( CP_ACP, 0, wbuf, -1, putf, n, NULL,NULL ); cout<<putf;}
てんぷらてんぷら
天麩羅うまいよなw
dynamic_castと純粋仮想関数によるオーバーライドって どっちの方が実行速度が遅いのですか? コンパイラはVC++2005を使ってます。
速度は実測が基本。
心底不思議な質問だよな。 必要なものはすべて揃っているのに、どうして自分でやらないのか。
それもそうか
947 :
デフォルトの名無しさん :2007/11/02(金) 15:35:44
#include <windows.h> #include <iostream> #include <string> #include <fstream> using namespace std; typedef int (__stdcall *FNC)(LPCSTR); typedef void (__stdcall *FND)(LPCTSTR ,LPCTSTR ); main(){ locale::global(locale("japanese")); setlocale(LC_ALL, "japanese"); HINSTANCE hd = LoadLibrary("nkf32.DLL"); FNC SetNkfOption=(FNC)GetProcAddress(hd,"SetNkfOption"); FND NkfConvert=(FND)GetProcAddress(hd,"NkfConvert"); fstream fp("file",ios::in); char buf[20010],buft[20010]; fp.getline(buft, 20000); int n; SetNkfOption("-w -X -Lu -d"); while(!fp.eof()){ NkfConvert(buf,buft); n=MultiByteToWideChar(CP_UTF8,0,buf,-1,NULL,0); wchar_t* wbuf=new wchar_t [n+1]; MultiByteToWideChar(CP_UTF8,0,buf,-1,wbuf,n); wcout<<wbuf<<endl; n=WideCharToMultiByte(CP_ACP,0,wbuf,-1,NULL,0,NULL,NULL); char* putf = new char[n+1]; n=WideCharToMultiByte(CP_ACP,0,wbuf,-1,putf,n,NULL,NULL); cout<<putf; fp.getline(buft, 20000);}}
gccでc++をやっています。 wwwからファイルのダウンロードを行うべくソケットを使って実装していました。 スレッドセーフにするため、関数名の末尾に_rが付くものに置き換えていましたが 引数のシグネチャが違っていてわけわかりません スレッドセーフでオススメのライブラリはないでしょうか?
ソケット直叩きのレベルなら、boost.asioかACEあたりかな
950 :
デフォルトの名無しさん :2007/11/02(金) 19:44:03
winsock2はだめなの? いつもこれだけど
質問です CHoge ← CChild という継承を行い、CChildで virtual int test() という関数をオーバーライドしたとします この状態で p = new CChild(); とやり、CHogeのコンストラクタでtest()を呼び出したとしても、オーバーライドされていないtest()が呼び出されますよね この実装自体は別に構わないのですが、何故このような仕組みになっているのでしょうか? コンパイラ的には、オーバーライドされたほうを呼び出させることは難しくないと思います (CChildのコンストラクタの頭でCHogeのコンストラクタを呼ぶ前に、vtblだけは初期化してしまえばいいですよね) 事実、Javaはオーバーライドされたほうのtestが呼ばれます 何故C++では、オーバーライド前のtest()を呼ぶ仕組みになっているのでしょうか?
952 :
デフォルトの名無しさん :2007/11/02(金) 19:47:10
ファイルのダウンロードって全部落とさないと他のアプリからは読み込み不可能で良いんじゃないの? あと分割するなら初めに書き込む位置決めておけばいいし
struct Base { Base(void) { ::printf("Base"); } }; struct Member { Member(void) { ::printf("Member"); } }; struct Derived : public Base { Derived(void) { ::printf("Derived"); } Member mem_; }; これ実行したら分かるかもしれない。
じゃなくて、実体化させたら分かるかも、だね。ごめん。
すいませんOS書くの忘れてました。Linuxです
>>949 先ほど書店でBoost.Asioの解説読んでました。これ使うとだいぶ楽になりそうです
でもhttp1.0や1.1の実装は自分でやらないといけないんですね
>>952 理由はわかりませんが、gethostbyname、getservbynameあたりの関数がスレッドセーフではないと定義されているんです
明日にでも本屋行ってBoostライブラリの書籍買って試してみます
今すぐboostのsnapshotを落して試せばいいと思うよ 本のサンプルコードはサポートページで配布してるし
HTTPとかは実装のサンプルソース入ってなかったっけ?
>>951 間単にいうともし派生クラス(CChild)のtest()が呼ばれたら
恐いことになる可能性があるから。基底クラス部分の初期化
の最中は、派生クラスの部分の初期化はまだ行われて
おらず、基底クラス部分の初期化時に派生クラスでオーバーライド
されたメンバー関数の呼び出しが可能だとしたら、まだ初期化されて
いない派生クラスのメンバーにアクセスしてしまう危険があるから。
>>951 CChild としては未だコンストラクトされてないから。
「コンストラクトされていないが関数だけは呼べる」
ということで呼ばせてくれた方が良かったと俺は思うけど。
そんなとこだけ安全>>利便としてくれても嬉しくない。
>>951 基底クラスのコンストラクタが実行されるとき、
まだ派生クラスオブジェクトは存在しない(作られていない)ので、
派生クラスでオーバーライドしたほうの関数が呼ばれるのはおかしいという理屈に基づいている。
そして
>>959 が書いたように現実的な視線での理由もある。
963 :
938 :2007/11/02(金) 21:17:59
BCCですよ
>>963 BCCにもバージョンがたくさんあり、その都度STLのデベロッパが違って
たりして混乱するんだが。
最新版は5.9.2だよ。
965 :
938 :2007/11/02(金) 21:32:08
>>964 5.5.1です でもコンパイラが違っていても、NKFでUTF8に変換して、それをwindows APIで
wchar_t、wstringに変換すれば確実ではないですか?
ちょっと気になったんだけど
>>938 は何のプログラムを書いてるのかな。
もしかしてShiftJISのファイルを読み込んでstd::wstringに入れて扱いたいだけなのに、
「なんだかよく分からないけど動かないからNKFを通したら動いた」
みたいな事になってるんじゃないかと心配なんだ…。
967 :
デフォルトの名無しさん :2007/11/02(金) 21:38:38
日本語ファイルの形式によらずにwstringにいれたいんです
いれちゃダメ♪
969 :
デフォルトの名無しさん :2007/11/02(金) 21:42:11
テキストエディタ作っている人は自前でコード判定しているんですか?
>>956 そのスレッドセーフでない二つの関数は、既に非推奨になっている。
getaddrinfoを使え。
HTTPクライアントなんてリクエストヘッダ送信するだけなんだから簡単ジャマイカ
>>959 なるほど。
逆にJavaは、派生クラスのものも含めてメンバ変数の初期化が(未定義であってもその型に応じたものが自動的に)行われるから、コンストラクタの中でオーバーライド後の関数を呼んでしまっても平気
ってことですね?
ありがとうございました
C++はスピード優先や、Cとの互換性も考えてそうなってるんでしょうね。おもしろいです
973 :
972 :2007/11/02(金) 22:00:07
>>973 Effective C++読むと良いよ
>>938 それだと入力がUTF-8/16のようなUnicodeなファイルでは、
情報の欠落が発生することになるだろ。
wchar_tが8バイト位ある環境なら大丈夫じゃね
977 :
938 :2007/11/02(金) 22:31:09
>>947 をみて下さい
UTF8に変換して読み込むことにしましたよ
978 :
デフォルトの名無しさん :2007/11/02(金) 23:23:28
初心者です。Visual C++ 2005 Express Editionのフォームアプリケーションです。 RS232Cから受信したデータによって画像の切り替えをしたいのですが どのように記述すればよいですか?このままだとReadFileが無視されます。 //Form1.h (省略) #pragma endregion private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { //変数宣言やら初期設定やら //画像のビットマップを生成する Bitmap^ bmap=gcnew Bitmap("../yakyuu/img/3.bmp"); Bitmap^ clr=gcnew Bitmap("../yakyuu/img/white.bmp"); //4x4の画像を描画する for(int i=0;i<4;i++) for(int j=0;j<4;j++){ int X=10+i*310; int Y=10+170*j; gr->DrawImage(bmap,X,Y); } while(1){ ReadFile(hc, &data, 1, &dwRead, NULL); if(data==END) break; if(data>=1 && data<=16) gr->DrawImage(clr,10+((data-1)%4)*310,10+((data-1)/4)*170); } }
>>977 nkfってUTF-16LEの出力ってできないの?
UTF-16LEのファイルを読み込めば、わざわざMultiByteToWideCharで変換する必要もない。
読み込みには、std::ifstreamでバイナリモードを使えばいい。改行の扱いが問題になるが。
Paintイベントのハンドラでそういう処理はしない。 なぜなのかは本とか学習サイトとかドキュメントとか読んで把握してください。 (↑これサボって先へは一歩も進めないので、ちゃんとやるように) スレッドを使うのは技術的にまだ難しいだろうから、 タイマーで定期的に読んでImageに書いて Invalidate、Updateし、 Paint では(描画済みの) Image をDrawImage する、等。
981 :
938 :2007/11/02(金) 23:36:34
サンクス 次に対応してます やってみます -w16 -w16B0 UTF16 コードを出力する。 (Big Endian / BOM 無し) -w16B UTF16 コードを出力する。 (Big Endian / BOM 有り) -w16L UTF16 コードを出力する。 (Little Endian / BOM 有り) -w16L0 UTF16 コードを出力する。 (Little Endian / BOM 無し)
encodingのauto-detectionに関しては俺も知りたいな。 Mozillaのソースとか読むと良いのかな? マルチプラットフォームでライセンス緩めの適当なライブラリがあると有難いんだが。 Windows限定だと、MLangでコードページ50932を指定すると JIS, EUC-JP, CP932の自動認識はしてくれるようだね。
>>973 まぁJavaの場合はnullか0かfalseで初期化されてるから、少なくともゴミ値を読んで暴走するようなことはない
NullPointerExceptionが起きるくらい
すんませーん、↓みて、フォームに画像の表示はできたんですよ。
Visual C++ 2005 Express Editionを用いた易しい画像処理(1)―原画像を読み込み、RGBとCMYの三色に分解する
http://homepage3.nifty.com/ishidate/vcpp05_g1/vcpp05_g1.htm そんでもって、ウィンドウにも表示してみたいなぁと思って貼り付けたんですが、ビルドできない。
フォームの方にあった、↓も貼り付けてみたけど、
using namespace System::Drawing;
こんなエラー↓がでました。
.\TestWin.cpp(7) : error C2653: 'System' : 識別子がクラス名でも名前空間名でもありません。
.\TestWin.cpp(7) : error C2871: 'Drawing' : この名前を指定された名前空間は存在しません。
環境はVC++ 2005 Expressっす。
CLI、.NET Frameworkがらみはドトネトスレへどうぞ
>>984 「CLRなんとか」という種類のプロジェクトを作れ。
>>986 やってみるっすー
>>985 そういや、bitmapクラスってドトネトみたいね。
eclipseしか使ったことないもんで、新しい環境は右も左もわけわかめやね。
988 :
938 :2007/11/03(土) 00:15:25
バグあるけど、UTF16LEで読みできたよ #include <windows.h> #include <iostream> #include <string> #include <fstream> using namespace std; typedef int (__stdcall *FNC)(LPCSTR); typedef void (__stdcall *FND)(LPCTSTR ,LPCTSTR ); main(){ locale::global(locale("japanese")); setlocale(LC_ALL, "japanese"); HINSTANCE hd = LoadLibrary("nkf32.DLL"); FNC SetNkfOption=(FNC)GetProcAddress(hd,"SetNkfOption"); FND NkfFileConvert = (FND)GetProcAddress(hd,"NkfFileConvert2"); SetNkfOption("-w16L0 -X -Lu -d"); NkfFileConvert("file","templary"); fstream fp("templary",ios::in | ios::binary ); wchar_t *wbuf= new wchar_t [1024*1024*5]; int n=0; while(!fp.eof()){ fp.read(( char * ) &(wbuf[n]), 1024 ); n+=1024;} wcout<<wbuf<<endl; }
992 :
デフォルトの名無しさん :2007/11/03(土) 00:26:48
fp.read(( char * ) &buf, 1024 ); は何文字読み込んだのかどうやってわかりますか? freadはバイトが帰ってきますが
>>992 std::istream::gcount()
を呼ぶか、
かわりにstd::istream::readsome()
を使う
どうでもいい事かもしれないけど &buf に不安を感じた
995 :
デフォルトの名無しさん :2007/11/03(土) 00:31:08
>>989 スーパーありがとう!
ドトネトの説明にもGDI+のbitmapをカプセル化してあるって書いてあるね!
GDI+のチュートリアルかなんか探してみるっさ!
.
.
.
1000ならジュースでも飲むか
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。