- ベストアンサー
初歩的なんですが…
自分の母語はJavaなのですが、先日C++を始めました。 やっぱり似ているのでスイスイいけてはいたのですが 初歩的な所でつっかかりました… 自分でも調べたのですが、できないのかを調べるのことは難しくて… よかったら教えてください。。 Javaでは、例えば、 Method(String str, int num) で定義されたメソッドを呼ぶとき( aはint型の変数として適当な値が入っているとして) Method("文字" + a, 99); という感じで呼べます。≪"文字" + a≫が文字列として扱われるからなのですが、、 C++はこうゆうことができないのでしょうか? やりたいことを具体的に書きますと、 BOOL TextOut( HDC hdc, // デバイスコンテキストのハンドル int nXStart, // 開始位置(基準点)の x 座標 int nYStart, // 開始位置(基準点)の y 座標 LPCTSTR lpString, // 文字列 int cbString // 文字数 ); を呼ぶときに、 TextOut(hdc, 0, 0, a + "回", 3); という感じで呼びたいのですがもちろんダメです。 調べたところ、 wsprintf()を使って一旦別の変数に入れるという段階的な方法が見つかりました。でもこれだとなんかスマートな感じがしなくて、変数も消費してしまいますし… ダイレクトでJavaのようにすることはできないのでしょうか? 何かこういった場合に使える演算子などありませんでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
回答ではありませんが,一応ご参考まで. > Method("文字" + a, 99); ↑は, Method(new StringBuffer().append("文字").append(a).toString(), 99); と同等なコードとしてコンパイルされるそうです(↓). クラス StringBuffer http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/StringBuffer.html なので, > wsprintf()を使って一旦別の変数に入れるという段階的な方法が見つかりました。 > でもこれだとなんかスマートな感じがしなくて、 確かにスマートではありませんが,やってる処理内容はほぼ同じで, プログラマが自分で書くか,コンパイラがこっそり変換するかの違いだけ. > 変数も消費してしまいますし… Java だと「変数」は消費しなくても,「StringBuffer オブジェクト」は 消費 (使い捨て) してますよね.
その他の回答 (4)
- jacta
- ベストアンサー率26% (845/3158)
> Method("文字" + a, 99); この方法だと、aを16進で表記したいとか、桁をそろえたいとか、ちょっと凝ったことをしようとすると記法が変わってしまいますね。 #4の回答で取り上げられている「Exceptional C++ Style」での結論についてもう少し詳しく書くと、 1. 文字列に変換するだけであれば、デフォルトでboost::lexical_castを使う。 2. 単純なフォーマットで、テンプレート化が必要な場合は、std::stringstreamまたはstd::strstreamを使う。 3. 複雑なフォーマットで、テンプレート化が不要な場合はstd::tr1::snprintfを使う。 4. パフォーマンスが問題となる場合は、std::strstreamかstd::tr1::snprintfのうち、実測しか結果がよい方を使う。 5. std::sprintfは使うべきではない。 といったところです。 ただし、Boost C++ Librariesが使えない場合、1.の選択肢はなくなりますし、逆に、使える場合には、boost::formatも候補として上がってきます。また、std::tr1::snprintfは、少なくとも現時点では標準ではありませんし、実際に使えない環境も多いので、選択肢から外さざるを得ない場合も多いと思います。なお、std::tr1::snprintf関数のワイド文字版であるstd::swprintf関数であれば現時点でも標準関数です。 C++では、状況に応じて最適な方法を使い分けるのが基本です。常に便利な方法を使うとなれば、もっとも汎用的だけれども、もっとも重量級の方法として実装せざるを得ず、機能要件は満たせても、非機能要件を満たせなくなる可能性があるからです。
お礼
なかなか難しいお話ですね… でも、 >C++では、状況に応じて最適な方法を使い分けるのが基本です。 >常に便利な方法を使うとなれば、もっとも汎用的だけれども、 >もっとも重量級の方法として実装せざるを得ず、機能要件は >満たせても、非機能要件を満たせなくなる可能性があるからです。 ここは納得できます。 自分の中の固定観念を捨てて、柔軟に色々な方法を取り入れていきたいと思います。 どうもありがとうございました。
- lv4u
- ベストアンサー率27% (1862/6715)
C++を開始して悩む個所は、私と同じですね。同僚もC#を始めたときに、数字-->文字変換で悩んだと言っていました。 「Exceptional C++ Style」を読むと、この問題は17ページにもわたるページを費やして議論されています。 議論の中心は「C言語の使いやすいけど危ないsprintf系と、安全だけど使いずらいC++系のstream系あるいはboostのlexical_castを使うか?」って議論です。 この議論の中に、「sprintfを使うなら、より安全なsnprintfを使うように」ってありました。で、私はC++のやり方にこだわるより、判り易さ優先ってことで、sprintfの代わりに、手軽なsnprintfをとりあえず使っています。 それからダイレクト(自動的)な数字-->文字変換って、C言語からやってきた人にとっては、可能かもしれないけど、ちょっと違和感を感じてしまうところもあります。また、それ以上に見やすいフォーマットで出したいという理由もあって、出力前に、事前にsnprintfでフォーマットしています。
お礼
同じところで悩んだ方がいらっしゃるとわかって安心しました。。 やっぱり違う言葉なのだから、自分の中のデフォルトも 変えていかなきゃならないのでしょうかね? C++ではそれが普通なんだと思えるように頑張りたいと思います。。 どうもありがとうございました。
- rabbit_cat
- ベストアンサー率40% (829/2062)
MFCのCString::Format()とか、 boost::formatとか、 std::ostringstreamとか でしょうか。
お礼
すみません、、ちょっとわかりませんでした。 もっと自分のレベルが上がったときに参考にしたいと思います。 ありがとうございました。
- koko_u_
- ベストアンサー率18% (459/2509)
C++ というか MFC なら CString を使えば良い。 その場合 CDC::TextOut(int x, int y, const CString&) を使う。
お礼
色々やってはみたのですが、どうもまだ自分には早いようで うまくできませんでした…せっかくなのにすみません ありがとうございました。
お礼
>Method(new StringBuffer().append("文字").append(a).toString(), 99); なるほど… 確かにコンパイラがやってたら、せっかく節約しても意味がないかもしれませんね。。 貴重なご意見ありがとうございました。