1 :
v(^・^)v :
03/02/20 22:04 C++に関する質問はこちらへどうぞ。
ただし質問の前にFAQに一通り目を通してください。
また、テンプレートライブラリ(STL含む)に関する質問は
専用の別スレへどうぞ。
過去スレ、関連スレ、関連リンクなどはこちら
>>2-15
2 :
v(^・^)v :03/02/20 22:04
3 :
v(^・^)v :03/02/20 22:04
4 :
v(^・^)v :03/02/20 22:05
5 :
v(^・^)v :03/02/20 22:05
6 :
v(^・^)v :03/02/20 22:05
7 :
v(^・^)v :03/02/20 22:05
乙かれ
9 :
v(^・^)v :03/02/20 22:19
v(^・^)v
v(^・^)v ぉっ
We're like morning sun〜♪
心擦れ鬱枯れー
STLつかうと一気に実行ファイルサイズが10倍に?!
こら!もう!すぐ調子に乗るんだから〜
>>15 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>17 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
>>17 環境じゃなくて最適化の結果によるだろ。
STL のコードが全部インライン展開されるなら、オブジェクトファイルサイズは
リンクの形態と無関係に膨れ上がる。。
static変数を関数中で宣言すると、関数が呼び出されるたびに毎回初期化されてるか否かの条件分岐 するんだよな。
21 :
デフォルトの名無しさん :03/02/22 14:44
C++の言語仕様やライブラリは一応覚えたつもりなんですが、 次に実際のプロジェクトの設計やコードを見て勉強したいと考えています。 VC++のオープンソースプロジェクトでソースや設計が比較的綺麗なものってありませんか?
Apache
>>18 >>19 いや、本当なんだってば(汗。
-vi オプションを付けるとインライン展開を使ってくれるが、
それでもファイルサイズは膨れあがったりしないよ。
ちなみに -D_RTL_DLL を外して -vi オプションを付けた時と
付けない時でファイルサイズを比較しても、そんなに大きな
差はない。
ところで、
>>18 さんの意見はどういう意味でしょうか?
> ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。
この部分がよくわかりません。DLLを使えば、元々スタティックリンクされる
はずだったコードがDLLに追い出されるので、その分ファイルサイズが
小さくなるという意味で書いたのですが。
std::vectorとDLLの関係もイマイチわからん
>>26 STLはDLLに追い出せてないと思います。何せテンプレートで、コンパイル時
にしかわからないものばかりのはずですから。
ただ、インライン展開を抑制しても有効にしても、STLを使った時と使わない時
でファイルサイズが10倍も違ったりはしません。
まぁ、VC++はstd::stringとかstd::wstringをDLLに置いてたりするが。
29 :
デフォルトの名無しさん :03/02/22 18:34
C++やってみたいんだけど、何がこれでできるんですか?
汎用的なソフトウェアの構築
凡庸的なソフトウェアの構築
>>29 物凄い気持ちいいオナニ。
辞められなくなってサルになるよ。
そして実際の子作りは永遠に遠のいた夢となります。
砂粒でまとめ上げて城を築けます。
すげえな・・・C++って・・。シェンロンみたい。
35 :
デフォルトの名無しさん :03/02/22 22:38
>>28 何度も言っているが、
「Visual C++はC++ではない。」
誤解無きよう。
36 :
デフォルトの名無しさん :03/02/22 22:41
アフォ?
VC++はC++のスーパーセットだ。 お分かりか?
39 :
デフォルトの名無しさん :03/02/22 22:49
VC++厨、必死だな。
いや、サブセットだろ。標準満たしてないし
標準仕様に完全準拠し、かつバグのないコンパイラなど存在しない。
点プレも実体化しておけばDLLに置けまっせー
製品名なんだからスーパーセット、サブセットって話には ならないと思うんだけどな。
この文脈ではVC++はMSの実装したコマンドラインコンパイラを意味するだろ。
46 :
デフォルトの名無しさん :03/02/22 23:36
これでいいの?
47 :
デフォルトの名無しさん :03/02/22 23:51
>>42 で思い出したが、最近テンプレートの使われている
ライブラリをビルドして.lib作って普通に別のプログラムで
ヘッダだけインクルードしてそのスタティックライブラリを
リンカに読ませてビルドできるんだけど、OKなんだよね?
48 :
デフォルトの名無しさん :03/02/22 23:56
>>48 実体化してない状況でlibはおっけー?という話なんだが
その辺を聞きたい。
実体化されてようがされてまいが、exportされてない限りtemplateの 実体はお前がincludeしたヘッダの中にあるだろうが。
51 :
デフォルトの名無しさん :03/02/23 00:28
47はtemplateを定義したのか、それとも使っただけなのか。 前者ならコードのサイズはゼロだからlib,a,dllは作れない。 (staticの実装は別)で後者ならもうそれは立派なクラスだから libでも、aでも、dllでも、oでも好きにするがいい。
int f(){hogehoge} と int g(){hogehoge} という2つの関数があって、コンパイルした結果が同じだとしたら 最適化で f==gになるんだろうか?
>>52 VC6だとテンプレートの展開結果については
まとめてくれることがあるみたい。
.mapファイル吐かせたら、複数のシンボルが同じアドレスになってた。
C++でIEのhtmlファイルに書かれている文字列を 取得して表示させたいんだが どんな感じで書けばいいんだろう。 初心者な質問でごめんなさい・・・
I〜略〜2::toString();
クラスの生成時にmemsetを使ってメンバ変数を初期化する場合 class A { int hoge_a[10]; char hoge_b[20]; : : public: A(){memset( this , 0 , sizeof(A));} : }; このような使い方は有りでしょうか? さらにメンバにvirtual関数があった場合も使用しても問題ないのでしょうか?
>>56 ついでに言うと、Cのお馬鹿な文化はC++には持ち込むなと。
>Cのお馬鹿な文化 オブジェクトインスタンスを生成時に0で埋めるのはまともなOOPLでは常識なわけだが。
エッ・・・ (; ゚Д゚)
>>56 sizeof(A)は本当にクラス内の変数の大きさだけを返すのだろうか。
thisやselfを0やnullで埋めてるソースなんて見た事無いが。
どうしてもthisを弄くりたかったら、offsetofでも使うしかないな。
std::vectorとか使えばよかろうに・・・
自分が持ってるメンバを責任持って初期化するのは当然だとは思うが。 でも、ここ1年ぐらい生の配列メンバに持ったクラスなんか書いてないな。
超初心者ですが、ただのC++と、Visual C++ってちがうんですか?
人生初心者は (・∀・) カエレ!!
>>61 virtual関数があるとsizeof(A)は正確な値を返さなかったね、たしか
>>56 C++では無理。
>>62 そりゃそうだ普通は言語レベルで勝手に0で埋めるからね。
この動作はもちろんオーバーヘッドが大きいのは間違いないけど
つまらないバグの発生を抑えてくれる。
ヒープやローカル変数の未初期化領域を参照できてしまうなんてあってはならないことだ。
class A { char buf[10]; public: virtual void func() {} }; たとえばこれで sizeof(A) が 10 を返す処理系は少ないだろう。 memset(&a, 0, sizeof(A)); なんてしたら、とっても嫌〜なヨカン。
「俺が知っている値」==「正確な値」
と言うわけで、C++では横着せずに、地道に各メンバーを初期化しましょう。
newの実装をcallocに変更 すると余計なバグが増えそうだな
つまり使っていいかどうか分からないでFA?
77 :
デフォルトの名無しさん :03/02/24 00:04
te
各メンバの初期化って基本型だけでいいだろ。 基本型以外はその型のコンストラクタで初期化されてるはず。
皆が使っているプログラミングソフトを教えてくれ。
80 :
デフォルトの名無しさん :03/02/24 00:09
オブジェクトのポインタを宣言して obj *a,*b; b->x = 1; *a=*b; としたとき、a->x = 1 となるのは当然として a=b となってポインタも同じところを 指すようになりますか?
>>56 vtbl へのポインタを隠しメンバに持ってたりするからね。
0で埋めたらエライことに。
82 :
デフォルトの名無しさん :03/02/24 00:15
>>78 いやそれは分かるんだが、
>>56 の使い方をしてバグなんかの問題は
ないかって事に関しての答えはどうなん?
>>82 どうしても、そうなっちゃうんだけど・・・。
>>80 の続きで
メンバ関数が
func()
{x=2;}
として
a->func();
とするとa->x=2となってしかも
b->x=2となっちゃうんだけど、何で?
C++の設計思想にいたく賛同した奴が、 急にCコンパイラのみの環境に放り込まれたときに陥る罠を列挙してください。 とりあえず、スコープの途中で変数定義してエラーになるのは思い出した。
>>85 newとコンストラクタがなくてメンバを初期化できず鬱。
>>86 *a=*b
でポインタも同じところを指すようになるってこと?
>>85 つい struct キーワードを忘れてしまう
>>84 なりません。
struct A {
int x;
A() { x = 2; }
};
int main()
{
A* a = new A;
A* b = new A;
*b = *a;
a->x = 3;
std::cout << b->x << std::endl;
delete a; delete b;
}
>>85 //でコメントを書く、ってのはC99だと罠にならないか…
とりあえず、sizeof('a') == 2
>>85 スマートポインタが無くてリソースの解放し忘れ多数。
>>91 確かにならんな〜。
何で俺のはなるんだ?
>>85 STLが無くて、基本的なアルゴリズムを思い出せずに鬱
>>91 *b = *a;
a->x = 3;
を
a->x = 3;
*b = *a;
にしたらどうなるかな?
>>96 void main( )
{
one_image *in_image = new one_image;
one_image *noise_image;
one_image *median_image = new one_image;
in_image->load_image_data();
noise_image = in_image;
noise_image->make_noise();
*median_image = *noise_image;
int code = median_image->median();
}
最後の行をやっても*noise_imageに影響ないはずなんだけど
一緒に変わってしまう。何で?
>>99 多分コピーコンストラクタが書かれてないからだと思う。
メンバにポインタとか持ってないか?
>>101 クラスの定義は下だけど、*imageに問題があるってこと?
class one_image
{
protected:
int x_size, y_size;
unsigned char *image;
public:
one_image();
one_image(int HSize, int VSize);
one_image(struct base_image *base);
virtual ~one_image();
void load_image_data();
void save_image_data();
void set_imagedata(struct base_image *base);
void make_noise();
int median();
};
コピーコンストラクタじゃなくて operator= ・・・だとおもう
>>102 その通りです。デフォルトのコピーコンストラクタは単なる
ビットのコピーなので、ポインタは考慮してくれません。
( ´-`).。oO(one_image・・・どこかで見た事がある・・・)
代入演算子が書かれてないからか。
これと同じことが起こっている。 struct A { int* x; A() { x = new int(0); } void func() { *x = 2; } }; int main() { A* a = new A; A* b = new A; *b = *a; a->func(); std::cout << *a->x << std::endl; std::cout << *b->x << std::endl; delete a; delete b; }
>>104 ちょっと調べてみましょう。原因が分かったことだし。
>>105 たぶん同一人物でしょう。前も書いたことあるから。
これで解決。めでたしめでたし。 struct A { int* x; A() { x = new int(0); } void func() { *x = 2; } int operator=(const A& a) { return *x = *a.x; } }; int main() { A* a = new A; A* b = new A; *b = *a; a->func(); std::cout << *a->x << std::endl; std::cout << *b->x << std::endl; delete a; delete b; }
ていうか、vector<unsigned char> を使えば万事解決じゃん?
111 :
デフォルトの名無しさん :03/02/24 00:57
デフォルトのコピーコンストラクタがビットのコピーですって? 全部の要素について operator= でしょう?
>>111 スマソ。コピーコンストラクタは関係ないわ。
なんとなく delete する順番が気になってるのは自分だけ? a,b って作ったら b,a って消したくなる
>>111 コピーコンストラクタがoperator=ですって?
>>113 その方が何かメリットあればそうする。何かあったっけ。
コピーコンストラクタが呼び出されるのはどういう場合かを述べよ。
>>114 そもそもコピーコンストラクタなんて
どこでも呼ばれていないけど
>>113 依存性があろうがなかろうがいちいち考えるのが面倒なのでデフォルトでそうしてる。
>>118 そしたらaがbに依存してたらやっぱりaを先に消すわけだね。
コピーコンストラクタは次のような場合呼ばれる。 A a; A b(a); // コピーコンストラクタが呼ばれている
>>120 その場合b, aの順に生成するだろ。
いつも依存性と生成順序ばらばらにしてるの?
>>122 そうではない。俺は出てきた順にdeleteしている、ただそれだけだよん。
>>121 引数が一つでexplicitが無いと
暗黙の型変換としても呼ばれるよ
結論。メンバにポインタを持っていたら、自前のoperator=と コピーコンストラクタを書こう。でよろしいか?
> one_image(struct base_image *base); > void set_imagedata(struct base_image *base); こんなのがあるなら、本当は浅いコピーがやりたい可能性も十分ある。
operator=は次のように書いた方がいいと思うが。 struct A { int* x; A() { x = new int(0); } void func() { *x = 2; } A& operator=(const A& a) { *x = *a.x; return *this; } }; int main() { A* a = new A; A* b = new A; *b = *a; a->func(); std::cout << *a->x << std::endl; std::cout << *b->x << std::endl; delete b; delete a; }
prototype pattern?
>>111 配列メンバも operator= なのかと小一時間
>>127 受け取るのにconst付けたなら
返すのにもconst付けたら?
>>130 Effective C++の15項に、operator=の返り値はconstにしない方が
良いという内容があるよ。
>>131 constの意味わかってる?
何でわざわざ禁止にするのか
その上でもう一回読んでみて
>>132 A a, b, c;
(a = b) = c;
というコードが通らないようにconstをつけ人がいるらしいけど、
int i, j, k;
(i = j) = k;
は通るので、組み込み型との互換性を無くさないように、
operator=の返り値はconstにしないのだと書いてある。
こんな糞議論をしなきゃいけないような糞言語は今後二度とつかわねーと叫びながら町内を走り回りたい気分でいっぱいです。
>>133 スマソ
勘違いしてた
組込型は通るコードだったんだ
この仕様はC言語互換のためなのかな?
>>137 そうかもしれないが、Effective C++の著者は相当パラノイアだな(w
ふむ。で、その書き方は何の役に立つの?
>>139 役には立たんだろ。ただ意図しないエラーが出なくなる、それだけの
ような気が。
>>139 そんなこと全然考えてなかった
何かの役に立つのかな?
ま さ に 本 末 転 倒
143 :
デフォルトの名無しさん :03/02/24 01:59
ぶはは。
>>137 少なくともVC++の場合、Cとしてコンパイルすると
>error C2106: '=' : 左のオペランドが、左辺値になっていません。
となるが。
>>144 VC++はANSI-Cにすら準拠してないのです。
ご愁傷様。
Cで=演算子は左辺値を返さない。
>>144 で正しい
>>139 void set_str( const CString& s ) {
(m_str=s).TrimLeft()TrimRight().MakeLower();
}
とか、代入演算子に限らず自分を書き換えるだけのメソッドは全て
自分への参照を返すように決めておくと何かと便利。
const CString &なのに?
書き込んだ直後に間違いに気づく。 ●5点
m_strの型、というかのoperator = の結果型がわからんので何とも言えぬ気が
>>150 「operator=の結果型をconstじゃない参照にする書き方は
何の役に立つか?」 に対するレスのつもりだったので、そこんとこは
推測して頂きたいわけだが。
152 :
デフォルトの名無しさん :03/02/24 13:56
153 :
デフォルトの名無しさん :03/02/24 15:38
AV電話相談室 アダルトビデオについて質問のある方大募集!! 料金は無料!! TEL 046-239-1539
private継承って皆さん使ってますか? 俺は使う場面がよくわからないので使ってないのですが。
このような事ができるとすれば、純粋仮想関数の意味が なくなってしまうような気がするのですが・・・・・俺だけ? struct Base { virtual void who() = 0; }; struct Derived : public Base { void who() {} }; void Base::who() { std::cout << "純粋仮想関数のメンバ関数だよん" << std::endl; } int main() { Derived d; d.Base::who(); }
>>155 Baseのインスタンスは作成できないから意味がある。
VC7/istream でカンマ区切りのデータを読み込もうと考えたのですが、 ロケールの関係で数字を読み込むとカンマが桁区切り記号と誤認されてしまい読み込みに失敗してしまいます。 STLのコードを見た限りではoperator>>は問答無用で桁区切りを読み込むようになっており、 動作を変更するオプションは見当たりませんでした。 ,を読み込まない関数を書くのは簡単ですが毎回それではスマートさに欠けます。 何か標準で用意されている方法はあるでしょうか?
>>154 継承したいメンバを制限する時。
単独ではあまり役に立たないが、アクセス宣言と共に使うと
必要なメンバだけ引っ張り出せる。
>>157 こんなのは?
int main()
{
std::ifstream ifs("comma.txt");
while (true) {
char buf[128];
ifs.getline(buf, sizeof(buf), ',');
if (!ifs) break;
std::cout << std::atoi(buf) << std::endl;
}
}
>>154 例えば次のような事ができる。意味論的にどうなるのかは知らないが。
struct Base {
int i;
int j;
int k;
};
class Derived : private Base {
using Base::i;
protected:
using Base::j;
public:
using Base::k;
};
>>160 この場合 using Base::i; は冗長だね。
ただ次のような事をすると usingがないとエラーが出る。
struct Base {
int i;
int j;
int k;
};
class Derived : private Base {
// using Base::i;
protected:
using Base::j;
public:
using Base::k;
Derived(int ii) : i(ii) {} // エラー
Derived() { i = 1; }
};
using std::cout; using std::endl; ... みたいな感じでソースの半分以上が using文なんですが、素直に using namespace std; 使うべきなんですかねぇ。
いいえ、問題ありません。そのまま続けて下さい。
まあ動作には問題はないよな。面倒そうなだけで。
165 :
デフォルトの名無しさん :03/02/24 20:14
init() try{ run(); }finally{ done(); } ってC++でどうやって書くの?
>>165 class Hoge {
Hoge() { init(); }
~Hoge() { done(); }
};
Hoge a;
run();
class Hoge { Hoge() { init(); } ~Hoge() { done(); } }; Hoge a; run(); ってCでどうやって書くの?
ここはC++スレです
>>166 それって処理の内容毎にfinally用のクラスを興さないといけないって事?
>>169 そう。
むしろオブジェクト側に隠蔽できて便利ってこと。
>>165 処理系依存でも良ければ、__finallyキーワードを使え。
なかったら諦めろ。
いいじゃんこれで。 class at_exit{ public: typedef void (*finalizer_type)(); at_exit(finalizer_type f) : finalizer(f){} at_exit(at_exit& a){ finalizer = a.finalizer; a.finalizer = 0; } ~at_exit(){ if(finalizer != 0) finalizer(); } protected: finalizer_type finalizer; }; main{ init(); trye{ at_exit(done); run(); }catch(...){ std::cerr << "exception!" << std::endl; }
at_exitだと誤解を招くか。at_endの方がよかったかな。
ダイヤログについての質問もアリですか? ダイヤログのエディットボックスにカーソルがあるときに、 enterないし特定のキーを押すとイベントが起こるようにしたいんですがどうしたらいいですかねえ
176 :
デフォルトの名無しさん :03/02/24 23:43
Hoge &operator = (Hoge &obj); の&って変数のアドレスを取り出すときのやつと考えて良い?
>>176 参照(reference)です。参照演算子とは異なります。
だめ
>>179 うー、スレ違いっすね
合うスレ探してみます
c++してみたいんだけど、まず何をそろえればいいの? なるべくfreeの奴紹介してください。お願いします。
>>181 おまえがWindowsで貧乏人で
MFCとか完璧Unixエミュレーションとか多くを望まないなら、
cygwin別名poor man's Unixを薦める。
今ならgcc-2.95あたりがついてくる。
at your own riskで、ソースからgcc-3.xを作ることもできるはずだ。
emacsは動かんぞ。xemacsなら動くかも知らん。vi(vim)を使え。
漏れはWindowsでVMwareでLinuxだが、cygwinも重宝している。
>>183 cygwin の gcc も 3.x になったぞ。
emacs 互換エディタには、あとxyzzyってのがある。
いまcygwinインストールしてるんだけど、 ヒジョーに難しそう・・・・。ガン狩ります
186 :
デフォルトの名無しさん :03/02/25 14:17
>183 何故Borlandではない?
使い方がわからん・・・・。今なんか入力できるやつが出 たんだけど、何を入力すればいいんですか?
>>187 それを言うならVC++もC++に対する冒涜。
てか Borland のどのへんが冒涜?
>>186 のいうBorlandってのはフリー版のことか・・・
Borland C++はテンプレート周りが少々弱いことを除けば、 標準C++に対する準拠度はほどほどに良いと思うが。 もちろんg++にはかないようがないが。
>>193 g++って準拠度に関してはそんなにいいの??
最適化はいまいちらしいけど。
Intelはどう?
>>195 じゃあ準拠度ならg++,bccで、最適化ならiccやVC++か。
template周りに限るけど、準拠度を測るには、Boostをコンパイルして どれだけ通るか試してみればよい。 Comeauでさえ通らないものがあるからね。
>>196 初学者はおかしな癖を覚えないよう、最適化の性能よりも準拠度の高い
コンパイラで学習するといいかも。
借りているサーバーのg++は古すぎて(2.7.2)ごく簡単なソースのコンパイルさえまともに通らん(涙 カーネルもLinuxの2.0系だし(涙 2.7.2が出た当時の仕様に沿って書けばOKなんだろうけど。
200 :
デフォルトの名無しさん :03/02/25 14:57
200
>>199 2.7.2・・・・俺が初めてC++をやり始めた時は既に2.95.2だった。
202 :
デフォルトの名無しさん :03/02/25 16:02
std::ifstreamのインスタンスを、ファイルをオープンしたまま他の関数に 渡すにはどうすればいいでしょうか? 次のようにするとコンパイルできません。 void func(std::ifstream ifs); int main() { std::ifstream ifs("ifstream_open.cpp"); std::string str; func(ifs); ifs >> str; std::cout << str; } void func(std::ifstream ifs) { std::string str; ifs >> str; std::cout << str; }
当たり前。
>>203 どうすればいいのでしょうか?
Cの場合だと FILE ** のようにして切り抜けていましたが。
std::ifstream * としてポインタで渡すのがいいのでしょうか。
void func(std::ifstream &ifs); でいいんじゃん
>>205 参照か!その手がありました。
しかしその場合、関数からの返りに勝手にデストラクタが呼ばれて
ストリームがクローズしてしまうような事はありませんか?
(゚Д゚)ハァ?
>>207 どういう場合にデストラクタが呼ばれるのかよくわからないのです。
---質問の主旨が変わった転換点---
本体の生存期間は大丈夫
ifstreamのデストラクタが呼ばれる == ファイルがクローズする なので、ちょっと怖いのです。
とりあえず、入門書を読み返しましょう。
>>211 参照で渡した場合はそのインスタンスに関してコンストラクタも
デストラクタも呼ばれないから安心しろ。
どこかにある実体を「参照」してるだけだからね。 実体そのものではない。
>>210-214 そうなると、参照はポインタと同じとまではいかなくても、ポインタと似た
ような考え方でよいのですね。
ありがとうございます。今までどうやってストリームを他の関数
に渡していいのかずっと悩んでいました。
入門書にはそのような例が出てなかったのです。
一体どんな入門書買ったんだよん?
>>216 ええと、手元にあるだけを列挙すると・・・・
・「独習C++/標準講座C++」(ハーバート・シルト著)
・「C++Primer 改訂3版」
・「詳説C++」(大城正典著)
こんなもんです。
それより ifstreamってコピーで複製できなかったのか・・・
>>218 コンパイルすると、「iosのコピーコンストラクタを生成できません」という
エラーが出ました。
コピーコンストラクタがprivateである事が原因のようです。 :/mingw/include/c++/3.2.2/bits/ios_base.h: In copy constructor `std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)': C:/mingw/include/c++/3.2.2/bits/ios_base.h:424: `std::ios_base::ios_base(const std::ios_base&)' is private C:/MinGW/Learn/Learn2/ifstream_open.cpp:12: within this context C:/mingw/include/c++/3.2.2/streambuf: In copy constructor `std::basic_filebuf<char, std::char_traits<char> >::basic_filebuf(const std::basic_filebuf<char, std::char_traits<char> >&)': C:/mingw/include/c++/3.2.2/streambuf:479: `std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]' is private C:/MinGW/Learn/Learn2/ifstream_open.cpp:12: within this context
まあ、ストリームクラスなんかコピーしても何のメリットも無い品。
>>221 もしできたとしても、破棄時にデストラクタが呼ばれてストリームが
クローズしてしまうでしょうから使い物にならないでしょう。
ポインタや参照について書かれている本を持ってても 頭で理解したつもりになってて実際には使えなかっただけだろう。
>>223 そうなのです。基本型に関しては参照は理解したつもりでいまし
たが、それをライブラリと共に使う方法を知りませんでした。
>>224 ひとつの山を越えようとしている。ガンガレ!
>>225 ありがとうございます。2chにはこんな親切な人が大勢いたのですね。
なるほど、こういう事もできるから参照は便利ですね。
もうポインタからはそろそろ卒業しなければ。
void func(std::ifstream& ifs);
int main()
{
std::ifstream ifs;
std::string str;
func(ifs);
ifs >> str;
std::cout << str;
}
void func(std::ifstream& ifs)
{
std::string str;
ifs.open("ifstream_open.cpp");
ifs >> str;
std::cout << str;
}
?間違い探し?
Cygwinの初期設定?が良くわからん。あの背景が黒くて・・・ 誰か使ってる人、詳しく教えてください・・・
ありがとう。初期設定メンドクサ。
>>226 ポインタも参照も使えるなら、迷わず参照を使え。
参照は、ポインタと違って、インクリメント/デクリメントや添え字参照が
できない分、意図が明確になる。
漏れとしては、歴史的な理由によるが、thisが参照じゃないのが嫌。
OfficeのCOMは、アプリケーションによって、パラメータがポインタ
だったり山椒だったりして反吐。その差を変換演算子かなんか使って
隠そうとしているので余計反吐。
>>231 > OfficeのCOMは、アプリケーションによって、パラメータがポインタ
> だったり山椒だったりして反吐。その差を変換演算子かなんか使って
> 隠そうとしているので余計反吐。
COMは言語に依存しないというのを分かってますか?
234 :
デフォルトの名無しさん :03/02/25 19:55
WideStudioって知ってる人!
やっと図書館でプログラミング言語C++がみつかった・・・
本屋さんは?
239 :
デフォルトの名無しさん :03/02/25 20:05
図書館に沢山置いてあるから借りてるよ 新しいものもおいてあるしね C++ならば20冊ぐらいあった 貸し出しされているものもあるだろうから もっと沢山蔵書があるだろうけど
FILE* から fstream に変換する方法を教えてください。
FILE*を捨てる。
FILE* -> ファイルデスクリプタ -> fstreamって無理だった? やった事無いから知らんが。
>>233 COM用に拡張されたコンパイラに依存している。
> COM用に拡張されたコンパイラ はつみみです
246 :
デフォルトの名無しさん :03/02/25 21:45
newの戻り値確認している?
>>246 std::bad_alloc例外をチェックすれば十分じゃないの?
なんだ、標準化する前のC++の話かよ。 確かnewに失敗したらNULLを返すんだっけ。 標準C++でも new(nothrow) とすれば互換の動作にはなるが。
n e w な ん か 使 う な
>>251 (゚Д゚)ハァ?
(゚Д゚)ハァ?
(゚Д゚)ハァ?
(゚Д゚)ハァ?
(゚Д゚)ハァ?
new 使わなきゃコンス(ry
n e w なんか使うな。 new を使え。
255 :
デフォルトの名無しさん :03/02/25 23:37
本とか読むと、 string str("abc"); みたいな書き方してあるけど、これをそのまま 関数に渡したりとかしたらオーバーヘッド すごそうだけどやはり string *str = new string("abc"); でポインタを関数に渡すべき?
えー、何言ってるの?
257 :
デフォルトの名無しさん :03/02/25 23:40
スマソ、自分でもわけわからん事言ってしもた。 要するに、文字列をそのまま値渡しとか していいものか、と聞きたかったわけ。
山椒渡しは?
new しなくても &str とすればポインタで渡せる
>>255 受ける関数側で func(std::string& str) のように参照で受ければ?
そうすればコピーコンストラクタは発動しないからかなり速くなる。
今からベンチマークやるからちょっと待ってて。
関数側が const string& で受けるようにすればいい
結果。 func1(string with copy constructor) = 515085 func2(string with pointer) = 8990 func3(string with reference) = 8985 予想通り、std::stringをそのまま渡すとコピーコンストラクタが 発動してすごいオーバーヘッドが生じた。 ポインタと参照はほとんど差がない。
>>257 >>255 の大ボケは無視して答えると、一般にはユーザ定義型を
渡す場合は値渡しではなくconst referenceを使用するようにすべきだろう。
もっともstringに関しては参照カウントとcopy on writeを用いて
実装されていることが多いはずなので、思ったほどの負荷は無いと思われ。
# そのお陰で
# string s("abc");
# string t(s);
# s[0] = '!';
# で t まで書き変わっちゃう実装とかが多いみたいだけどね。
ていうか、そのレベルの疑問は「Effective C++」辺りを読めば
あっさり解決する代物なので、読んでおくことを勧める。
264 :
デフォルトの名無しさん :03/02/25 23:52
みなさん、サンクス。
FILE*を返してくるライブラリを使っているんですが iostreamに割り当ててつかうことはできないのですか?
Rogue Waveだと FILE *fp=fopen("test","r"); std::ifstream ifs(_fileno(fp)); std::cout << ifs.rdbuf(); などとできるようだが
>17 >俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して このBorland-C++5.6.2ってCマガジンに付いてくるのと 違うものなの? -D_RTLDLL オプションってCマガジンに付いてくるのでも 有効なの?というかそもそもこのオプションは何ですか?
>>245 漏れが勘違いしていたようだ。
__uuidofみたいなものが、必須なのだと思っていた。
>>268 多分#define _RTLDLLと同じ。
271 :
デフォルトの名無しさん :03/02/26 09:57
Visual C++.netなのだが、DOSのプログラムは作れるのか?
作れま千。
>>268 Borland-C++ 5.6.x は、C++Builder6の付属品です。
-D_RTLDLL オプションが有効なのも、それに対してです。
_RTLDLLを有効にすると、stlp45.dllなどの共有DLLを使ってくれる
ようになるので、実行ファイルのサイズが減少します。
274 :
デフォルトの名無しさん :03/02/26 21:54
初心者だけど、最初の #include <iostream> って何の意味があるの?
>>274 が初心者だと分かる、という重大な意味がある。
276 :
デフォルトの名無しさん :03/02/26 22:05
それどうでも良い。
今日もまたusing namespace std;を忘れた。
279 :
デフォルトの名無しさん :03/02/26 22:21
僕はセミコロンを良く忘れる。
>>270 ,273
> Borland-C++ 5.6.x は、C++Builder6の付属品です。
> -D_RTLDLL オプションが有効なのも、それに対してです。
そうですか、わかりました
どうもありがとうございました
281 :
デフォルトの名無しさん :03/02/27 00:07
>>274 いらないよ。coutとか使う時にいる。
>>247 そこからC++の世界の一部を展望できるが、それ以上先に進む事は出来ない。
本当の入り口はもっと別な場所にある。
284 :
デフォルトの名無しさん :03/02/27 11:53
「標準」C++勉強したかったらコレ嫁!とかいうソースありますか? 参考書で部分的な知識は知ったけど、実際にどういう局面でソレを使ったらいいかピンとこない状態です。 生Cだったら出てくるんですが。 公開ソースといえばunix由来のものが多いのですが、unix系だとまだ生Cが多いし、C++使ってたとしてもQt/KDEとかmozillaとか、コンパイラ/ライブラリの標準準拠度がいまいちのころ作られた代替ライブラリを使ってる。 Win系だとやはりMFCやVCLべったりなのはともかく、呼び出しだけしょーがなくC++にしてるけど本体は実は生Cとかわらん、というのも多いし。
285 :
デフォルトの名無しさん :03/02/27 12:08
やはりテンプレだろう。 STL のソースを眺める。 さらに、VC なら ATL WTL を眺める。
287 :
デフォルトの名無しさん :03/02/27 15:56
質問させてください! C++の勉強は一通りしました。 次は、VC++.NETの勉強をするか、BCB6の勉強をするか迷ってます。 どちらの方が良いでしょうか? スレ立てるまでも・・・スレがなかったので、ここで質問させていただきます。 本気で迷ってたりするので、よろしくお願いします!
>C++の勉強は一通りしました。
>>4 の書籍は全部読んだ?
>>288 いや・・・そんなに本は読んでないんですが・・・
まぁ、大体が分った程度でしょうか・・・
そろそろ次のステップへと考えてます。
マジで悩んでるんで、ネタナシでお願いしたいのです・・・
勉強して、何がしたいのかって問題やね
>>289 仕事するんだったらVC++.NET、趣味で使うならBCB6。以上。
>>289 Delphi
目的もなしにどの道具がいいと言われてもなぁ
勉強目的なら両方やっとけ、GCCモナー
というのが率直なところ
C/C++以外にも多言語やると視野が広がるよ
>>286 basic_stringからながめてみますた
gcc(3.2)はリファレンスカウント。iterator!=pointer
stlportはフツーに確保。NUL terminated.
vcもフツーに確保。
bccはリファレンスカウント
こんなかんじか。
つーか一般論として一通り言語の学習が終わったと思うなら、 次の段階は何か実際にプログラムを作ってみることだ。 そうすれば自分にどんな知識がかけているか分かる。
>>294 できればどんな場合に自分に欠けているものがあるかわかるのか
具体例をお願いします。
>>297 それが実行する場合、何、欠けるいくらかのいくらかがあるか
どうか判明するかどうか知らせてください。
いろいろレスありがとうございました。 何をしたいか・・・。 とりあえず、ゲームを作ってみたいと思ってます。 それと、アーカイバとかも自作したいなぁ〜と思ってます。 プログラムを仕事としたいとは、今の所思ってないので・・・ それじゃ、BCB6が最適でしょうか? お金貯めないと・・・高いっすね。BCB6・・・ ありがとうございました。
ほんとは私が荒らし。
ゲーム作るならFreeのBorland C++とWin32SDKとDirectXSDKでいいと思う
vectorを使用する方法はよく学習されません。 サイズは自動的に変更されますか。 それがmallocを使用しなくても、システムは領域を自由に安全にしますか。
>>304 翻訳ソフトで訳したような文は気持ち悪いからやめろ。
>>300 Noahのソースでも見てクローン作れ。
>>304 Since a sentence which was translated with translation software is unpleasant, stop.
>>308 日本語がよく見つからなかったので、それは自動翻訳へ当てはまり
翻訳しました。意味は通過しませんか。非常に、親切な人々はここに
います。私は評価します。
std::set, std::mutiset の必要性を教えて下さい。
#include <iostream> std::cout<<311 //(↑ストリームで質問を流し込み中) <<"Metrowerks CodeWarrior ver.8の規格準拠の程度はいかほど?" << std::endl
; ↑忘れた…鬱
>>310 よくこういう質問する人がいるけど、必要性がわからないなら
使わなければいいだけのような気がするんだよね。
もしよかったら何で知りたいのか教えてください。
>>314 単純に基礎知識として知りたいだけじゃないかなぁ。
>>310 値をポンポン放り込むだけで、重複無し&&ソート済みの状態に
なってて欲しい時にset、後者の願望だけの時にmultisetとか・・・。
316 :
デフォルトの名無しさん :03/03/01 13:03
C言語の関数はDLLとかにして、VBから使えるようにできますが、 C++のクラスをDLLにして、VBから使えるようにすることはできますか?
317 :
デフォルトの名無しさん :03/03/01 13:05
できません
.NETなら可能
便乗質問お願いします。JavaとC++で、同じ事は可能でしょうか。 よろしければ.NETは無しの場合をお願いします。
muri
IEで表示されてる文字列を取得するのって どうやればいいんですか?
>323 レスサンクスです。 〜略〜のところが・・・
>>322 まず取得したい文字の先頭でマウスの右ボタンを押す。
そしてそのまま指を離さずに取得したい文字の一番最後まで持っていき指を離す。
すると文字が選択状態になるので編集メニューからコピーを選択する。
326 :
デフォルトの名無しさん :03/03/02 00:36
右ボタンで文字列選択って基本か?
選択されないぞ
おいおい、お前ら相手が初心者だからってデタラメ教えるなよ!
>>322 右ボタンじゃなくて左ボタンだからな!
すまん、肝心なことを書き忘れてた。 1. コントロールパネルからマウスのプロパティを開いて「左きき用」を選択
331 :
デフォルトの名無しさん :03/03/02 04:20
メンバ関数へのポインタを作って呼び出そうとしましたがうまく 行きません。どこがおかしいのでしょうか。 struct A { void func1() { std::cout << "func1()" << std::endl; } void func2() { std::cout << "func2()" << std::endl; } }; void (A::*func[2])() = { &A::func1, &A::func2, }; int main() { A *a = new A; a->func[0](); delete a; }
スンマソン。速攻解決しますた。 int main() { A *a = new A; (a->*func[0])(); (a->*func[1])(); delete a; }
継承を覚えたので記念カキコ
じゃあ漏れもoverloadとoverrideをはじめて使った記念カキコ
じゃあ俺漏れもクラスとかいうのを初めて使ってDLLを初めて作った記念カキコ
抽象クラスのコンストラクタで自分の純粋仮想関数呼んで落ちた記念カキコ
ぬるぽ記念カキコ
338 :
デフォルトの名無しさん :03/03/02 22:23
配列の要素の数ってどうやって調べるんですか?
.size();
sizeof a / sizeof *a
キネンニナグッテアゲルヨ
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>337
すみません。聞き方がまずかったです。 char a[30]; として abcd とだけ入力したとき この4と言う数は どうやったら分かるんですか?
std::char_traits<char>::length();
int len(char *p) { if (!*p) return 0; return 1 + len(p + 1); }
constを愛せよ。
346 :
デフォルトの名無しさん :03/03/03 01:17
袋クラスCFukuroとボールクラスCBallを作って CFukuroの中にボールクラスの配列をつくりたいんですけど、 袋に入れるボールの数をあとからintを引数としたメソッドで決めたいのですが どうやってやればいいのでしょうか?
std::vector<CBall> bag;
>>346 袋クラスの中にボールクラスCBallのポインタをコンポジションで持ち、
後からメンバ関数内でnewする。
350 :
デフォルトの名無しさん :03/03/03 01:49
すいません、コンポジションって何ですか? class CBall{ }; class CFukuro{ CBall *balls; } void CFukuro::SetBalls(int num){ balls = new CBall[num]; } って感じですか?
class CFukuro { vector<CBall*> bag; } void CFukuro::SetBall(CBall* ball) { bag.push_back(ball); } とか
352 :
デフォルトの名無しさん :03/03/03 01:58
ベクターって、私みたいな初心者にはつかいやすいって聞いたのですが できるだけ、配列でやりたいんですよね。ゲームつくるもんで。 あと、個数を設定したいのです。
>void CFukuro::SetBalls(int num){ >balls = new CBall[num]; >} delete[] balls; を挟んでおかないとリークしそうな悪寒。
別にvectorにしたからって実行速度がめちゃくちゃ落ちる沸けでもないのに。
>>350 まあそういう感じ。
CFukuroのデストラクタにCBallのdeleteを入れといた方がいい。
ついでにCFukuroのコンストラクタではballs(0)をやっといた方がいいな。 袋にボールを入れないでデストラクタが呼び出された時のために。
>>352 ただ、クラスへのポインタを持った場合、Cのrealloc()に相当する
処理が面倒なので、後から袋にボールを追加するような場合は
std::vector()の方が相当使いやすいと思われる。
358 :
デフォルトの名無しさん :03/03/03 02:28
質問なのですが、 class A { std::vector<int> v; }; のようになっていたとして、このstd::vectorのメンバ v はAのインスタンス を作った時にきちんと初期化され、インスタンスが破棄される時にstd::vector の後始末もきちんとしてくれるものなんですか?
>>358 当然。メンバにクラス変数を持っている場合は、そのクラス自体の
コンストラクタより先にメンバのコンストラクタが呼ばれる。
解体の時は逆にクラスのデストラクタが呼ばれた後、メンバの
デストラクタが呼ばれる。
クラス変数のメンバを明示的に初期化したい場合は、クラスの
コンストラクタの初期化部分に並べて書く。
360 :
デフォルトの名無しさん :03/03/03 07:12
try,throw,catch,age!
fstreamを使った構造体の バイナリデータとしての書き込みって このようにしかできないのですか? //以下ソース struct record { //hoge }; int main() { ofstream giko("giko.dat", ios_base::out | ios_base::binary); record data; //hogehoge genka.write((char*)&data, sizeof(data)); return 0; }
真っ先に
>>348 の答えが出ないのはC++スレだからなのか?それとも意地悪なのか?
363 :
デフォルトの名無しさん :03/03/03 13:58
すいません、ここで聞くのが妥当か分からないのですが…、 UML図を書けて、それの簡単なテンプレコード(もちろんC++で)が 吐けるようなフリーソフトってありますでしょうか?
配列の要素数てことだと
>>340 氏の出したような回答しか出せないと思うけど。
>>361 それが嫌だったらfopen()とfwrite()を使うしかない。
368 :
デフォルトの名無しさん :03/03/03 14:11
>>361 自分もこれと一緒な感じでプログラムしてる
ところでfstream以外はios_base::binaryっていらないですよね?
strlen() が出たのは
>>342 の後だからね。
静的配列長なら、 template< typename T, size_t N > size_t length_of( T const (&)[N] ){ return N; } とかある
よく読んでなかった。スマソ
個人的には、
>>343 にあったような char_traits<char>::length がお勧め。
char_traits<TCHAR>::length( str ) とかやると、Winでは少し幸せになれるし。
>>364 レスありがとうございます。既にございますか…。
ただ申し訳ございません、よろしければもう少し情報をいただないでしょうか。
どうもそれらしきものが引っかからなくて…。
gplではないですよね…ってあれはライセンスか…うーん。
C++でstructを使う時は、構造体(かそれへのポインタ)を要求するCの関数を呼び出すときくらい?
>>375 C++スレだから?とも聞いているんだけど。
何を言いたいのかというと、C++ではCの関数は使わないのが文化かマナーなのかなと。
そういうのはないんじゃない。単純にCのより安全で便利なのが あるから積極的に使ったらどうって話なのでは。
>>378 なるほど。安全か。
確かにCの関数は丁寧に扱わないと危険だな。
ありがとう。
>>370 上手い。だが、VC++ 6.0は
: error C2265: '<Unknown>' : サイズが 0 の配列への参照は不正です。
: error C2266: '<Unknown>' : 非定数の大きさの配列への参照は、不正です。
とか、とんまなこと言いやがる。
ダメだ…これだけ探しても分からない…。 どなたか、gtplについてご存じの方は、いらっしゃいませんでしょうか。
>>374 単なるデータ構造のばあいはstruct。つーか全てのメンバがpublicならstruct。
標準ライブラリでも、pair<>やnumeric_limits<>はstructである場合が多かろう。
ま、ぶっちゃけstructだろうがclassだろうが関係ないんだが。
384 :
デフォルトの名無しさん :03/03/03 21:41
VisualC++のコンパイルするコマンドってどうするんでしょうか? やったことないので困っています。
cl.exeだよ!なんでそんな事も分からないの? 邪魔なんですよ!
・・・の前にvcvars32.batを実行しておいた方がいいか。
388 :
デフォルトの名無しさん :03/03/03 21:48
>>385 あんたは何も教わらずに生まれてきたときから知ってたのかよ?
偶然思いついたのかよ?こんなくだらない決まり事知ってるくらいで偉そうにすんな
389 :
デフォルトの名無しさん :03/03/03 21:50
>>350 コピーコンストラクタと代入演算子は最低いるよ。
俺は生まれる前から
俺は逝った後から
どっちが本物の無敵なんだよ。
394 :
デフォルトの名無しさん :03/03/03 22:07
mapってハッシュ?
お馬鹿なC++は任意の型からハッシュ値を算出することができないのでそれはない。
ああそうか。文字列とはかぎらないよな。
397 :
デフォルトの名無しさん :03/03/03 22:30
すいません、コンパイルした跡に出来る.exeファイルで プログラムを実行すると、コマンド入れた後に即座に終了するんですが。 なんでですか?
>>397 何も言わずにmainの最後にgetchar();
399 :
デフォルトの名無しさん :03/03/03 22:33
>>398 すまん、もう少し場所を詳しく教えて。申し訳ない。
>>399 #include <cstdio>
int main()
{
/*
いろいろ
*/
getchar();
return 0;
}
401 :
デフォルトの名無しさん :03/03/03 22:34
>397 DOS窓開いてそこから実行すれば閉じない。
403 :
デフォルトの名無しさん :03/03/03 22:37
ところで、俺の参考書には using namespace std; ってあるんだけど、これはいらないの?
>>403 それを忘れるようでは立派なプロフェッショナルにはなれないぞ。
つかその本古杉。新しいの買え。
>>403 標準ライブラリを使わなければいらないでしょ。
Cの標準ライブラリもC++ではstd名前空間にあるんだっけ?
406 :
デフォルトの名無しさん :03/03/03 22:39
ごめん、2000年出版物。3ねんまえだす!
2000年なら一番新しい仕様でしょ。
>>407 最近の流行は
using namespace System;
なわけだが。
409 :
デフォルトの名無しさん :03/03/03 22:43
>>402 XPはコマンドプロントってでるけど、いっしょでしょ?
俺の場合それでやると認識されてないって言われるんです。
412 :
デフォルトの名無しさん :03/03/03 22:45
そのまえにusing〜ってなんのいみがあるんですか?
>>405 #include <cstdio>ってしてあるならstd名前空間にある
#include <stdio.h>ってしたならstd名前空間に無い
だからstd::getchar()が正しい。
けどコンパイラによっては正しくないから不思議
>>408 まるで標準ライブラリが既に時代遅れだと言っているようだな。
>>412 usingしないと
std::cout << "hello,world" << std::endl;
のように見るに耐えないコードになってしまう。
417 :
デフォルトの名無しさん :03/03/03 22:48
でgetchar() いれてみたが、未定義の関数を呼び出したってことで エラー。くそぉー・・・・たすけて。
ネームスペースを明示的に指定した方が名前の衝突もなくて良いと思うわけだが。
>>417 #include <cstdio>
std::getchar();
>>418 std"だけ"はusingした方がいいと思う。
>>418 衝突してから明治すればいいじゃん
ふつークラス名が衝突するなんてありえねー
422 :
デフォルトの名無しさん :03/03/03 22:51
大変御恥ずかしながら、スペルミスでした。 しかし、1回目は終わらなかったけど2回目はだめですた。 もうだめ?
標準ライブラリでstd以外のnamespaceってないの?
>>424 見苦しくなるから。
ちなみに標準ライブラリと同じクラス名のクラスをつくるなんて阿呆だ。
あるよ。いっぱい。
using namespace std;に反対する奴は 人の名前を常にフルネームで呼ぶんだよな?
標準じゃないけど、using namespaceのおかげで、WTLのCStringとATLのCStringが衝突事故を起こしたよ。
>>482 C++相談室の426さん。
2番受付までお越しください。
431 :
デフォルトの名無しさん :03/03/03 22:58
string s;だと組込型を使っているような気分だけど、std::string s;だとやっぱり所詮はクラスなんだなと思ってしまう。
標準ライブラリってクラスだけだと思ってる?
433 :
デフォルトの名無しさん :03/03/03 23:02
>>432 いや?
現にcoutはクラスじゃないでしょ?
s/クラス/クラス名/
>>431 std::size_tの立場はどうなるのですか
だったらクラス以外にも定数や関数名と衝突する可能性あるでしょ。
標準は別格なんだからNS使わずに衝突を回避するのが人間の知恵ってもんだろ。
using反対派は本当にstd::を書いているの? もしかしてスタンダード?
全言語のページからstd::coutを検索しました。 約20,500件中1 - 10件目 ・検索にかかった時間0.10秒 全言語のページからcout -std::coutを検索しました。 約206,000件中1 - 10件目 ・検索にかかった時間0.23秒
>>438 std::書いてるよ。それが当然だと思ってるから。
人間だから、回避しそこねる可能性がるから名前空間があるんじゃないの?
>>440 coutやendlで面倒だと思わない??
面倒だが、std::を含めて名前と考える
そりゃ、クソ長いネームスペースだったら、関数内でusing〜する事はある。 しかし、そういうケースはほとんど無い。
#include <iostream> namespace std{ int cout; } error C2371: 'cout' : 再定義されています。異なる基本型です。
446 :
デフォルトの名無しさん :03/03/03 23:09
ペゾルトのサンプルコードなんですが、 #define DIVISIONS 5 int x, y; x = (x + DIVISIONS) % DIVISIONS; y = (y + DIVISIONS) % DIVISIONS; これって x = x % DIVISIONS; y = y % DIVISIONS; と等価じゃないですか? どうでせう? なんで、わざわざ加算してるんだろ。
妥協案としてusing std::cout;とかいうのもあるわけだが。 つーか、windows.hをincludeしてるとminやmaxがマクロと 被って死ぬほうがよっぽど……
てかusingして誤動作したケースなんてあるか? 俺は一度もないぞ。妄想で物言うなよ。
>>448 俺も無い・・が
それは他人のライブラリをちゃんと活用してないだけなのかもしれない罠
誤動作はないが、コンパイルエラーはある。
#define cout std::cout #define endl std::endl これでいいじゃん(^-^)v
>>446 xやyが-DIVISIONSの値になる時があるなら意味があるかも。
>>450 コンパイルエラーが出たら修正すればいいだけだろ。
アンチは費用対効果をもう一度考えてみろ。
>>454 うるせー!!
確かに問答無用で置き換えてしまうけどよ・・・
修正するくらいなら最初からNameSpace::ClassNameって書きますよ?
だからローカルでusing使えばいいって
459 :
デフォルトの名無しさん :03/03/03 23:22
ここでよかったのか迷いましたが、書きます。 #pragma once というのは、積極的に使っていっていいものなんでしょうか? それとも #define _FUNC_H_ #ifdef _FUNC_H_ というかんじにdefineを使って2重インクルードを防止したほうがいいのでしょうか?
>>457 じゃあ今まで衝突したのが何回でusingしても衝突しないのが何回かカウントしてその比率を出してみろ。
>>459 断然後者でしょ。
ちなみに
#ifndef FUNC_H_
#define FUNC_H_
だよ・・・
>>459 両方書けばいい
#ifdef HAS_PRAGMA_ONCE
#pragma once
#endif
とやってコンパイラによってHAS_PRAGMA_ONCEを定義すればいい
>>461-462 即効での回答ありがとうございます。
ifdefを使っていこうと思います。
if'n'defだっつーの
>>460 そんなバカな事言ってないで、ちゃんと名前空間を指定しなさい。
それでも面倒くさくて using namespace を使いたかったら、関数内とか限られた場所に
しなさい。グローバルでこれを書くのは止めなさい。
貴方が良くても他のプログラマが迷惑を被ります。
快適な開発環境作りに皆様のご理解とご協力をお願い致します。
>>466 ひとつのファイルは一人で書かないかい?そこまで細かくモジュール化しない?
まさかヘッダーファイル内でusing namespaceなんて馬鹿なことはしないだろうし。
原理主義者の思考停止っぷりはある意味感動的だな。
そのうち万に一つの誤作動を防げるとか言い出しそうだけど そしたらそもそもC++使うのが間違いだよな(藁
470 :
デフォルトの名無しさん :03/03/03 23:46
おまえらusing namespaceが死滅寸前に追い込まれたときどうするよ? ちゃんと対策とってるかよ 死滅対策をよ 死滅後の行動とってるかよ
>>465 くっ謎のコンパイルエラーが・・・
ん?
おお!
nが足りなかったのね
またまた助かりました
このスレにしては珍しく論争が起きたな。 まあ結論としては標準ライブラリは使うなということだな。
おまえら470が死滅寸前に追い込まれたときどうするよ? ちゃんと対策とってるかよ 死滅対策をよ 死滅後の行動とってるかよ 別に放っておいてもいいか
おまえらboostが死滅寸前に追い込まれたときどうするよ? ちゃんと対策とってるかよ 死滅対策をよ 死滅後の行動とってるかよ
おまえら474が死滅寸前に追い込まれたときどうするよ? ちゃんと対策とってるかよ 死滅対策をよ 死滅後の行動とってるかよ 別に放っておいてもいいか
>>467 > まさかヘッダーファイル内でusing namespaceなんて馬鹿なことはしないだろうし。
俺は傍観者だが、てっきりこのケースも込みで話してるんだとばかり。
>>451 using std::cout
using std::endl
にしとけ。
あ、セミコロン忘れた。 using std::cout; using std::endl;
とりあえず、アンチ using namespace std; 派は、using namespace std; 派を 説得するに足りる理由をまだ出してないな。
ライブラリの実装の詳細まで表に晒してしまうという問題点がある寝。
ハァ?
だからローカルですりゃいいじゃん
そうそう、グローバルでしかもヘッダに書く奴はDQN
グローバルでヘッダ以外ってなんですか?
そもそもグローバルなんてものが存在する時点で言語としておかしいだろ。
>そうそう、グローバルでしかもヘッダに書く奴はDQN というやつがいるからusing namespace std;しないのだが 実際理由がわからん。ひょっとしておまえも?
そのヘッダをインクルードしたファイル全てに名前空間の中身を さらしてしまうからでは。
namespaceの存在意義とは何ですか?
でその実害は?ということをアンチは一言も説明していないのだね。
名前の重複だよ。 重複が発生したら書き換えれば良いてのは無しね。そんなブサイクなソース見たくないから。
>>491 で、その不細工なソースの実害は?ということをアンチは一言も説明していないのだね。
回数や割合って話も出たが、出来得る限りそうならんように、 未然に回避しようという試みだろう名前空間の導入は。何も 自分が書いたソースだけじゃなく他人が書いたライブラリを 利用するときも衝突は起こる可能性はあるだろ。
494 :
デフォルトの名無しさん :03/03/04 01:02
自分のネームスペースの中でusing namespace std;するのはありですか? namespace my_ns { using namespace std; void print() { cout<<"pu"<<endl; } }
int n; int foo(int x) { int n; ... } たとえば上のコードでローカル変数nを宣言し忘れた場合誤動作してしまう。 それを未然に防ぐためにはすべての変数名の重複をなくせば良いわけだが それをしないのはどうしてだ?
>>492 std::〜を何回も書くブサイクなソースが嫌だからusing使うんじゃなかったのか
>>497 すべてに毎回書くのは明らかに「非効率」だからusingを使うんだよ。
重複箇所を括りだすのは当たり前だろう。
boost から stl に採用されて移植、みたいなクラスがあったとして、 boost::shared_ptr とか書いてたのを std::shared_ptr って書き直すのってけっこう大変。 using してると 一行書きかえるだけで対応できる。 移植は滅多にないかもしれないけれど、 std → stlport ( __STLPORT_NAMESPACE ? ) はやった事がある人結構居るんじゃない? 面倒だったでしょ? つまり、自作名前空間や支持されていないライブラリの名前空間は using しないのが良いのではないだろうか。
だからローカルにすりゃどっち派も丸くおさまるって。おっちゃんの言うこと聞いとけって。
>>499 boost::shared_ptrを一括置換したらいかんのか
using namespace std;に反対する奴は もちろんthis->を省略したりはしないんだよな?
アンチは説明責任をはたせ〜〜〜〜〜〜〜
>>504 んで、しばらくして「釣りでした」とか言い訳して
もっといじめられるのな(藁
float f; double d; f=100/3; d=100/3; cout << setprecision(15) << f << endl; cout << setprecision(15) << d << endl; では、33と33。 f=100.0/3; d=100.0/3; では、少数以下も表示されます。 左辺の型に合わせて、右辺もキャストされるんじゃなかったっけ?
いや、俺は激しくまじめなんだけど。 this->を省略しないことで未然に防げる不具合が現実のコードの中に現れることがある。 いや、実際には誤動作ないしはビルドエラーが出てからthis->を明示することが多い。 でもわざわざ毎回は書かない。それは面倒だし上の問題は比較的容易に発見・修正できるから。 つまりやらなかった場合のメリットとデメリットとやった場合のメリットとデメリットを比較して やらないほうが賢明であると(半ば無意識に)判断したから。 このことと上で議論されているnamespaceの問題との類似性に全く気がつかないとしたら ちょっとプログラミングの適正に問題があるんじゃないのとか思ってしまうよ。
100/3 のほうは結果の 33が float や double に変換される
だからローカルに書いとけって。
ローカルってどこよ?
>>508 thisを省略しないことで防げる不具合とは?
引数とかグローバル変数とかぶっちゃうってこと?
そんなあなたにはグローバル変数にg_と付けたりメンバ変数の末尾に_をつけることをお勧めします
>>509 そうやったね。
5ヶ月ぶりにプログラムやったもんだから・・・。
もしかしてほかにもいろいろと忘れてしまってるかも・・・。
やべーなこりゃ。
>>508 そりゃthis->を書かなきゃならないところで書かないおまえが悪いって話だろ。
明示的にthis->しなきゃならない場所がわからずプログラミング
してる方がよっぽど問題ある奴だと思うが。
this-> を書かなきゃいけないのってメンバ関数をポインタを使って 呼び出す時以外にあったっけ?
>>514 というか、this->を書かなきゃならないところはどこっ?
わからん、教えて、変数名がかぶることじゃないの?
プププッ たくさん釣れましたな(藁
まず、ヘッダでusingするのがダメなのは異論無いな。 そんなわけで、インライン関数やテンプレート関数の定義をヘッダに書く場合に、 名前空間の指定は、ローカルスコープでusing(namespace)することになるわけよ。 で、「ヘッダでなければ、usingを関数外に置いてよい」なんてことにすると、 ヘッダかそうでないかでコーディングスタイルを分けなきゃいけなくなるだろ。 インラインにするかしないか迷ってるときなんか、悩ましい話だな。 めんどくさいから関数外でusingするのはやめとけって結論に、ならないか?
>>519 ならないだろ。もちっと文法のおさらいが必要だな。
>>516 だからつけなきゃいけないところでつけるのは当たり前じゃん。
今そんな話じゃないだろ。
>今そんな話じゃないだろ。 省略可能なところは省略すべきって事で意見の一致を見たという話だよな。
大体な、全角文字の後に半角の?使う時点でキモイんだよ。
524 :
デフォルトの名無しさん :03/03/04 02:10
ふう。アンチは敗北したようだな。 これからはヘッダにバシバシusing namespaceしろよ。
525 :
デフォルトの名無しさん :03/03/04 02:12
もうどうでもいいよ
>>522 >>508 は単に省略不可能なところで省略したって話。
本人は省略不可能だと気づかなかっただけ。
結論:馬鹿ほど良く吠える。
じゃ、ローカル派大勝ってことで一件落着ですな。
え?文法?どういうこと?
>>528 C++といえどもグローバルは実質存在しないんだから
ローカルもまたその言葉の意味を失うだろ。
便宜的表現にかみつくなよ。 ローカル変数、グローバル変数くらい聞いたことあるだろ。
C++厨って普段重箱の隅をつつきまくってる割に どうしてこんなに重要で根本的な所を理解していないんだろう?
で、アンチ using namespace std; 派は、using namespace std; 派を 説得するに足りる理由をまだ出してないな。
>>532 ありませんが何か?
private, protected, publicと何か関係がありますか?
ぶっちゃけた話、必ず .cpp ファイルで using namespace std; してる人は それをヘッダに移動しても何も変わらないと思うよ。
538 :
デフォルトの名無しさん :03/03/04 02:30
てかアンチは自前のnamespace作らないのか?
てかアンチは自前のclass作らないのか?
てかアンチは自前のぬるぽ作らないのか?
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>542
反応はえぇ・・・
545 :
デフォルトの名無しさん :03/03/04 02:34
要するにアンチは文法を理解していないと。
ぐっじょぶ
>>545 漏れか?漏れのことか?
いまだに
>>520 で何を突っ込まれてるのか理解してないぞ。
誰か解説
ヘッダでも namespace MyLib { using namespace std; ... } ってやればMyLib.hをインクルードしてもstdで汚染されないって話だろ。
using namespace MyLib; した瞬間に・・・。 つーか、標準でそろっているものに名前空間なんて要らないと思うんだけど、 何でそれを 「汚染」 と呼ぶんだろう。
たしか、関数を呼ぶときの引数って 途中でいじってはいけないというか、 どんなコードを吐かれも文句を いえないことになっているよね? こんなの。 f(x, ++x); それでは、キャストはどうなの? g(lparam, reinterpret_cast<HWND>(lparam)); こういうのは?
>>550 副作用のあるものと無いものを比べてどうしようというのだ?
f(x, x+1)といっしょ。
>>550 じってはいけないんじゃなくて、参照している変数の内容が変わるような事を
してはいけないという話。
キャストは、++ 演算子と違って変数の値を変更するわけではないので OK。
副作用完了点で調べてくれ。
キャストによって lparam 自体の値が変わる訳ではないから問題ない。
お前らまとめてケコーン
>f(x,x+1) とは違うと思うな。 引数の評価順が決められていないので ++x が先に評価されるか 後に評価されるかで結果が違ってくるという話だと思う。
>>552 引数の解釈順序は処理系依存じゃなかったっけ?
昨晩はC厨がネームスペースに嫉妬してたようで。
559 :
デフォルトの名無しさん :03/03/04 12:49
スマートポインタtypedefして使うべき?orんなことねぇ? typedef SmartPtr< A > A_ptr;したら、 typedef SmartPtr< const A > const_A_ptr;もしないとキビしいと思うけど、 こういうことしてる人いる?
using をかたくなに拒んで std:: つけまくる人に VB 触らせたら、えらい事になりそうな・・・
JavaやC#でも可。
NameSpace1NameSpace2:NameSpace3::NameSpace4::HogeHoge hoga(NameSpace1::NameSpace2::NameSpace3::NameSpace4::MageMage("age"));
ネストが深いときは別名を使う手もある namespace TempHoge = Hoge1::Hoge2::Hoge3::Hoge4; TempHoge::〜;
564 :
デフォルトの名無しさん :03/03/04 19:23
Withのネストなんてあったっけ?
それはシングルトンのクラスを作るが、これは建設者をセットします、 に、個人、また静止のメンバー変数からそれを単に呼ぶべきであるか?糞?
間違えてありました。 それはシングルトンのクラスを作るが、これはコンストラクタをセットします、 に、private、またstaticのメンバー変数からそれを単に呼ぶべきである?
>>566 それをシングルトンのデザインパターンにするために、
コンストラクタはprivateのことへの第1のセットです。
次に、必要なことはprivateのメンバー関数からコンストラクタにちょうど電話することです。
で、結局using namespace stdの結論は何ですか? 分かりやすく説明してください。
コーディングスタイルに結論は無し、って結論。
>>568 usingを十分に使用して使用しない人々は、単に怠惰であると考えられます。
役立たない所有は、C++が多くの問題で準備したメカニズムを利用しません。
571 :
デフォルトの名無しさん :03/03/04 20:39
個人的に using std::cout; using std::endl; using std::vector; (略) これで妥協。
また半角?くんの登場か。
いやー、もうすっかり春だなあ。
最近C++厨みないな。
引数の件だけど みなさん、ありがとね。 やっぱり大丈夫ですか
576 :
デフォルトの名無しさん :03/03/04 22:21
最近、次のようなコードを見ました。 class B{ virtual void f() = 0; }; class X : public B{ const B* b; public: X(const B* c):b(c){} virtual ~X(){ delete const_cast<B*>(b); } void f(){} }; C/C++ UserJournalにあったコードを簡単化したものです。 疑問は、 1 ~Xのconst_castに何か意味があるか? 2 なんでBに仮想デストラクタを置かないか? です。どうも変なコードなんですが、CUJの記事だし。 と悩んでます。
>>576 それコンパイルできないでしょ。Xのデフォルトコンストラクタがない。
>>550 f(x,x++)はまずいが、f(x,y++)なら問題ない。
だから++を使ってはならないというわけじゃない。
>>576 X(const B* C) にBへのポインタを渡そうにも、Bは抽象クラスだから
インスタンス作れないし、どこか移し間違えてない?
B から派生したクラスのインスタンスが渡される可能性もあるよ。
うろおぼえで書いちまってごめんなさい。 記事はテンプレートを使ってコンパイル時に計算を済まそうってやつで、 俺がひっかかったのは、テンプレートを使わない、普通のコードの方。 も一度思い出して、コンパイルできるのをウプしま。
>>581 その場合でも、Bから派生したクラスがデフォルトコンストラクタを
持つと、Xにもデフォルトコンストラクタが必要だと言われる。
卵が先か鶏が先かみたいな問題になってる。
>>583 ああごめん、X は Bから派生してたのか。
何か変だな。
585 :
デフォルトの名無しさん :03/03/04 22:48
というか、デフォルトコンストラクタは無くてもいいだろ
コードを簡単にしようと思ったんですが、なんだか長くなりました。 こんな感じです。 class B{ public: virtual void f() = 0; }; class D : public B{ public: void f(){} }; class X : public B{ const B *b1, *b2; public: X(const B* c1, const B* c2):b1(c1), b2(c2){} ~X(){ delete const_cast<B*>(b1); delete const_cast<B*>(b2); } }; class Y : public X{ public: Y(const B* c1, const B* c2):X(c1, c2){} void f(){} };
で、デザパタのCompositeだそうです。
DがリーフでYがコンポジットですね。
でも、
>>576 のような疑問がわくのです。
メインのコードでないので手を抜いたのかとも思うのですが、
なんか、ものすごくいやな感じがするんです。
タイトルわかりました。 March号のC++ Expression Templates です。記事そのものにはあんまり興味ないんですが。
>1 ~Xのconst_castに何か意味があるか? deleteはvoid *を受け取るconst void *じゃない >2 なんでBに仮想デストラクタを置かないか? bug
>>579 >
>>550 > f(x,x++)はまずいが
あ、はい、「大丈夫」と書いたのは
キャストの方についてです
++xはまずいですよね
>>587 const_castそのものは*b1と*b2のconst性を取り除くものだろうが、
delete時にはconst性を取り除く必要はないので冗長だね。
Xが仮想デストラクタを持っていないのは、すぐにでも問題になりそうだ。
class B{
public:
virtual void f() = 0;
};
class D : public B{
public:
void f() { }
};
class X : public B{
const B *b1, *b2;
public:
X(const B* c1, const B* c2):b1(c1), b2(c2) {}
~X(){
delete const_cast<B*>(b1);
delete const_cast<B*>(b2);
std::cout << "~X()" << std::endl;
}
void f() {}
};
class Y : public X{ B* b; public: Y(const B* c1, const B* c2) : X(c1, c2) { b = new X(0, 0); } void f() {} }; int main() { D d1, d2; X* xp = new Y(&d1, &d2); delete xp; }
しっかしBorland-C++5.6.4だと
>>591 >>592 のコードコンパイルすると
コンパイラがあぼ〜んするね。具体的にはリンカ起動してくれない
のでexeができない。
>D d1, d2; >X* xp = new Y(&d1, &d2); X *xp=new Y(new D,new D);
>>589 >deleteはvoid *を受け取るconst void *じゃない
たしかにそうですね。でも、
>>591 さんが言うように、必要あるのか
わからんのです。
コンパイラが警告すら出さないので。
しかし、constを簡単にはずせるのも不思議でつ。
Bに仮想デストラクタがないのは、バグということで、よさそうですね。
>>586 には、
int main()
{
Y y(new D, new D);
}
つけて、BC5.6でコンパイルできます。
人と話して、少し気がすみました。
みなさま、ありがとうです。
>コンパイラが警告すら出さないので。 キャストしなくても、警告を出さないという意味です。 ためしたのは、BC5.6っす。
>>593 です。
スマソです。コンパイラがあぼ〜んしていたように見えたのは、いつのまにか
コンパイラオプションに-Sがついてアセンブリ出力していたせいでした。
取ったらちゃんと無事コンパイルできました。
g++もいいが、日本語でエラーを出してくれるBCCはやはり手放せない。
598 :
デフォルトの名無しさん :03/03/05 00:47
憂鬱本やら、デザパタの本やらを揃え、 これでおいらも設計厨とばかりに、意気込んでみたのですが…。 いざ設計とやらを初めてみると、WndProcに縛られたり、 ライブラリの関係で理想通り出来なかったりと、色々参っています。 そもそも独学のせいか、どうも設計の方法って言うのが良く分からなくて…。 ここからもう一歩踏み出すには、どんな努力が必要でしょうか…。 自分でも曖昧な上、お馬鹿な質問だとは思うのですが、結構真剣でして…よろしくお願いします。
>>598 富士の樹海を歩いてみるとか。人生違ってくるかも。
嫌なAPIは、素敵な自作クラスでWrapしろ
うーん、やっぱり質問が曖昧すぎたようで…。
設計が上手い方って言うのは、どうやって腕を上げたんだろう…。
やはりこのまま、数をこなすしかないのかな…スレ汚し失礼しました。
>>600 どうもです…
>>598 Java や Python でしばらく遊んでみてから C++ に戻ってみたら?
WindowsのAPIは全部ラップして目の前から消したくなる。
∧_∧ ( ´∀`)< サランサップ
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
>>605 (_フ彡 /
∧_∧ ( ´∀`)< 「ぬるぽ」と言ってみるテスト
サセルカ!
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
>>608 (_フ彡 /
610 :
デフォルトの名無しさん :03/03/05 20:21
double linked listでqueueを実装する。 一方のスレッドが要素をpushしていき 他方のスレッドが要素をpopしていくとした時、 要素の数が3以上の時はスレッドセーフであり 3未満の時はpush()/pop()内の処理を mutexなどで保護しなければならない。 なお、要素数のインクリメント・デクリメントのタイミングは push()では処理の最初、pop()では処理の最後とする。 これであってる?(厳密にはpushは3,popは2と安全な数は変わってくるけど とりあえず両方安全な数を調べたい) 図解 A→B→C→ ←A←B←C 要素Aはpush専用スレッドからのみアクセスされる 要素Cはpop専用スレッドからのみアクセスされる 要素Bは両方のスレッドからアクセスされる可能性がある。
要素の数が何個だろうがmutexを使うべきだと思う 個の処理は
マルチスレッドかつパフォーマンス最優先なんで べきとかいわれても困るんだけど。 実際の運用時にはqueueはだいぶ長くなるはずだから(短ければ暇だろうし) 実質mutexなしで動くんじゃないかと期待してる。
>>612 ソフトの名前を言って下さい。買いませんから。
>>598 知識、経験、センス、バランス感覚、といった要素のどれが欠けても
良い設計者にはなれない。ので、
> やはりこのまま、数をこなすしかないのかな…
が正しいと思われ。
ただ、意識してそれをやり、いろいろな観点から評価する、それを
反復的に繰り返す、ということが大事だと思う。
>610 現在要素数5個->push処理に入る->競合を防がないpush処理を始めようとしたその時! pop->pop->pop->pop->pop さあ、push処理の続きだ->どかん! と俺の脳内で実行されたけどどうですか?
要は要素数のテストとロックをatomicに実行できなければそういう 危険があり、atomicにしたければそれをcritical sectionに しなければならないという当たり前の話だよな。 まあ「性能最優先」であって「たまに落ちてもよい」んであれば 「どかん!」がめったに発生しないのであればかまわん気もするが 後で保守担当者が泣きそうな予感。
>>615 そりゃまずい・・・
ではこれを追加したらよいかな?
volatile bool entering_push;
void push()
{
entering_push = true;
...
entering_push = false;
}
void *pop()
{
if(entering_push && size() < 3)
return 0;
...
}
保守担当「このコードあやしいんですけど〜」 610「何が言いたいの?パフォーマンス最優先なんで あやしいなんていわれても困るんだけど。」
ヴォヴォヴォvoidの大爆笑〜♪
620 :
デフォルトの名無しさん :03/03/05 21:40
現在要素数5個->push処理に入る->entering_push = true;をする直前で pop->pop->pop->pop->popの途中で さあ、push処理の続きだ->どかん!
622 :
デフォルトの名無しさん :03/03/05 21:48
pushもpopもスレッドセーフになってないんですけど。
これで完璧? pushに失敗するのが笑えるけど実際には OSのタイムスライスはpush/popより十分大きいから最悪のケースは発生しなさそうだ。 volatile bool entering_push; volatile bool entering_pop; bool push() { entering_push = true; if(entering_pop && size() < 2) return false; ... entering_push = false; } void *pop() { entering_pop = true; if(entering_push && size() < 3) return 0; ... entering_pop = false; }
>>623 if(entering_pop の直後に entering_pop = true; が実行されたら?
会費操作にアトミックなコードを書けない限り、mutex のたぐいを使うしかない。
mutex を使う事の何がイヤなんだ?
> 会費操作 これ何だかイヤだ・・・
>>623 フラグの変更はクラスでラップしてコンストラクタ・デストラクタ内で行え。
そしたら例外が発生しても大丈夫だから。
パフォーマンス最優先なんでクラスでラップなんていわれても困るんだけど。
え?pop()だとかsize()だとかはクラスのメンバ関数じゃないのか?
というか、void*かよ。
>>602 >>607 がんばります、がんばりましょう(´Д⊂
>>603 話を聞くとJavaは随分素直みたいですねぇ。元々興味ありましたし…。
早速SDKを落としてみました。この際なんでもやってみたいと思います。アドバイス感謝です。
>>614 真摯なご忠告ありがとうございます。思ってた以上に困難な道のりなんですねぇ…。
仰るとおり自省を忘れずに、こなしていきたいと思います。なんだか絵の上達法に似てますねぇ。
何だ、半角?くんか
生産者と消費者の計2threadの競合を回避したいだけなら、 以下に示すPetersonのアルゴリズムが使えるはず。 # TanenbaumのModern Operating Systemsなどに載っている。 だが、本当にこんなことをやる必要が有るのか測定してからに したほうがよいと思われ。 volatile int turn; volatile int interested[2]; /* which is 0 or 1, indicating the caller thread */ void EnterCriticalSection(int which) { int other = 1 - which; interested[which] = 1; turn = which; while (turn == which && interested[other] == 1) /* busy wait */; } void LeaveCriticalSection(int which) { interested[which] = 0; }
>>627 クラスでラップしても下手なコード組まなきゃパフォーマンスは一切落ちんぞ。
パフォーマンスはもっと別のところがネックになると思われ
635 :
デフォルトの名無しさん :03/03/05 23:43
ttp://www.emit.jp/prog/prog_opt0.html の解説の意味がわかりません
なぜメンバ変数よりもその場で定義した変数(ローカル変数とでも言うのかな?)の方が早いのですか?
解説には
>「ループ内で書き込んでいるバッファ中に、参照しているメンバ変数が存在しているかもしれない」
>つまり、「ループ内の書き込みにより、メンバ変数の値が書き換えられ、ループの条件が変わるかもしれない」
>ことをコンパイラは考慮しているのである
とありますが、いったん代入しても同じだと思うのと、
forのカウンタにメンバ変数を使わないのはセオリーだとわかっていますが、
なぜメンバ変数を使うと速度が遅くなるのでしょうか?
まったく理由がわかりません。ご存知でしたら教えてください。
637 :
デフォルトの名無しさん :03/03/06 00:11
ポインタのアドレスが変更されているときの対応。
638 :
デフォルトの名無しさん :03/03/06 00:18
RMP4のソースを使って、デコードついでにストリーム再生 させる物作れと言われたが、わけわかめです。。。 DirectShow自体わからんのに。。。 どなたか見本を作ってください。。。
639 :
デフォルトの名無しさん :03/03/06 00:24
>>636 勘違いしないでね、メンバ変数が×なのではないのよ。
改悪例をみてね。
> なぜメンバ変数を使うと速度が遅くなるのでしょうか? 直接の理由は、最適化が難しくなるから。 難しくなるだけであって、遅くなるかどうかは別問題。 constでないメンバ変数はthis経由でいつでも書き換えられる可能性があるので、 これを最適化時に完全に把握するのは困難あるいは不可能。 ローカル変数は生死のスコープが極めて短く、ポインタ経由で参照される ことが少ないので、安全な最適化が実用的な時間で行えることが期待できる。 要するに、最適化時に値の変化を把握できるかできねえか、という話。 完全に把握できれば、たとえばレジスタに載せることができる。 環境依存なネタとしては、ローカル変数が取られるであろうスタック はキャッシュに乗ってる可能性が高い、というのもあるけど・・・ そんな低レベルな話じゃないよね。
>ポインタのアドレスが変更されているときの対応 >constでないメンバ変数はthis経由でいつでも書き換えられる可能性がある ここがよくわからないのです。 マルチスレッドでもあるまいし、forループ中に書き換えられるってことはあるのですか?
struct Test { int m; void foo() { for(int i=0; i<m; i++) bar();//メンバ関数の中でメンバ変数mが変わるよね //この関数がインラインなら最適化できるかもしれないけど } void bar(); }; void Test::bar() { m--; }
643 :
デフォルトの名無しさん :03/03/06 22:18
ぬるPO!
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>643
645 :
string勉強中 :03/03/06 22:33
引数に文字列バッファのアドレスを渡して何らかの文字列をセットしてもらう関数ってあるよね。 文字列はstringを使うとします。 この場合、いったん仮のバッファで文字列を取得してstringオブジェクトに代入するしかないんでしょうか?
>>641 そのコンテクストにおいてマルチスレッドであるかないかを判定できるくらい上等なCコンパイラって少ないと思います。
648 :
デフォルトの名無しさん :03/03/06 22:45
ナイクもってきて!ナイク。
>>648 std::strstream使えば、ほとんど事足りるでしょ。
sprintf()からはおさらばしよう。
>>648 スマソstd::stringstreamね。
いまだにtypoする。
とりあえずvector<char>で受けてstringにassignなりするという奴だな、この場合。
cin とか std::getline() から直接 string に 読み込んだら?って俺も勘違い?
具体的に文字列をセットする関数とはどのような関数を指すのか 言ってもらわないと答えにくい。
int hoge(char* buffer, size_t len); みたいなCの関数の結果をstringに格納する方法についてだろ?
>>657 そう
例えば
void WINAPI ListView_GetItemText(
HWND hwnd,
int iItem,
int iSubItem,
LPSTR pszText, <-- これ!
int cchTextMax
);
>>654 みたいにワンクッション入れるしかないんでしょうか?
わたしの脳内ではstringから書き込み可能なポインタがサックリ
とれたりするんですが。
APIならしょうがないな。すなおにTCHARで取ってきてstringにコピー。
vector<char>のまんまでもいいんじゃないの、別に
>>660 はウィンドウズフォルダをc:\windowsときめ打ちして後に禍根を残すタイプ。
やっぱり昔懐かしのchar(TCHAR)配列を使うしかないんじゃないのかなー
C++の議論って傍から見てるとギャグにしか見えないんだけど 当事者はいたってまじめだから倍笑えるよね(藁藁
>>663 まぁ、確かにそういう面はあるわな。
やたらめったら何重にもラップしたがるし。
開発者がギャグで作った言語だからな。
へんなJava厨が来た
でもあたしは C++ 好きだよ。キスしたいくらいに。
いいかげんstdからchar*を追放しろよ・・・
669 :
デフォルトの名無しさん :03/03/07 01:32
template <class F> void AAA(const std::string& s, const std::string& d, F f) { while(...略...){ ... f(s.substr(...略...)); } } とした時、 void Print(std::string& s) { cout << s; } で、 AAA(s, d, &Print); はできるのですが、 class CCC { public: Print(std::string& s){cout << s;} } で、 AAA(s, d, std::mem_fun_ref(&CCC::Print)); とやってみましがC2784でコンパイルがとおりません.(vc6です) 色々調べて見たのですが何が間違っているのがさっぱりわかりません. 何か根本的に間違っているのでしょうか?
670 :
デフォルトの名無しさん :03/03/07 01:36
書き間違いました. class CCC { public: Print(std::string& s){cout << s;} do{AAA(s, d, std::mem_fun_ref(&CCC::Print)); } } の AAA(s, d, std::mem_fun_ref(&CCC::Print)); でエラーが出ます
>Print(std::string& s){cout << s;} とりあえず、ここは Print(const std::string& s){cout << s;} こうしなさい
void もつけて
クラススコープの中で do{} ?
674 :
デフォルトの名無しさん :03/03/07 02:15
>>673 書き間違えました.メンバ関数です
do(){AAA(s, d, std::mem_fun_ref(&CCC::Print)); }
675 :
デフォルトの名無しさん :03/03/07 02:18
do はキーワードだから関数名として使えないんじゃない?
676 :
デフォルトの名無しさん :03/03/07 02:28
あーすいません、実際には別の名前使ってます
BCC5.5.1では通った。 #include <iostream> #include <functional> #pragma argsused template <class F> void AAA(const std::string& s, const std::string& d, F f) { ; } void Print(std::string& s) { std::cout << s; } class CCC { public: void Print(std::string& s) { std::cout << s;} void hoge() { AAA("hoge0", "hoge1", std::mem_fun_ref(&CCC::Print)); } }; int main() { return 0; }
std::mem_fun_ref(&CCC::Print)); は第一引数にCCCの参照を受け取る関数オブジェクトを作ります 一方グローバルのほうのPrintは引数を受け取らない関数です 引数がいる関数といらない関数をそれぞれ渡しているわけで 関数AAA内でf()と呼ばれていたらだめだよね というか、俺の説明がだめか・・・後はよろしく
VC++ 7.0を使っています。以下のコードでエラーC2327 [data2 : 外側のクラスのメンバは型名、スタティック、または列挙子ではありません。] が発生します。struct中の宣言を一つだけにすればコンパイルは通るのですが、 二つにしたとたんエラーが出ます。これは私が悪いのでしょうか? コンパイラが悪いのでしょうか? class C { static const intwidth=64; static const intheight=64; struct { float data1[width][height]; int data2[width][height]; //ここでエラー }S; }; ・補足 struct{ //これでコンパイルは通ります float data1[width][height]; //int data2[width][height]; }S; struct{ //これでも通ります //float data1[width][height]; int data2[width][height]; }S; struct{ //これでもなぜか通ります int data2[width][height]; float data1[width][height]; }S;
すみません、
>>679 のコードでは再現できませんでした。
再現するための最小のコードを訂正として乗せます。
class C
{
public:
static const intwidth=64;
static const intheight=64;
struct S
{
float height[C::height][C::width];//この行と下の行の順番を入れ替えるとなぜかコンパイルできる
intdata[C::height][C::width];//
}
};
heightの名前がかぶっているのが直接の原因だと思いますが、
別の名前空間に存在するはずなんです・・・
私が悪いのか、コンパイラが悪いのか。教えてください。
enum を使ったほうが。const であっても静的メンバは配列のサイズ指定に 使えなかったような気が。 class C { public: enum { width=64, height=64 }; struct S { float height[C::height][C::width];//この行と下の行の順番を入れ替えるとなぜかコンパイルできる intdata[C::height][C::width];// } };
>>680 あのう、intwidth、intheightというのがいけないのだと思いますが。
VC++7.0で下記のコードちゃんと通りましたよ。
>>681 static constなデータメンバに限って、クラスボディで初期化していれば
配列のサイズを指定するのに使えるよ。
class C
{
static const int width = 64;
static const int height = 64;
struct {
float data1[width][height];
int data2[width][height];
} S;
};
int main()
{
C c;
}
>static constなデータメンバに限って、クラスボディで初期化していれば あれそうなの?VC++の独自拡張とかでなくて規格でも許されてるのかな。
>>683 C++Primerには書いてあった。ちょっと待って、refman.pdfの
該当部分探してみるから。
>>683 あった。規格書pdfのP158の項目4。
選択してコピペする事はpdfビューアではできないらしいので場所だけ
書いておくね。
>>682 そのdata1という変数名をheightにしたら…
という話では。そのためにC::をつけてるんだろうし。
>>686 そうか?俺はてっきり int height と書くべき所を intheight と
くっつけて書いてるせいだと思ってたが・・・・・
そんなのただの写し間違いだと思うけど… intdataにもなってるし、順番かえるとコンパイル通るって言ってるし。
みなさん、お返事ありがとうございます。
>>687 すんません、その間にはtabが入っていて、コピペで削除されてしまいました。
class C
{
public:
static const int width=64;
static const int height=64;
struct S
{
float height[C::height][C::width];//この行と下の行の順番を入れ替えるとなぜかコンパイルできる
int data[C::height][C::width];
}
};
>>682 さん、このコードでコンパイルが通るかもう一度確かめていただけないでしょうか?
>>685 さんによればこのコードは大丈夫なはずなんですが・・・
これはVC++ 7.0のバグということでよろしいんでしょうか?
回避策はenumを使うことでしょうかね?
>>685 どうもお手数かけまして、9.4.2 Static data members にちゃんと
書いてあるね。こんな変則的な技があったとわ。
bccは通ったから、バグかモナー
すみません、
>>689 のstruct Sの最後の「;」が抜けてました。
>>688 本当だね。C::とクラス名を限定しなければエラーにならないが、
C::heightとかと書くと、順番を入れ替えないとエラーになる。
>>689 やってみました。確かにVC++7.0では通りません。バグっぽいですね。
Updateを待つか、.NET2003を待ちましょう。取り敢えずMicrosoftには
フィードバックしておきましょう。
695 :
デフォルトの名無しさん :03/03/07 17:03
あの、今、VC++6.0使ってるんですけど、.NET(VC++7.0?)の使い勝手と比べて、 どのくらい違いますか? 6.0使っていれば、そのまま.NETもすんなり使えるでしょうか? バージョンアップしようかどうしようか迷っています。
696 :
デフォルトの名無しさん :03/03/07 17:25
質問です。 std::fstream でファイルを開いたとき、 そのファイルはロックされますか?
>>695 操作面だけの話しですが、
細かいところけっこう違うけど、カンでいけます。
(最初、プロジェクトプロパティが見つからなくて悩んだ)
MSDNが統合されて、俺的には便利です。
あと、クソ6.0ように何の理由もなく落ちたりしてません。今のところ俺の環境では。
ところでWinSock関連のスレないですかねぇ?
>695 ただしクラスウィザードが無くなるので そのあたり激しく使い勝手悪い所感。
>あと、クソ6.0ように何の理由もなく落ちたりしてません 自分の環境ではコード補間などの機能をオンにしておくと 突然コンソールが立ち上がって、落ちます 込み入ったテンプレートを書いてるときによくなりました
__,,,,_ /´  ̄`ヽ, / 〃 _,ァ---‐一ヘヽ i /´ リ} | 〉. -‐ '''ー {! | | ‐ー くー | ヤヽリ ´゚ ,r "_,,>、 ゚'} < ぬるぽマンセー! ヽ_」 ト‐=‐ァ' ! ゝ i、 ` `二´' 丿 r|、` '' ー--‐f _/ | \ /|\ / ̄/ | /`又´\| |  ̄\
コウタイシサマトテヨウシャシナイゾ ( ・∀・) | | ガッ と ) | | Y /ノ 人 / ) < > _/し' //. V (_フ彡/´ ̄ ̄  ̄`ヽ, / 〃 _,ァ---‐一ヘヽ i /´ リ} | 〉. -‐ '''ー {! | | \ / | ヤヽリ ´゚ ,r "_,,>、 ゚'} ヽ_」 ト‐=‐ァ' ! ∩∩∩ ゝ i、 ` `二´' 丿 │ │ r|、` '' ー--‐f │ / _/ | \ /|\ │ │ / ̄/ | /`又´\| |  ̄\ / /
VC6.0ProからVC7のアップグレードっていくら?
704 :
デフォルトの名無しさん :03/03/07 21:54
お願いします。 vector<X*> v; v.push_back(new X); ってやると警告がでます。 何がいけないんでしょう? それともコンパイラが悪いの? BC5.5です。
>>704 BCC5.6.4ですが警告出ません。
確か5.6.2の時までは警告が出てたように記憶しています。
C++をやってみたいのですがエディタはどれがいいのでしょうか? やっぱWordですか?MSのオフィス系なら使った事があるのですが・・・ あと初心者にお勧めの本を教えてください。
なんていう警告?
>>706 メモ帳とプログラミング言語C++第3版
>>705 ありがとうございます。私はフリー版使ってますので。
>>707 すみません。今、別のマシンからなので、正確には再現できません。
xがどうしたとかいう不思議な警告です。
もちろん、xなんて変数は使っていません。
(
>>704 ではクラス名にXを使いましたが、実際は別の名前です。
それでも、xがなんたらとでるのです。)
結論は、BC5.5の問題ですね。
>>707 std::vectorのために一時変数を使用するとかいう警告が出てた。
push_backがconstでない参照型で受けていたからのような記憶が。
>>710 >>711 ありがとうございます。
たしかに、参照型がどうのだったと思います。
push_backの受け取る型がconst参照なんですよね。
しかし、それなら、問題ないはずですよね。
void func(const A& a){
なんちゃら
}
にたいして、
func(A());
みたいなことしてもよいはずなので。
違うでしょうか?
警告が出ても、間違いがないなら、別にかまわないのです。
>>712 逆、逆。const「でない」参照で受けていたように思う。
>>713 えーと。それだとコンパイラ通らないような。
言葉遣いの問題かな。push_backの宣言は、
void push_back(const T& x);
でわ?
>>714 だとすれば、それで警告でるならBCCのバグ。
gccやVC++では出ない。
>>715 ありがとうございます。
>だとすれば、それで警告でるならBCCのバグ。
そんな気がします。
void push_back(const X** x) てことだよね。最終的には const X* へのポインタを受け取るのだから、 X* tmp = new X v.push_back(&tmp); みたいな一時変数を用意しますよという旨の警告じゃないのかな。
>>717 どんなコンパイラもだいたいそうしてそう。
void push_back(const X** x) よりも void push_back(const X*& x)
のような気もするが。
それは良いとして、それを警告として出すか出さないかの違いだけだ
ろう。BCCは細かすぎたので5.6.4からこの警告を消してしまったのでは?
警告を出すか出さないかはバグとは言わなそう。 処理系依存という事でどう?
ISOで問題ないコードで警告を出すなら、バグと言えるかもしれない。 しかし、もうどうでもよいことではあるな。
俺は逆に BCC のうるさいのに慣れてしまっているから、逆に 何も言われないと不安になる
722 :
◆mx1DoE6qEk :03/03/07 23:16
エディットボックスが一個だけあるダイアログがあります。 このダイアログからデータを取るメソッドを作るとしたら、 std::string CMyDialog::GetDialogData() とするべきか、それとも void CMyDialog::GetDialogData(std::string& outString) とするべきかどっちでしょうか。 参照で受けても、どうせ文字列をコピーするんだったら、式の中に組み込める 上のタイプの方が便利な気がするんですが、今後もしかしたらダイアログに アイテムが増えるかもしれません。先のことを見越して下のタイプにする方が いいのでしょうかどうなんですか
両方用意したらどうでしょうか
>>720 それは結構あるでしょ。
無限ループで警告を出したり、if(a=func())こんな構文でも警告を出したりするし(ただし警告レベルを高く設定した場合)。
725 :
◆mx1DoE6qEk :03/03/07 23:33
726 :
◆mx1DoE6qEk :03/03/07 23:33
BOOL CMyDialog::GetDialogData(CDialogItem& item)
728 :
◆mx1DoE6qEk :03/03/07 23:41
cost std::string& CMyDialog::GetDialogData() でしょ普通は。
costって何だ… const std::string& CMyDialog::GetDialogData()
731 :
◆mx1DoE6qEk :03/03/08 00:29
>>729 メンバを返すわけじゃないので、参照は返せないんです。
というより、引き数で返すか返り値で返すかDOTCHが良いんでしょうか
>>731 返り値で返すってえと、関数内部のstaticな変数でも返すのか。
返り値で返そうとすると関数の成否が分かりにくいので俺は引数で返すが。
返り値で返す場合は否の場合0(NULL)を返せばOKでは?
735 :
◆mx1DoE6qEk :03/03/08 00:44
>>732 だから、たとえば
std::string CMyDialog::GetDialogData()
{
return ((CEditBox*)GetItemByID())->GetString();
}
みたいなのと
void CMydialog::GetDialogData(std::string& outString)
{
outString = ((CEditBox*)GetItemByID())->GetString();
}
みたいなのとドッチがいいのかって事です
あとアイテムが増えた場合、アクセッサ関数を増やすのか、GetDialogDataの引き数を増やすのかも
どっちがいいのかわかりません。
>>735 だから、
>>727 のようにダイアログデータを構造体かクラスにして単一のアクセサで
やり取りして、成否を BOOL で返せばええんちゃうかと。
>735 おれもそんなことで悩んだことがあるが、これに正解は無い、どっちもある意味いい マジで悩むぐらいだったら面倒でも2つ用意したら?
ちなみに俺は、 bool hoge(std::string& buffer); inline std::string hoge() { std::string buffer; hoge(buffer); return buffer; } 的なことをしたりするが。
740 :
◆mx1DoE6qEk :03/03/08 01:15
>>737 それも手だと思いますが、例えばGetじゃなくてSetの場合、このやり方だと
特定アイテムだけセットするのがメンドイとか、あとダイアログごとに構造体
作ってたらメンドクサイなーとか思ってしまいます
>>738 二つ用意ってのはなんだか嫌な感じです。EffectiveC++には、最小で十分な
インターフェースを持たせろとか書いてありますが、なんか重複してる時点で
嫌な気分になります。あとアイテムが増えたときの解決方法はどうしたらいいですか
どういう方向への拡張を想定するのかにもよると思うなあ それが決まってないならイイもワルイも無いっしょ
>>740 じゃあ引数から取るほうにしれ。
アイテムが増えたときのためにアイテムIDとstd::stringを引数にしる。
743 :
◆mx1DoE6qEk :03/03/08 01:31
>>741 ダイアログはちょっと例が悪かったかもしれないです。
ダイアログに限らず、アクセッサはどういう場合に値をreturnする事が許されるのか?
アクセスしたいデータごとにアクセッサメソッドを付けるのが正しいのか?
引き数をたくさん持ったメソッド一つを付けるのがいいのか、あるいは構造体でゴソッと
やるのがいいのか?
なんというか、アクセッサメソッドの設計自体に関する疑問といいますか・・・
>>742 増えたアイテムがstring系のアイテムじゃなかった場合はどうすればいいですか。
>>743 文字列と関係ないのであればそれ用のメソッドを用意しる。
745 :
◆mx1DoE6qEk :03/03/08 01:45
>>744 ごめんなさい、ダイアログを引き合いに出したのはマズかったです。
アイテムIDとかが使えない場合を考えてください。例えば
class CPerson
{
protected:
std::string name;
std::string address;
int age;
};
とあった場合、アクセッサは
std::string GetName();
std::string GetAddress();
int GetAge;
とするのか
void GetPersonData(std::string& name, std::string& address, int& age);
とした方がいいのか、どう思いますか
std::string GetName(); std::string GetAddress(); int GetAge; ふつうこっちだろ
>>745 void GetPersonData(std::string& name, std::string& address, int& age);
は明らかにおかしい。
せめて
void GetPersonData(const std::string& name, const std::string& address, int age);
だろ。
そもそもCPersonにデータを操作するメソッドを集約して外に出さない。
なんとなくいいたいことはわかる。 JavaのBeanだと、アクセッサは決められた命名規則に従って定義して、 操作はアクセッサメソッドを直截呼んでもいいが、より汎用的に 取り扱いたい場合はReflectionを用いることが出来る。 HashMapに保持しているkey=value形式のデータと相互変換したい場合など だな。 C++でどうするのが「美しい」かは知らないが、少なくともReflectionは 使えないので、利便性を重視するなら、多少直交性を欠く設計になっても やむを得ないと思われ。 利便性と直交性は対立することが多いし、mx1DoE6qEkはその両方を 求めている気がするが、それは無いものねだりだろう。
std::pair<std::pair<const std::string&, const std::string&>, int> GetPersonData()
>>751 boost::tuple<std::string, std::string, int> GetPersonData()
753 :
◆mx1DoE6qEk :03/03/08 02:09
なんかケースバイケースにやるしかないのかなあって気がしてきました。 std::string GetPersonName(); も式の中に組み込めるから便利だし、 void GetPersonData(struct PERSONDATA& outData); これもデータが一発で取れて便利 ドッチを使うかは一概には言えんと
プログラムなんて書くから悩むんだよ。
755 :
◆mx1DoE6qEk :03/03/08 02:16
結論:仕事を変えろ
756 :
デフォルトの名無しさん :03/03/08 02:17
こんなのは? class CPerson { public: struct PERSONDATA { std::string name; std::address; int age; }; private: PERSONDATA persondata; public: const PERSONDATA* GetPersonData() const { return &persondata; } };
>std::address なんだこれ(w std::string address;
>>757 いつでも使えるわけじゃないが、それはそれで面白いな・・・
760 :
デフォルトの名無しさん :03/03/08 02:41
VC++でSTL使う時、警告レベル4にするとやたらワーニングでるのは仕方がないの?
>>760 C4786だろ。デバッグモードで出る。
#pragma warning( disable : 4786 ) 入れとけ。
762 :
デフォルトの名無しさん :03/03/08 03:47
>>761 それはもう止めてます.
その他に
デバッグモードで4100 4511 4512 4663 4018 4511 4146 4245 4244 4071
リリースモードでは、800個以上出て調べる気も起きません.
いくら動くとはいえ、これじゃあんまりだと思いまして・・・
763 :
デフォルトの名無しさん :03/03/08 03:54
いましらべてみたらリリースモードで出ている警告のほとんどが 4710: ・・・・・はインライン関数ではありません 4702: 制御が渡らないコードです。 でした.
764 :
デフォルトの名無しさん :03/03/08 04:08
デバッグモードだと40個程度なのに・・・ ちなみに 4702: 制御が渡らないコードです。 はthrowを書いた行で7個ずつ出ています
VC++のSTLの警告の件。 ついさっき知った方法。 #pragma warning(push,3) VisualC++.NETのSTLはこれで警告を止めてある。
766 :
デフォルトの名無しさん :03/03/08 07:26
c/c++の質問なんですが 関数を作る時、 仮引数でその値を変更する必要が無い時は、 constをつけますよね。 こんなかんじで abc(const int a){ return a }; このconstをつけるとどんな得なことおきるんですか
>>766 関数 abc 内において、a の変更を禁止する。
a への代入はできず、a へのポインタを非 const のポインタ変数に代入することも
できない。
得なのかどうかは場合によるけど、a を変更してはいけないということを関数 abc()
のコーダーやメンテの中の人に伝える事ができる。
>>767 > コーダーやメンテの中の人に伝える事ができる
とりあえずこれはわかりやすい利点だよね。
>>768 &がついてないけど…
引数ってコピーだろ?
なにかの本で「まぎらわしいから
const付けるな」といっている人も
いたが…
いちおう区別がついているつもりの
私はconstをつけれるときはつけるが…
>>769 コピーだからこそ変更できないようにする
という意味もある
参照だと思っていた変数が実はコピーだったなんて状況を防ぐためにね
案外見つかりにくいもんだよ、こういうバグは
ほとんどの引数にconstをつけて回るのは無駄だろ。 その点constを廃止して変更可のout/refを導入したC#は合理的。
それを変更してはいけないというのは、それがコピーか参照かは全く関係無いと 思うんだけど。
コピーの変更をわざわざ禁止する理由は? いちいちローカル変数にコピーするなんてばかげてるよ。
void foo(const int *p); void foo(int* const p); の違いが判ってればいいんじゃないでしょーか
>>774 上・・・ポインタは変更不可、ポインタが指すアドレスの内容は変更可。
下・・・ポインタは変更可、ポインタが指すアドレスの内容は変更不可。
ということでいいのですか?
777 :
デフォルトの名無しさん :03/03/08 11:32
日本語で考えると良いよ コンストイントを指すポインタ イントを指すコンストポインタ
なるほど。 関数定義に律儀にconstつけて回ってたらほとんどconstになってしまいますよね? 値を返す引数は参照渡しにする、constは即値のみに使うというのは邪道ですか?
>>778 > 関数定義に律儀にconstつけて回ってたらほとんどconstになってしまいますよね?
?????????
値を返す引数、という表現はおかしいか。 なんと表現したらいいんだろう? ・・・というもやもやをはっきりさせるためにconstがあったりして。
>>abc(const int a){ return a }; これ、俺がconst覚えた時によくやった 参照やポインタでも無いのにconstつけたりして 関数を使う側から見ると、このconstにはまるで意味が無いから しないほうがいいと思う。混乱の元
constをつけることで参照渡しだと早とちりするヴァカもいる
個人的には"値を返す引数"には参照渡しよりポインタ渡しを使いたい。
784 :
デフォルトの名無しさん :03/03/08 11:54
const foo & hoge ( const foo &bar ) const { return bar; }
関数内で引数の値を変更したくないならconstつけてもいいと思うが。
なんかこのpart16スレは、いつもより宗教論争的なことが 起こりやすいね。
>個人的には"値を返す引数"には参照渡しよりポインタ渡しを使いたい。 内の会社でもC上がり先輩にそういわれた でも、参照で渡されたやつはほぼNULLじゃ無いので NULLチェックが要らないという利点があるんだよなー まあ、先輩に従ってますが
788 :
デフォルトの名無しさん :03/03/08 12:00
最近では使うようにしてる int main(const int argc, const char* const* const argv)
int &n = (int&)0; if(n) n = 0; これをサポートすればC++から90%のポインタを削減できるだろうな。
Cとか関係なくて、受け取るのか、渡すだけなのかという意図が 明確になるから。こういうのはNULLチェックしない。受け取る 関数にNULL渡す方が悪い(w
791 :
デフォルトの名無しさん :03/03/08 12:09
>>765 やっぱりそれしかないんですか・・・・
しかたがないからデバックモードで自分の書いたヘッダ、ソースで出ている警告を取り終わったら
#pragma warning(push,3)
するようにします.
>>790 せめてassertくらいはいれといてよ。
C/C++でassert使ってる人って意外と少なくない?
俺の周りでは一人しかいなかったよ。
>>792 そんなこと言ったら
俺の近くにはSTLを使ってる人すら少ない
794 :
デフォルトの名無しさん :03/03/08 12:29
>>793 今いるところは try ... catch 禁止だ。(w
うちはfor禁止。ループはwhileでかけだとさ。
templateはCあがりには一番とっつきにくいのです・・・ try-catch禁止なら例外スルーするライブラリなど使うなってことか。 for禁止に至ってはまったくもって意図不明。
例外スルーに該当するページが見つかりませんでした。 全言語のページから例外スローを検索しました。約44件中1 - 10件目
例外を全くcatchしないんじゃないか?
プロは大変だなぁ。 趣味だと好き勝手できるから、もうすっかり テンプレート無しには生きられない体だよ。
>>796 STLはtemplateの知識を基本的に必要としないし。
STL拡張するなら別だけど。
実務で直接template使ったことはまだないな。
template は STL でしかお世話になってないな。今のところ。
このかぶりかたは恐い。
Cだとテンプレートがないからvoid *使ったり関数を分けたり・・・・結構不細工だな。
複雑なマクロを定義してみて結局罠にハマったりな。
>>783 > 個人的には"値を返す引数"には参照渡しよりポインタ渡しを使いたい。
渡す側もポインタであることを明示するし、
受けた側もポインタ経由での代入操作になるから、
(参照ならconstが付くはず)
値を操作するという意図が明確に伝わるんだよね。
ついこないだもこういう指導をしてさしあげたが、イマイチ理解して
もらえなかったようだ。俺はC/C++どっちも使うんだが、片方しか使わ
ない人と話すと苦労するよ・・・
>801 おれも前までそうだった・・・ 就職してあまりに理不尽なこと言われて頭がクラクラした それはおまえの勉強不足の認識違いだろと、何度も思った
ポインタと参照の機能を明確に区別しなかったストラップがすべての元凶。
boostにATL/WTLも使ってやれよ
>>795 そのwhile、ひょっとしてwhile (true)じゃなくて、while (TRUE)か?
813 :
デフォルトの名無しさん :03/03/08 13:54
BOOL B = TRUE; bool b = B; ってあり?
C++3rdにはこう書いてあるよ。 >整数は暗黙のうちに bool値に変換できる。0以外の整数は true、 >0は falseに変換される。
815 :
デフォルトの名無しさん :03/03/08 14:03
makeで main.exe : pro1.obj pro2.obj; link pro1.obj pro2.obj pro1obj : pro1.cpp pro1.h; cl pro1pp pro2obj : pro2.cpp pro2.h; cl pro2.cpp としたときpro2.objができないのですがどこがいけないのでしょう?
つか、C++の参照は、演算子オーバライドしたときに 変にならないように導入されただけのものだからなぁ。
最後のセミコロンは要らない気がするけど。 clなら/cつけないといろいろうるさいし。
819 :
デフォルトの名無しさん :03/03/08 14:44
catch(...) で、受け取った例外が何かを調べる方法はありますか?
ない
>>817 −cオプションってHELP見てもよく分からないんだけど。
どうすればいいの?
g++とオプションが同じなら・・・ cl -c -o main.obj main.cpp これでmain.cppがコンパイルされてmain.objができるんじゃない?
823 :
デフォルトの名無しさん :03/03/08 15:56
メンバ関数を指すポインタの配列を作りたいのですが、 エラーになります。 何かこれに変わるような方法はないでしょうか。 j = fcn[i](); のように使いたいのです。
>>823 Borland C++の__closureが便利だが標準C++にはない。
>>823 struct A {
virtual void func1() { std::cout << "A::func1()" << std::endl; }
virtual void func2() { std::cout << "A::func2()" << std::endl; }
};
struct B : public A {
void func1() { std::cout << "B::func1()" << std::endl; }
void func2() { std::cout << "B::func2()" << std::endl; }
void func3() { std::cout << "B::func3()" << std::endl; }
void (*func4[3])();
};
void (A::*func[])() = {
&A::func1,
&A::func2,
};
void (B::*func2[])() = {
&B::func1,
&B::func2,
&B::func3,
};
void (B::*func4[])() = {
&B::func1,
&B::func2,
&B::func3,
};
int main() { A *a = new B; B *b = new B; (a->*func[0])(); (a->*func[1])(); (b->*func2[0])(); (b->*func2[1])(); (b->*func2[2])(); int i = 2; (b->*func2[i])(); (b->*func4[1])(); std::cout << sizeof(func[0]) << std::endl; std::cout << sizeof(func2[0]) << std::endl; delete b; delete a; }
>>821 >>822 さんがほとんど答えてくれたけど、-cオプションというのは、
コンパイラに *.obj または *.o を生成した時点でストップせよと
いう指令。
ポインターについて聞きたいんですけど、 #include<iostream.h> void sub(char *[]); int main() { char *G[] ={"あけぼの","わかのはな"}; sub(&*G); cout<<G[0]<<endl; return 0; } void sub(char *g[]) { g[0] = "たかのはな"; return; } 一応「たかのはな」が表示されるのですが、 sub関数内ではgはポインターに見えないです。タブーなんでしょうか? ダメな場合、どうするのがベターなんでしょうか? よろしくおねがいいたします。
829 :
デフォルトの名無しさん :03/03/08 16:26
なんでsub(G);にしないんだろう。
>829 ・・(汗 そうですね。 ポインターがうまくいかないので、 *やら&やらいろいろつけてたらこうなりました。 他は問題はないのでしょうか?
>>830 > sub関数内ではgはポインターに見えないです。
どうしてそういう結論に至ったの?
ポインタになっているはずだけど。
猫にでもわかる〜で tp://www.kumei.ne.jp/c_lang/cpp/cpp_06.htm エイリアスとポインターの部分があったんですが、 *がついてないのは「かんちがいするからダメ」 みたいに読めたので、 てっきりこれじゃダメなのかと思ったんです。
833 :
デフォルトの名無しさん :03/03/08 16:45
>>825-826 即レス有難うございます。まだわからないところがあるので質問させてください。
そのコードにある、
void (A::*func[])()
というのは、Aのメンバ関数へのポインタの配列、という宣言でしょうか。 だとすると、
(a->*func[0])();
を
(a->(*func[0]))();
とするとエラーになるのはなぜですか? また、
void (A::*func[])();
void (B::*func2[])();
void (B::*func4[])();
これらはグローバル変数なのでしょうか。
>>833 ->* で一つの演算子だから、 -> と * に分けるとエラーになる。
また、
void (A::*func[])();
void (B::*func2[])();
はグローバル変数だが、もしメンバ関数が private とか protected で
宣言されてたら
void (B::*func4[])();
のようにメンバでポインタを持つしかない。
>>832 それってプログラマがきちんと関数の引数の型を把握しておかないと、値渡しなのか参照渡しなのか区別がつかないってことじゃないの?
void func1(int a,int b)という関数とvoid func2(int &a,int &b)という関数があり、呼び出し側にint x,yという変数があるとする。
それらを引数にfunc1,func2を呼び出した場合はどちらも引数リストが(x,y)になるでしょ。
>>833 もう少し具体的に書くと、メンバ関数へのポインタというのは、純粋な
意味での関数へのポインタとは違う。
static なメンバ関数へのポインタ以外は、必ず this がないと
呼び出せない特殊なオフセットのようなものだと考えてくれ。
static なメンバ関数なら this 無しで呼び出せる。これはシングルトン
デザインを実現するのによく使われる。
ポインタを使う場合はfunc2がvoid func2(int *a,int *b)という形になって、 呼び出すときの引数リストは(&x,&y)になるから区別がつくってこと。
>>832 たぶんおっしゃる通りなんだと思います。
参照というのがまだ良く分かってないので、
半分ぐらいしか理解できてませんが(汗
ちゃんと理解できるように、続きやってみます。
答えていただいてありがとうございました。
>>834 > ->* で一つの演算子だから、 -> と * に分けるとエラーになる。
よくわかりました。有難うございました。
ですが、Bを class として宣言すると
void (B::*func4[])();
が、Bの private メンバにアクセスできないと言われるのですが。
>>839 スマソ。俺が勘違いしてたようだ。
void (B::*func4[])();
もグローバル変数変数だ。
今試してるからしばらく待ってくだされ。
>>839 俺は今まで勘違いしてたようだ。どうもクラス内部にメンバ関数への
ポインタを持つことはできないらしい。
>>840-841 今調べて来ました。
public: static void (B::*func4[3])(); /* 宣言 */
void (B::*B::func4[])().... /* 定義 */
(b->*B::func4[1])(); /* 実行 */
とすればよいようです。
丁寧にお答えいただき、どうもありがとうございました。
>>842 そうか、staticなメンバならメンバ関数へのポインタを保持する
事ができるのか。初めて知った。
勉強になりました。
844 :
デフォルトの名無しさん :03/03/08 18:24
結構初心者が多いんだな
クラスのstaticメソッドはCのコールバック関数として登録することもできるよ。
クラスのstaticメソッドはメンバ変数、メソッドにアクセスできないよ。
>>846 そこら辺はやり方しだい。Cのラッパークラスでは二通りの方法がある。
class Wrapper
{
static Wrapper *This;
static Callback(void *p)
{
This->bar = This->foo();
とか
Wrapper *self = (Wrapper*)p;
}
}
848 :
デフォルトの名無しさん :03/03/08 20:56
error C2679: 二項演算子 '=' : 型 'unsigned char' の右オペランドを扱う演算子は定義されていません とエラーが出るのは何ででしょうか?
その行クリックしてF1押すか前後のソースを晒せ
>>849 for(j=0; j<=base1->y; j++){
for(i=0; i<=base1->x; i++){
k1 = j*base1->x + i;
h[k1] = base1->sh[k1];
}
}
・・・・?!なんだこりゃーーーー!!!!バタッ
class Giko {}; class FusaGiko : public Giko {}; Giko g; FusaGiko fg; で、fg = g; みたいなのをやりたい場合の 一般的なやりかたをおながいします。
ところどころに全角文字が入ってるのは関係あるの?
>>850 これだけでは、base1、h、i、j、k1 の正体さらしてくれないとわからん。
どの行がエラーになったんだよ。
つーか変数名に全角使うな。
849 の前者の方を実行してみたか?
>>854 エラー行はh[k1] = base1->sh[k1];
変数定義はint i,j,k1; base1は構造体baseの変数。
struct base
{
int x, y;
unsigned char *sh;
};
class c
{
protected:
unsigned char *h;
}
helpを見たら次が出てきたけど、どうすればいいのやら。
class C
{
public:
C(); // int を引数にとるコンストラクタはありません
} c;
class D
{
public:
D( int );
D();
} d;
void main()
{
c = 10; // エラー
d = 10; // OK
}
日下部mainキタ━━━━━━(゚∀゚)━━━━━━ !!!!!
> c = 10; // エラー > d = 10; // OK 当たり前じゃん。何を訴えたいの?
858 :
デフォルトの名無しさん :03/03/08 21:45
polynomial("2x^5-2x^3-7"): ()の中はstring型でこれを動的配列を用いて係数だけを下のように 確保するにはどうすればいいんでしょうか? -2 0 -2 0 0 -7 :-x^5の係数は2, x^4の係数は0, x^3の係数は-2, x^2の係数は0, xの係数は-7
あと、派生クラスの中で、基底クラスの部分を分けて扱うことはできるんでしょうか?
>>852 だと、FusaGiko の中で Giko の部分だけをファイルに保存するとか。
fwrite( &Giko , 1 , sizeof(Giko) , fp );
みたいな感じで。
>>855 結論を言おう。
850 が class c のメンバ関数の一部なら、850 のコードできコンパイルエラーは出ない。
inline関数について質問です。 inline関数は、通常の関数と違って呼び出される位置より前に関数の 定義がないといけないということがPrimerに書いてあったのですが、 べつにプロトタイプ宣言がされていれば、コンパイルエラーはでません。 なぜでしょうか?これってちゃんとinline展開されてる のでしょうか?
>>861 プロトタイプ宣言に inline と書いてあったとしても、定義部分が実際に
呼び出す部分より後にあったらまず100%インライン展開はされない。
例えば、int配列 id[15]とかそういうのがあって int j=2; int point = id [ j & 1]; とかいう記述が出てきたのですが、このj & 1というのは何を表すのですか? 論理式とかのたぐいですか?
>>863 コンパイラによるんじゃない?
VC7はリンク時にinline展開することもできるし。
プロトタイプ宣言に inline と書いてあったとしても、定義部分が実際に 呼び出す部分より後にあったらまず100%インライン展開はされないという 動作をコンパイラがしたら、それは単にソースの先読みとかコンパイル順の やりくりができないショボイ実装だからだと思われ。
>>864 j が奇数だったら id[1] 、偶数だったら id[0] をアクセスするだけだろ。
となるとですね、自分はVC++.NETを使っていますが、 コンパイルがOKだということは、ちゃんと展開されていると 解釈していいのですか? 展開されない処理系ならエラーや警告を出してくれれば問題無いの ですが・・・。
Standardだと問答無用で展開してくれない。
その展開するしないはどうやって判断できるんですか? コンパイラから知らされるのですか?
コンパイル後のアセンブラのリストを出力させて確認する。
>>867 そうなんですか。ありがとうございます。
VC++.NETで/Oxオプションでコンパイルしてみたら、inlineの プロトタイプ宣言をして、関数本体を呼び出した後で定義したら、 ちゃんとインライン展開されていた。
まあ、VCは-Ob2, __forceinlineなんてのがあるから、 このくらいでは根を上げないだろう。
VB だとどうですか?
>>791 すっかり流れちゃったけど。
んなことしなくたって
#pragma warning(pop)
で自分のソース部分だけ警告レベル4にできるでしょ。
移植性を考えると、やはりinline関数は先に定義しとけば 間違いないという考えでやったほうがいいのかなぁ・・・。
inlineにこだわりすぎるのもどうかと・・・
別にinlineじゃなくても動作変わんないしね
むしろinline展開させないキーワードが欲しい。
短くて頻繁に呼び出すメンバ関数なんか、inlineに しとかないとオーバーヘッドもバカにならんでしょ。 inlineにこだわるべきかは、作るモノによるんだろうけどね。 だからこだわる時はこだわらなきゃいけないんだから、 そういうのは、はっきりさせておいたほうがいいと思うけど。
最適化オプションなどによるパフォーマンスチューニングは後回し、
というのは半ば常識かと思ってたが、いまだに
>>884 みたいなのが
いるんだねえ。
短いのはヘッダに書いてインライン 長いのはソースに書いてアウトライン
>>885 意味不明。後回しっていずれやんじゃねぇか。
コンパイラによる差もあるのに。
やる事無くなったら他人の仕事まで押しつけられるよりは コンパイラオプションを弄って仕事してるフリをすべきだと思う。
そりゃ、特定のコンパイラを前提にした話か
釣りっぽいが、マジレスすると
>>885 が前半で言ってることはまさに
その通りだが、inline ぐらいは始めから意識しとけ。
そだね もしSTLがinline化されなかったら誰も使わんし
894 :
デフォルトの名無しさん :03/03/10 16:07
C/C++の真偽の評価について質問なのですが ( i == 0 || data[i-1] == hoge ) で i == 0 の部分で真が確定した場合は data[i-1]は評価されないことが保障されているのでしょうか?
されてます
保障はされないけど保証はされている。
即レスありがとうございます!誤変換の訂正も…
>>894 蛇足だが、|| 演算子をオーバーロードしたら短絡評価は再現できない
ので両方とも評価してしまう。だからEffective C++には || 、 &&、, は
オーバーロードしないようにしようと書いてある。
しもた、More Effective C++ ね。
ほほう。そうなのか・・・ まー俺は演算子なんて=とかしかオーバーロードしないですが、 こーゆー細かい情報知らないとハマるんだよなぁ。
はじめまして C++ではJAVAのようにパッケージングすることができないので 関連あるクラス同士を整理しやすいようにするには頭文字を そろえるなどとするしかないのかなと思っています。 実際にはパッケージングのかわりにdll化をするのが正しいのでしょうか?
>>902 そうなんですか
namespaceについてはあまりよくわからないので調べてみます。
どうもありがとうございました。
おまえら知ってましたか! string str()//こんな関数があったとして const string &s=str();//これが正しいことを!! 最近知りました
なぜ正しく動くのか説明できるか?
>>904 だうと!って言いそうになっちまうんだけど、正しいんだよなぁ。
便利な機能ではあるんだけど、どうにも紛らわしい。
あったなそういうの。3rd のどこかに書いてあった。
これが正しいおかげでconstの参照で返すことに戸惑いがなくなりました const string &str(); この関数を string str(); にこっそり置き換えても安全なんですよね? メンバ変数で持っていたけど 将来的にはそうじゃなくなる場合よくあるので
>>904 それをさらに他のconstに代入して使うこともできる。
const std::string& s = func();
const std::string& t = s;
こういう芸当ができるのはconstのリファレンスだけだ。
s が生きてるうちは参照先が死なないことが保証されているんだっけ。
>>911 このパーシスタンスに関する規則はやっぱり特殊だと思うが。
他に似たようなパーシスタンスに関する規則ってあったか?
あった、3rd の「5.5 リファレンス」(邦訳本では135ぺージ)。
おれはこのやり方に対して一時変数の参照だからだめだよ、これ とかなんとか知ったかぶっちゃって大恥じかきました
>>915 この規則があまりに特殊であるが為に人から説明を受けても
すぐには信じることができなくて、大恥をかく羽目になりやすいんだろうな。(w
>>916 そのとおり 関数内のローカル変数を参照で返したらだめなのと理由一緒だろ?と言ってしまった これにこりて、もう二度と知ったかぶらないようにしようと自戒
安全とは言えどこか気持ちが悪いな。
919 :
デフォルトの名無しさん :03/03/10 23:42
Visual C++ 6.0 と.NETと使い勝手ってどのくらい違いますか? 6.0使っていれば、.NETもすぐ慣れますか?
春になって随分と厨房臭いスレになったな
>>904 関数から返される(本来なら無名のはずの)一時変数に名前を付けるから、
と考えると、分かりやすいかも。
でも、おそらくコンパイルされたコードは、
const string s = str();
と同じになりそうな気がする。
>>904 例外を参照でうけるようなものだろうか…?
C++用のリファクタリングツールとか メトリクス測定ツールとかってどんなのがありますか。 できればフリーのもので。 Java用なら腐るほど見つかるんだけどなあ…
const リファレンスはオブジェクトの寿命を延すために使うものではない。 const リファレンスでオブジェクトの延命をしようなんて馬鹿げてる。
なにこのひと
928 :
デフォルトの名無しさん :03/03/11 22:36
このeの参照先のインスタンスを直下のブロックの外に持ち出すことはできませんか? catch(MyException &e) { } // ここでeのインスタンスを参照したい。
>>928 悪いことはいわないから、自分が何をしようとしているのか良く考えなさい。
C#のException.InnerExceptionを実装したいだけなんですが。
>>926 IS 12.2 の 5項に一時オブジェクトの寿命について記述されているように
関数のリファレンス引数にバインドされた一時オブジェクトは、関数呼びだしを含む
式が完了(complete)するまで存続することになっている。
それ以上に長生きさせることはできないのだよ。
A temporary bound to a reference parameter in a function call (5.2.2) persists
until the completion of the full expression containing the call.
>>931 同じIS12.2の5項には、こうも書いてある。
コンストラクタの初期化子でリファレンスメンバ(変数)にバインドされた一時オブジェクトは
そのコンストラクタが終了するまで存続する。
A temporay bound to a reference member in a constructor's ctor-initializer(12.6.2)
persists until the constructor exits.
>>927 cppll方面におばかなことを考えているやつがいるらしい。
C++ は影でコソコソこういうことやってたりするからね。でも こんなトリッキーなコード書かずに済むようにしてほしい。
>>928 参照じゃなくてコピーを取るんでは駄目なの?
>>935 どうやって?
例外クラスすべてにコピー用のメソッド書いて回るの?
コピーできる例外ならコピーして保存しておけばいいんではない? C#のException.InnerException てのがどんなのなのか分からない ので勘違いならスマソ。
>>937 こんな感じでeをe2の補助的な情報として取っておきたいんだよね。
なので最上位クラスExceptionへのコピーでは情報が欠落してしまう。
try{
try{
...
}catch(MyLibException &e){
throw MyAppException("アプリの例外として再throw。eも取っておく", e);
}
}catch(MyAppException &e2){
cout << "例外の直接の原因は" << e.InnerException().ClassName() << "である" << endl;
}
実行結果
例外の直接の原因はMyLibExceptionである
そもそも e の参照先のインスタンスというのも、元の (throw したインスタンス) のコピーかもしれんし。
>>931-932 おー、サンクス。12 Special member functions のとこかよ。
やっぱり、そういう仕様ってことなのね。
んー、やっぱ人伝いに聞いた仕様は気をつけんとな。
941 :
デフォルトの名無しさん :03/03/13 00:41
前スレ追い越しage
942 :
デフォルトの名無しさん :03/03/13 01:28
const std::string& CNumber::GetValueAsString() { char buff[256]; mprintf(buff, "%d"m_intValue); return std::string(buff); } こういうのってやっても大丈夫なんですか。
大丈夫
944 :
デフォルトの名無しさん :03/03/13 01:36
何で何で意味不明理解不能!じゃあこの返り値の寿命は?ってそうか、一時オブジェクトか。 コピー返しするよりも効率が良いと。 じゃあこれは? const std::string& CNumber::GetValueAsString() { std::string ret; char buff[256]; mprintf(buff, "%d"m_intValue); ret = buff; return ret; } あと、constにしないとダメなん
駄目
946 :
デフォルトの名無しさん :03/03/13 02:06
>>945 駄目ってどっちが?
ローカルオブジェクトを返すのが駄目か、constでないと駄目なのか
>>942 >>944 両方駄目
定数参照されることで一時変数が生成された式を越えて有効性を保証されるだけで
ローカル変数がスコープを越えて生存できるわけではない
948 :
デフォルトの名無しさん :03/03/13 02:12
じゃあ参照をreturnしようと思ったら、メンバ変数とかグローバル変数みたに、
GetValueAsStringよりも寿命が長いやつを返すか、>942みたいにその場で
作ってreturnするしか無いって事?
アクセッサとして値を返すのに使うんだったら、
>>942 みたいな事が出来ない
ケースもあるわけ?
例えばstd::strinにstring(const char*)みたいなコンストラクタが無い時とか。
950 :
デフォルトの名無しさん :03/03/13 02:21
じゃ参照で返せるのはGetValueAsStringよりも寿命が長いやつのみって事ね。 アクセッサとかでこれやると、後で中の仕様が変わったときにインターフェースまで 変わっちゃうからイヤだ
const std::string& CNumber::GetValueAsString(std::string &ret = std::string()) { char buff[256]; sprintf(buff, "%d", m_intValue); ret = buff; return ret; }
駄目
偶蹄目 奇蹄目 馬犬目
>>952 お前まさか、デフォルト引数のオブジェクトが
呼び出される側のスコープに含まれるとでも
思ってんのか?
あ、ごめん。BCC じゃないとだめぽ。 g++ だとエラーになんね。 VC でも動くかどうか知らんけど、g++ なら const std::string& CNumber::GetValueAsString(std::string &ret = demi<std::string>()) とかって、やればOKだべ。 demi に関しては cppll を漁ってくれ。
>>959 覚えたてor見慣れない機能を好んで使う悪い例だな。
あれだ、えーと、Write only codeってやつだろ。
人に見せるコードなら、こんなんになるかの。
std::string CNumber::GetValueAsString();
void CNumber::GetValueInto(std::string& storage);
>>960 ┌─┐
|も.|
|う |
│来│
│ね│
│え .|
│よ .|
ヌルポ . ゴルァ │ !!.│
└─┤ プンプン
ヽ(`Д´)ノ ヽ(`Д´)ノ (`Д´)ノ ( `Д)
| ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U
〜 〜  ̄◎ ̄ . ̄◎ ̄  ̄◎ ̄ ◎−>┘◎
ショウガナイヤツダナ
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>961
じゃあreturnで値を返したい場合はコピーを返すのがいいのね。
964 :
デフォルトの名無しさん :03/03/13 13:21
今まで局所的にdynamic_castを使っていたのですが、 それすらネックになってしまい、やむを得ずstaticなダウンキャストに切り替えた所、 実行速度が全体で20倍近く速まりました。 …は、いいのですが、これいうダウンキャストは合法なんでしょうか? 型チェックは一応問題ないと思います。
>>964 内部で閉じた処理に使うならダウンキャストもOKと思われ
理より速度を選んだってことだよ
行儀良くないけどなー
やむをえないって、コメントは入れとこう
>>965 ありがとうございます。おかげで、びくびくしてたとこへオーソライズされた気分です。
禿本貸し出し中で、処理系依存かなぁとか、その辺も心配だったので…。
目立つコメントいれておきます。レス感謝です。
void* に dynamic_cast した場合は、もう dynamic_cast で元に戻すことはできないの?
void*にdynamic_castって意味有るの? 普通void*にキャストする場合static_castじゃないの?
void* にならキャストは要らないんでわ。
void*には単なる代入でOK。 void*から元のクラスに戻すにはreinterpret_castが必要。
スマソstatic_castでいいです。
Σ(д`≡;´Д) part17 はどこ?
reinterpret_cast も static_cast も 不正な型変換があっても bad_cast例外をなげてくれませんよね。 やっぱ共通ベースクラスをつくって dynamic_cast かなぁ。
>>974 ポインタをdynamic_castしても例外を投げてくれませんよね。
リファレンスの場合だけです。
976 :
デフォルトの名無しさん :03/03/13 21:26
#include <iostream> using namespace std; int main() { cout << "abc"; return 0; } error LINK 2019 未解決の外部シンボル fatal error LINK 1120 外部参照が未解決です。 と出て本文にはフォーカスがかからないのですが、どういうエラーなのでしょうか?
コンパイラオプションが間違ってる
int i = 30; ostringstream s; s << i; s.str(); これもっと短くかけませんか。
>>978 int i=30;ostringstream s;s<<i;s.str();
ostringstream s; s << int(30); s.str();
boost::lexical_cast<std::string>(30);
983 :
デフォルトの名無しさん :03/03/13 22:09
使いきりage
1000!!
埋め
986 :
デフォルトの名無しさん :03/03/14 06:23
このスレッドは1000を超えますた。 またのお越しをお待ちしておりまつ。
1001!!
5670000000!!!
まったり1000!!
千!
千尋!
一回だけ手伝うよ。
throw NullPointerException;
throw new NullPointerException;
ぬるぽ言うならいまのうち
| ̄ ̄ ̄|___ | ヌノ| |______| ∧∧ || ( ゚д゚)|| / づΦ
________ |___ | |レポ | |_____| || ∧∧ ||(゚д゚,,) Φ⊂ ヽ
________ | ̄ ̄ ̄|___ | | ヌノ|レポ | |______|_____| ∧∧ || || ∧∧ ( ゚д゚)|| ||(゚д゚,,) / づΦ Φ⊂ ヽ
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。