1 :
v(^・^)v :
03/03/13 21:54 C++に関する質問はこちらへどうぞ。
ただし質問の前にFAQに一通り目を通してください。
また、テンプレートライブラリ(STL含む)に関する質問は
専用の別スレへどうぞ。
過去スレ、関連スレ、関連リンクなどはこちら
>>2-15
2 :
v(^・^)v :03/03/13 21:54
3 :
v(^・^)v :03/03/13 21:55
4 :
v(^・^)v :03/03/13 21:55
6 :
v(^・^)v :03/03/13 21:55
7 :
v(^・^)v :03/03/13 21:56
8 :
v(^・^)v :03/03/13 21:56
9 :
デフォルトの名無しさん :03/03/13 21:58
Java!
10 :
デフォルトの名無しさん :03/03/13 21:58
11 :
デフォルトの名無しさん :03/03/13 21:59
ぉっ
13 :
v(^・^)v :03/03/13 21:59
終わりです
乙彼
STLつかうと一気に実行ファイルサイズが10倍に?!
持つ彼〜
STLを使い出すと今までと同じ労力で10倍の規模のプログラムを作れてしまう、 という意味なんだろ?
>>16 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
21 :
デフォルトの名無しさん :03/03/13 23:07
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの?
>>21 #include <stdafx.h>
後死ね。
>>20 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
>>22 言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
25 :
デフォルトの名無しさん :03/03/13 23:16
>>20 それ前スレの俺の書き込みのコピペ(w。
もうBorland-C++は5.6.4になってるよ(w
デジャブ。ワロタ
>>29 そうか。
じゃあ、次のスレを立てる人にはもっときっちりやって貰わないといかんな。
class foo { int _id; public: foo(int id) : _id(id) { } foo(foo& f) : _id(f._id) { } foo& operator=(foo& f) { _id = f._id; return *this;} virtual ~foo() {} }; int main(int,char**){ foo bar(0); bar = foo(1); return 0; } 以上のコードを gcc 3.2でコンパイルしたら no match for `foo& = foo' operator candidates are: foo& foo::operator=(foo&) っていわれるんだけど、俺間違ってないよね?
>>32 まちがってる
foo(const foo& f) : _id(f._id) { }
foo& operator=(const foo& f) { _id = f._id; return *this;}
コピーコンストラクタや代入演算子はconstの参照だ
一時オブジェクトは非const参照できない
BCC とかなら gcc ほどそのへんの制限きつくないから通るだろうけどね。
>>33 より厳密に言うなら一時オブジェクトというより
右辺値の非 const 参照できないってこと。
35 :
デフォルトの名無しさん :03/03/14 23:26
class Unko[ int x,y,z,a,b,c; }; void *p: p=new Unko(); delete p; これはメモリリークしますか?
>>35 メモリリーク以前に、コンパイルが通りません。
37 :
デフォルトの名無しさん :03/03/15 01:13
void *p:をdeleteした場合って、デストラクタ呼ばれたっけ?
呼ばれにゃい。
んなもん15秒あれば試せるだろ・・・
15秒でエディタ起動・ファイルの作成・コンパイル・起動までできるの?
>>37 pがどんな型情報を持っているのかと小一時間。
>>40 俺のPCにはVisual Studioと検証用の使い捨てプロジェクトが常に立ち上がっているわけだが。
>>35 ウンコが処理されないようなコード書くなよ。
>>35 実は渡されたモノはうんこだという事実を知る由も無く
処理を要求されるoperator deleteが不憫だ。
45 :
デフォルトの名無しさん :03/03/15 11:12
こんにちわ。質問があります。 1つの関数で2つ以上のオブジェクトをnewして返したいんですが、 void func( ObjectA* a, ObjectB* b ) { a = new ObjectA; b = new ObjectB; } とやってもできないんです。引数じゃなくて、返値でやればできるんですが、 そうすると1つしかnewできません。 何がいけないのか教えてください。
端的に言えばポインタ引数はあくまで値渡しだから。
>>45 void func( ObjectA* &a, ObjectB* &b )
{
a = new ObjectA;
b = new ObjectB;
}
>>45 void func(ObjectA*& a, ObjectB*& b )
{
a = new ObjectA;
b = new ObjectB;
}
ケコーン
まぁ、std::pair<>とか構造体とか使えば何個でも返り値でいけるわけだが。
>>52 複雑なパラメータの受け渡しにはclassやstructを使うのが定石だろ。
pairは見たことない。
tupleだな
pair は class とは別のものであるらしい
パラメータの受け渡しにパラメータブロック構造体を使うのは可か不可か。考えて見よう。
可・不可ってあたりが学生臭いなあ それぞれの長所、短所、どっちにしろ同じこと、ぐらいにしようよ
学生ってのは誉め言葉でうか
宿題なら自分でやれって意味だと思うし
60 :
デフォルトの名無しさん :03/03/16 17:23
C++でテキストファイルを読み込む場合、ifstreamが使えますが、 Cのfreadでまとめて読み込む方がずっと速いと聞いたことがあります。 実際、単純に考えるとそうなりそうですが、ifstreamを使って、 ファイルの読み込みを高速化する方法はないのでしょうか。 前に2チャンネルのどこかのスレで見た気もするのですが、 今どこにあるかわからなくなってしまいました。 お願いします。
>実際、単純に考えるとそうなりそうですが、 まずは実際にどのくらい遅くなるのか計ってから書きこもうな
>>60 よくわからんが、ifstreamのバッファを大きくするとか?
>>60 >Cのfreadでまとめて読み込む方がずっと速いと聞いたことがあります。
取り合えず本当に早くなるのか結果を見せて下さい。
64 :
デフォルトの名無しさん :03/03/16 19:29
60じゃないが ifstream - 1052[ms] cstdio - 991[ms] std::ifstream fs; for(int i= 0; i< 1000; i++) { fs.open("test.txt", std::ios::in); fs.read(ch1, 290); fs.close(); } FILE* f; for(int j= 0; j< 1000; j++) { f = fopen("test.txt","r"); fread(ch2, sizeof(char), 290, f); fclose(f); }
ioのコストが高いから あまり変わらないのかもね
おれはC++でも_open _read _write _closeしかつかわない つーかそれが普通だとおもってたんだが違うのかな?
おれはC++だとfstreamしか使わない おれはそれが普通だと思ってた
おれはC++ではCreateFileしか使わない おれは普通だと想ってる
ひとそれぞれだね!!
おれはC++でもぬるぽを使っている おれは普通だと思ってる
ユダンモスキモ・・・
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>70
72 :
デフォルトの名無しさん :03/03/16 22:27
だまってこれ使え class FilePtr { public: explicit FilePtr(const char* text,const char *wr){ pfile = std::fopen(text,wr) ; if(!pfile) throw int( 0 ); } ~ FilePtr() { if(pfile) std::fclose(pfile); } operator std::FILE* () { return pfile ; } private: std::FILE* pfile; }; int main(){ try{ FilePtr fptr("test.txt","r"); } catch(int){ std::puts( "Non File" ); } return 0; }
>>72 だまってこういうコード書いてもいいですか。
int main() {
FilePtr fptr("test.txt","r");
FilePtr fptr2 = fptr;
}
便乗質問ですけど、
>>64 Cのfreadだと何バイト読み込んだかわかるけど、
C++のreadだと、何バイト読んだかわからないですよね。
それとも、方法があるのでしょうか?
gcountがあるJARO
>>75 う。ありがとうございます。
gcount...。getにしか使えないのかと思ってました。
読んだ後にlengthした方がええよ
78 :
デフォルトの名無しさん :03/03/16 23:48
>>73 そんなもんだめ
コピー、代入は自分で考えて下さい。
おれはprivateに放り込みますけどね
if (FILE* fp = fopen(...)) { } 上のように書いたらVC6.0でコンパイル通っちゃったのですが、 C++的にはこれはアリなのでしょうか? 今まで一度もこういう記述を見たことが無いので・・・
>>78 privateに放り込むよりメンバをconstにするほうがいいぞ。
class FilePtr
{
public:
explicit FilePtr(const char* text,const char *wr) : pfile( std::fopen(text,wr) ) { if(!pfile) throw int( 0 ); }
~FilePtr() { std::fclose(pfile); }
operator std::FILE* () const { return pfile ; }
private:
std::FILE* const pfile;
};
>>82 readとかwriteのメンバ関数はないの?
84 :
デフォルトの名無しさん :03/03/17 00:14
>>82 え? コピーコンストラクタがとおるのでは?
85 :
デフォルトの名無しさん :03/03/17 00:19
<<をオーバーロードしたいのですが、 組込型が引数な場合はどうすれば良いのでしょうか。 こんな風では当然あいまいだと言われてしまって…。 #include <fstream> std::ostream &operator <<( std::ostream &s, int d ) { ++d; return s << d; } int main(){ std::ofstream f; f.open("hage.txt"); f << 777; f.close(); return 0; }
>>84 あーそうだねぇ。やっぱりめんどくせぇなー。
>>84 class noncopyable
{
noncopyable(const noncopyable &);
void operator =(const noncopyable &);
protected:
nocopyable(){}
};
を用意し
class FilePtr : noncopyable
{ /*...*/ };
とすればいい
ちなみにboostに同名のクラスがある
>>87 class noncopyableの定義も、boost/noncopyable.hppのインクルードも
同じくらいにめんどくさいと思ったのデスヨ。
「その場で」「直接」な手段と思ったのですがねぇ。無念。
90 :
デフォルトの名無しさん :03/03/17 01:28
>>90 ありがとうございます。
しょうがないのでostreamをオーバーライドすることにします。
>>85 組み込み型をラップするクラスを作り、それについてオーバーロードすればよい
>>85 なんで
std::ostream &operator <<( std::ostream &s, int d )
{
++d;
return s << d;
}
こんなことがしたいんだ?
s<< 777 + 1;
でいいじゃん
operator<<をオーバーロードして何がしたいのか教えてください
後でソース読み直したときに混乱しそうだ。
>>96 いやはや、長引いちゃってすいません。
目的は2つありまして…。まず、いま既に<<を膨大に使って
txt出力しているソースがあるのですが、これを全て
別の注釈付きな書式で書き出す必要がありまして…。
1度出来れば良い&手書きで直していると、
ミスも出そうなので、一気に根本を乗っ取れたらなと。
もう1つはまだ、与しやすいのですが、
doubleやfloat型の「0.0」という数字を、<<にて小数点が付いたままtxt出力したいなと。
(普通にやると「0」になってしまうので)
C++で文字列(const char*)の比較する場合、stringに代入しないなら char_traits::lengthで両方の長さ調べて短いほうでchar_traits::compareして・・・ っするしかないの?
>>98 class wrapstream
{
ostream *os;
public:
wrapstream(ostream &p):os(&p){}
template <class T>
wrapstream &operator<<(const T &a)
{ (*os)<<"--- "; (*os)<<a; (*os)<<endl; return *this; }
};
cout<<fixed;
wrapstream ws(cout);
ws<<10.0<<20.0;
これでどうでしょうか?
小数点がついたまま出力したりするのはios_baseで設定することができるのでそれを参照してください
>>100 す、素晴らしいコンポジションであります_| ̄|○
もはや、手作業による長く地味な書き換えしか無いと思ってたのが、
出力先を置換するだけで、一瞬にして作業が終わってしまいました。
いやはや、いくら感謝してもし足りません。ありがとうございました。
うほっ!うまそーな魚!いただきマンモース!!!!!!!
ごちそうサマンサ。
char_traits::length()は内部でstrlen()を呼び出してるだけじゃん。
のーのーのーチッチッチッ
構造体をクラス宣言の中で宣言したときと、 外で宣言したときの違いを教えてください。 中で宣言すると、メンバ関数の戻り値に 宣言した構造体を用いることができないようなのですが、 それ以外に違いや制限はあるでしょうか? // ↓中で構造体を宣言 class c { struct s { // 〜 }; // 〜 }; // ↓外で構造体を宣言 struct s { // 〜 }; class c { // 〜 };
>>109 返せるよ。
class A {
struct B {
int i;
} b;
public:
B func() {
return b;
}
};
BがprivateでAがfriendを持たないと怒られるかも
>>110 ありがとうございます。
インライン関数にするとエラーがなくなりました。
インライン限定なんですね。
クラス内部情報の管理に使う構造体なので
宣言を外部に見せたくなかったのですが、
インライン関数ばかりにするわけにもいかないので、
もう宣言を外に見せるようにするしかないですかね。
>>112 悪いけど...
> インライン関数にするとエラーがなくなりました。
と言うことから...
> インライン限定なんですね。
と結果を出す奴は、プログラマには向いてないと思う。
class A {
struct B {
int i;
} b;
public:
B func();
};
A::B A::func()
{
return b;
}
111 が答えだと思うんだが・・・。 構造体を見せたくないなら、構造体へのポインタをメンバにすればよかれ。
class A { struct B { int i; B(int j) : i(j) {} } b; public: A(int i) : b(i) {} B func() { return b; } }; int main() { A a(123); std::cout << a.func().i << std::endl; }
>>113 その方法でうまくいきました。
自クラスで宣言した構造体なので、スコープ演算子を
使わなければいけないとは思いつきませんでした。
>>114 VC++6.0を使ってます。
>>116 class A {
struct B {
friend class A;
// 〜
};
// 〜
};
とやってみたのですがエラーでした。
(
>>111 はこういう意味ではない?)
>>118 BはAのスコープ内にあるから、言ってみれば A::B だからfriend class
宣言なんて不要だよ。
120 :
デフォルトの名無しさん :03/03/18 04:03
(本当の)配列をnewで確保するのはどう書けばいいの? int (*p)[10]; として、 p = new (int [10]); なら、 new int[10]と解釈されるみたい。 無理矢理、new[]を使って、 p = new [1][10]; なら出来るけど・・・
スコープ演算子を使ってないとは思わなかった・・・
>>120 (゚Д゚)ハァ?
new int[10] の何が不満なんだ?
>>120 p = reinterpret_cast<int (*)[10]>(new int[10]);
>>120 その悲しみはよく分かるが配列型を基本型と同じには扱えないのが
C/C++の悪しき特長だ
一応書いとくと以下のことね typedef int array[10]; main(){ int *ip=new int;// OK!! array *ap=new array;// Error!! }
レス thanks.
規格読んでたんだけど、よく分からなかった・・・
>>122 いや、ただの疑問。
>>123 これだと、delete時にもキャストしなければならない罠。
>>124-125 なるほど、つーことは配列へのポインタは必ずnew[]を
使わなければならないってことか・・
127 :
デフォルトの名無しさん :03/03/18 09:35
Write a program in which you hard code a table that contain the state names state post office abbreviations, and the population's size(you should find these data on-line ,or in some reference book). the program should prompt the user to enter a state name. let the program do a sequential search to find the corresponding state postalcode and population size. the program should display these data.
128 :
bloom :03/03/18 09:52
ファイルの削除の仕方を教えてください。
気合
del *.*
std::remove()
133 :
デフォルトの名無しさん :03/03/18 11:59
typedef struct tagVMRGUID { GUID *pGUID; GUID GUID; } VMRGUID; g++でコンパイルするとGUID GUID でエラーになるんですが 何か間違っているんでしょうか?
あ。GUIDの定義はコレなんですが… typedef struct _GUID { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID, *REFGUID, *LPGUID;
エラーメッセージを省くな馬鹿野郎
>>133 GUID は構造体の名前なんだから
変数の名前として宣言しちゃだめ。。。
>>135 失礼しましたエラーはこう出てます。
strmif.h:27642: declaration of `GUID tagVMRGUID::GUID'
winnt.h:1167: changes meaning of `GUID' from `typedef struct _GUID GUID'
>>136 レスありがとうございます。
そうなんですか。これはMicrosoft製のヘッダなんですけど・・
回避できないものでしょうか…。
>>136 ハァ?適当なこといってんじゃねーよ。
struct S
{
};
struct X
{
struct S S;
};
>>133 ということで、struct GUID;として定義されてれば、
structを付ければ曖昧さが無くなるんだが、
typedefだとどうしていいのかわからん。
回避ってんなら、
typedef struct tagVMRGUID
{
GUID *pGUID;
struct _GUID GUID;// 適当なコメント
} VMRGUID;
これくらいか?
>>138 ありがとうございます。修正してみたのですが
同じエラーになってしまいました。
138 のコードをコンパイルしてみると同じエラーになるようです…。
名前を変更したら通ることは通るんですが…。
struct S {
int a;
};
struct P {
S S; // エラー
};
int main( void) {
P p;
p.S.a = 1;
>>138 大変失礼しました。
Struct S S で通りました。
struct _GUID GUID; が通らない…。
141 :
デフォルトの名無しさん :03/03/18 14:49
>>133 うそ?????????????????????
typedef struct A{ const static int n = 5;}C ;
struct B
{
::C C;
struct A A;
};
142 :
133=139 :03/03/18 17:45
>>141 何度もレスをいただき、誠にありがとうございます。
141さんのコードのようにグローバルスコープに合わせると
コンパイル通りましたー。
GUID GUID の部分ばかり修正していて *pGUID; の修正を
忘れていました。ここもエラーになっていたようで…。
うつけものです。すみません。。基本知識が不足しているので
規格書を読み直してみます。
今回は皆様にご助言をいただきとても助かりました。
ありがとうございます。
↓修正結果はこうなりました。
typedef struct tagVMRGUID {
::GUID *pGUID;
::GUID GUID;
} VMRGUID;
144 :
デフォルトの名無しさん :03/03/18 18:00
おい!てめーらくそか!? 俺の仕様書にわざとコーヒこぼしただろ!! ココならいえる。
何か、ime.nu の広告がむちゃくちゃ増えてないか?
ホンとだw
CからC++へのスムーズな移行にはどんな本が必要。 Cがそれなりに分かっているなら「憂鬱な〜」がイイって聞いたのですが。 それともチャンと「Effective〜」のような教本読まないとイクナイ?
>>148 Effective〜のような本はどっちにしろ読むべし
>>149 ありがとうございます。
Effective読んだ後に憂鬱摘み食いしながら
MoreEffective読むことにしてみます。
151 :
デフォルトの名無しさん :03/03/19 21:40
struct vector3_t { vector3_t(float x, float y, float z) : x(x), y(y), z(z) {} vector3_t(const vector3_t &v) : x(v.x), y(v.y), z(v.z) {} vector3_t() : x(0.0f), y(0.0f), z(0.0f) {} . . . union { struct { float x; float y; float z; }; float v[3]; }; }; ベクトルを表す構造体&共用体なんですが、いまいちやってる事の意味が分かりません。 共用体によって扱いを楽にしてるのはなんとなく分かるんですが、上の3行って一体・・
マルチですか 若いっていいですね
>>152 スレ違いだから来ただけだろ。失せろボケ
まあいいや、可哀想なのでマジレス。 union { struct { float x; float y; float z; }; float v[3]; }; とりあえず、死ね。 処理系依存互換性皆無
155 :
デフォルトの名無しさん :03/03/19 21:51
>>154 あの、151の通りであってるんですが。共用体が構造体に入ってるんです。
もう少し勉強してくらさい。
>>151 コンストラクタの初期設定子
ようは、構築時にメンバの初期設定してるだけ。
vector3_t v(1.0, 2.0, 3.0);
とされると、v.x = 1.0; v.y = 2.0; v.z = 3.0; となる。
vector3_t v1(v);
とされると、v1.x = 1.0; v1.y = 2.0; v1.z = 3.0; となる。
vector3_t v2();
とされると、v2.x = 0.0; v2.y = 0.0; v2.z = 0.0; となる。
俺も、極めてわかりにくい構文だと思う。
後、無名共用体、無名構造体は
>>154 の言う通り処理系に依存する。
初期化子の事を聞きたいのかね
>>157 CEOのAndre LaMothe氏がOpenGLのパーティクルシステム用に書いたコードの一部なんですが、
この人のコードはとってもワイルドな感じです。
んで、こういう書き方をするメリットって?
構造体と配列のメモリレイアウトの互換性も規定されてない
メリットというか定数メンバやリファレンスメンバの初期化では 必然的にその構文に頼らざるを得ないな。
164 :
デフォルトの名無しさん :03/03/19 22:57
エラーコードを取得するメソッドがついてる クラスがあるとして、やっぱりメンバメソッドの頭で エラーコードのメンバ変数を初期化する 処理を入れてあげるのって普通? もっと格好いいやり方ですかね? ようするに、エラーコードを持ったクラスの設計で もっといいやり方ないでつかね?
エラークラスを投げる
あんまし、簡単に済まさないでさ、 もうちょっと知恵をわけてくれたっていいじゃんよ。 例外じゃないよな?って思うときだってあるじゃん。 エラーと例外って意味違うジャン。
>>166 ここに質問したら、おまいが抱えてる問題を手取り足取り
解決してくれると思ってますか?
しかも質問内容に見合う回答内容もらってると思うが。
掲示板てのは基本的に情報収集&交換の場、
ヒントを得られれば上等と思ってくれたまい。
それが質問スレであっても、だ。
ヒントがあって考える、それすら出来ないヤツは(略
あ〜そうかよ。どうせわかんねーんだろ(プ お前らの知識を試してみたんだが、この程度だったか。
文盲あるいはチョソは発言禁止
てゆーかさ、それを考えるのがクラス設計だと思うわけで、 そのクラスの性質とかいろいろな状況考えないと一概に言えないと思うのよ。 んで、一般論を言えば165じゃねーのってことじゃん?春厨君。
エラークラスを投げるのが嫌ならグローバル変数にでもセットしてろすっとこどっこい
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□ □□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□ □□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□ □■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□ □□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□ □□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□ □□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□ □□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□ □■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□ □□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□ □□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□ □□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□ □■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□ □■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□ □□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□ □□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□ □□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□ □□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□ □■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□ □□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□ □□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□ □□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□ □□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□ □■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□ □□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□ □□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□ □□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□ □■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□ □■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□ □□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□ □□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□
176 :
デフォルトの名無しさん :03/03/19 23:42
そか?ゴメンゴメン。 例えばこんな感じ。 class Hoge { private : int m_ErrCode; public : Hoge() : m_ErrCode(0){} bool Method1( void ) { m_ErrCode = 0; //←全てのメソッドの頭でこれを入れるのが //なんか格好悪いような気がするんです ・ ・ ・ } ・ ・ ・ int GetErrorCode( void ) { return m_ErrCode; } }; もっといいやり方とかパターンとか、ないかなと。
すっとこどっこいもここまでくるとすっとこどっこいが 可愛そうになるほどすっとこどっこいだな。
>>176 どうせ、各々のメソッドが成功かどうかを返すんだろ ?
だったら、失敗した時だけエラーコードをセットすれば良いと思う。
(当然、メソッド成功時は GetErrorCode() の値は保証しないことをドキュメントに書いとく。)
169は私じゃないでつ。
>>178 それだったら、その場で例外投げるとかエラーコード返すなりすればいいじゃん。
何もエラーコードを保存する必要はないような気がするが。
俺は別に格好悪いとは思わないけど。何がいけないんだろう。
int GetErrorCode(void){return m_ErrCode=NO_ERROR;}
エラーコードが揮発性でいいなら、 GetErrorCode内で初期化してしまう
初期化とかはべつに問題じゃなくてね。 もうちょっと足してみると bool Method1( void ) { m_ErrCode = 0; //←全てのメソッドの頭でこれを入れるのが //なんか格好悪いような気がするんです ・ ・ if( なんか失敗 ){ m_ErrCode = 失敗コード; return false; }
iostreamの設計を見なされ
エラーコードを返したら駄目なのですか?
格好悪いなら取れば? WindowsみたいにGetLastErrorとでもしておけば辻褄があうだろ
bool Method1( void ) { if( なんか失敗 ){ m_ErrCode = 失敗コード; return false; } よし、これでどうだ
>>179 なるほど。そういう手もありかな?
>>181 戻り値をboolと書いてしまったのが
まずかったですね。
boolじゃなくてたとえばstringが戻り値だったとして
失敗して空のstringが返ったとき、なぜ空だったのか
GetErrorCode()で取得みたいな場合も。
>>188 あ、そっか。あったですね。
std::fstream strm( "Data.txt", std::ios::out | std::ios::in| std::ios::trunc );
if( strm.fail() == true )
fail()ってどうなってんだろ?後で見とこっと。
あれstd::ios::trunc ってどんな意味?
>GetErrorCode()で取得 こういうのはマルチスレッドに弱かったりするからなぁ 戻り値はエラーコード専用として使い 引数でstringもらったら?
if(strm.fail() == true) この根底の仕方は駄目でしょ
if( strm.fail() ) あ。こか。
エラーコードを重要視したいがために引数返しに するのって、悲しいコードな気もするんですね。
だったら例外で良いじゃん
>>197 COMは規約としてそうなっている
重要なのは一貫性だと思う
class Hoge { private : int m_ErrCode; public : Hoge() : m_ErrCode(0){} bool Method1( void ){ //処理 if( なんか失敗 ){ m_ErrCode = 失敗コード; return false; } //処理 return !(m_ErrCode = 0); } //… int GetErrorCode( void ) { return m_ErrCode; } };
>>199 COMなってるね。
見えた。一貫性だね。
一貫して全てのメソッドの頭に書いとけば
それはそれでいいね。
別のクラスでは例外投げ使ってたりとか
したらこのクラスは、やっぱよくないしね。
これも例外投げで統一するべきだしね。
catchでエラー取得って、使う側にしたら
スンゴイ使いズらい気がするんだよね…
if(!FAILED(p->foo())) { if(!FAILED(p->foo())) { if(!FAILED(p->foo())) { }}} こんなのよりマシだと思う、例外は 実際COMのエラーはVBとかJとかでは例外として送出されてた
>>200 Method1の前にMethod2が失敗してたとしたら
Method1は常に失敗してしまうじゃん?
だからメソッドの頭にm_ErrCode=0が
必要だと思っちゃうわけですよ。
その頭に書いちゃうことは格好がいいか?ってこと。
話がもどっちまった。
>>176 (196)
ハァ? マルチスレッド? んなInternational Standardに
ないもんは知らねーYO! ちなみに
if(strm.fail())
は、格好にこだわるならむしろ
if(!strm)
の方が格好がいいかと。
std::ios_base::out | std::ios_base::truncは
ファイルを切り詰めるんじゃなかったかな。
>>200 のは m_ErrCode に 0 を代入してそれを否定してるんだから
true が返るときは必ず m_ErrCode == 0 が保証されるんじゃない?
トリッキーだけど。俺は return m_ErrCode=0, true; と書きたい。
すまそ、マルチスレッドの話であったか。
>>203 すまぬ、マルチスレッドなどと訳のわからぬことを書いた。
てっきりMethodをマルチスレッドで同時実行するのかと。
逝ってきます y=-( ゚д゚)・∵ ターン
とまではいかないまでも(w、
>Method1の前にMethod2が失敗してたとしたら
>Method1は常に失敗してしまうじゃん?
これはなぜに?そういうクラス仕様?そうでなければ
このコードは自動的に最新のエラーコードに更新されると
思うのだが。
>>206 別にマルチスレッドの話ではないと思う
>>203 同じクラスのメソッドが失敗したということは
その状態のまま他のメソッドを呼んではだめでしょ
あれそうなの?分からなくなってきた。そうでなければ
>>200 の
コードはどこが問題になるのだろう。
悪い。私が見間違えた。 200のコードは満たしてます。 問題ないでつ。
211 :
デフォルトの名無しさん :03/03/20 01:46
なぁ・・・俺・・・いまだに参照とポインタの使い分けに悩むんだ・・・ もう・・・ポインタ一本で行っていいかな・・・?
い い と も
下に書いたクラスみたいなのをいくつも作るときに、 楽ができるやり方ありませんか? class Test { Test () { if (m_instance) throw Error (); m_instance = this; } ~Test () { m_instance = 0; } static Test* m_instance; };
Ctl+C Ctl+V
>>214 うちの環境ではそんなコマンドないけど・・・
C-h k C-c C-v
C-c C-v is undefined
うちの環境では C-M-a C-p C-@ C-M-e M-w で C-y って、マジレスキボン…… templateっぽいけど、さっぱりわからんかった
>>216 あのさ、何がしたいんだかわかんないよ。
class Test の微妙にそれぞれ違うバージョンを作りたいって事なんだろうけど、
どう微妙に違うのかわかんないと案の出しようが無いだろう。
仮想キーコードとスキャンコードの違いを教えてください。 …これってAPIスレの方が適切だったりしますか?
ごめんなさい、スレ立てるまでもないと勘違いして誤爆しました
>>217-218 >>213 のTestみたいに、好きな時に作れるけど同時に一つしか存在できない
クラスを、いくつか作りたいんです。なのでboostのはちょっと。
今は、すべてのクラスでTestみたいなのを個別に書いてるんですが、
もうちょいなんとかならんのかなと思いました。
Testには書けてませんが、デフォルトコンストラクタ以外のも使いたいです。
>>219 そうみたい。
template <class SubClass> class singleton { static SubClass *inst_; public: singleton() { if (inst_) throw Error(); inst_=static_cast<SubClass *>(this); } ~singleton() { inst_=0; } static SubClass &instance() { return *inst_; } }; template <class SubClass> SubClass *singleton<SubClass>::inst_=0; //使い方 class Test : public singleton<Test>{};
224 :
デフォルトの名無しさん :03/03/20 16:54
ソケットのクラスで何がよく使われてますか? それとも自作が基本ですか?
>>224 よくわからんが、ACE とかはどうだろう?
>>224 .NET風の薄いラッパを自作して使ってる。
227 :
デフォルトの名無しさん :03/03/20 22:09
linuxのデバイスドライバを作るのにC++を使いたいのですがどうにもうまくいきません どこか良い開設サイトをご存知ありませんか?
228 :
デフォルトの名無しさん :03/03/20 22:20
std::copyやstd::swapを、自分で定義した型でオーバーロード する時、オーバーロード関数はstdに入れちゃう?Koenig lookup させる?そもそもオーバーロードなんてしない?
>>194 >> GetErrorCode()で取得
> こういうのはマルチスレッドに弱かったりするからなぁ
煽り ? 単なる無知 ?
エラーコードがスレッド毎に保存されることぐらい常識だと思うが...。
>>229 煽り? 周囲の文を読んでいるか?
クラスのメンバ変数だぞ?スレッド毎に保護されるわけ無いだろ…。
>>230 でも、Koenigでやるのも地獄だし、誰かがstd::を付けたら
結局ダメだし。
ぬるぬるだな。
だな
企画違反でも入れちゃうのだっ
イヤ〜ン
ノ∩
⊂ ヽ ←
>>233 /( 。Д。 )っ
U ∨ ∨
・@;∴‥
∧_∧ ∩ :: :.
( ・∀・)/ :: ::
(つ / :: :'
人⌒l ノ :: :: ガッ
し(_)
238 :
名無しさん@Emacs :03/03/20 23:28
>>237 それ何?説明読んだけどイマイチ分からんかった。
C++の文法を拡張した物のC++へのトランスレーターって事?
ある関数 f があるとき、この関数を使って出来ることは ・fを呼び出す ・fのアドレスを取る の2つだけである、ってのは正しいかな?
stdに入れるのがイレギュラーなのは確かだけど、だからといって namespace myns { class Class1 { ... }; swap(Class1 &x, Class1 &y) throw(); ... namespace junk { using std::swap; } template <class Iter> void foo(Iter s, Iter e) { using namespace junk; Iter i1, i2; ... swap(*i1, *i2); } } なんて絶対やりたくないんだけど。 やっぱりオーバーロードしようとするのが間違い?
>>240 俺は常に.cppの頭でusing namespace std;する人なので
それは考えたことがなかった。。。けど、そんな複雑にせんでも
template <class Iter> void foo(Iter s, Iter e) {
using std::swap;
Iter i1, i2;
...
swap(*i1, *i2);
}
だと何か問題あるのか?
>>231 すまん書き間違えた...
×: エラーコードがスレッド毎に保存されることぐらい常識だと思うが...。
○: (マルチスレッドを考慮に入れるなら) エラーコードをスレッド毎に保存することぐらい常識だと思うが...。
まさかやり方知らないとか ?
> エラーコードをスレッド毎に保存することぐらい gccだとどうやるの?
threadハンドルをキーにmapする。
>>241 それだとmyns::swap()が見えない。
ちなみに単にswap()だけ、あるいはusing namespace stdだと、
*i1,*i2がprimitive型の時にstd::swap()が見えなくなる。
>>242 >>245 だからメンバ変数だっていってんだろ!!
オブジェクト一つずつにそんなことする気か?
>threadハンドルをキーにmapする。
これじゃ足りねーよ
>>244 スレッドは C++ の標準じゃねーから、単に gcc と書かれても困る。
てかスレッドごとにインスタンス作れよ
あるクラスのstaticなメンバ関数で共通に使いたいmutexを初期化したいのです。 Javaだったらスタティックイニシャライザでクラスに属するリソースの初期化処理をやりますよね。 でも、C++では言語としてそのような機能はないみたい(あるのかも知れないが、私は知らない)。 そこで、以下のようにグローバル変数で初期化しているのですけど、 namespace _hoge { pthread_mutex_t mutex; class Initializer { public: Initializer(){ pthread_mutex_init(&mutex, NULL); } }; Initializer initializer; }; なんかダサい気がします。もっとよい方法を識者の方に伺いたいです。 (ちなみに、mutexをクラスのメンバにしてPTHREAD_MUTEX_INITIALIZERで初期化すると 「インテグラルじゃない値を初期化しようとしてる」みたいな警告が出るのでもっとダサい)
コンストラクタ内で初期化しろ。 二回目以降はスキップ。 ダサいのがいやならカエレ!
>>250 pthread_mutex_t を、initするクラスでラップしといてから
template<class T>
inline CMutex& common_mutex_of() {
static CMutex mutex;
return mutex;
}
>>251 コンストラクタ内で初期化する方法だと、mutexを初期化するのは、メインスレッド
でやらないと駄目。でもメインスレッドから hoge::init() みたいなのを呼ぶのはダサい(呼び忘れるから)。
で、コンパイル時か、実行時でもmain関数より前に初期化を行いたい。
チョッと待て、
>>252 も呼び出す時がいつかで競合の問題がある
ほら
pthread_mutex_t mutex;
bool pinit(){ pthread_mutex_init(&mutex, NULL); return true; }
bool pinitialized=pinit();
これでどうよ?
namespaceっていつから流行ってんの? それ一般的に使われてんの? 学究的な興味なんざ小指の爪の先ほどもない。 職業プログラマとして必要な技術?
無理しないでnamespaceと対になったinitializerクラスで我慢しとけよ。
>>255 あ、それでいいのか。
でもやっぱグローバル変数使わざるを得ない?
staticなメンバ変数と関数だけで済ませられないでしょうか。
(駄目なら、グローバル変数での初期化が定石ってことでいいのでしょうか)
>>256 標準ライブラリで使われている気が、、、
>>258 staticなメンバ変数はほとんどグローバル変数と同じようなもんだぞ?
マジで標準ライブラリに? うーむ、ぐぐっても解説等出てこないから比較的新しい技術なのかと思っていたが、 C++の標準的な「何か」なのかな・・・ CからC++へ、なんとなく体で移行してきたんでわからんことが大杉。 本腰入れて勉強しないと限界みたい・・・
とあるライブラリの関数foo()と別のライブラリの同名関数foo()を同一ソースでコールしたい。 さてどうする?
>>259 確かにそうですね。結局、namespaceで保護するのが関の山ですかね。
>>239 正しくない。
意味のある使い方がまだある。
>>263 なるほど。っていうか、無名namespaceってのは初めて知りました。
mutex を、それを利用するクラスのメンバにして、
初期化は無名namespaceのグローバル変数を使ってやると。
それが一番かもしれないですね。
ぬるい話題が多いな。 るいじの質問もあるし… ぽんと,いい考えがうかばないのか?
ぬるくない問題はC++では解決できないからねぇ。 そういう人はとっくにC#に以降済みだし。
ミノガスカヨッ
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>266
C#だとよ(w
270 :
デフォルトの名無しさん :03/03/21 10:35
>>270 おお!特殊化なら合法だったんだ。
これで幸せになれそうです。ありがとうございます。
>>270 テンプレートライブラリを作成するときにstd::swap(a,b)を使うことを考えると、
自前のswap処理を作ったならstd::swapの特殊化をしておくべきだと思うんだが、
boost::scoped_ptrなんかは、boost::swapが定義されてるな。
これだと、
scoped_ptr<T> a,b;
std::swap(a,b);
と書いても、a.swap(b)にはならないな。
274 :
デフォルトの名無しさん :03/03/21 23:25
クラステンプレートが static なデータメンバを持っているとき、複数のコンパイル単位で、 その static なデータメンバの定義を行っても、リンク時に一つにまとめられてしまうよう なのですが、これは規格に則った動作でしょうか。 -- X.h -- template<class T> class X { static T x; }; template<class T> T X<T>::x; -- Foo.cpp -- #include "X.h" void foo() { X<int> a; } -- Hoge.cpp -- #include "X.h" void hoge() { X<int> b; } ここで Foo.cpp と Hoge.cpp をコンパイルしてリンクしても、とくに X<int>::x の 多重定義にはならず、正常にリンクされます。(g++ と VC++ で確認) しかし、C++第3版の 13章7節によると「非inline の static メンバは、どこかの翻訳単位に ユニークな定義を持たなければならない。」とあり、上のような動作は保証されていない ようなのです。
>>274 14.5.1.3にX.hの内容と同じ例があげられている。
その挙動を疑うなら、以下のソースも疑うことになると思うのだが・・・。
-- X.h --
template<class T>
void f();
-- Foo.cpp --
#include "X.h"
void foo()
{
f<int>();
}
-- Hoge.cpp --
#include "X.h"
void hoge()
{
f<int>();
}
あ、ごめん。訂正。 -- X.h -- template<class T> void f(){}
? これ同じ例か?
?HogeHoge@@YAHG@Z を元に戻すテーブルかなにかはありませんか?
>>278 WinならUnDecorateSymbolNameというのがある
undname -f ?HogeHoge@@YAHG@Z ?HogeHoge@@YAHG@Z == int __cdecl HogeHoge(unsigned short)
Σ(*゚Д`;)ア…ア…アッハァァァァァァァァ?!! すばらしいですぞ、このような時間に!!! はげしくあげしく、感謝します。
282 :
デフォルトの名無しさん :03/03/22 06:37
以下のように、相互にincludeしたいのですが、エラーが出てしまいます(´Д⊂ こういう場合は、2つのクラスを、同じヘッダにまとめるしか無いのでしょうか? ----------------A.h #ifndef A_H #define A_H #include "B.h" class A(){ A( B* b ); }; #endif ----------------B.h #ifndef B_H #define B_H #include "A.h" class B(){ B( A* a ); }; #endif ----------------
----------------A.h #ifndef A_H #define A_H #include "B.h" class B; class A(){ A( B* b ); }; #endif ----------------B.h #ifndef B_H #define B_H #include "A.h" class A; class B(){ B( A* a ); }; #endif ----------------
>>283 見事にリンクできました。これがクラスの前方参照…。
助かりました。ありがとうございました。
285 :
デフォルトの名無しさん :03/03/22 12:02
初歩的質問です。 int x=0; int *a = &++x; // OK int *b = &x++; // エラー bの初期化でエラーになるのはなぜでしょうか? コンパイラによれば'&'に左辺値がないとのことですが・・・。 自分のイメージとしてはxのアドレスでbを初期化した後、 xをインクリメントするという感じなのですが・・・。
&(x++)
287 :
デフォルトの名無しさん :03/03/22 12:28
優先順かな。 下は&xが評価された後にインクリメントされるから、 一時領域のインクリメントはできないのか、あいまいさではじかれてるのかどっちかでしょう。 エラーコードを見ればどっちかわかる。
ちなみに私が知りたいのは、どうしたら自分のイメージどうりに 動かせるかではなく、なぜエラーになるのかです。 結合順位からいえば、もともとインクリメント演算子の方が強いのですが・・。
禿本の p161 に説明があるけどピンとこないな。 >論理的に可能であれば、左辺値の被演算子を取る演算子の処理結果は、 >その左辺値被演算子を示す左辺値になる。 (略) >int *p = &++x; // p は x を指す >int *q = &(x++); // エラー: x++は左辺値(xに格納されている値)ではない x に副作用が発生するタイミングは前置でも後置でも ; に至るまでの いつかでしかないと思うのだけど前置のみ左辺値になるのはどうして だろう。
>>289 まあ ++x は、極論すれば、{x = x + 1, x} と同じだからアドレスがとれる。
でも、x++ は、{(x = x + 1)} と言う式になるから、アドレスが取れない。
だから、前置は式評価前にインクリメント、後置は式評価後にインクリメントするからだろ?
本の解説でも、コンパイラのエラーメッセジでも あくまで&に対する左辺値が無いということが原因みたいですね。 ちなみに int *r = &(x += 1); // OK これはOKでした。これが前置と同じことなんですかね・・・。 後置だとカッコの中身が先に評価されないとか(超適当)。
式ってのはxね。
>>292 前置の場合 x の副作用が式の評価前に行われるのは保証されてるの?
int a, b, c; a = 0; b = a++; c = ++a; bは0、aは1になるのはわかってんだよね?
× bは0、aは1 ○ bは0、cは1
あーちがう! このままじゃcは2になるやん。 まぁ雰囲気だけ味わってくれ・・鬱だ死のう。
cは2じゃないか?
int& operator++(int&); int  operator++(int&,int); int  x = 0; int* a = &(operator++(x)); int* b = &(operator++(x,0));
301 :
デフォルトの名無しさん :03/03/22 14:20
T& operator++(void) { m_nakami+=1; return *this; } T operator++(int) { T temp=m_nakami; m_nakami+=1; return temp; } 後者の返り値は値(一時変数だから参照を返せない)だから アドレスがとれないってことじゃなくて?
基本型でない型の振る舞いと対称性を保つためにエラーにせざるを 得ないということ? template とか。本末転倒な気もするけども。
はぁ?
Cではどっちもエラーになるな。
> int* b = &x++; ↑こんなコード、コンパイルできるようにしてもなんのメリットもないだろ。
>>305 だからなんなんだ?
勉強のできないやつってのは、なぜそうなるか?どういう原理なのか?
といったことにはまったく興味をしめさず、できればいい、動けばいい
的な考えなんだよな。だから応用もきかないし、所詮そこ止まりの人間。
そういう奴はベーシックでもやってりゃいい。
>>306 オーバーロード可能な演算子のシグネチャとして、
C++では演算子'++'を
>>300 のように定義した。
この定義には「基本型でない型の振る舞いと対称性を保つ」目的があったかもしれない。
その結果、Cではコンパイルできなかった式'&++x'はコンパイル可能になった。
ここは「コンパイル可能にせざるを得ない」という話になるだろう。
だが、'&x++'「エラーにせざるを得ない」なんて話には、どうにもつながらない。
ちなみに、300==305。
>>307 何のメリットも無いのに、Cと異なる挙動とする意味でもあるのか?
>>306 もし
>>302 の疑問が正しいのであればそもそもC言語でも駄目なのはどうしてだ?
C言語では基本型以外にoperator ++は定義できない
>>何のメリットも無いのに、Cと異なる挙動とする意味でもあるのか? そういうこと言っているわけじゃねぇだろって もっと一般的な話だろ(プログラムに限らずな)
>>300 Cと比較すると解釈が逆になることが分かるな。
でもメリットて話だとしたら、&++x にどんなメリットがあったのか
疑問だ。Cと同じように左辺値になり得ないとしたら問題が起こる
のだろうか。
>&++x にどんなメリットがあったのか疑問だ。 意味がわかりません!!メリットなんて別にないだろ!!
>>312 メリットが無いのであれb &++x も C と同じように左辺値に
ならなければよかったんでは。
>&++x も ++x も
VC++って標準C++とは限らないんだな・・・。 for(int i = 0; ... ; ...) このiのスコープもデフォルトではforブロック外だよな、.netは。 ほかにも、標準C++に沿ったコーディングでエラーにもなるし。 標準C++のコンパイラってあんの?
ストラップにメールだしてくれ。
>>306 > &++x も C と同じように左辺値にならなければよかったんでは
左辺値にならないとしたらオーバーロード可能なシグネチャの定義が、
int operator++(int&)
というようなものになり、
ユーザー定義型で効率のよい実装が難しくなる。
>>310 あれ?外してた?あんた
>>307 か?
何を突っ込まれたのかわからない。ごめん。
&++x ←これって左辺値じゃないよね? ++x ←これは左辺値になるけど x++ ←これは左辺値じゃない
まあ、確かに++xを左辺値にする必要はないのかな?
(++x)=10; とかできてもうれしくないしな・・・
メリットうんぬんじゃなくて、結合やらなにやらの思想の統一性から こうしたのかもしれないね・・・。なにを基準に決めたのか知らんけど。
でも ++x = ++y とか書きたいときがある。ない? 今議論されてることって一貫性の問題?
激しくかぶった。ごめ。
しかしK&Rにせよストラウストラップにせよ、わざわざ 読者をなやますようなコードをちりばめるね・・・。 参考書というよりは教科書チックだな。
C++では (x = y) = z; がエラーにならずに通るからね。Cでは見事に エラー。
>>322 *++x = *++y;
こうじゃないの?
++x = y++
は何が起こるの?
++x = ??? ってけっきょく???で上書きされるから インクリメントを事前にしても意味ないんじゃ・・・。
効率の問題で ++x が左辺値になることを許してしまうというのも なんだかな・・・。
別に効率の問題ではない。 勘違いしているだけでしょう。
int x = 0; int y = 5; ++x = y++; cout << x << endl; cout << y << endl; result: 5 6
はあ ++xは意味がないですね
++x = x++;
>>332 それは x = x++; と同じで結果が未定義なのでは。
int x = 0; ++x = x++; cout << x << endl; result: 2 (VC++.net)
(++x)++;
>>334 result:
2
(BCC5.6)
2
(MingGW 3.2.2)
++++++++++x;
++--+--++----x;
もうめちゃくちゃだな
341 :
デフォルトの名無しさん :03/03/22 17:35
質問です。 #include <cstdio> とすれば、<stdio.h>で定義されている関数がstd名前空間内に入っている形で 利用できると理解していたのですが、 std::puts("俺"); が、「'std'はクラスでも名前空間でもない」と言われます。また、 ::puts("誰"); だとコンパイルが通ります。私の勘違いなのでしょうか。 環境はVC6.0です。
VCは標準C++準拠じゃありません。
>>341 VC6.0を窓から投げ捨てろ
それかSTLportをインストロール
>>342-343 そういうことでしたか。
VCを投げ捨てる決心がつくまでの間は、namespace std{ と } で
何とかやっていけそうです。有難うございました。
345 :
デフォルトの名無しさん :03/03/22 18:48
多倍長計算ができるC++用のライブラリの中で、信頼の置けるものはありませんか?
346 :
デフォルトの名無しさん :03/03/22 21:31
例外処理ってどんな時に使用しますか?
MFCではファイルの読み込みでEOFに達すると例外を投げます。 ハァ
349 :
デフォルトの名無しさん :03/03/22 21:41
>>347 実はその「例外的」の例外の定義について深く知りたかったり…。
ageてしまった。スマソ
351 :
デフォルトの名無しさん :03/03/22 21:43
>>346 例外でもなんでもなく、ごく自然にあり得るエラーでも、
すぐ例外投げて責任転嫁する糞な設計のライブラリを
嫌々渋々使わされるとき。
>>349 人によって例外の定義は変わる。
ファイルが開けないというのを例外だという人もいれば
それは非常によくあることだから例外ではない、戻り値で知らせるべきだという人もいる
だからごめんなちゃい、わかんないよ
>>351 そんなライブラリ使うの止めて、あんたがすばらしいライブラリつくりゃ委員で内科医 ?
Javaはコンパイルエラーで例外を吐きます。 ハァ
init(); run(); done(); と失敗することを全く考えずに正常系の処理をとりあえず書く。 で、後から判明した失敗する要因をすべて例外として投げる。
>>348 iostream系もEOF(やその他エラー)で例外投げるようにできなかったっけ?
exceptions() で例外の設定できるね
いちいち戻り値をチェックしなくていいから楽チン
>>355 ワラタ。
ありがちな泥縄設計だね〜
一部の人にはシャレにならなかったりw
>>359 正常系-例外の分離が本質じゃないのか、C++の例外は?
たとえばWindowsのSEHですらcontinueがあるのに、
それすらもない例外なんだから、それ以外の用途は無いだろ
bool operator==(T const & a, U const & b) って、クラス T のメンバに bool T::operator==(U const & b) があればいらないですよね?
>>361 ユーザー定義の変換がある場合は、そうとも言い切れない。
>>362 どんな変換の場合でしょうか?
T型への変換があった場合でも T::== が呼ばれますよね?
>>363 ↓MEMBERの定義を変えてコンパイルして見れ。
#define MEMBER 1
struct S;
struct T
{
    T();
    T(const S&);// S to T
#if MEMBER
    bool operator==(int) const;
#endif
};
#if !MEMBER
bool operator==(const T&,int);
#endif
bool f(const S& s,int i)
{
    return s == i;
}
365 :
デフォルトの名無しさん :03/03/23 02:26
あるエラーが発生した時、もう復帰が不可能または復帰する必要無しである場合 全て例外投げてます。 って安易な考えじゃだめなのかなぁ。
>>365 「復帰が不可能または復帰する必要無し」とかいう用件は、
ライブラリを使う側、使う場所で決まると思うが。
>>367 iostream の exceptions みたいにすればいいじゃん。
C++よりはJavaかC#なんかの標準ライブラリの例外の投げ方見てると参考になるよ。 で実際は>355的な発想でちゃんと設計していくんだけど 例外的な使い方としてgoto的な例外(処理中止例外みたいなの)も織り交ぜるのが通のやり方。
>>368 エラーが発生した状態を保持できるようにするのは
そう簡単に決心がつくものじゃない。
全ての処理の前にその状態を問い合わせる必要が出てくる。
371 :
デフォルトの名無しさん :03/03/23 13:29
>>367 もちろん、エラー後の処理を判断しかねる場所では、戻り値でエラーを返します。
特にループ内でも頻繁に使用されるような関数であれば、例外処理のようなコスト
の高い処理を毎回行ってその都度判断を行う事は避けた方が良いと思います。
でも、判断できる場所では、例外無く例外を投げてます。
ってやり方をしてたら、部下に
「例外処理は本当の例外が発生したときのみ使用した方が良いのでは?
想定できるエラーで例外処理を行うのは邪道だと思うんですが」
と意見されてしまいますた…。
>想定できるエラーで例外処理を行うのは邪道だと思うんですが 想定できないエラーってなに?という線引きの話だけど メモリが足りない、ファイルがオープンできない、 他のプロセスが書き込んだあるべきデータが存在しない。 ライブラリにおかしな引数が渡された。 といった自分は悪くないけど発生しうるエラーはすべて例外にするかな。 自分が悪い=バグはそれ専用の例外を投げる。 偶数はスキップして奇数のみを処理する。 という普通にあり得るケースはコスト以前に例外にはしない。
>>372 この手のどっちでもいいことって、宗教戦争になるからなぁ。
> ファイルがオープンできない、
これ1つとっても、ユーザーがファイル名を入力していたなら単なるエラー処理とも言えるし。
自分が作成したファイルだったりしたら、例外とも言えるし。
ようは好みの問題だろ。結論なんか出ないよ。
> 自分が悪い=バグはそれ専用の例外を投げる。 その場合は悪あがきせずにabort()するべきだと思うが。 ネットワークアプリだったら、バグっているのに実行続けたら、 セキュリティホールになるだろ。
「想定できないエラーが生じたら例外」って、誰が考えたんだ? throwって書いた本人は間違いなくエラーを予測しているだろうが。 俺は、自分自身を復旧させる気が無くて、デストラクタ以外の 今後の動作を保証したくない時か、単にprivate関数の中での エラーを一番外のpublic関数でまとめて処理したい時に例外にしてる。
ああ、いわゆる参照オブジェクト系のクラスを設計する時は
同じくそういう手法を用いてます。
逆に、値オブジェクト系のクラスを設計する時は、
なるべくエラー処理を例外処理で行わないよう気をつけてます。
パフォーマンス的な問題で…。
ちなみに、私の部下が言った「想定できないエラー」とは
>>372 さんが中段に書かれているような事でした。
実はその部下に正直に「私は例外処理に詳しくないので、休日使って調べてみる。ごめん」
と言ってしまいましたが、上司として言っちゃダメな事なんだろうなぁ…。
378 :
デフォルトの名無しさん :03/03/23 18:31
>>376 理想の上司とは「これは仕様だ」といって突きすすむような人のことだよネ。
380 :
デフォルトの名無しさん :03/03/23 19:56
>>378 ありがとうございます。とても勉強になりました。
(もしかしてここに書いてある内容は常識だったりしますか…?)
>>379 正しい知識を基に(環境要因を含めて)妥当な判断を下せて
(多少強引でも)突き進める人、が私的に理想の上司かなぁ。
ネタにマジレスと知りつつも。
理想の上司ってのは言語に詳しい必要ないからなぁ。
ここはマ板ですか?
383 :
デフォルトの名無しさん :03/03/25 00:15
すみません。 (void **)&pDirectInput という表記は一体どういう意味なのでしょうか。void型って型が指定されてないんですよね? それの2次元配列?にキャスト?ポインタのアドレスを2次元配列にキャスト?意味わからないです。。
pDirectInputへのポインタを、void*へのポインタへキャスト。
>>383 void ** はvoidへのポインタのポインタ。但し、void *型はオブジェクトの
大きさがわからないので、アドレス演算をしようとしたり、実体化しようと
するとエラーになる。明示的なキャストが必要。それ以外は普通の
ポインタへのポインタと同じ。
386 :
デフォルトの名無しさん :03/03/25 00:45
ポインタに更にポインタがいる場合ってどういう時ですか?
>>386 具体的な例って言うと、ポインタ配列をソートしたりする必要がある時
かなあ。
389 :
デフォルトの名無しさん :03/03/25 01:04
あぁ、なるほど。ありがとうございました。二度とこねぇよ!
>>389 その場合はこのAA貼れ。かっこいいぞ。
┌─┐
|も.|
|う |
│来│
│ね│
│え .|
│よ .|
バカ ゴルァ │ !!.│
└─┤ プンプン
ヽ(`Д´)ノ ヽ(`Д´)ノ (`Д´)ノ ( `Д)
| ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U
〜 〜  ̄◎ ̄ . ̄◎ ̄  ̄◎ ̄ ◎−>┘◎
ヽ(`Д´)ノ モウコネエヨ!!
( ) ウワァァン!!
/ ヽ
392 :
デフォルトの名無しさん :03/03/25 01:09
┌─┐ |あ.| |り | │が│ │と│ │よ .| │っ .| バカ ゴルァ │ !!.│ └─┤ プンプン ヽ(`Д´)ノ ヽ(`Д´)ノ (`Д´)ノ ( `Д) | ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U 〜 〜  ̄◎ ̄ . ̄◎ ̄  ̄◎ ̄ ◎−>┘◎ ヽ(`Д´)ノ オレイヲイウノガテレクサイゼ!! ( ) ウワァァン!! / ヽ
argvが手っ取り早い例かと
394 :
デフォルトの名無しさん :03/03/25 01:11
文字列の配列→やっぱり2次元配列の事なのね
>>394 C++的にはstd::vector<std::string>だろ。
文字列の配列ごときはコードに直接表現できる。
Cとは違うのだよ、Cとは。
396 :
デフォルトの名無しさん :03/03/25 01:21
悲しいけどここC++スレなのよねぇ
Cにmany improvementsをプラスしたものがC++。だからCでできる 事はC++でも大抵できる。敢えてそれをしないのは、それに替わる もっといい手段が提供されてきたから。
399 :
デフォルトの名無しさん :03/03/25 05:59
質問です。 フルスクリーン動作のゲームをWindowで動作させる監視プログラムを作りたいのですが ゲームそのものの画面の解像度は変えずに ディスクトップが1280x1024動作、ゲームが640x480動作を考えてまして 監視しているプログラムだけの画面を切り替えるようにするにはどうすればよいのでしょうか? ちょっと、わかり難い質問でスミマセン。。。
1.DirectXのウインドウモードでフルスクリーンをエミュレートするプログラムを書く 2.該当アプリのDirectX呼び出しを乗っ取る 3.こんな質問をしているようじゃ絶対作れない 4.そもそもスレ違い
401 :
デフォルトの名無しさん :03/03/25 06:39
>>400 やっぱりDirectXの機能を使うしかないですか・・・
仮想的に画面を作るという方法が楽なのかな・・・
>>395 std::stringのcopy constructorとoperator=がnothrowだと
保証してくれるなら使ってやるよ。
>>402 強い保証が欲しいなら自分でラップすればいい。
コピーしてswap使うとか、boost::shared_ptr使うとか、いろいろあるだろ。
404 :
デフォルトの名無しさん :03/03/25 10:39
質問です。 (ファイル"A.h") namespace Aspc { class Aclass { Bspc::Bclass Bobj; }; }; ---------------------------------- (ファイル"B.h") namespace Bspc { class Bclass { Aspc::Aclass Aobj; }; }; こんな関係のヘッダをインクルードしようと思ったのですが どうしたものだかと悩んでしまいました。 ご教授お願い致します。
>>404 'class'が見えてなかったよ・・・ごめん。
前方宣言しる。
>>404 namespace Aspc {
class Bclass;
class Aclass {
Bspc::Bclass Bobj;
};
};
----------------------------------
(ファイル"B.h")
#include "A.h"
namespace Bspc {
class Bclass {
Aspc::Aclass Aobj;
};
};
>>404 あぁあ、classの中でもやっぱりインスタンスには前方参照は効かんぞ。
そのクラス定義は、論理的にムリだ。
前方宣言+auto_ptrくらいにしとけ。
スレ汚し、まことにもうしわけない。
>>405 うあ やはり無理があったですか。
どうやっても片方で名前空間が通せませんでした。
了解しました。構成を見直してみます。
ありがとうございました。
Aの中には必ずひとつのBを入れてください。 Bの中には必ずひとつのAを入れてください。 さぁ、Aをひとつ、くださいな。
>>404 ワラタ
sizeof(Aclass)はいくつになるんだよ。
namespace Aspc { class Bspc::Bclass; class Aclass { Bspc::Bclass& Bobj; }; }; ---------------------------------- (ファイル"B.h") namespace Bspc { class Aspc::Aclass; class Bclass { Aspc::Aclass& Aobj; }; }; 実体はコンストラクタで作られ
404です 皆さま レスありがとうございますー
結局、どっちみち相互依存が大きいので
独立させる意味なしと判断しますた。
namespace Aspc {
class Aclass;
namespace Bspc {
class Bclass {
Aclass Aobj;
};
};
class Aclass {
Bspc::Bclass Bobj;
};
};
とりあえず今回はこれで回避。
>>412 試してみましたが、やはりどうしても
先に読まれるほうの class Bspc::Bclass; のあたりで
Bspcが未定義になってしまうかと思われます。
>>410 あー、上記は例を簡略しすぎてアレな関係になってますが
実際はクラス同士を持ち合っているわけではないのでご心配なく。
>>413 ほんとは AclassとBclassって、
お互いのポインタか参照を持ち合ってるのか?
たびたびすみません
>>414 もちょい正確にすると、
("A.h")
namespace Aspc {
class Aclass {
void UpdateA();
void FromBclass( データ );
Aspc::BaseClass* pBase;
};
class BaseClass { //実体保持
void Update(); //AobjとBobjの更新ループ
private:
Aspc::Aclass Aobj[n];
Bspc::Bclass Bobj;
};
};
--------------------------------------
("B.h")
namespace Bspc {
class Bclass {
void UpdateB(); //任意のpAclassにデータを投げる
Aspc::Aclass* pAclass[n];
};
};
がんばって要約するとこんな関係ぽ。
名前空間とかおぼえたてで プロトタイプ宣言で
どうにかするのかなと思い。
やっぱりBclassはAspcなしでは動かさないので、
Aspcに内包することにしました。お騒がせしましたー
----ファイルcmycl.h---- class mycl{ public: static int i1; }; ----ファイルcmycl.cpp----- #include"mycl.h" int mycl::i1 = 1; ----ファイルtest1.cpp---- #include"iostream.h" #include"mycl.h" int main(){ mycl c; cout << c.i1 << "\n"; return 0; } とやって、 bcc32 test1.cpp cmycl.cpp とコンパイルしたのですが、エラーが出てしまいます。 静的メンバ変数を使えるようになりたいのですが、ご教授お願いします。
>>416 どんなエラーが出たのか書け。
あと、インクルードするファイル名を確認しろ。
419 :
デフォルトの名無しさん :03/03/25 22:34
VC++6.0,Winでのチラつかない描画に関する質問。 オフスクリーン描画、WM_PAINTで転送がメジャーだろうけど もっとかんたんな方法ない?フラグ立てるだけ、とか。
ぬるぽを使ってはいけない理由を詳細に説明してください。
423 :
デフォルトの名無しさん :03/03/25 23:38
ぬるぽって何? nullっぽい って言う意味?
とりあえずここではバルスよりも禁句とされている
なるほど・・・ ヌルポインタのことか あまり使わない単語だから気づかなかった(汗
( ´∀`)<ぬるぽ
429 :
国語が足りない奴 :03/03/26 08:03
struct BMP{ struct BMP BP; }; この構造体をエラーなしにしたい時はどうすれば いいですか? でるエラーは「struct BMPは未定義」です。
>>429 メンバ変数をstruct BMP *BP;にする。
431 :
デフォルトの名無しさん :03/03/26 18:53
今、Borand C++ Compiler 5.5を使い独習C++で勉強しているんですが、 コンパイルすると次のようなエラーが表示されます。 致命的エラー F1003 c:\Boland\Bcc55\include\stdcomp.h 5: error 指令: Must use C++ for STDCOMP.H 凄く簡単な下記のようなソースでもコンパイルする際にエラーになります。 一度再インストールしてみましたが、無理でした。 何か対処法はないのでしょうか? #include <iostream> using namespace std; int main() { cout << "Hellow world!\n"; return 0; } よろしくお願いします。
filename.cpp
>>432 解決しました。本当にありがとうございます。
ついCの癖でそのまま.cにしていました。
434 :
デフォルトの名無しさん :03/03/26 22:47
質問というかなんというか、ちょっと気になったので、 ご意見が伺えればと思います。 たとえば、 class Hoge { public: hoge_t value() const { // 初期化してないときは、ファイルから読み込んだりして // メンバを初期化したい。 // でも、いつ使うか分からないのでコンストラクタでは // 初期化したくない。 // でも、意味的には絶対にconst なのに。。。 } }; みたいな、メンバを作りたくなったことってないですか? そんな場合ってどうしてます? 1. しょうがないので、constをはずす。 2. Hoge* h = (Hoge*)this; 3. グローバルな領域に、いつも触れるオブジェクトをおいておいて、 それを参照する。 4. その他 くらいですかね? 1. は、そのためにconstを使わないというのが、のちのち別の弊害を 呼びそうで嫌です。 2.や3.は、このクラスのconstが信用できなくなりそうで嫌です。 結局、オーバヘッドが気になるけど、コンストラクタで初期化して しまったのですが、なにか良い解決方法ってありますか? よろしくです。
>>434 // 初期化してないときは、ファイルから読み込んだりして
// メンバを初期化したい。
// でも、いつ使うか分からないのでコンストラクタでは
// 初期化したくない。
// でも、意味的には絶対にconst なのに。。。
constの意味解ってますか?
>>434 キャッシュ要素やレイトバインディング用には
mutableキーワードが使えるけど
437 :
デフォルトの名無しさん :03/03/26 23:05
>>435 ちゃんと読んでくれ。
>>436 そんなものがあるとは、しりませんでした。
なかなか、知らないことってあります。
でも、使い方は難しそうですね。
コーディング規約で使うなとか、書かれそう。
非const のメンバ関数の評価を必要があるまで行わない、みたいな
機構をコンパイラがサポートしてくれたら、、、
とつくづく思います。
438 :
デフォルトの名無しさん :03/03/26 23:49
>>436 そんな便利なものが、、、と思ったが使い方が難しいですね。
結局、コーディング規約で使用不可になるのも時間の問題かと、、、
必要なときだけ評価してくれるメソッドが作れる仕様になって
くれないかな。と思うよ。
>>437 いまいちいみがわからn。
ちょっと解説してくれ
const版と非const版をオーバーロードするんじゃダメなのか?
441 :
デフォルトの名無しさん :03/03/27 00:40
そーでなくって、 たとえば、円周率の1万桁目を返すメソッドがあったとする。 毎回、1万桁を計算するのは嫌なので、必要なときに計算したい。 これは、意味的にはconstであると考えられる。 もちろん、コンストラクタで計算するというのもありだが、 もし使わないとしたら、計算時間がもったいない。 どうしよう、、、、 という話です。
442 :
デフォルトの名無しさん :03/03/27 00:47
>>438 使い方が難しいといったのは、constという指定では、本来メンバに
副作用があってはいけないと思います。
が、mutableでは、それができることになります。
ちょうど、friendのようなもので、よほどドキュメントが整備されて
居ない限り、動作を追うのが難しくなります。
本来、副作用を極小化することによって、想定できない動作を防ぐために
classやconstというのはあるはずですから。
そこで、たとえば副作用があってもいい、コンストラクタや非constの
メソッドを呼び出したときに、その動作のうち、時間がかかってしかも
使われないかもしれない初期化のコードなどの評価を必要があるまで
遅延させることができたなら、より安全に記述できるんじゃないかな
って思ったって訳です。
面罵のconstとmutableキーワードを言語仕様から取っ払え。
>>442 ==441なのか?
mutableが最も威力を発揮するような場面なら
使うのが吉かと。
445 :
デフォルトの名無しさん :03/03/27 01:00
>>444 442=441=.... です。
確かに、素直に使うのが吉なような気はしますが、、、、
friendと同じように、禁止されるんでないかなーという
一抹の不安が。
>>445 禁止されたら邪悪な方法を使え!
class AAA {
int a;
int* p;
public:
AAA() : a(0), p(&a) {}
void asd(int i) const { *p = i; }
};
素人さんにはお勧めでき(以下略
いや、ま、 p = new int; ってやれば邪悪でも何でもないんだけどね、、、
448 :
デフォルトの名無しさん :03/03/27 01:32
んー、難しいですねぇ。 というか、 int* p => int const * const p; という型に変換されないあたりが、なんか仕様的に嫌に思えてきました。
449 :
デフォルトの名無しさん :03/03/27 05:33
C++ではvoid *は使わないんですか?(T.T)
450 :
デフォルトの名無しさん :03/03/27 06:11
>>449 void *って何につかうの?
通常目的の型のポインタを使うと思いますが。
> int* p => int const * const p; int f( int* p ) { int const * const q = p; return *q; } 変換できるぞ。
452 :
デフォルトの名無しさん :03/03/27 07:01
friendやmutableに気をつけろってんならわかるが、 禁止までされてる場合の理由ってどうなってんですか?
>>434 class Hoge {
public:
hoge_t value() const {
return GetHogeT();
}
private:
hoge_t& GetHogeT(void){
static hoge_t tmp;
return tmp;
}
};
じゃだめなのか?
(メンバの変わりに常にGetHogeTを介して操作する)
>>453 Hogeインスタンス複数作ってあぼーん
>>434 そういう場合は
Hoge* pThis = const_cast<Hoge*>(this);
pThis->メンバ = 値
なんてするのがセオリーかな。
第2の選択肢として変更するメンバをmutable宣言する、ってのもある。
mutableは「決してconstではない」という意味で、全てのメンバ関数から
変更できてしまうので、今回の例では適切ではないだろう。
要約すると、概念的にはconstだが、メンバ変数の値を変更する必要がある場合
1.1部のメンバ関数でしか値を変更しない、または値の変更が例外的な場合は
const_cast<Hoge*>(this) を使う。
2.それ以外、つまり多くの関数で値を変更する場合や値の変更が例外的でない
場合は該当メンバ変数をmutable宣言する。
456 :
デフォルトの名無しさん :03/03/27 10:20
volatileつけるとboolが呼ばれるみたいなんだけど なぜなんでしょうか? #include<iostream> using namespace std; void test(char*) { cout << "char*" << std::endl; } void test(bool) { cout << "bool" << std::endl; } int main() { test(static_cast<char*>("a")); //char* test(static_cast<volatile char*>("a")); //bool test(static_cast<const volatile char*>("a")); //bool }
>>456 引数を明示的にvolatile char*と宣言するとちゃんと呼び出されるので、
volatileを付けたことによりchar*とはマッチしなくなり、次にポインタが
暗黙的にboolに変換されたためと思われる。
void test(char*)
{
std::cout << "char*" << std::endl;
}
void test(bool)
{
std::cout << "bool" << std::endl;
}
void test(volatile char* p)
{
std::cout << "volatile char*" << std::endl;
}
void test(const volatile char* p)
{
std::cout << "const volatile char*" << std::endl;
}
int main()
{
test(static_cast<char*>("a")); //char*
test(static_cast<volatile char*>("a")); //volatile char*
test(static_cast<const volatile char*>("a")); //const volatile char*
}
458 :
デフォルトの名無しさん :03/03/27 11:34
>>449 スレッドへの引数に使う。
Cでもいえることだが。
C++は強く型付けされてるとよく聞くけど 暗黙的な変換に関しては なんかしっくりこないことが多い気がする。 一般の関数で行われる標準変換も便利といえば便利だが、 ときには必要もない時もあるし、 動作を変更したいときだってあるはずだと思う。 となるとtemplateと関数オブジェクト使えってことになるわけだが、 それはそれで面倒な訳だが...。
>>459 volatileが勝手に外れるのがしっくりくるのか?
>>460 それもそうだねw
勝手にはずれて一見正常に動いてるように見える恐さと
見当違いなものが呼ばれてる恐さの攻めぎあい...。
462 :
デフォルトの名無しさん :03/03/27 14:00
struct X { int f(); int f() const; int f() volatile; int f() volatile const; }; int f( X volatile const & x ) { return x.f(); }
というか、そもそもbool<->intの変換とかtype*->boolの変換さえなけりゃ問題ないんだろうに。
【フジテレビ】今夜9時〜10時54分
『FNS最高視聴率祭り国民のチャンスライン電話でもらえる1000万』
という番組が放送されるわけだが、この番組は解答者(ゲスト)が
クイズに答えるのだが、どの解答者がその問題を正解してるか視聴者が
スタジオに電話し答えるわけだ。そして、そこに2ちゃんねらーを出演させようじゃないか!
■手順■
1.番組中に公表される番号に電話する。
2.運良くつながる(つながらない場合は根気よくかけ直す)
3.司会者が「もしもし〜」などと切り替えしてくる。
4.大声で「オマエモナー」と叫ぶ。
5.あとは賞金ゲットのために頑張ってください。
※このレスを見かけたら、できれば5つ以上のスレに貼り付けてください。
【企画本部】
http://that.2ch.net/test/read.cgi/event/1048752014/l50
466 :
デフォルトの名無しさん :03/03/27 22:32
extern "C"の使い方がよくわかりません。 たとえば、標準ライブラリでhoge.hというヘッダがあってもchogeがない場合は、 extern "C" { #include <hoge.h> } とするのでよいでしょうか?
× 標準ライブラリ ○ 標準っぽいライブラリ
>>466 extern "C" は主にC++の名前マングリングを防止するためにある。
Cで書かれたライブラリをリンクする場合はインポートする関数を
extern "C" で囲まないとリンカエラーになる。
>>468 ありがとうございます。
そこまではわかるんですが、それで、
>>466 は正しいのでしょうか?
そういうコードを見たことがないので、不安になったのです。
ヘッダをインクルードする時でなくて、ヘッダそのものに、
#ifndef __cplusplus
extern "C" {
#endif
// 本体をここに書いてある
#ifndef __cplusplus
}
#endif
としてあることが多いような。
されてないなら
>>466 のようにするしかない。
ifndef でなくて ifdef でした。 すまん。
>>471 >>472 ありがとうございます。
しかも即レスで。
このスレはレベルが高いので助かりますです。
( ´∀`)<ぬるぽリング
まんぐろんぐ に いんぽーと か ここは卑猥なインターネットですね!!!
ろんぐ→りんぐ (-_-)ウツダシノウ ダンッ ──< ===E∩三⊂∀・ )
478 :
デフォルトの名無しさん :03/03/28 11:30
クラスを引数とすると、そのクラスの新しいインスタンスを返すような メソッド(いろいろなクラスのインスタンスを管理するクラスで) を作る方法を教えてください。
479 :
デフォルトの名無しさん :03/03/28 11:35
仮想関数を一つも持たないクラスAから派生クラスを作成する場合、 クラスAのデストラクタはvirtualでなければならないのでしょうか?
>>479 class A{};
class B : public A{};
A *a=new B;
delete a;
とするようなことがあるのならvirtualにする必要がある
わかりにくくてすみません。 こんな感じのものを作ってみました。 Factoryクラスがオブジェクトを管理しています。 クライアントがcreateメソッドを呼び出すと、 指定したインスタンスが得られます。 ifの羅列になってしまうのですが・・・ class Factory{ private: std::list<Object*> m_obj_list; public: Object* create(const type_info& a_type){ Object* nobj; if(a_type == typeid(Integer)){ nobj = (Object*)new Integer; }else if(a_type == typeid(Symbol)){ nobj = (Object*)new Symbol; }else{ throw new UExceptionNotSupportType; } m_obj_list.push_back(nobj); return nobj; } }
>>482 まだいまいちよくわからないのだが
class Factory{
private:
std::list<Object*> m_obj_list;
public:
template <class T>
Object* create(){
Object* nobj=new T;
m_obj_list.push_back(nobj);
return nobj;
}
}
Factory f;
f.create<Integer>();
これじゃだめなのか? なんの役に立つんだこれ?
>>483 なるほど。ありがとうございます。
インタプリタ作成中なんですが、オブジェクトの管理をする部分です。(GCとか)
>>479 n個のクラス C0, C1, C2 〜 C(n-1)があり
クラスCm(1<=m<n)はクラスC(m-1)より派生しているとする
また、クラスCmのデストラクタはvirtual宣言されていないものとする
0 <= a < b < nのとき以下のポインタpaがあるとき
Ca* pa = new Cb;
delete pa; によって
C0のデストラクタがvirtualであるときは
クラスCbから継承ツリーを逆にたどりC0までのデストラクタが順に呼び出される
C0のデストラクタがvirtualでないときは
クラスCaのデストラクタのみ呼び出される
オブジェクトCx(0<=x<n)がデストラクトされるとき
デストラクタがvirtualであるときは
クラスCxから継承ツリーを逆にたどりC0までのデストラクタが順に呼び出される
デストラクタがvirtualでないときは
クラスCxのデストラクタのみ呼び出される
デストラクタを正しく呼び出したいのであれば、virtualを付けなければならない。
>481 >485 まさしく481の例のようなことをしたかったわけです。 なるほど、よくわかりました。 ありがとうございました。
>>484 関数をこうしたほうが使いやすいかな
template <class T>
T* create(){
T* nobj=new T;
m_obj_list.push_back(nobj);
return nobj;
}
488 :
デフォルトの名無しさん :03/03/28 16:59
std::string::c_str() は例外を出す可能性があるから、 きちんと例外処理したほうが良いというのは本当ですか?
>>484 のObjectって何?Javaかとおもっちゃった。
const修飾子について教えて下さい。 やりたいことはMAX.cppのMAX_SIZEを1個変更する事で すべてのクラスのMAXサイズを変更できるようにしたいのです。 [AAA.cpp] extern const int MAX_SIZE ; class AAA { chars[MAX_SIZE]; }; [BBB.cpp] extern const int MAX_SIZE ; class BBB { char s[MAX_SIZE] ; }; [MAX.cpp] const int MAX_SIZE=256 ; んでこれらのソースをコンパイルすると 「定数式が必要です。」でエラーになります。 #defineを使う方法もあるのですがデバッガに かけた時に変数名が消えてしまうのでやりたくないのです。 constとexternの使い方まちがってますか? 環境はVC++6です。
C++だとconstは内部リンケージじゃなかったっけ?
>>490 こりゃ無理だろ
[max.h]
const int MAX_SIZE=16; // or enum { MAX_SIZE = 16 };
[a.cpp]
#include "max.h"
class A { char chars[MAX_SIZE]; };
[b.cpp]
#include "max.h"
class B { char chars[MAX_SIZE]; };
これでどう?
enum使え。
494 :
デフォルトの名無しさん :03/03/28 20:09
class Hoge { public: static int c; }; int Hoge::c = 100; int main () { Hoge *pHoge = NULL; cout << "c = " << pHoge->c << endl; return 0; } これ動くのだけれど保証されていますか。 お願いします。
>>494 インスタンスのメンバには一切触れないから大丈夫だと思うが
すなおに
cout<<"c = "<<Hoge::c<<endl;
としてはだめなのですか?
今日からC++始める。 図書館で独習C++第3版と 1000万人のコンピュータ科学1入門編気軽にプログラミング っての借りてきた。 BCPadで作ってとGCCでコンパイルします。 よろしくお願いします
>>496 いばらの道になるかもしれませんが、ガンガってください
491さん 492さん 493さん どうもありがとうございます。 コンパイル通りました。 const修飾された変数は、格ソース固有の持ち物 であって外部に見せる(公開)する事はできない。 よって、*.hにconst変数を記述し各々のソースに 取込んだとしても、各ソースにconst変数が確保 される。 と理解しましたが合ってますか? s/格/各/
499 :
デフォルトの名無しさん :03/03/28 23:44
VC++の質問もここでいいのかな?? MFCでアプリケーション作成しているのですが、midiを流す方法がわかりません。 DirectXの知識がないので、APIを使えばできるとか聞いたのですが。 まだWindowsプログラミングは初心者なものでどうしていいか・・・ アドバイスお願いします。
>>499 スレッド一覧の検索ぐらいしようよ・・・
だからスレ違いって言っちょるだろが!
502 :
デフォルトの名無しさん :03/03/29 00:00
windows 用のソースで class xxx { public: union { struct { xxx xxx; // xxx は他のクラス float xxx; }; struct { float xxx, xxx, xxx, xxx; }; float xxx[4]; }; . . . てのがありまして、これを linux の g++ でコンパイルすると、 struct の 所で、
(つづき) anonymous class type not used to declear any object と言われます。それで struct の定義の後に とりあえず s1, s2 と名前を つけたら、今度は、 member "struct quat::{anonymous union}::{anonymous} quat::{anonymous union}::s1" with constructor not allowed in union と言われました。 それでさらに union に u1 と定義してみましたが、同じエラーになりました。 これってどうすれば通りますか?
最近はじめったばっかりで"Hello world"からはじめてたんですけど。 インクルードファイル"stdio.h"が開けないってエラーでました。 #include<stdio.h> main() { printf("Hello World\n"); } 初歩的すぎてごめんなさい。
はいはい、ネタ質問は他所でどうぞ。
>>504 これと
#include <stdio.h>
これの違い調べてみ
#include "stdio.h"
そしたらついでに分かるから
お手上げでつ(´Д`;) ""は文字列・・・? <>・・・?
( ゚д゚) リファレンス読むとかしないわけ?
マジで初心者なんで。。。 なんかここにいるべき人間ではなさそうなので・・・逝ってきます・・。 でもやれるだけはガムバルつもりでつ。
#include <iostream>で逝っとけ。もしくは #include <iostream.h>
>>504 ヘッダーファイルへのパスが通ってねーんだよ!ヴォケが。
513 :
デフォルトの名無しさん :03/03/29 08:50
list201.cppのソース #include<stdio.h> #include<stdlib.h> int main(int ac, char *av[]) { int n; printf("引数 %d 個\n", ac); if(ac != 1){ n = atoi(av[1]); printf("値 %d \n", n); return n; } return 999; } list202.cppのソースが #include<stdio.h> #include<stdlib.h> void main(int ac, char *av[]) { int n; if(ac != 1){ n = system(av[1]); printf("戻り値 %d \n", n); } } としたときに、list202 list201とコマンドを実行したとき 戻り値 999 と表示されるはずなのに 戻り値 0 となってしまいます。どうしてでしょうか?
>>513 当然。system()は実行したコマンドの戻り値を返すわけではない。
「コマンドプロセッサ」の戻り値を返す。だからコマンドプロセッサが
正常に起動されたら0を返す。
それからとても激しく環境依存です。
515 :
デフォルトの名無しさん :03/03/29 10:50
>>513 これはc++ではないですね。
--- a1.c ---
int main (int argc, char *argv[]) {
if (argc != 1)
return atoi (argv[1]);
return 0;
}
--- a2.c ---
int main (int argc, char *argv[]) {
if (argc != 1)
printf ("%x\n", system (argv[1]));
return 0;
}
のとき
./a2 './a1 0' ---> 0
./a2 './a1 -1' ---> ff00
./a2 './a1 3' ---> 300
コンストラクタのについて教えて下さい。 以下のソースをコンパイル&リンクすると コンストラクタ(2)がリンク時に「 LNK1120: 外部参照 1 が未解決です。」 となり、リンクできないのですが何故なのでしょう? コンストラクタ(2)の本体(という言い方でいいのかな?)をclass{ } 内に持っていくとリンクまで通ります。なんでかなぁ? [aaa_class.hpp] class aaa { public : aaa() { cout << "コンストラクタ(1)が呼ばれた\n" ;} aaa(int size,char *s) ; }; [aaa_class.cpp] aaa::aaa(int size,char *s) { cout << "コンストラクタ(2)が呼ばれた\n" cout << size << '\n' ; cout << s << '\n' ; } [main.cpp] int main(int ac,char **av) { aaa d1; aaa d2(10,"ABCDEFG") ; }
>>516 aaa_class.cppがコンパイルされてないとか
>>516 一応、[aaa_class.cpp] と[aaa_class.hpp]に using namespace std; を書いておけ
うちではコンパイル通るぞ
激しくミスった 「ありがとう」と書くつもりやったんやけどクソレスになるから 「やめる(C)」をクリックしようと思ったらそれが「書(ry
521 :
デフォルトの名無しさん :03/03/29 19:59
パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ パシャ ∧_∧ ∧_∧ ∧_∧ ∧_∧ ∧_∧ ∧_∧ ( )】 ( )】 ( )】 【( ) 【( ) 【( ) / /┘ . / /┘. / /┘ └\ \ └\ \ └\ \ ノ ̄ゝ ノ ̄ゝ ノ ̄ゝ ノ ̄ゝ ノ ̄ゝ ノ ̄ゝ
522 :
デフォルトの名無しさん :03/03/30 00:38
メンバーが変数だけならstructを使いますか?
>>522 というか全部のメンバを初めからpublic属性にしたい時にstructを
使うと楽。public: とタイプせずに済む。
一時的にしか使用しないクラスって new する意味ってあるの? void func() { std::string str = "onigiriwassyoi"; puts(str.c_str()); } void func() { std::string* str = new std::string("onigiriwassyoi"); puts(str->c_str()); delete str; } の違い。
変数名の最初に _つけちゃ駄目って聞いたけど何で?
_で始まって大文字が続く識別子はC++の予約後 __で始まる識別子はC++の予約後 _で始まる識別子はCの予約後 いちいち説明するのが面倒なので _で始まる識別子は使うなと言ってるだけ 変数名以外にも#define識別子とかにも使うなよ
>>526 「処理系の実装者のために予約されている」だな。
ちなみに __ は始めだけじゃなくて、それを含む名前全部だったはず。
528 :
デフォルトの名無しさん :03/03/30 04:09
先頭がアンダースコアになっている名前は、実装や実行時環境の特別な機能のために予約されているので、アプリケーションプログラムではそのような名前を定義しないようにすべきである。 禿げ第三版日本語版より。
529 :
デフォルトの名無しさん :03/03/30 05:18
>>526-528 Σ(゚Д゚)
使いまくってた。
>禿げ第三版日本語版より。
って何の本?
詳細キボンヌ。
>>529 禿げ = Bjarne Stroustrup
つまりはプログラミング言語C++第三版のこと。
531 :
デフォルトの名無しさん :03/03/30 06:05
>>530 情報ありがとう。
7000円は、高すぎる。
EffectiveC++とC++FAQを買って
ある程度読んだ俺には
買う必要は、ありますか?
とりあえず、明日本屋で流し読みしてみる。
532 :
デフォルトの名無しさん :03/03/30 06:13
>>530 ストラウストラップ先生を禿げと呼んでいるのか。
いいセンスだ。
533 :
デフォルトの名無しさん :03/03/30 06:15
漏れもK&RもC++も読んだことないなぁ 規格書はよく見るけど
それはそれでイイ
4人のギャングに騙されると、メンバに _ を付けてしまう罠 でも確かに m_ ってダサイよなぁ、とか思ったりも
>>536 _を前につけるのはC/C++規格違反だから
後ろに付けるっていう案もあるが、すごい違和感あるよな
>>537 後ろはあかんね。前が駄目なんで一時期やってたが、どうも合わない。
やっぱり最初(変数の)に情報が来ないと、認識しづらいのかな。人間って。
>>538 そうか? 俺はもうメンバ変数の後ろにアンダーバーが無いと
なんか落ち着かないのだが
_(([a-z])+[_A-Z]*)? はC++で使ってもよいことになってたはず。 Cでは駄目だが トニカク説明するのが面倒だから _で始まるのは駄目と いうのは同意 後ろに_をつけるのは慣れた。
なんかちょっと変。 _ 自身と _の次に英小文字か来るのはOKといいたかった
_asm __asm もokなんですか?
後ろにアンダースコアを2つ付けてるYO。変数名・関数名にも普通に アンダースコア使っているから1つだとどうにも目立たず。
>>545 うしろも駄目って事?「それを含む名前全部」てことだと n_files
みたいなのも駄目って意味にも取れるけど。
って違うね。
>>527 氏の言ってるのは _ から始まっていたら _hoge_
こういうのはだめだって意味じゃない? hoge_ hoge__ は問題ないと
思うんだけど。
>>547 [17.4.3.1.2]
Each name that contains a double underscore ("__")
or begins with an underscore followed by an uppercase letter (lex.key)
is reserved to the implementation for any use.
>>549 引用さんくすです。なんだかややこしい規則だなあ・・・。つまり正確には
アンダースコア2個は前だろうと後ろだろうと駄目で、アンダースコアから
始まる場合は次の文字が大文字でなければいい、もしくは後ろにのみ付ける
分には問題ないということですか。
ANSIの規則を書き換えると以下のようになる 規則1・アンスコで始まって、大文字またはアンスコが続く識別子は常に予約済み(全てのスコープ、全ての名名前空間で) 規則2・アンスコで始まる識別子はファイルスコープを持つ通常の識別し(関数、変数、typedef、列挙体定数)に対して予約済み もし安全重視の側に立つのならアンスコで始まる名前を付けてはならない しかし、次の例外を憶えて使っても良い アンスコで始まって数字か小文字が続く識別子を構造体/共用体のメンバや、 関数・ブロック・プロトタイプスコープでつかっても良い
つまりだ int _a;//NG void foo() { int _a;//OK } struct Foo { int _member;//OK int _Member;//NG };
553 :
デフォルトの名無しさん :03/03/30 15:11
ずっと前から謎だったんだが、STLportの実装で使われている名前が全部 これらの「実装のために予約」された名前になっているのはどういうわけだ?
なるほど、単純に _ の後に小文字が続けばいいというものでは ないってことですね。勉強になりますた。てか本当ややこしいな・・・。 後ろにのみアンダースコアは1個てのは、うまく網目掻い潜ってる というか、そこまでしてアンダースコアを使うか、というか(w
>>553 おれが思うにコードをわざと読みにくくしてるのでは?
単なる思い上がりでしょう。
正しく動くこととパフォーマンスと実装(コンパイラ固有の問題)を重視してるから、 規格を遵守することはさほど優先じゃないだけだろ。
STLの実装者は'実装のために予約された名前'を使う対象には入らないの?
>>558 それの答えがどうであれ、ローカル変数にまで予約された名前を使う理由にはならん。
>>551 構造体がありなら、クラスもありって解釈でいいかな。
だとすると…メンバに使える!!!(*゚∀゚)=3
どうなんだろ…。
>>561 ややこしい規格を持ち出さないと説明がつかなくなるからやめとけ。
typedef enum _E { HOGE0, HOGE1, HOGE2 } E; int foo( E e ) { return (int)e; } なんでこのコードが VC++ で通らないのか、やっと解ったよ
なんで?
最近それを知って _ をメンバの後ろに付けるよう矯正しますた。 最初は気持ち悪かったけど一日で慣れてしまった……。
>>563 typedef enum E { HOGE0, HOGE1, HOGE2 } E;
こう書けばいいのに・・・・
enum E {...};だけでイイだろ?
>>568 そうだ。ここC++スレだ。
Cならダメだだから。
「だ」が一つ多いし(鬱
>>567 Cって、列挙体のタグ名とtypedefのタイプ名ってかぶってもいいの?
>>568 うん、とりあえず、そんな風に修正したの。
「typedefとenum定義って同時にしちゃ駄目なのかなぁ。
VC++のバグかなぁ」
って思いながら...(←痛すぎ)
あ、いや、もともとCのコードを移植したものだったし、
>>574 ヒープより、フリーストアのほうがいいかも。
質問してもいいですか?
質問していいか質問していいですか?
質問して良いかの質問なんてしないでください
返答しないでください
581 :
デフォルトの名無しさん :03/03/30 22:20
template<typename T> void template_function(T){} struct {} global_instance_of_unnamed_struct; void f() {     template_function(global_instance_of_unnamed_struct); } こいつがコンパイルできてしまうのはバグですか?
これか? [14.3.1] -2- A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.
>>587 もっと具体的に言うと、
 のあとに、;が無いから。
...は!もしかしてwindowsだとふつうにみえるのか...
ん〜?どれどれ?  
なるほど、そうなのか。
WindowsつーかIEだな<実体参照の;がなくてもとおる。
592 :
デフォルトの名無しさん :03/03/31 00:47
593 :
デフォルトの名無しさん :03/03/31 07:56
C++の関数からCの関数を呼ぶときは、プロトタイプの前後に __cplusplusなんとかってのをつけとけばいいけど、 逆にCからC++の関数を呼ぶときはどうすればいいの?
C++の修飾名でcallする。
595 :
デフォルトの名無しさん :03/03/31 08:06
手を挙げればいい
C++でコンパイルする。
COM+/DCOM
598 :
デフォルトの名無しさん :03/03/31 08:30
>>596 ヘッダとライブラリしかない場合は?
C++の就職名でcallか〜?
599 :
デフォルトの名無しさん :03/03/31 08:34
#include <stdio.h> char *nanashi[6]={"逝ってよし","(・ё・)クサー","来るな","あっちいけ","吊れ"}; void main() { int i; for (i=1;6<=i;i++) { printf ("デフォルトの名無しさん %d",nanashi[i]); }; };
違う違う。 ループに一度も入らない。
>>598 ↓これでいける?
// cxx_tunnel.h
#if defined(__cplusplus)
extern "C" {
#endif
void c_func();
#if defined(__cplusplus)
}
#endif
// cxx_tunnel.cpp
#include "cxx_tunnel.h"
#include "cxx_lib.h"
void c_func(){ cxx_func(); }
// source.c
#include "cxx_tunnel.h"
void func(){ c_func(); }
>>603 #id defined() はANSI-Cから取り入れられた構文なので、
新しい人はこちらの方を好んで使う人もいる。
正直、どうだっていい。
つまらん間違いだけど ×#id defined() ○#if defined() typoですた。
Cスレで質問していたのですが、こちらにも流れてきました…
http://pc2.2ch.net/test/read.cgi/tech/1048995232/151- C++なら、構造体の宣言は
struct Foo;
ですむので、関数の宣言でも
struct Foo;
void func(Foo *f);
というぐあいに、(実体を書かずに)宣言だけですませることができます。
これでコンパイル依存が減って作業がはかどります。
これをCでやるにはどうすればいいのでしょうか?
typedef strct { /* ... */ } Foo;
といったぐあいに他のヘッダでFooを定義しているときに
他のヘッダで
extern typedef Foo;
void func(Foo *f);
とできるのでしょうか?
タグ名を使って
extern struct Foo_tag;
void func(struct Foo_tag *f);
と冗長(?)にするの?なんかやだなぁ
>>607 なぜC++のスレでCの質問をするのでしょうか。
>>608 Cスレで質問したとき、どうも、コンパイル依存について
あまりふれられずに話が進んでしまっているようなので…
C++だったら、「Effective C++」の34項が
とても有名だと思うので、こちらでも質問させて
いただきました
これをC版のstructでするにはどうするのでしょうか?
>>607 void foo(struct Foo *);
typedef struct Foo
{
int i;
} Foo;
void foo(struct Foo *f){}
はいどうですか?
>>610 > void foo(struct Foo *);
Fooって何?そんなもの知らない。
>>612 Fooの定義をする前にFooという名前を使ってはいけないだろ。
それとも上にまだ何かあるのか?
>>609 CでやるならCの流儀に従え
いやならやめろ
>>613 いえ、上には何も無いですよ
void foo(struct Foo *);
でsturct Fooと書いてあるからFooは構造体の名前だということがわかるため
前宣言はいらないと思っていたのですが・・・ひょっとして駄目なのですか?
ちなみにVC7ではコンパイルできます
CでもC++でも関数引数内で型の定義は出来ない。 あらゆるユーザ定義型とユーザ定義型へのポインタ、参照は それを別の宣言、定義で使用するまえに宣言しておかなければならない。 struct Foo; void foo(struct Foo *); で足りるんだからそうしとけ。 K&RでもARMでもなんでもいいから宣言と定義の項を悟りをひらくまで 読み続け呂。
gccじゃどうやってもコンパイルできないが・・・
>>617 読みました、駄目みたいですね。
VCでコンパイルできるもんだから勘違いしてました。
struct Foo;
void foo(struct Foo *);
typedef struct Foo { int i; } Foo;
void foo(struct Foo *f){}
じゃあ、これで
>>617 610さんと私で、ごちゃごちゃしてますが…(^^;
617さんは私におっしゃっているのでしょうか?
私は、宣言と定義について、勉強が足りないです。
614さんがCでやるならCの流儀で…とおっしゃってますが
やはりそうなのでしょうか…
タグ名を使うべきなような気がしてきました。
typedefはしない方が良さそうな…
>>620 Cスレの151です。名前をまちがえました
いい加減スレ違いだからおわり typedef struct tagFoo Foo; void foo(Foo *);
624 :
デフォルトの名無しさん :03/03/31 22:41
冗長なexplicitって無害?
本当にexplicitにしたいものがどれだか分からなくなるのが問題なら、有害。
>>623 スレ違いが過ぎたようなので、終わります
たくさんアドバイスをしてくださって
どうもありがとうございました
>>625 なるほど。
私は基本的に全部explicitにしたい派なので、その点については無問題です。
いままで引数を増やしたときはこまめにexplicitをはずしていましたが、
これからはつけっぱなしにしてみます。
628 :
デフォルトの名無しさん :03/04/01 01:13
NULLを返す(ような)コンストラクタって作れますか? A *a=new A(); if(a==NULL){ puts("Aの作成に失敗"); } ってなことをしたいのですが。
作れる。 昔はそんな感じだったがいまはstd::bad_allocを投げるのがお約束になってる。 例外じゃいかんのか?
A *a=NULL; try{ a = new A(); }catch(...){} if(a==NULL){ puts("Aの作成に失敗"); }
#include <new> A *a=new(std::nothrow) A(); if(a==NULL){ puts("Aの作成に失敗"); }
Aのコンストラクタがエラーになったときの処理とちがうんかいな?
だったら適切なfactoryを一個つくりゃいいんじゃないの? 無理にじかにnewしなくとも
みなさん回答どうもありがとうございます。
>>629 作れるんですか?よろしければ作り方教えていただけると助かります。
コンストラクタに渡した引数の値がおかしいときとかに
newを失敗させるってことをしたいんです。
foo(new A()); みたいなこともしたいので、できれば例外処理は使いたくないです。
factoryっていうのは A *CreateA(){ ... } A *a=CreateA(); こんなものでしょうか。(googleで調べたけどfactoryの意味わからんかったです) これだとなんだか悔しいんですが。
637 :
デフォルトの名無しさん :03/04/01 02:16
改行コードがLFCRCRのテキストファイルを 読み込みたいんですが、どういう方法がいいのでしょうか? たとえばABC\n\r\rDEF\n\r\rというテキストファイルを std::list<string>に改行コードなし文字列を 行ごとに格納していきたいのですが getline()関数でデリミタ文字を\rを指定すると 前後にLFとCRが残ってしまいます。 やっぱりgetline()を使わず 1文字ずつ読み込むのが妥当ですかね?
>>636 A* new_A() { try{ return new A(); }catch(...){ return 0; } }
foo(new_A());
うん。そっくり。
>>637 std::getline()はデリミタに'\0'を指定して一度に全部読み込め。
int main()
{
std::stringstream file("\n\r\rabc\n\r\rdef\n\r\r");
std::string str;
std::list<std::string> ls;
std::getline(file, str, '\0');
while (true) {
std::string::size_type n = str.find_first_of("\n\r\r");
if (n == std::string::npos) break;
if (n) ls.push_back(str.substr(0, n));
str.erase(0, 3);
}
std::list<std::string>::const_iterator pos;
for (pos = ls.begin(); pos != ls.end(); ++pos)
std::cout << *pos << std::endl;
}
>>639 ああこれやと行末に\n\r\rがないとおかしくなるなあ。直そ。
こんなもんやないかな。 int main() { std::stringstream file("\n\r\rabcd\n\r\rdef\n\r\rghi"); std::string str; std::list<std::string> ls; std::getline(file, str, '\0'); while (true) { if (str.length() == 0) break; std::string::size_type n = str.find_first_of("\n\r\r"); if (n == std::string::npos) n = str.length(); if (n) ls.push_back(str.substr(0, n)); str.erase(0, n + 3); } std::list<std::string>::const_iterator pos; for (pos = ls.begin(); pos != ls.end(); ++pos) std::cout << *pos << std::endl; }
>>641 ありがとうございました
おかげで何とかなりそうです
自分のファイル入出力にくっつけて検証したいと思います
>>641 find_first_ofでいいのか?
std::list<std::string> f( std::istream& source , const char delimiter[] )
{
std::string all;
std::getline( source , all , '\0' );
std::list<std::string> lines;
if( !all.empty() )
{
std::string::size_type pos = 0;
do {
const std::string::size_type start = pos;
pos = all.find( delimiter , start );
lines.push_back( all.substr( start , pos ) );
} while ( pos != std::string::npos );
}
return lines;
}
こんなのはどうだろう std::string str = "ABC\n\r\rDEF\n\r\rGHI\n\r\rJKL"; std::list<std::string> strlst; std::string::size_type begpos = 0, endpos; while ((endpos = str.find("\n\r\r", begpos)) != std::string::npos) { strlst.push_back(str.substr(begpos, endpos - begpos)); begpos = endpos + 3; } if (begpos != str.length() - 1) { strlst.push_back(str.substr(begpos)); }
void main() { std::ifstream stream; char rBuffer[6555]; std::string str; std::list<std::string> ls; stream.rdbuf()->pubsetbuf(rBuffer, sizeof(rBuffer) / sizeof(char) ); stream.open("LFCRCR.txt", std::ios::in | std::ios::binary ); while (!stream.eof()) { std::getline(stream, str, '\n'); std::string::size_type n = n = str.length(); if (n > 2) ls.push_back(str.substr(2, n)); } stream.close(); std::list<std::string>::const_iterator pos; for (pos = ls.begin(); pos != ls.end(); ++pos) std::cout << *pos << std::endl; } どうしても何百MBのテキストファイルを読み込むのに 毎行検索すると速度的に非常に遅くなるので 改行コードは必ずLFCRCRが来ると決めうちして こんな感じに読み込むとそこそこ速度が出ました 急造なんで問題は多分ありますけど
非常に危険をはらんだコードのような気もします とりあえずお休みなさい ありがとうございました
std::istream& getline_for_637(std::istream& src, std::string& dst, const char* delimiter) { std::istream::sentry k( src, true ); if( k ) { dst.clear(); const char* comparing = delimiter; for( std::istreambuf_iterator<char> cur(src), end ; cur != end && *comparing != '\0' ; ++cur ) { const char c = *cur; if( c == *comparing ) { ++comparing; } else { if( comparing != delimiter ) { dst.insert( dst.end() , delimiter , comparing ); comparing = delimiter; } dst.push_back( c ); } } if( *comparing != '\0' ) { src.setstate( std::ios::eofbit ); dst.insert( dst.end(), delimiter, comparing ); if( dst.empty() ) { src.setstate( std::ios::failbit ); } } } else { src.setstate( std::ios::failbit ); } return src; }
>>643 スマソ。find_first_of()ではまずいやね。
Cで言うとstrcspn()やからね。
find()がstrstr()に該当するから、find_first_of()は使わないでくだされ。
650 :
デフォルトの名無しさん :03/04/01 14:28
COleVariant に文字列をCHAR型の文字を代入するにはどうすればいいのですか?
COleVariantて何ですか?
652 :
デフォルトの名無しさん :03/04/01 19:23
質問お願いします。VC6では通る、以下のようなコードは やはりSTLの実装依存になってしまうのでしょうか? vectorは内部的に、その型の配列である…というのが保証されていると良いのですが…。 #include <vector> #include <iostream> void func( int* array, int num_array ){ for(int i=0; i<num_array; ++i) std::cout << array[i] << std::endl; } int main(){ std::vector<int>vec; vec.push_back(1); vec.push_back(777); vec.push_back(1000); func( &vec.at(0), vec.size() ); return 0; }
>>652 > func( &vec.at(0), vec.size() );
この方が、わかりやすいかと。(Effective STL 16項)
func( &vec[0], vec.size() );
>>653 >>654 レスありがとうございます。やはり無理なんですね。
実際にはfuncの部分が、こちらではいじれないライブラリなので、
残念ながらvectorの使用を諦めなければになりそうです。
…また可変長配列手書きの時代に巻戻り…残念です。
それとも仕様が変わりそうにない、他のSTLを使えばいいのかな…。
>>655 じゃだめなのか? 自分で言うのも何だが。
VC++なんて、窓から投げ捨てろ!
と、書いている間に…
>>655 や、本当だ。分かりやすいです。
というか…Effective STLに載っていると言うことは、
常套手段として認められているのでしょうか!
ちぃ、手元にその本がみつからず…これからちと探してきます。
これは期待です。有益な情報ありがとうございました。
>>656 一番安全なのは、配列同様の配置を保証した、
偽vectorを自前で実装することでは。
で、必要なときはそのヘッダファイルを使い回すと。
660 :
デフォルトの名無しさん :03/04/01 20:42
どうしてあそこまで実装にこだわった標準が「vectorの中身が配列」 というのを保証しなかったんだ?あと「stringはcopy-on-write だからコピー・代入で例外を投げない」というも。 今更言ってもしょうがないけど。
>>652 もうEffectiveSTLの該当する項を読んだりしてるかもシレンが、
最近の修正で、「&vec[i] == &vec[0] + i でなければならん」と
規格に定められた。ので、問題ないはず。既に世に出てるコンパイラで
こうなってないものも特に無いようだし。
>>660 > stringはcopy-on-write だからコピー・代入で例外を投げない
vectorの方はともかく、こっちはCOWでない実装も相当たくさん
存在するのだが。特に独自にthread-safetyを保証しようとしたりすると。
>>659 仰るとおりで、先ほどまで私も、昔自作したtemplateを前にため息ついてました。
>>660 激しく同意です。その一文がこれまでにもあれば…。
>>661 うほっ!良い規格!いや素晴らしい情報です。修正入ったんですねぇ…。
嬉しすぎです。当方、もう二度と配列なんて定義しなそうな勢いです。
お礼が遅くなってすいません、20時にしまる書店へ裸足で飛び出したもので…
皆様レスありがとうございました。深く感謝です。
定数をクラスの外部に見せずに 宣言する方法はないでしょうか? 例えば、 #include "Base.h" const int BUFFERSIZE = 10; class Derived : public Base { Derived( int size = BUFFERSIZE ); ~Derived(); // 〜 }; と言う風に宣言したとき、もし"Base.h"でも BUFFERSIZEと言う定数が同様に宣言されていたら コンパイルエラーになってしまいます。 includeするヘッダファイルにすでに同名の 定数が宣言されているかどうかを調べて、 衝突しない名前を考えるのが面倒なので、 同名の定数を宣言できる方法があれば うれしいのですが、そんな方法はないでしょうか?
クラス内に書く
整数型なら"enumハック"でぐぐれ
>>665 namespaceを使えばいいのでは。
\ │ / / ̄\ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ─( ゚∀゚ )< ぬるぽぬるぽぬるぽ!! \_/ \_________ / │ \ ∩ ∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\∩ ∧ ∧ \( ゚∀゚ )< ぬるぽぬるぽぬるぽ!! ぬるぽぬるぽ!! >(゚∀゚ )/ | / \__________ ________/ | 〈 | | / /\_」 / /\」  ̄ / /
namespaceって何だっけ?
usingって何だっけ?
>>666 クラス内に書くと、純粋仮想関数の記述が間違っている、
といったエラーになってしまいます。(VC++にて)
>>667 なるほど。enumでうまくいきますね。
整数型という限定がありますが。
>>668 "namespace"で検索してみました。
こんな便利な仕組みがあったんですね。
(わたしがC++の勉強に使った書籍には
namespaceの説明はありませんでした)
これだと整数型以外でも使えますね。
ありがとうございました。
cl.exe は static const を純粋仮想関数とかほざいて 受け付けてくれないからねえ・・・
そんな古い本は窓から投げ捨てなさい。
VC++7だとうまくイったな。
ANSI以前のC++にはなんの価値もないからなあ。 CにはK&Rみたいなのがあるけど、C++にはそういった ものがない。古い本は焚書だよ。
テンポラリーな int のアドレスって作れますか? void foooooo( int* pi ){} foooooo( &int( 0 ) ); みたいな。 実際には上のコードはエラーが出ます。
C:広辞苑 C++:現代用語の基礎知識
>>678 struct Int
{
int i;
int *operator&(){ return &i; }
};
void foo(int *){}
foo(&Int());
注意事項 絶対に使うな!
早い話、山椒で受け取るようにすればいいわけで・・・
あ、わかった。Win32のReadFileやWriteFileで使いたいんだな?
int i = 5; my_cout << i で、 i = 5 ってやりたいんですが(つまりi=を書く手間を省略したい)いい方法って無いですか?
my_cout << 5
>>684 シンボル名は実行時には通常取得できないので
Cスタイルマクロ使うしかない。
#define NAME_AND_VAL(a) (#a << " = " << (a))
とか定義して
my_cout << NAME_AND_VAL(i);
とか。
687 :
デフォルトの名無しさん :03/04/03 10:07
struct A{ virtual void hoge() = 0{ } }; これってVC6で通るんだけど、正しい構文なんですか? 規格には、 virtual void hoge(){} = 0; は駄目ってあって確かにこれは駄目だけど・・・
>>687 通常は抽象基底クラスの関数は外部で宣言しないとエラーになる。
また抽象基底クラスの自体は直接インスタンスを生成できないだけで、
間接的に継承された子クラスから呼び出すことはできる。
#include <iostream>
struct A {
virtual void func() = 0;
};
void A::func() { std::cout << "A::func()" << std::endl; }
struct B : public A {
void func() { std::cout << "B::func()" << std::endl; }
void func2() { A::func(); }
};
int main()
{
B* b = new B;
b->func();
b->func2();
delete b;
}
foooooo( int* ) は自作関数ではないので、 受け取りを書き換える事は出来ません。 struct, class で wrap するつもりはありません。 どうやらテンポラリーは無理みたいなので諦めました。 どうもありがとう class Int { public: Int( int i ){ m_int = i; } private: int m_int; public: operator int() const { return m_int; } }; foooooo( &Int( 0 ) ); foooooo( &Int( 1 ) ); foooooo( &Int( 2 ) ); foooooo( &Int( 3 ) );
>>689 よくわからんが
int x;
foooooo(&(x=0));
foooooo(&(x=1));
foooooo(&(x=2));
foooooo(&(x=3));
じゃだめなのか?
>>688 ありがとうございます。純粋仮想関数でも定義できるんですね。
こうしておくと、あるクラスでの仮想関数オーバーライドにおいて、
(直下の)基底クラスの仮想関数が純粋かどうか気にする必要がなくなりますね。
692 :
デフォルトの名無しさん :03/04/03 19:37
auto_ptrの一時オブジェクトって、どうやってコピーしているの? 例えば auto_ptr<int> foo() { auto_ptr<int> ap; return ap; } void bar() { auto_ptr<int> ap2 = foo(); // *1 } という場合、gcc3.2で試してみると、fooの戻り値の一時オブジェクトを auto_ptr_refに変換して、それからap2のコンストラクタを呼んでいる ようなんだけど、これって暗黙のユーザー定義変換を2回実行している ことにならない?*1の行が auto_ptr<int> ap2(foo()); なら分かるんだけど。
暗黙の型変換はauto_ptrからauto_ptr_refの1回だろ?
>>693 auto_ptr_refからauto_ptrへの変換も暗黙の型変換だと思うけど。
struct hoge {};
struct moge {
moge();
moge(const hoge &) {};
};
struct fuga {
fuga();
fuga(const moge &) {};
};
int main() {
fuga f = hoge();
return 0;
}
ってやったらエラーになる。
>>692 >auto_ptr<int> ap2 = foo();
>auto_ptr<int> ap2(foo());
これらは同じ意味
「ヘキサゴン」て言おうよ
上はデフォルトコンストラクタのあとで代入演算子のオペレータ(があれば)を呼び出す。 下はパラメータ付きコンストラクタを呼び出す。 ほとんどの場合において求める動作と結果が同じなので、 上の書き方がされていたとき、下と同じ処理をしてもよいと、規定されてる。 同じ動作を意図して書かれる場合もあるが、デフォルトコンストラクタの 処理コストが大きい場合には、同じ動作にならずに困ることもある。
>>692 やっとみつけた。
えー、まずは、
T x = a; // copy-initialization
T x(a); // direct-initialization
と呼ぶそうだ。
[8.5 -14-]
If the initialization is direct-initialization, or if it is copy-initialization
where the cv-unqualified version of the source type is the same class as,
or a derived class of, the class of the destination, constructors are considered.
ってことで、direct-initializationか、またはcopy-initializationで
且つ初期化する型が初期化子の型とcv修辞子を除いて同じ場合
コンストラクタによる初期化を検討する、ってことらしい。
「初期化する型が初期化子の型とcv修辞子を除いて同じ場合」のみ、
copy-initializationとdirect-initializationは同じ意味になる。
auto_ptrの場合は、auto_ptr_refからの変換コンストラクタを、
auto_ptrからauto_ptr_refへのユーザー定義変換1回で
呼び出すことができるので、これで決定となる。
お、
>>698 もこれで解決?
最近規格書漁りが多いなぁ。
何だか explicit らへんの話も分からなくなってきた。 >auto_ptr<int> ap2 = foo(); これは >auto_ptr<int> ap2(foo()); これの書き方を変えただけのものだと思ってたんですが、そうでは ないということでしょうか。
>「初期化する型が初期化子の型とcv修辞子を除いて同じ場合」のみ、 >copy-initializationとdirect-initializationは同じ意味になる。 ああなるほど。
700はおれじゃなかった。
Drectxを使ってフルスクリーンモードで描写しながら DialogWindowを表示したいのですが どのようにすればよいでしょか?
DirectXって何ですか?DialogWindowって何ですか?
間違えました。 DirectX Dialog box でした。
>>108 んー。調べてみます。
入力を見せないで、入力されたものを吐くプログラムをつくって
それをpipeで繋いでうまくできるかもしれません。
他板で教えてもらえました。 迷惑かけてすんませんでした。
Exceptional C++で質問です。 項目22のBasicProtocolって言うクラス作る必要あるんですか? 解答ではメンバにしろって書いてあるみたいですが。 関数だけのクラスならクラスにくくらず関数だけ書いて、 Protocol1、Protocol2で呼べばいいと思いますが?
もっと易しい本から嫁
>>712 そのクラスが関数だけである、とどこに書いてある?
追加のメンバがあるかもしれないが云々...とは書いてあるが。
仮に全部フリー関数だけだったとしても、MessageHelperオブジェクトと
いう一つの実体としてくくる設計はアリだろう。
715 :
デフォルトの名無しさん :03/04/04 12:50
すいません引越し直後でネットがつながらないので携帯から失礼します コードのコの字も分からない人間ですがC++を始めたいと思います 今書店にいるのですが教本が多過ぎてどれが良いのか分かりません まず一冊これを買えという定番があれば教えて頂けないでしょうか
>>715 >コードのコの字も分からない人間ですがC++を始めたいと思います
あー、そう。
君は晴比古の本でいいよ。
宣伝発見
718 :
デフォルトの名無しさん :03/04/04 13:00
>>715 日経ソフトウェアのムック『ゼロから学ぶC++』とかは?
あと『独習C++』とか
>>720-721 なるほど
晴比古という方の本がまだ見つからないので
合わせて探しに新宿に行ってきます
ありがとうございます
723 :
デフォルトの名無しさん :03/04/04 15:23
iostreamで、ディスクエラーなどでI/O自体が失敗した時は、 どういう振る舞いになるのですか?eof?bad?
724 :
デフォルトの名無しさん :03/04/04 17:12
>>722 マジにとるなよ。
晴比古というのはダメな参考書を書いている人だから
絶対に買うな。あと三田とか岩谷とかも避けるように。
晴比古本でも、「新C++言語入門シニア編(上・下)」は、 最新の ANSI C++ の規格にそって書いてあるから、 他の入門書よりもずいぶんマシだと思うが。 初心者には最適だと思うぞ。 ~~~~~~~ ビギナー編はダメダメだが。
C++いきなりやる香具師は必ず失敗する。 C++やるには、アセンブラ・Pascal・C必ず一通り齧らなければ モノにならんでしょ。 C#なら、いきなりこれから初めても大丈夫みたいだけど。 大した違いは無いような感じだけど意外な差があるのが言葉の世界
いやいや、別に良ーんでないの?
ポインタをdeleteした後にはNULLを代入した方がいいのですか? なぜですか?
>>728 0を代入しておくと、間違ってdeleteしても無視されるから。
そのせいで間違ってdeleteしているバグが隠蔽される。
ありがとうございます。 じゃ、デストラクタの中などでdeleteする時はほっといてもいいんですね。
732 :
デフォルトの名無しさん :03/04/04 21:37
あの〜スミマセン!! MassageBoxの出し方教えて下さい。 ガッコウの兄貴に指示されました。 コニチワ、マッサージボックスで出せなさいと。 どうすればいい?
std::cout << "MessageBox";
#define MassageBox MessageBox
>>732 www::google << "MessageBox";
732はマルチです。
いくら必死でもマルチはいかんな。 それとも釣りかな。
738 :
デフォルトの名無しさん :03/04/04 21:54
すみません質問してもよろしいでしょうか? CSVファイルを読み込む ↓ 中の値を全て2倍にする ↓ 処理した値をCSVファイルとして出力 というプログラムをC++で組みたいと 考えているのですが、どのような アルゴリズムを使用すればよいか、 ヒントでもよいので回答していただけないでしょうか?
すみません。初心者です。 C++で、一定時間ごとに、画面をキャプチャするなんていうアプリを作れるのでしょうか?
2倍するところは、2を掛ければよさそうだな
初心者はまずできることからやろうよ。
掛け算は「×」でなく「*」、、と。
743 :
デフォルトの名無しさん :03/04/04 22:20
744 :
デフォルトの名無しさん :03/04/04 22:21
なんでテンキーには「*」がないんですか?
ほんとだ。 若干形が違った。
>>746 レスありがとうございます。
アドレスを教えてくださいませんでしょうか?
>>713 例えばどんな本がいいですか?
>>714 読み落としていました。有難うございます。
> 仮に全部フリー関数だけだったとしても、MessageHelperオブジェクトと
> いう一つの実体としてくくる設計はアリだろう。
アリだというのは分かりますが、実際こういう設計ってあるんですか?
インスタンスを作るとメモリが消費されると思うのですが間違いでしょうか?
外部関数として使うのに対して、クラスにしてインスタンスを作成してから使う場合の
メリットってなんですか?
>>750 URLのことをアドレスと言ってるようではレスがつかない。
携帯のURL教えて〜
イラク戦争の中継を見ながらこう書いてしまったことはありませんか――― vector v; v.bush_back(0);
ややウケタw
757 :
デフォルトの名無しさん :03/04/05 11:12
>>757 デフォルトのアロケータをサポートしない処理系でSTLを使うのは
一種のチャレンジだ。
759 :
デフォルトの名無しさん :03/04/05 11:39
>>758 そこのところは書き換えました。
解決しました。
>>751 クラスの静的メンバを使う場合、そのクラスのインスタンスを生成しなくても利用できるよ。
設計時に関数の固まりをオブジェクトとしてとらえたかどうかでクラスにするか、
namespaceで囲むだけにするか、それともただの大域関数にするかを決めればいい。
761 :
デフォルトの名無しさん :03/04/05 17:19
関数の引数として、クラスオブジェクトのポインタ渡しと参照渡しで、 何か違いってあるのですか?
参照渡しで受け取る場合ぬるぽが来る心配がない。
ポインタ渡しだと、基底クラスのポインタを渡せる。 つまり多態を使うときはこっち。
参照渡しでもぬるぽは来る(…と言っても、そんなもん渡すんじゃねぇ!と いう意思表示としては使えるが…)し多態も出来ますが。
>>764 同意。
参照を選ぶときは、ぬるぽを考慮していないという意思表示に使ってます。
766 :
デフォルトの名無しさん :03/04/05 19:36
僕も 0 を渡したときにしかるべき動作をする、 って仕様ならポインタ、そうでなければ全て参照渡しにしてます。 とくに const T& hoge ってのは慣用句みたいなものなので 覚えておきましょう。
>763 参照でもポリモできるでしょ?
ねーねー、C++って何ができるの?ゲームでも作れるの?
C++は、言語です。
「日本語って何ができるの?」って聞いてるようなもんだ。
>>770 にも何かができるような言語は、
今後永遠に生まれることがないはずです。
773 :
デフォルトの名無しさん :03/04/06 01:18
delete NULL; を実行したとき、処理時間を奪われる以外の 作用がないことは言語仕様として定められて いるのでしょうか? if ( p != NULL ) delete p; は、 delete p; に置き換えても全く問題はないのでしょうか?
ない
delete p; p = NULL; としないと危ないと思われ。
NULLなんてc++にはありませんが何か?
>>776 それってよく見かけるけど
俺はdelete p;した後pを使うようなコードを書いた事が無い。
メモリの解放はなんらかのスマートポインタにやらせる。
明示的にdeleteを呼び出す事は滅多に無い。
そもそもp = 0;しなきゃ危ないコード
(例えばpを複数回deleteする可能性があるとか)
を書くのが問題なんじゃないのか?
778-780 には同意できるが、777 には首をかしげる。
#include <cstddef>
>>781 首をかしげるだけなら誰にでもできるね。
Javaのserialize(deserialize)みたいに、動的にオブジェクトのクラスを 発見するにはどうすればよいですか?
VC++ の std::runtime_error や std::logic_error が、 文字列を std::string で保存しているのを知って驚いた。
×プログラムが自分で管理する ○プログラマが自分で管理する
>>784 intも全部クラスにしてクラスのタイプを返すメンバ関数をオーバーライドする
#include <stdio.h> void main() { for (int i = 0; i < 1000; i++) ; printf("%d", i); } 上のコード、BCBなら通らないけど、VC++なら通ってiの値が表示されるのですが、 どっちが正しいのでしょう?
激しくスマソ、テンプレたどったら分かりました。 スレ汚してすみませんでした。
どうわかったのかも書いてくれるとわかりやすい
C&C++FAQ の 「for文の( )内で宣言された識別子の有効範囲はどうなっていますか。」を見ると、 for文のカッコ内で宣言された変数は、そのfor文内のみ有効だと書いてあった。 だから、790のコードを通さない方が正しい。 VC++も結構いい加減なんですね。
>>793 そのように、どう解決したか書いてくれるとそれが妥当かどうかの検証ができる。
VCは6だとしたら、いいかげんなのではなく当時はそれで良かった。
規格はその後だからね。
(あってるかな?)
>>7994 今度から気をつけます。
規格が決まったのは最近なんですか。
いやぁ、猫でも(ryを読んでて、790でコンパイルが通るような事が書いてあって、
あれっおかしいな?と思ってBCBで確かめてみたんだけど、
気になったので、VC++でも試したところ余計に分からなくなって・・・。
ちなみにVC++.NETです・・・。
>>795 C++の規格は98年。VC6はそれよりちょっと前か?
>>790-795 > (あってるかな?)
合ってないよ。
規格がどうのこうの言うんなら、「Microsoft 言語拡張機能」を Off してから議論しろや。
>>795 同じく 98 年、ただし stdC++ よりも数ヶ月リリースが早かった。
796 宛てですた。
>>787 とうとう自己管理プログラム言語が完成したか。
>>798 それならVC++6.0が標準規格に準拠していなくてもおかしくないんじゃない。
VC6が出た時期なんてたいした問題じゃない。 VC6に含まれている大量のコードはそれ以前にかかれたもの。
803 :
デフォルトの名無しさん :03/04/06 21:11
>>793 「for文内部」だと { } も含まないのかな?
() だけ?
有効範囲じゃなくても、スコープから外れるわけじゃないのかね?
いい加減、VC6は捨てろ。 古臭いMuleを使ってるのを見ると吐き気がする、 それと同じだ。
エディタとコンパイラを同一視している奴がいるな(w
806 :
AGENT-GC :03/04/06 21:41
Visual Studio .NET でC++できるんすか?
MuleでC++はできません。
809 :
AGENT-GC :03/04/06 21:48
やっぱVisualBasicC++っすよね? C++するにはボーランドとマイクロソフトどっちがいいっすか?
うるさい
811 :
デフォルトの名無しさん :03/04/06 21:52
>VisualBasicC++ 落ち着け
>>805 ハァ?馬鹿かおまいは?
新しいコンパイラぐらい買えっつーいみだボケ
デストラクタは明示的には呼び出せない、と聞いて試したのですが、 普通の関数みたく呼び出すことができました。 ただしインスタンスは生きたままで、その後普通に他の関数をコールできました。 こういうものなんでしょうか? あと、C++が起動、実行時にどのようなメモリの取り方をするのかが、 よくわかるようなサイト等はないでしょうか? 先輩が、インスタンスとは、クラスが必要とするメモリをmallocで取得してるようなもの & C++は起動時に、リンクしているヘッダで宣言されてる全てのインスタンス分のメモリを取る と言ってたのですが・・・するとそれらは全てヒープ領域に取られると言うことですか? どなたか詳しい方お願いします。
>>813 ヒープ領域はnewでオブジェクトを作成したとき
だけじゃないですかね?
newの実装とかは俺も知りたいけど、解説している
サイトは知らないなぁ。
デストラクタは明示的に呼び出せる。 その後インスタンスはたまたま生きてるかも知れないが、 いつ何が起きてもおかしくないのでやらないように。 ヘッダで宣言されている「インスタンス」なんてあったっけ・・・? あ、std::cin, std::cout, etc. があるか・・・ってそりゃ「定義」だが。 そりゃ、ヘッダでスタックに置いたならスタックに、 ヒープに置いたならヒープに取られるに決まってる。 何か話がかみ合ってない気もする。
>>813 allocatorに関して調べるとよろし
>何か話がかみ合ってない気もする。 すんません、C++初心者なもので。 例えば、ヘッダに class test1 { ・・・ }; class test2 { ・・・ test1 tst; ・・・ }; とか書いた場合、tstはいつ、どこに領域が取られるんでしょうか?
VCのnewはmallocを使ってるけど
>>818 そのヘッダをインクルードしたソースファイルごとにできる
>>818 Test2をスッタクにおいた場合はtstもスッタクに。
タイミングはTest2の構築時とほぼ同じと思うが、それが正解なのかどうかはわからん。。
>>818 宣言と定義について書いてある本をさがして読むように。
スタックにとる場合は関数やメソッドの中で。たとえば
int foo() { test2 foo; }
起動時に静的な領域に取るなら関数の外で
test2 foo;
もしくはクラスの静的メンバとして
class zoo { static test2 foo; };
test2 zoo::foo;
ヒープに動的に取る場合は
関数やメソッドの中で
test2 *pfoo = new test2;
>>818 それだけなら、領域は取られない。
どっかで、インスタンスを生成した時に領域が確保される。
test2 test_on_static; // (1)
void foo()
{
test2 test_on_stack; // (2)
test2 *test_on_heap = new test2; // (3)
...
}
(1) は、プログラム実行前に静敵領域に領域が確保されてて、main() の実行前にコンストラクタが呼ばれる。
(2) は、関数 foo() の入ってきた時にスタック上に領域が確保され、そのあとコンストラクタが呼ばれる。
(3) は、この文が実行された時にヒープ上に領域が確保されて、そのあとコンストラクタが呼ばれる。
>>820 一体何がソースファイル毎にできるんだ ?
もう少しちゃんと勉強しろよ。
>>821 スッタクって、アンタ...。
書き方でスタックに取るかヒープに取るかなんて決まっていない。
スッタク萌え
皆さんありがとうございます。
>>823 (1) は、プログラム実行前に静敵領域に領域が確保されてて、main() の実行前にコンストラクタが呼ばれる。
(1)の場合、明示的にデストラクタを実行はできるんでしょうか?
静的領域にあることは別に問題とはならないのでしょうか?
>>816 デストラクタは明示的に呼び出せるとのことですが、BohYohのFaqに、
明示的に呼び出すことはできませんとありました。
実際のところどうなんでしょうか。
unsigned char buf[sizeof(T)]; T* p = new (buf) T(); // これであってるかな?placement new p->~T();
>>826 >デストラクタは明示的に呼び出せるとのことですが、BohYohのFaqに、
>明示的に呼び出すことはできませんとありました。
そのfaqを読み間違えてるのではないか?
なるほど、わかりました。仕様書まで調べていただいて感謝です。 皆さんありがとうございました。m(__)m
ま た 「 仕 様 書 」 か ・ ・ ・
だって一番正確なんだもん。 $18ぐらい大した額じゃないっしょ。
>>826 > (1)の場合、明示的にデストラクタを実行はできるんでしょうか?
> 静的領域にあることは別に問題とはならないのでしょうか?
実行はできるけど、実行結果は保証されないよ。
(暗黙のデストラクタ呼び出しを禁止できないから、2重にデストラクタが呼び出されれてしまうからね。)
> デストラクタは明示的に呼び出せるとのことですが、BohYohのFaqに、
> 明示的に呼び出すことはできませんとありました。
> 実際のところどうなんでしょうか。
呼び出すこと自体はできる。
ただし、暗黙にデストラクタを呼ばないようにする責任はプログラマにあるよ。
ほとんど、
>>827 のケースしかないと思う。
>>833 "Standard" ←→ 「規格」
"Specification" ←→ 「仕様」
どっちでもいいのかなぁ?
標準書でいいじゃん
ofstream fo; fo.open(filename); この場合、無いファイルは作られるのでしょうか? よろしくお願いします。
>>826 あれを使うのは、mallocやallocatorで取って来た、未初期化の
生のメモリを扱いたい時、たとえばコンテナを自分で実装したい
時くらいかなあ。いずれにしても、アラインメントやら例外安全
やら、面倒な問題がいっぱいあるから、C,C++のメモリの扱いを
完全に把握してから使うべし。
C++って基礎が大事?今文字を出力したりするコード書いてるんだけど、こんなの役に立つかなぁ・・・ と思いまして。
>>839 プログラミングにおいては、例え、ただ文字を出力するだけのコードであっても
コードを書いて慣れることに何らかの意味があると思ふ。
何事も基礎は大切
>>840 ありがとう。それを聞いてやる気が出ました。
っつーわけで今「if文」を勉強中。
>>837 std::ofstream のデフォルトは std::ios::out だから、ファイルがあっても
内容を空にする。なければ新規作成する。
超初心者で申し訳ない。 int main() で始めるとき、intしかつかえないんですか?
>>844 質問の意味が良く分からない
mainの戻り値はintにするしかないが
>>844 確実なのはstringにしたら落ちるという事だ。
デーモンとか作るときは void じゃね?
>>844 int以外で返して、その後どうしようとしてるの?
>>843 レスありがとうございました。わかりました。
あと、一行目の理由がわかるように精進します。
以下のようなクラスAのvectorをソートしたいのですが、ソートの基準は文字列なんです。 このときの叙述関数はどのように書けばいいのでしょうか? Cの標準関数で文字列の比較をぐぐってみたのですがstrcmpしか引っかからず、もちろんこの関数はつかえません。 class A { char label[20]; int value; // : }; void foo(void) { vector<A> vec; // : sort(vec.begin(), vec.end(), cmp); } bool cmp(const A& a, const B& b) { return (a.label < b.label); // <-----ここの書き方が? }
>>850 なぜstrcmpが使えないのか500文字以内で述べよ。
そもそもcmp()の第二引数の型がおかしいわけだが。 20文字以下ということならstrncmp()とか、memcmp()とか。
>>852 ABC\0DEFGのような文字列がありうるからmemcmpはありえないと思うが。
>851 すいません。 strcmpの仕様の勉強不足でした。 申し訳ありませんでした。
switch と if〜elseif〜else って何が違うんですか?
>>855 分岐先の数が違う。
switch : 多方向分岐
if : 2方向分岐
ついでに藻前の質問はスレ違い。
switch は if と比べて、条件を簡潔に書ける/フォールスルーができる/コンパイラが 最適化しやすいという利点と、複雑な条件を書けないというデメリットがある。
>>846 普通おちることはないだろ。逆なら、おちることはありうるが。
>>856 > 分岐先の数が違う。
ハァ ? if〜 else if 〜 else 〜 だぞ。
~~~~~~~
ついでに、なんでスレ違いなのか聞きたいもんだ。
>>858 まあC言語と共有する問題はC言語スレのほうが相応しいのではないかとは思うが
>>861 俺のC++参考書に載ってたんですが・・・。
すれ違いならごめんね。
そりゃ載ってるだろう
864 :
デフォルトの名無しさん :03/04/09 22:44
アカデミック買ったんだけど何やったらいいのかな
みんな最初は2chブラウザを作って一人前になったんだよ。
とりあえずHello,world!!やっとけ。 何それって聞くなよ。わからなかったらお前は才能がないと言う事だ。
>>866 人間関係クラスタが気の利いた台詞を発言することを提唱。
>>867 ZOEなのか、EVAなのか、それともそれ以外なのか、そこが問題だ。
(´-`).。oO(ハロワ・・・)
俺は、新しい言語を覚えるときは とりあえずヒットアンドブローを作る。
>>864 とりあえず、Kanimiso128を作ってくれ
872 :
デフォルトの名無しさん :03/04/10 19:37
質問です。 ファイルAにある関数内から、別のファイルBに定義したクラスのメンバー関数を使うにはどうしたらよいのでしょうか? 変数や関数は、extern宣言しますが、クラスの場合もそうですか?
873 :
デフォルトの名無しさん :03/04/10 19:45
自分はC言語を勉強した人間です。 C++とVC++を勉強したいのですが、 お奨めの書籍等ありましたらどうかご教授ください。
875 :
デフォルトの名無しさん :03/04/10 19:51
>>872 ヘッダファイルにクラスの定義を書いて、
無限ループになるとどうなっちゃうんですか? パソコンがフリーズしそうで試せません。
>>872 クラスについて基本から勉強することを(略
879 :
デフォルトの名無しさん :03/04/10 20:21
>>872 クラスも型なので変数と同じあつかいでいいです。
>>880 普通のOS・・・・
友人を引っ掛けて試して見ます。
>>876 ,878,879
レスありがとうございます。
エラーが出なくなっても、デバッガでお目当ての関数内を
トレースできなかった(なぜかスルー)ので質問させていただきました。
またよろしくお願いします。では。
無限ループ while(1){ cout << "\t\b\b"; }
>>883 OSがWindowsXPだと落ちます。
886 :
デフォルトの名無しさん :03/04/10 23:43
質問です。 構造体の中身をゼロで初期したい場合。 struct Hoge_t{ int a,b,c; }; memset( &Hoge_t,0,sizeof(Hoge_t) ); で 大丈夫ですよね。 それで たとえば、 構造体を public なクラスとして扱う場合に、 struct CHoge{ int a,b,c; Hoge_t(){}; ~Hoge_t(){}; }; memsetで ゼロで埋めても大丈夫でしょうか?また、メモリ確保を malloc で とる場合(まぁ new を使えばいいんでしょうが) CHoge = malloc( sizeof(CHoge) ); と sizeof を使用して確保しても大丈夫でしょうか?
>>886 おとなしく初期化を使いましょう。
CHoge() : a(0), b(0), c(0) ....
malloc()使うとコンストラクタを呼び出してくれないのでやめましょう。
クラスをクラス化したクラスをください。スクリプトにつかうので。
Ruby では一応クラスもクラスだぞ。
ゲーム用のスクリプトなのでRUBYではダメです なければintとcharを駆使しますが
状況がヨクワカラン。
892 :
デフォルトの名無しさん :03/04/11 10:40
クラスオブジェクトは関数の引数として、ポインタで渡してもいいんですよね。 参照とどう違うんですかね?
「参照 ポインタ 引数 違い」これくらいでぐぐればいいようだが。
C++にクラスオブジェクトなんてないんだが。 たぶんクラスのインスタンスであるところの オブジェクトのことだろうけどさ。
>>886 コンストラクタ、デストラクタの中身がない場合なら
OK。ただし、「中身」には、メンバ変数の初期化の
ために暗黙に生成されるコードも含まれるので
注意。だから、intやらconst char *だけの構造体
でなく、std::stringみたいのを含んでいたらアウト。
あと、たまーにポインタをmemsetで潰してもNULL
ポインタにならないプラットフォームがあるので注意。
memsetよりもこの方がいくない? static CHoge zero; *this = zero;
>>886 への解答で
仮想関数があったら駄目
という、教えが出てないのはどういうことですか?
899 :
デフォルトの名無しさん :03/04/12 03:08
ポインタのほうがすき。
900 :
デフォルトの名無しさん :03/04/12 13:51
キリンさんのほうがもっと好き。
俺のゾウさんが好きなんだろう。オラオラ
これで象?ネズミの尻尾の間違いじゃないの
チンポ何センチ級?俺は18〜19センチ級だと思うんだけど。
長さに級とかつけないで・・・。ミリまでちゃんとしる。
905 :
デフォルトの名無しさん :03/04/12 17:47
18.0〜19.999999999..............センチの範囲内と言うことだろうか?
ずいぶん誤差の大きいものさしだな
907 :
デフォルトの名無しさん :03/04/12 18:27
doubleで示せる20.0に一番近くて20.0未満の数字ってなんだろう。
911 :
デフォルトの名無しさん :03/04/12 19:39
グレト!!
C++の基本的な部分を抑えた人が作るプログラムって何?
>>915 そりゃまた随分グローバルな挨拶ですね。
、、、
/ヽ /ヽ / ヽ / ヽ ______ /U ヽ___/ ヽ | ____ / U :::::::::::U:\ | | // ___ \ ::::::::::::::| | | | | | U :::::::::::::| | | .|U | | ::::::U::::| なにこのスレ・・・ | | | ├―-┤ U.....:::::::::::::::::::/ | |____ ヽ .....:::::::::::::::::::::::< └___/ ̄ ̄ :::::::::::::::::::::::::| |\ | :::::::::::::::::::::::| \ \ \___ ::::::
920 :
デフォルトの名無しさん :03/04/12 23:13
お勧めの解説本おしえてくらさい。 入門編からポインタ位までを扱った初歩的な奴、定番を教えてください。 条件は日本語で書かれてることです。
●●● Hello worldって死滅しちゃうの??? ●●●
>>925 見つからない。(´・ω・`)
「標準C++の基礎知識」「標準講座C++ ― 基礎からSTLを利用したプログラミングまで」
買います。
VisualC++3週間完全マスター
俺は「詳説C++」と「Effective STL」で乗り切れてる
ポインタ完全制覇を鼻で笑って流し読みできればアプリ製作でポインタに困ることはほとんどない
930 :
デフォルトの名無しさん :03/04/13 00:22
コンパイラーのコンパイルエラーメッセージで十分だろ。 そういう問題じゃなくて?
初心者はエラーを出すまでが長い
932 :
デフォルトの名無しさん :03/04/13 00:27
HogeClass Hoge; HogeClass *pHoge; pHoge = &Hoge; delete pHoge; : : Hoge.Func(); // 何か処理。 ってやったら、やっぱまずいですよね。 実行時の影響ってどんなのがありますか?
>>932 うわぁそりゃひどい。
影響とかそんなレベルじゃない。
未定義動作へ突入。
なぜnewで得たものでない領域をdeleteしようとする。
>>932 Hogeはヒープには存在しないから、危険です。
>>932 未定義動作はシステムを不安定にする。
任意の小さな変更(たとえば、セミコロンを挿入する、プログラムを別の曜日に実行する、Enterキーを押し下げる前に微笑み方を変えるなど)によって
システムがどのように振舞うか(あるいは、どのように間違った振る舞いをするのか)といった大きな事象が変わってしまうかもしれない。
プログラムがファイルを削除することもあるだろうし、間違った答えが返ってくるだけかもしれない。
場合によってはまったく正常に動くかもしれない!
937 :
デフォルトの名無しさん :03/04/13 00:54
struct Test { void Func() {} }; int main() { Test* t = 0; t->Func(); return 0; } 未定義ですか? gccでやってみたら、何も起きなかったが…
VC++だったら落ちるよ。
public:書くのが面倒だからってstructにするなよ。
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >_∧∩
_/し' //. V`Д´)/ ←
>>937 (_フ彡 /
>>938 ウソは書かないように。落ちませんでしたが。
Test::Func() が非仮想メンバ関数、かつ、メンバへの参照がないので、
thisへの参照はおこなわれることがないよね。
VCの実装上も、そうなっているようです。
しかし、もしTestが多重継承だったら、勿論、話は違ってきます。
ああ、これが噂のぬるぽか。よくわかりますた。 ありがとうございました。
>>938 VC++で試したが落ちない。つーかこれは落ちなくてもフシギではない。
Func()が仮想関数だったらまず落ちるが。
これを利用したテクニックもある。
struct Foo
{
void Func()
{
if(!this)//NULLだったら処理しない。
return;
}
};
ただ、これを勧めている訳ではもちろんない。
でも未定義なのは確かか?それとも規格上も安全?
VC++5.0なら落ちたが。
#include <iostream> using namespace std; class Test { public: void Func(){ cout << "(゚∀゚)アヒャ" << endl; }; }; int main() { Test* t = 0; t->Func(); return 0; } BCCでテスト。 「警告 't'に代入した値は使われていない」ってのが出たが、通った。
通ったってコンパイルが?そりゃ通るだろ。
ぬるぽに決まってる!って思ってたら本当に実行できてしまった罠。
>>950 それで、そのコードが実行できたってことでなにが主張したいの?
>>952 動作するか検証しただけですが、何か問題でも?
>>953 未定義動作の結果を見てなにを検証したというのか?
ぬるぽでも動くのか。 奇怪だな。
>>954 未定義だけど「動いた」って書いただけだろ。
何をムキになってる?
>>956 未定義なのがわってるなら、まぁいいんだが。
>>937 みたいなやつがそれ見たら、誤解しかねない。
>>932 ? に何がくるかだと思うが。
// case 1
phoge = &hoge;
delete phoge;
これはヤバい。
new されてないのを delete してる。
どうなるかは分からんが、普通は落ちる。
// case 2
phoge = new Hoge;
delete phoge;
hoge.foo();
問題なし。
// case 3
phoge = new Hoge[9];
delete phoge;
これはヤバい。
配列 new したのを単一 delete してる。
普通、配列 new した場合はその個数を配列の直前に保持しておくが、
単一 new の場合はそんなものはない。
従って、実際に確保されたメモリブロックは phoge よりちょっと前なのが普通であり、
delete に渡されたアドレスはその先頭とはずれている。
その後どういう動作になるのかは分からん。
仮にその余分なメモリを確保しない仕様のコンパイラであっても、
phoge[1] 〜 phoge[8] がデストラクトされないまま解放されてしまうだろう。
ミス。 // case 1 phoge = &hoge; あと、こう置き換えて。 Hoge → HogeClass phoge → pHoge hoge → Hoge foo → Func
>>958 聞いてもいないことを長々と解説するなよ。うざいぞ。
>>962 はぁ?それならcase 1で十分なうえに既出だろ。
だれも配列newの話なんかしてない。
(・A・)まったりしろよ君たち…
なんでこうムキになる奴が多いんだろうね(´ー`)y─┛~~
967 :
デフォルトの名無しさん :03/04/13 01:50
だってC++だもん
正直言って、普通とか規約とかどうでもいい。 ただ動けば問題ない。 科学と一緒。 認知できないものは存在しない。
スマン,ナントナク
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >_∧∩
_/し' //. V`Д´)/ ←
>>967 (_フ彡 /
971 :
マイク ◆yrBrqfF1Ew :03/04/13 01:56
C++は最高だよ。 2ちゃんネラは常にダメだが。
動いているように見えてるだけかもしれない
科学と一緒。 認知できてから考えれば良い。
そんな考え方だから2000年問題みたいなんが起こるんだ。
2000年問題? 将来はもっと凄い問題が待ってるぜ!
問題が起こった方が刺激があっていいYO!
さて、そろそろ次スレの季節ですね。
>刺激があっていいYO! 確かに…わくわくするな(`エ´*)
ちょうど一ヶ月だ!
983 :
デフォルトの名無しさん :03/04/13 02:31
>>932 VC++6.0とXPだと動作が不安定になる。
以降の処理で問題なく動くときもあるし、いきなり落ちるときもある。
しばらく大丈夫かと思えば、やっぱり途中で落ちたり、
Hoge.Func()が予期しない処理をしたりする。
まあ、慣れないことはしないに越したことが無いってことだ。
どうせ誰も2038年問題のことなど何も考えてないだろ
985 :
デフォルトの名無しさん :03/04/13 02:33
っていうか、慣れるって・・・ 慣れたら念力で常に正常実行できるとか?(w
>>984 その頃には最新のコンピュータが、
問題のあるコンピュータのコードを書き換えてくれるようになってるよ。
988 :
デフォルトの名無しさん :03/04/13 03:41
20年後ってVC++使いって需要ありますかね?
989 :
デフォルトの名無しさん :03/04/13 03:42
量子コンピューターが実用化されたら、 今のプログラマーは置いてきぼりかな・・・
そのころには年金で宇宙旅行にでもいってるよ
get
v(^・^)v
1000取り始め
996
997
998
999
1000!!!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。