STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの?
しかしなんでMSはSTLのランタイムDLL作らんのだろう?
>>15 それを実現させようとするとDLLでなくDCL(Dynamic Compile Library)になってしまう。
17 :
デフォルトの名無しさん :2005/10/05(水) 22:28:43
すいません。 opertor<<= は C++の構文でこれは、どう解釈するればよいでしょうか?
<< はシフト演算、 a <<= 1; は a = a << 1;
19 :
デフォルトの名無しさん :2005/10/05(水) 22:49:01
ありがとうございます。 シフト演算は理解できるのですが、 opertor というキーワード(予約語)が気になっています。 特別な意味があるのかと思いますが、よくわかっていません。
struct T {int i;T():i(1){}}; void operator<<=(T& x,const T& y){x.i+=y.i;}; //operator<<= という名の関数 #include <iostream> int main(){ T x,y; x <<= y; // ここで「operator<<= 」と定義した関数をつかっている std::cout << x.i << std::endl; return 0; }
21 :
デフォルトの名無しさん :2005/10/05(水) 23:14:03
ありがとうございます。 誤記でした。opertor(誤) operator(正) 演算子ではないのですね。 関数を定義しているという理解でよいでしょうか? 頭が固くてもうしわけありません。
operator<<= は省略記法として <<= の使える演算子関数、と本に書いてある 要するに関数であってると思う。
23 :
デフォルトの名無しさん :2005/10/05(水) 23:25:06
ありがとうございます。 初心者がコードを読むにはまだまだ、知識が必要。 C++言語はむずかしいことを実感。挫折中です。
>>14 #include <stdafx.h>
あと死ね。
>>24 言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
>>21 構文上はそうなんだけど、実際には演算子を定義していると思え。
27 :
デフォルトの名無しさん :2005/10/06(木) 03:35:22
これからVC++をはじめようと思っているのですが、初心者にでもわかりやすい本を紹介してください。 一度、サンプルソースをいじろうと思って触ってみたのですが、 フォームに表示する文字のフォントサイズをどうやって帰ればよいのかも判らずそのままになってしまいました。 今度こそしっかりと覚えたいので、よろしくご紹介ください。 よろしければ、フォームに表示する文字(テキスト)のフォントサイズを変える方法もお願いします。
The C++ Programming Language C++ Primer (3rd Edition) Effective C++ More Effective C++ Exceptional C++ More Exceptional C++ ちょwどれもさっぱりなんだが もう一個下なのはありませんか?
31 :
デフォルトの名無しさん :2005/10/06(木) 23:24:08
>>26 ご支援ありがとうございました。
一般的にコンパイル時の警告メッセージの定義はあるでしょうか?
無視してはいけないものと思えばよいでしょうか。
>>31 警告は、そのうちエラーになる前兆だと思うといい。
警告が全く出ないようにするのも一つの楽しみ。
>>32 楽しみじゃなくて常識って言ってくれるかな
34 :
デフォルトの名無しさん :2005/10/07(金) 00:22:10
質問です。 fstream::get() などの方法で、ファイルから16ビットの文字、 ひらがなやカタカナなどを直接取得して認識する事は 出来るのでしょうか…? それともバイナリで処理していかないとダメなのでしょうか?
>>34 char std::fstream::get()だから、環境依存。
wcahr_t std::wfstream::wget()ってのはあったっけ。あればこちらを使うとよい。
今規格書見たけど無かった。
×wcahr_t ○wchar_t 普段使わないとtypoするなorz
std::wstringのgetlineじゃん
コーディングはすきなんだが、コンパイルがいかんせん好きになれない なにか、ソースをコンピュータに評価されている気分になる
お姉様系美人教師に採点してもらってると思え
ハァハァ 僕をもっとしかってください ハァハァ
コンパイラの擬人化決定
42 :
34 :2005/10/07(金) 01:38:51
VC家長女タン - 最先端の難しい問題もそつなくこなし解答の内容も評価が高い。 典型的優等生。窓組にしか顔が利かない社交性の低さはご愛嬌。 今ならタダで付き合ってあげちゃうYO! VC家次女タン - っていうかお前居たっけ? VC家3女タン - 難しい問題どころか標準的な問題でも解けずにすぐに泣き出してしまう ダメな子。でもダメな子ほど可愛い。 GCCタン - 家庭は貧乏だけれども地道な努力を積み重ね安定した実力を築き上げた 努力の子。窓組からペンギン組まで顔の広さも天下一品。 ただ、解かなくてよい問題まで解いてしまういらんことしいな部分も。 ICCタン - 最先端の問題も難なくこなし、解答の内容も一線級。 お高くとまった高飛車なイメージと、差別的な発言が見られるという噂を どうするかが今後の人気を左右する? DMCタン - 母国語で出される問題が難しくて嫌だと勝手に自分専用のコトバを 作っちゃった子。その熱意があるなら母国語をもうちょっと頑張りましょう。 BCCタン - っていうかお前超頑張れ。
GJ!
これも付け足してくれ。 MCWタン - 標準的な問題はそれなりにこなし、顔もそれなりに広かった。 昔はリンゴ組に人気だったけど、今は身売りされてどうなる事やら。 ゲームは今でも得意。
46 :
デフォルトの名無しさん :2005/10/07(金) 03:32:40
httpでアクセスして,ページのソースをmyDataBufferに格納しました↓ BOOL bOK = InternetReadFile(hFile,myDataBuffer,(DWORD)(size),&dwSize); ただヤフーのページのため,EUC-JPでエンコードしないと文字化けします C#では以下のクラスがありますが,C++ではどのようにしてエンコードするのでしょうか? //C#の場合 Encoding.GetEncoding("EUC-JP").GetString(myDataBuffer);
48 :
デフォルトの名無しさん :2005/10/07(金) 10:07:28
class Base { public: Base() { } virtual void func()=0; }; class Derived : public Base { public: Derived() { doSomething(); } void func() {} void doSomething() {} }; Baseから派生するクラスは全て、 コンストラクタでdoSomethingを実行した後に 派生クラス側のfuncを実行させたいのですが…… 私の今の知識では「基本クラスに派生クラスの関数を実行させる」ことは出来ないと認識していますが、 なんとか実行するトリックはないでしょうか。 お願いします。
>>49 基底クラス“のコンストラクタ”に派生クラスの関数を実行させることができないだけ。
>>50 なるほど、了解しました。
それは理解したのですが、相変わらずコンストラクタからは実行できずorz
特に「派生クラスのコンストラクタが終了した後に」virtualである関数を実行したいので、
コンストラクタの実行順(基底クラスが先)が壁になっています……
何に困ってるのかがよくわからんのだけど・・・。
>>49 (gcc 3.3.3)
struct base {
base() {}
virtual void func() = 0;
virtual void doSomething() = 0;
void func_wrapper() { doSomething(); func(); }
};
struct derived : public base {
derived() {}
void func() {}
void doSomething() {}
};
derived d;
d.func_wrapper();
>>53 それでもいいのですが……
・コンストラクト時にdoSomething, funcが完了している保証が必要
・doSomethingはfuncより先に行われる
・doSomethingはDerivedのメンバに依存する
・funcは独立していなければならない(後で別に呼ぶ可能性がある)
……Derivedの作成者に「コンストラクタの最後に必ずfuncを呼ぶ」というルールを強制するしかないのか……
守られるとは限らない訳だが……orz
>>54 class Base {
protected:
Base() {}
public:
template <class T>
static T *create() {
Base *p = new T;
p->doSomething();
p->func();
}
virtual void doSomething() =0;
virtual void func() =0;
};
struct Derived : public Base {
void doSomething() {}
void func() {}
};
Base *obj = Base::create<Derived>();
・・・汚いな(;´Д`) スマソ
56 :
55 :2005/10/07(金) 21:31:34
すっげぇバカな勘違いしてますた orz 無視してけれ(´・ω・`)
>>49 もはやDerivedとBaseが継承関係に無いけど、
class DerivedBase {
protected:
Base *owner_;
public:
DerivedBase() : owner_(NULL) {}
virtual ~DerivedBase(){}
void setOwner(Base *o){ owner_ = o;}
virtual void func(void) = 0;
virtual void doSomething(void) = 0;
};
class Derived : public DerivedBase {
public:
virtual void func(void) {}
virtual void doSomething(void) {}
};
class Base{
std::auto_ptr<DerivedBase> derived_;
public:
Base(std::auto_ptr<DerivedBase> d) : derived_(d) {
derived_->setOwner(this);
derived_->doSomething();
derived_->func();
}
};
つまり、is aとかhas aとかの関係が変なんじゃないの?と言いたい。
58 :
デフォルトの名無しさん :2005/10/08(土) 00:20:43
>>32 >>33 ご支援ありがとうございました。
みなさん、経験豊富なんですね。すばらしいです。
59 :
デフォルトの名無しさん :2005/10/08(土) 01:16:33
ふと疑問に思ったのですが,以下のようなプログラムはメモリーリークしないのでしょうか? char* Log; Log="123"; //(1)4byte確保 Log="1234567"; //(2)8byte確保 (2)のときに,(1)で確保された4byteはどうなるのでしょうか? 勝手に開放されるのでしょうか?
解放されない。しなくても良い。
61 :
デフォルトの名無しさん :2005/10/08(土) 01:21:21
>>60 それなら
for(int i=0;i<100000;i++){
Log="長い文字列";
}
とすると,大量のメモリを消費するということでしょうか?
しません
そもそも、文字列はメモリを動的確保しないじゃろ。 Log = "なにか"; は、文字列リテラルへのポインタを代入してるだけ。
64 :
デフォルトの名無しさん :2005/10/08(土) 01:32:32
もしかしてこの関数は使えませんか?! const char* GetMessage() { char* Message; Message="関数の中で確保"; return Message; }
65 :
デフォルトの名無しさん :2005/10/08(土) 01:35:31
66 :
デフォルトの名無しさん :2005/10/08(土) 01:36:21
となると,文字列にはガーベッジコレクションが実装されているのですか?
されてません。
性的なんだよ。
>>66 int i;
void f(){
int* p;
for(1000){
p = &i;
}
}
おまえはなにをしたいんだ
71 :
デフォルトの名無しさん :2005/10/08(土) 01:47:39
あ,分かりました! コンパイル時にすでにサイズが決まって,実行時のはじめに領域が確保される(=静的)んですね!! それだとこの場合は無駄なメモリを確保するんですね! bool bOK=1; char* Log; if(bOK) Log="短い文字列" else Log="超超長い文字列"
bOKが固定で、最適化で排除されなければね。
73 :
デフォルトの名無しさん :2005/10/08(土) 01:52:17
分かりました!!! ありがとうございます! ってか,よく細かいつまらないことまでご存知ですね! これでもC/C++歴5年ですが,,,
そうする必要があるのなら、無駄ではないんじゃない。
つーか、5年もなにやってたのかと。
char *str="hoge"; char str[]="hoge"; の違いを勉強する時に一度は目にする内容だけどなぁ。
ここは釣り堀じゃないですよ
名前を指定すると対応する関数を呼び出すようなものをクラス化しようとしているのですが、うまくコンパイルできません。どう書けばよいのでしょうか? ちなみにコンパイラはBCC++5.5です。以下のソースでは「クラスメンバーを初期化できない」というエラーになりました。 名前から関数への変換に、テーブルを使わずにif()の連続攻撃なら、コンパイルできますが、あまりに愚かしいので・・・ #include <string.h> class X{ public: void FuncA(void); void FuncB(void); typedef struct tagNAMETOFUNC{ char* Name; void (*Func)(void); } NAMETOFUNC; NAMETOFUNC NameToFunc[] = { {"FuncA", FuncA}, {"FuncB", FuncB}, }; void Select(char *Name){ int i; for (i = 0; i <= 1; i ++){ if (strcmp(Name, NameToFunc[i].Name) == 0){ NameToFunc[i].Func(); return; } } } };
>>78 std::map< std::string , boost::function< void () > >
class X { typedef void (X::*FUNCTYPE)(); struct NAMETOFUNC { char* funcName; FUNCTYPE funcPtr; }; static const NAMETOFUNC funcList[]; void FuncA(); void FuncB(); }; const X::NAMETOFUNC X::funcList[] = { "FuncA", &X::FuncA, "FuncB", &X::FuncB, };
>>80 うわっ、これメンバ関数を呼び出す時は
X x;
(x.*x.funcList[i].funcPtr)();
なんて奇っ怪な書き方をしないとだめなのか。x.とx.*が一個ずつ出てくる所が
気持ち悪い。
メンバ内からなら、 (this->*funcList[i].funcPtr)();
>>55-57 アドバイスありがとうございます。
アスペクト指向的なトリックは使えそうかも……
確かにis aないしhas aの関係がおかしいかもしれません……
というより過度の一般化を試みていると言った方がいいかも。
もう一度その辺りを見直してみて、身の丈にあった設計を考えてみます。
84 :
デフォルトの名無しさん :2005/10/09(日) 01:45:19
ファイルへバイナリで書き込むとき、数値を直接記述することは出来ないのでしょうか int number = 84; ofstrm.write( (const char*)&number, 4 ); を ofstrm.write( (const char*)84, 4 ); として読みやすくしたいなと
>>84 禿げしく遅いけど。boost::format当たりに何かいいのがあると思う。
#include <iostream>
#include <fstream>
class Binary {
int x, y;
public:
Binary(int i = 0, int j = 0) : x(i), y(j) {}
int getx() const { return x; }
int gety() const { return y; }
};
std::ostream& operator<<(std::ostream& os, const Binary& bin)
{
const int x = bin.getx();
for (int i = 0; i < bin.gety(); i++)
if (!os.put(reinterpret_cast<const char*>(&x)[i]))
return os;
return os;
}
int main()
{
std::ofstream test("test.bin", std::ios::out | std::ios::binary);
test << Binary(84, 4);
}
あ、やっぱこれまずいわ。 第一に環境依存。 第二に4バイトintでlittle endian(x86等)だと3バイト以下が変。バグあり。 第二の方はfor文の中身をいじれば直る。 for (int i = bin.gety() - 1; i <= 4; i++) それから i = 0の時はエラーを返さないとだめだね。
for (int i = bin.gety() - 1; i < 4; i++) だめだ寝ぼけてる。スマン。
>>85 自己レス。little endianでなら
std::ostream& operator<<(std::ostream& os, const Binary& bin)
{
const int x = bin.getx(), y = bin.gety();
if (y == 0)
return os;
for (int i = 0; i < y; i++)
if (!os.put(reinterpret_cast<const char*>(&x)[i]))
return os;
return os;
}
big endianなら
if (y == 0)
return os;
else
for (int i = y - 1; i < 4; i++)
かな。うーん汚い。
環境依存でもこれでええやん write(fd, &number, sizeof(number))
>>89 FILE* 使ってもいいならそれでいいんだが・・・・
多分ストリームを使いたいんじゃないかと。
あ、チゴタ、FILE*じゃなくて、低レベルI/Oか。 もうだめだ寝る。
>>84 というわけで、具体的に何をしたいのか書かないと有効な回答が得られないのです。
>>84 お前がやりたいことはofstrm << '\x54';で十分のような。
int calculation( long long int *f, long long int *a, int n ) { int i = 1; int j; a[1] = f[1]; while( i < 10 ){ for( j = 2; j <= n; j++ ){ a[j] = f[j] - a[j-1] * i; } if( -1 < a[n] && a[n] < 1 ){ break; } else{ i*= -1; if( 0 < i ){ i++; } } } return i; } 組み立て除法で割り切れる数値を探すプログラムなのですが、 if( -1 < a[n] && a[n] < 1 ) の判定が上手く出来ません。 勿論 if( a[n] == 0 ) も検証してみました。 判定の直前で a[n] の値を出力すると0と出てくるので原因が分かりません。 どなたか助けてください。
もしかして long long int *a の元の配列の大きさは a[n]ではないか?
>>94 x=iで考えて
while( i < 10 ){
for( j = 2; j <= n; j++ ){
a[j] = f[j] + a[j-1] * i;
}
if( -1 < a[n] && a[n] < 1 ){
break;
}
i++;
}
97 :
94 :2005/10/10(月) 00:43:33
>>95 いや、それは大丈夫です。
配列の要素数は n + 1 となっています。
>>96 ?
どういう意味でしょうか?
98 :
デフォルトの名無しさん :2005/10/10(月) 01:02:29
おせーてください! constなメンバ変数を持つクラスを自作したわけなんですが、 operator=が必要になりました。デフォルトで済まそうとすると、 constには代入できねえよボユゲと言われてしまいます。 こいつを代入できるようにするにはどうすればいいでしょうか。
operator=内でconstメンバの代入はどう処理するつもり?
>>98 コンストラクタ・コピーコンストラクタはconstやリファレンスにも代入できるだろ。
それを利用してoperator=を書く。
間違った 代入ではなくて、初期化リストに書く。
103 :
98 :2005/10/10(月) 01:20:27
>>99-101 レスありがとうございます。
>それを利用してoperator=を書く
な、なるほど!コピーコンストラクタなら既につくっとります!
これでなんとかやってみます!
どうやるのか全然想像つきませんが!
というか、普通にコンストラクタでnewして、*thisに代入すれば いいじゃないか。
そもそもconstなメンバ変数をもつクラスに、 代入演算子を定義するのが根本的に設計が間違ってる気がする。
>>105 これをすると新旧インスタンスが2つできることになるけど
この場合どっちを明示的にdeleteするべきなの?
>>98 このように代入演算子中で一時オブジェクトを作り、*thisに代入する。
#include <iostream>
class A {
const int i; // 例えば
public:
A(int j = 0) : i(j) {}
A(const A& a) : i(a.i) {}
A& operator=(const A& a) {
return *this = A(a.i);
}
};
int main()
{
A a, b;
a = b;
}
109 :
98 :2005/10/10(月) 01:33:52
なんか・・いろいろレスありがとうございます
頭こんがらがってきましたがなんとかやってみますorz
>>106 はじめはprivate宣言してたんですが
それをvectorに格納しようとするとoperator=が使えないと
できないよなんて言われまして・・・
ポインタを格納すれば早いんですが
なんとか代入演算子を定義できないものかと
>>107 newはこの場合使うな。メンバにポインタが含まれている時のみ使う。
>>108 > A& operator=(const A& a) {
> return *this = A(a.i);
> }
これは自分自身を読んでね?
>>108 そいつは永久ループに入ります。
やるとすればこういう風にしないと。
#include <iostream>
#include <new>
class A {
const int i;
public:
A(int j = 0) : i(j) {}
A(const A& a) : i(a.i) {}
A& operator=(const A& a) {
new (this) A(a.i);
return *this;
}
void printi() const {
std::cout << "i = " << i << std::endl;
}
};
int main()
{
A a(123), b;
b = a;
a.printi();
b.printi();
}
>>113 new(this)の前にデストラクタ呼びましょうよ
>113 しかしそれはいろいろ危険性が
>>114 デストラクタも呼ぶなら自分自身が引数のときに代入をスキップするのも忘れるなよ。
おぉ目から鱗だ 完璧なoperator=をコピーコンストラクタ使って書くと結局どう書くのが正解?
というかやはり const メンバを持つクラスに代入を定義するところに難がある気がする 具体的にどういう設計かは書いてないからこれ以上は指摘しようがない >117 例外を送出しない swap を実装しているとして A tmp(a); tmp.swap(*this); return *this; っていうか基本
>118 あー、ちなみにこれは const メンバがない場合の話ね。 const メンバがあるクラスの代入については 118 の最初に書いたとおり
簡単な問題のように見えて、意外と難しい問題だな。
C++トリビア1と呼ぶか。まあ
>>118 さんのおっしゃっておられる
ように、constメンバは基本的に初期化しかできないので、
設計に難があるという事になるな。
>>117 new使うならこんな感じかな。
thisとaが同じインスタンスで、
さらにaがAを多重継承していて且つ、
thisとaでそれぞれ参照しているAが違う場合を考えると不正解だけど。
まぁ、そこまで神経質にならなくてもいいかな。
A& operator=(const A& a) {
if(this != &a){
this->~A();
new (this) A(a);
}
return *this;
}
122 :
121 :2005/10/10(月) 02:03:53
あとaがthisのメンバ変数になってる場合もアウトか
123 :
121 :2005/10/10(月) 02:07:16
あ、しまった。 二回コピーコンストラクタ呼び出すと回避できるね。 A& operator=(const A& a) { if(this != &a){ A b=a; this->~A(); new (this) A(b); } return *this; }
124 :
98 :2005/10/10(月) 02:07:16
>>113-116 感動しますた
しかし自分では全く思い浮かばなかったばかりか
コードを見た後も処理がいまいち理解できません。
まあそれはこれから勉強します。ありがとうございました!
>>118 球を表わすclass Ballが、メンバにpos,vel,accと定数mass,radius,rebound
を持っているという感じでして、代入は初め禁止してまして。
それを複数個保持したいなと。vector<Ball>を使おうかな、と。
そうすると
>>109 という
気持ち悪いC++って。 new (this) A(b); こういうnewの配置構文初めて見た。ま、確かにコンストラクタから コンストラクタを呼び出せない(呼び出しても結果が残らない)C++独特の trickだね。
×newの配置構文 ○newの配置構文の使い方
118と123はお互いのコードをどう思う? ツッコミたいこととか
>121-123 継承云々を抜きにしても、たとえば A のコピーコンストラクタが 例外を送出した場合のことを想像してみてくださいな >124 については違和感があるけれど言葉がまとまらないなぁ。妥当な気もするけど 誰かヘルプ
129 :
121 :2005/10/10(月) 02:29:14
>>128 じゃあ、例外を送出しない コピーコンストラクタ を実装しているとして、とかを条件に加えればOK
問題は自分が定義する外に責任転嫁しちまえ。
......ゴメン、例外忘れてたわorz
例外まで考慮すると、今のC++の文法だけでうまく書けるんかいな?
124 については、C++ というのは(上のように配置構文 new を使うなどしない限り) 一つのメンバの定数性がクラスオブジェクト全体の定数性に伝播するような モデル(それが良いか悪いかはともかくとして)なので、クラスオブジェクト全体を 非定数にしたいなら、メンバは全て非定数として宣言して、クラス内部における定数性は クラスの実装者が責任を持つしかしようがない、ということなんですかね? ちょっと強引かなぁ
>>131 > クラスオブジェクト全体を非定数にしたいなら、メンバは全て非定数
これは普通に考えて必然だろ。
メンバ radius が定数であるなら、 radius が 1 のインスタンスに
radius が 2 のインスタンスを代入すること自体が論理的に不可。
>>132 ああ確かにそうだな。やっぱり普通にprivateにしてアクセサ書くか。
クラス内の非constメンバの値の管理は自己責任だというのが
正しいC++の考え方だもんな。
あー、寝る前に変な質問が出てきたと思ったらやっぱりまともな結論に落ちるまでに紆余曲折あったか。
んなどうでもいいことイチイチ書くな
煽らずにはいられない性格
自己顕示欲が強いのに、面白いことがまったく書けない悲惨なセンスしてると、 どうしても煽りに頼った人目の引き方に走ってしまうんだよね。
SFINAEの読み方を教えてください
140 :
134 :2005/10/10(月) 11:31:51
>>137 ん、寝る前だったからうまい突っ込みを思いつかなかった。
素直に「非constにして隠蔽しろ」とでもすればよかったんだが。
142 :
namahage :2005/10/10(月) 18:07:54
logxのテーラー展開するプログラムってどうやったらいいんですか?
143 :
namahage :2005/10/10(月) 20:31:22
age
うるせー馬鹿
146 :
デフォルトの名無しさん :2005/10/10(月) 22:16:18
BM法の文字列検索の主な部分です。 while(strcmp(koukyou[m].name,"")!=0)のところがループしません。 データはすべてはいっていることは確認しました。 なにがわるいんでしょうか?教えてくださいおねがいします。 ヘッダ部分の宣言 class CSearch : public CFileData { public: CSearch(char *name); virtual ~CSearch(void); int result[300]; int skip[256]; void table(char *key); char *Search(char *text,char *key); void str_match(char *key);};
147 :
デフォルトの名無しさん :2005/10/10(月) 22:17:28
つづきです。 cpp部分。 #include "StdAfx.h" #include "Search.h" CSearch::CSearch(char *name) { file_koukyou(name); for(int i=0;i<300;i++){ result[i]=0;} } CSearch::~CSearch(void) { } void CSearch::table(char *key){ int k,n; n=(int)strlen(key); for(k=0;k<=255;k++) skip[k]=n; for(k=0;k<n-1;k++) skip[key[k]]=n-1-k; } char *CSearch::Search(char *text,char *key) { // return strstr(text, key); int m,n; char *p; m=(int)strlen(text); n=(int)strlen(key); p=text+n-1; while(p<text+m) { if(*p==key[n-1]) { if(strncmp(p-n+1,key,n)==0)//右端だけを比較 return (p-n+1);// } p=p+skip[*p];//サーチ位置をすすめる。 } return 0; } void CSearch::str_match(char *key) { char *p; table(key); int m=0; int j=0; int num; while(strcmp(koukyou[m].name,"")!=0) { p=Search(koukyou[m].name,key); while(p != NULL) { printf("%s\n",p); p=Search(p+strlen(key),key); result[j]=m; printf("%d\n",result[j]); j++; } m++; } }
ちょっとすいません enum Bool{TRUE,FALSE}; union T { char a; struct { Bool b :1; Bool c :1; }; }; でsizeof(T)が4になる理由をおしえてくれ
149 :
デフォルトの名無しさん :2005/10/11(火) 01:44:13
ageわすれ
パディング
お返事ありがたいんですが, どうパディングされたらビットフィールドの値を無視して4になるのかわからんのです。
ビットフィールドの値は無視されて無い。 enum Bool が 32bit になる筈だから、sizeof(T) == 4 になる。
153 :
デフォルトの名無しさん :2005/10/11(火) 02:16:43
よく理解できないんでもう一度考えてみます. レスありがとうございました。
>>153 ビットフィールドがどう配置されるかは処理系依存だけど、
「オブジェクトの型表現のサイズが指定したビットより大きい場合、余ったビットは詰め物として使われる」
とだけあるから、例えば
struct T {
int a:1;
};
sizeof(T) == sizeof(int)
になるし、
struct T{
short a:1;
};
sizeof(T) == sizeof(short)
になることは確か。
でこの場合、Bool b :1;の時点でsizeof(T) >= sizeof(int) (=4)は確定して、あまりのところにcが詰め込まれたんでしょ。
っていうか、普通は enum にビットフィールドを設定することって無いとおもった 上手く動かないことの方が多いんじゃないか
enumの値を保持するのに十分なサイズが指定されている場合には、元の列挙子と同じように使えなければならない と規格で決まってるから大丈夫。
ってことは、これってsizeof(BOOL)==sizeof(T)を強制できるってことか?
158 :
148 :2005/10/11(火) 12:48:49
struct S1 { union T; }; struct S2 { T t; }; とすると(ちょっと古いg++ですが) sizeof(T) == 8 sizeof(S1) == 1 sizeof(S2) == 8 となることが分かりました. いろいろと腑に落ちない部分がありますが触れてはいけないようなので別の方法を試みることにしました.レスくれた方ありがとうございます.
159 :
148 :2005/10/11(火) 12:53:08
すいません.嘘書きました(汗 sizeof(T) == 4 sizeof(S1) == 1 sizeof(S2) == 4 の間違いです
>>158 もともと何も問題起きてないと思うんだが、つか、C++/class じゃなくて、
基本的には C言語でのこの種の理解をしてないだけじゃないかしら
>>148 自分で作ってみたら?
サイズがシステムに最適化されるプリミティブなクラスでも。
>>154 > 「オブジェクトの型表現のサイズが指定したビットより大きい場合、余ったビットは詰め物として使われる」
これは規格からの引用?どこ?
9.6.1 だとしたら
「指定したビット数がオブジェクトの型表現のサイズより大きい場合」
の間違いじゃない?
sizeof(T) == sizeof(int) になることも
sizeof(T) == sizeof(short) になることも
確かだと言える根拠は無いでしょ?
全部処理系依存。
>>155 C だと (signed|unsigned) int しか使えなくて、
C++ でその他の整数型と enum が許されるようになったみたいだから、
移植性を気にする人は使わないんだろうね。
各ビットをフラグに使うだけなら論理積で十分だしなぁ
>>158 S1の T ってただの型宣言になってるぞ。
sizeof(S1) == 1 になって当たり前w
166 :
デフォルトの名無しさん :2005/10/12(水) 20:45:23
動的に変化する2次元配列の配列を作りたいのですが、 どうすればよいのでしょうか? 普通にnew演算子を使って作るのはできるのですが vectorを使った方が都合が良いです。 例えば std::vector< std::vector<int> > matrix; matrix.push_back(std::vector<int>(4)); … という具合にmatrix[*][4]は作れますよね。 こんな感じで matrix[*][9][4]のような物を作りたいのですが、 上手くいかなくて困り果てています…
class CSomething { public: int getInstance(){ /* なんちゃらかんちゃら */ }; }; int g_N = CSomething::getInstance(); int main() { return 0; } グローバル変数を↑こういう風に初期化するのって問題ないですか?
まずはstaticにするべきじゃないかな?
169 :
167 :2005/10/12(水) 21:14:49
>168 正しくは↓でした('Д`;) class CSomething { public: static int getInstance(){ /* なんちゃらかんちゃら */ }; };
>>167 いいけどその例ではgetInstanceが静的メンバでないとCSomethisng::で修飾してのアクセスはできないよ。
どういうプログラム組んでるか分からないから、わざわざ静的メンバ関数で グローバル変数を初期化する意義が読み取れない。 だからまあ、設計に関しての常套文句が二つ三つ出てヤメレって言うしかないわけだが。
>>166 動的な1次元のプロキシクラスを作って、それの配列クラスという形で、
2次元クラスを作るのが常套手段。
173 :
167 :2005/10/12(水) 22:11:05
>168-171 コード・文法的に問題あるとかってことはないぽってことですね。 ありがとうございました。 >171 確かにサンプルコードだけ見ると、何しようとしてるんだって感じですね。 実際にはもう少し意義ある形なので、ここはお目こぼしを[・∀・]
void foo(A& a) { bzero(&a, sizeof(a)); } なんで最初の要素しか0にならんのか 暫く気づかなかった
聞くは一時の恥 聞かぬは一生の恥
うん。がんばろう。
>>174 なんでなん?orz
>>174 class A { int i; };
std::cout << std::showbase << std::hex << &a << ' ' << std::noshowbase << sizeof(a) << std::endl;
俺の環境では
0x0023ff77 4
どう考えても最低4バイト初期化されるが・・・・・
>>166 自分で作るのが面倒ならboost::multi_arrayがその目的まんまだから使ってしまえ
>>176 >174はポインタを渡して配列を初期化するつもりだったんジャマイカ?
@boolとintってどっちが高速なんですか? AテンプレートってC++にしかないんですか?
>>181 @intに0か1を入れてbool代わりに使う という話ならどちらも大差ない
Aジェネリクスの概念は他の言語にもある
強力……っていうかむしろ大惨事発生装置。
185 :
181 :2005/10/13(木) 18:52:04
JAVAにありましたっけ?
最近出来た。コレクションからオブジェクト出すときのキャストを省略する目的で。
>>185 一応有る。Java Genericsでググるといっぱい出てくるよ。
JavaSDK1.5に入る予定だったけど、結局入ったのかどうかは知らない。
たしかC++程の強力さはないけど。
c++のテンプレートってさ Tになにを求められるか−たとえばTは++演算子が使えるインターフェイスでなければならない ってのがよみとりにくくて不便じゃない?
>>188 そこでC++ 0xではコンセプトを導入してそういうことをコードに書けるようにしようということになっている。
190 :
174 :2005/10/13(木) 21:54:52
struct A { int m1; int m2; }; A a; a.m1 = 1; a.m2 = 2; foo(a); cout << a.m1; cout << a.m2; ってな感じなわけですよ!!!!
191 :
デフォルトの名無しさん :2005/10/13(木) 22:46:58
趣味で正規表現をテストするオートマトンなんか書こうとしてます。 class abstract_status { }; class status : public abstract_status { string name; map<set<char>,abstract_status*> transition_map; }; class automaton { status *start; status *accept; status *current; list<status*> status_list; }; ってな感じで進めているのですが、transition_map の set<char> のところは単なる char にしたほうが良いかどうか。。。 あるいは、全く別の構造にしたほうが良いのか。。。 アドバスお願いします。
>>190 で、なんで最初の要素しか0にならんの?
>>191 set<char> にした場合の使い方がわからない。
素朴な疑問なんだが、set<char>同士ってoperator< で比較できるのか?
>>197 なにが「なるほど」なのやら。両方ともゼロになるだろ。
>174が書き間違えている悪寒。
今日のム板は初っ端からクオリティの低い書き込みが多いな それともC++関連だけか?
クオリティって言ってみたかっただけっぽい
>>197 sizeof(A) ならいいけど sizeof(a) だからダメって言うこと?
コンパイラがバグってるだけじゃない?
sizeof(A&) が 4 か 8 か、どっちよ? って話しだべ? 参照はポインタみたいなもんだから。 どっちが正しいか知らんけど、 VC7.1 じゃ 8 だったな。
>>205 ISO/IEC 14882:1998
5.3.3 sizeof
2. When applied to a reference or a reference type, the result is the size of the referenced type.
8になるのが正しい
ギョエー
208 :
デフォルトの名無しさん :2005/10/14(金) 22:54:12
>193 void automaton::tick(char input_char) { for(i=0; i<(current->second).size(); i++) { if (((current->second)->first).count(input_char) > 0) { current = (current->second)->second; return; }}}
209 :
デフォルトの名無しさん :2005/10/14(金) 22:55:51
あ、iterator 使わないと駄目だ↑
210 :
デフォルトの名無しさん :2005/10/14(金) 23:01:35
void automaton::tick(char input_char) { map<set<char>,abstract_status*>::iterator tmitr = (current->second).begin(); int i; for(i=0;i<tmitr->size();i++) { if ((tmitr->first).count(input_char) > 0) { current = tmitr->second; return; } tmitr++; }}
211 :
デフォルトの名無しさん :2005/10/14(金) 23:02:48
実際には automaton から status の中の変数は扱えないので 2段に分けて記述しています。
212 :
デフォルトの名無しさん :2005/10/14(金) 23:24:04
class CVal { public: CVal(int val, char * name) { v = val; } ~CVal() { } operator int () { return v; } private: int v; char * n; }; というクラスがあるのですが、このクラスを次のように使うとintにキャストされてうまくいきます。 CVal val(1, "なんか"); if(val == 1){... しかし次のようにprintf系に渡すとおかしくなってしまうようです。この場合どう扱われてるのでしょう? CVal val1(1, "foo"); CVal val2(2, "boo"); printf("%d, %d", val1, val2); ↑ 最初の1は正しく出るがval2は変な値になる。
printfは型チェックしないからキャストもされない。
そしてC++のiostreamなら型チェックがあるからoperator intで変換できる、という流れへ。 printfでは自分でstatic_castすればとりあえず動く。 printf("%d, %d", static_cast<int>(val1), static_cast<int>(val2));
なるほど。ありがとうございます。 ってことはほかの場所でも実はちゃんとintにキャストされずに動いてる可能性もあるわけですね。 ちょっと怖いですね。
こういうことがおこるのはprintfみたいに可変個引数を使っている場合だけだがな。
217 :
デフォルトの名無しさん :2005/10/15(土) 19:47:40
>>217 書いた人ですか?
最初のほうを読んで一つ目だけ。
>高度な型 - C++の構造体
>メンバ関数を持つことができる。(実際のプログラミングでは、使わないこと)
括弧部分が大きなお世話。
関数オブジェクトではstructにメンバ関数を書くのが普通だったりする。
あとは見出しだけざっと見ただけだが、templateやnamespaceの記述が無い・・。 標準C++ライブラリを使うには必須の機構だし、普通に使うものなので 今C++を語るなら書かないのは片手落ちだろうなあ。
C++では値の比較時(if文などの条件で)に、intより小さいサイズの型はintに昇格する よってunsigned char a=b=200;のときunsigned char c = (a+b > 255) : 255 : a+b;と書いても、予期したとおり動く Cでも同じなのかもしれんけど。 strstreamよりstringstream使うべき
>void型はC++で創始され、それがANSI Cに反映されたものであり、voidについてC++で正しいことはANSI Cでも正しい。 ダメすぎ。 総じて、よく判っていないながら実務経験だけはある香具師が、経験則から得たメモを書いているだけ。 書いた香具師のプロファイリングを楽しむにはいいが、参考にはならない。
重要な所が結構抜けてるね。 ・参照 ・メンバ初期設定リスト ・仮想基本クラス あとこういうの書くときはC++の設計と進化を読んで書いて欲しい。
>>217 つっこみどころが多すぎてつっこめません・・・
>>217 wchar_tはCでもtypedefで用意されている。そしてC++では組み込み型になっている。
> 列挙変数を enum キーワードを使わずに宣言できる。Cでは必要だった
構造体と共用体も同じくstructとunionが不要になったことが書かれてない。
>if (x < 100)
> double g = sin(x);
>else
> double g = cos(x);
この後でgが使えないのは、ifとelseの中身はそれぞれブロックが作られているからのはず。
forの構文は正しくはfor (宣言文または式文 式 ; 式 ) 文 となる。
今はprotectedはC++固有ではない。JavaとかC#とかみんなC++由来だけど。
>基底クラスと派生クラスの代入
本文の基底と派生を入れ替えると正しくなるw。
続く
続き <iostream.h>は古い。今は<iostream>。stdiostreamは非標準。 strstreamは標準にはあるが非推奨。<sstream>のistreamstream/ostringstreamがある。 iostream_with_assign類も非標準。 多重定義の解決には5番目に可変個引数 ... もある。 まあ、知らずとも大体想像通りに解決されるとでも書けばいい。 そういう目標でC++の多重定義解決の規則は作られた。 volatileはC由来。 ファイル内スコープの意味でのstaticは非推奨、無名名前空間が推奨されている。 使うべきでない機能として挙げるだけでなく理由も書け。 あと、本文中に1度もオブジェクト指向、ポリモーフィズムと言った言葉が出てこないのが異常。 テンプレート、名前空間、例外が全く出てこないのもどうかと。 しかしこれらを直しても所詮は付け焼き刃、根本的にお前自身がC++をよくわかっていないだろ。
Cにおいてchar型は自動的にintに昇格していたが、 C++においてもintに昇格したのち演算が適用される 8行目にして間違っている解説はなかなかないが それに気づかない人たちのなにやら難しいつっこみはいっそう無視してよい
いや、3行目の間違いが既に指摘されている。
細かいことだけど、constにbool、参照、ifとwhileの条件での変数宣言なんかも抜けているな。 inlineも説明なしで使われている。
何はともあれ結論はオナヌー文章ウザイってこった
C++とか書いている時点でもうダメダメ。
マトモな感覚のある奴なら全角英数字なんて滅多に使わん
HAGESHIKUDOUI
233 :
217 :2005/10/16(日) 17:35:35
いろいろ指摘していただいてありがとうございます。 オブジェクト指向の設計については省いた、 C++についてできるだけ簡素にまとめられたドキュメントありませんか? できれば言語仕様とオブジェクト指向設計、STLやらライブラリがからむのは 分けてかかれたものがいいんですけど。 皆さんのバイブルを紹介してもらってもいいですけど。
235 :
デフォルトの名無しさん :2005/10/16(日) 17:37:28
あーでもいまからならJAVAですかね? JAVA使うならJAVAで使えないC++の仕様とか下手に覚えない方が楽ですよね?
236 :
233 :2005/10/16(日) 17:44:00
>>234 評価高くてよさそうですが、C++はなにもわからないんでやめときます。
> 個人的には、記述内容の間違いを読みながら補正できる
> 「プロ」レベルの人以外は読むべきではないと思います。
> 少なくともこの翻訳された内容を鵜呑みにするのは問題が多すぎると思います。
241 :
デフォルトの名無しさん :2005/10/16(日) 18:35:59
>>241 D&EはC++の基礎をある程度知った上で読まないと意味がないかと
245 :
233 :2005/10/16(日) 22:17:40
>>244 > C言語を勉強した人向けとなっておりますが、全くその通りです。
なるほど。
これも定番ですがよさそうですね。
246 :
デフォルトの名無しさん :2005/10/17(月) 12:27:09
大量にあるメンバ変数の内容を他のクラスに伝えたい 場合、何かいい方法はありますか?
クラスでカプセル化してインスタンスの参照を渡す
10の-N乗(N=1のとき0.1、N=2のとき0.01...)を 1.0/pow(10, N);より高速に計算する方法はどうすればいいのでしょうか。
>>248 環境によってやり方は違ってくるだろうなあ
250 :
248 :2005/10/17(月) 16:33:18
想定しているNの範囲は1-20程度なので、テンプレートの特殊化を使い: template <typename T, int N> struct decimal_place { static const T type = 1/std::pow(10, static_cast<T>(N)); }; template <> struct decimal_place<float, 1> { static const float type = 0.1f; }; template <> struct decimal_place<double, 1> { static const double type = 0.1; }; template <> struct decimal_place<long double, 1> { static const long double type = 0.1L; }; ...(以下20まで) としておいて、 double X = decimal_place<double, 1>::type; のようにしようと考えてみました。これはウンコでしょうか(´д`)
>>250 Nが整数で20程度ならテーブル参照がいい気がします
>>250 何でもいいけどtypeじゃなくてvalueにしとけよ気持ち悪い
スレ違いだけど、ウンコは苦いよ。
256 :
255 :2005/10/17(月) 19:43:54
>>250 もういっそのこと
各型での結果をそれぞれ float.csv, double.csv, ldouble.csv にでも保存しといて
const float decimal_place_float[] = {
#include "float.csv"
};
const double decimal_place_doulbe[] = {
#include "double.csv"
};
const long double decimal_place_long_doulbe[] = {
#include "ldouble.csv"
};
とかってしたら?
258 :
248 :2005/10/18(火) 00:34:50
>>250 はマクロを使って定義自体はそれなりに簡潔に書けました。typeは糞ですなスマンコ
gccで-O3オプションをつければ、特殊化した1-20については
アセンブラファイルを見る限りコンパイル時に定数にしてくれるっぽいです。
テーブル参照も試してみます。
csvも面白いアイディアです。thxです。
>>258 template <typename T, int N>
struct decimal_place {
static const T value = decimal_place<T, N - 1>::value / 10;
};
これってできない?
#今臥せっててコンパイラつかえないの。
>>259 これでgccは通った(他は知らね)
template <typename T, int N>
struct decimal_place {
static const T value = decimal_place<T,N-1>::value/10;
};
template <typename T> struct decimal_place<T, 0> { static const T value = (T)1; };
最近のは整数値以外の定数もテンプレート展開されるのか。
263 :
248 :2005/10/18(火) 03:04:56
>>259-260 ウチのgccでもコンパイル通りました。
パフォーマンス的にも数字書く方式と変わらないです。
std::pow()で計算するより二桁ほど速く、十分なスピードです。
ありがとうございました。
static const メンバ変数に初期化子を付けていいのは 整数型と enum 型だけだよ。 float 等に対応するには value を関数にすればいいんだろうな。 でも最適化されにくそうだな。
inline指定した時に、展開されなくなる最低条件みたいなのありますか?
266 :
265 :2005/10/19(水) 14:49:04
とりあえず、調べて ・ループ ・静的変数 ・goto ・再帰 ・switch をやると展開されなくなるっぽいですね。 switchはなんか納得いきませんけど。 他にありますか?
269 :
265 :2005/10/19(水) 15:02:22
確かに、そうなんですよね。 でも、なんかガイドラインというか、 だいたい、これをやるとだめだ、 みたいなのがあるのかな〜と思って。
>>269 お前の脳内ガイドラインか?w
規格票ぐらい最低目を通しとけ。
「あるのかなぁ」のどこが脳内なんだか。 あまり頭の悪い煽りすんなよ、寒いから。
>>269 実際コンパイラによってかなり違うと思う。
g++3.2.3だと、gotoとforループを含む関数をインライン化した(static変数とswitchは試した範囲ではだめだった)。
273 :
272 :2005/10/19(水) 16:46:43
static変数も単純な関数ならいけるね。
>>270 英語が読めない馬鹿か。可愛そうに。氏んでいいよ。
>>271 説明になってないから。寒けりゃ練炭でも抱いて寝れば?wwww
激しくレベルが低い質問でとても恥ずかしいのですが教えてください。 Linuxでアプリケーション作っているんですけど、そのアプリケーションの 設定ファイルをそれぞれの一般ユーザーのホームディレクトリに作りたいと 思っています。プログラム自身は/usr/local/binに置くつもりです。 ofstream fout("hogehoge.txt"); でファイルを作ると実行ファイルと同じ場所に出来てしまいます。 というか、/usr/local/binではパーミッションで作れません。 ホームディレクトリはどのように指定してやればいいのでしょうか。 教えてください。お願いします。 FedoraCore4でフルインストール、フルアップデートな状態です。
>>275 もうちょっとマシな負け犬の遠吠えを期待したんだけどな。
練炭ねえ。やっぱり寒いわ、君のセンス。
犬といっしょに泥んこになって遊ぶ子供みたいだな
コンストラクタにconstはいりますか?
>>283 メンバ関数の場合のconstの有無からの連想で質問しているとしたら、要らない。
何故ならばコンストラクタではインスタンスを初期化しなければならないため、常にconstではありえない。
>>283 そもそもコンストラクタ(・デストラクタ)にconstはつけられない。
286 :
デフォルトの名無しさん :2005/10/21(金) 17:50:01
つかぬことをお聞きしますが、 BoostのURLにある hamaji _at_ nii.ac.jp / shinichiro.h 最後のhですが、niftyにおける「ハンドル名」は 花田なんてことはないですよね?
template<template <class T> class U> とは書けるのに template<template <typename T> typename U> と書けないのはなんでですか? いままで template 引数の中の class と typename は同じだと思っていたのですが・・・。
>>287 おそらくU<T>として使えるのはUがクラステンプレートの場合しかあり得ないからだろう。
ちなみにtemplate<template<typename T> class U>はできる。
289 :
デフォルトの名無しさん :2005/10/21(金) 18:12:17
最近C++を始めてみようと、 「Visual C++.net Standard Version2003 アカデミック」 を購入しました。 6枚のCDを出したり入れたりして4段階のセットアップが完了し 早速起動してみました。 よくわからなかったのでとりあえず ファイル⇒新規作成⇒プロジェクト で「test」と名づけたプロジェクとを作成したところ 以後「既存のプロジェクトを開く」の一覧から「test」を左ダブルクリックで選択すると 選択した瞬間にエラーが発生してC++が強制再起動します。 また、その後に作成した「test2」というプロジェクトは 選択時はセーフなのですが プロパティを見ようとすると同様に強制再起動します。 これの解決策をご教授くださいませ・・・
291 :
287 :2005/10/21(金) 18:27:20
>>288 反例がtemplateな関数ポインタとかで作れないかと考えてみましたが、断念しました。
というわけで、U はクラスしか取り得ないということで覚えておきます。ありがとうございました。
>>287 template<typename T> class U
でUという型名だとすると、これを
template<typename T> typename U
とは書けないからではなかろうか。
293 :
デフォルトの名無しさん :2005/10/22(土) 00:07:07
簡単なインストーラを作りたいんですが、どなたか教えてください。 実際、やることは簡単で、myapp.exeを指定したフォルダにコピーするだけです。 で、myapp.exeをインストーラと同じフォルダに入れておけば、myapp.exeを いったん読み込んで、指定したフォルダに書き込むプログラムはすぐできます。 しかし、そうではなくて、インストーラの中にmyapp.exeのデータを埋め込んで しまいたいのです。ユーザから見えないように。 また、インストーラをファイル1つにするために。 とすると、バイナリのデータファイルの内容を、実行可能ファイル(今の場合、 インストーラ)にマージさせることなどが可能なのでしょうか? そうでないなら、ファイル1つのインストーラはどのようにできているのでしょうか。 どなたか、教えていただけないでしょうか。
できる
C++とどう関係が?
298 :
デフォルトの名無しさん :2005/10/22(土) 18:15:35
staticクラスメンバについての質問なんですが 定義はどこでやるのがよいでしょうか? 今のところmain関数前にまとめて定義してたのですが 数が増えてきたり、初期化が複数行に渡ってるものがあったりで見づらくなってきました staticクラスメンバ用のヘッダファイルとか用意したほうがいいのでしょうか
>>298 クラスに対応したヘッダとソースを用意するのが一般的。
static メンバ変数の定義はそのソース側でやればいい。
ヘッダで変数の定義をするのだけはやめとけ。
ありがとうございます! ソースで宣言することにいたします
定義な
302 :
デフォルトの名無しさん :2005/10/22(土) 18:55:46
質問です template でも void * でも同じ動きをする関数では、 普通はどっちを使ったほうがいいでしょうか? template <class X> void funcTemplate_1 (X **p); void funcPointer_2 (void **p); みたいなやつなんですが・・ どなたかよろ m(__)m
>>302 「いい」の基準がわからん。
まぁ template 版のほうが型を知っている分、
良い仕事してくれるんじゃないかな?
テンプレートだと、型情報を失わないが、 型ごとに関数を作るからコードのサイズが大きくなりやすい。 ポインタだと、型情報を失うが、 関数が一つだからコードのサイズは小さく済む。 両方の利点を取るために下の関数を内部で呼び出すだけのinline関数を作るのが良いと思う。 そうすれば使うほうは型情報を失わないし、関数は一つしか作らずに済むから void funcPointer_2 (void **p); template <class X>inline void funcTemplate_1(X **p){ funcPointer_2(p); }
305 :
304 :2005/10/22(土) 19:09:11
あ、template関数の中でキャストするの忘れてた。
306 :
302 :2005/10/22(土) 19:12:20
おおお、そんな技が!凄い!
さっそくためしてみまっす。
>>303 >>304 >>305 ことば足らずですみませんでした。
どうもありがとうございます〜 m(__)m
307 :
293 :2005/10/22(土) 19:28:10
>>294 ありがとうございます。
わかりました。
>>295 ありがとうございます。
そちらのスレに質問を書きました。
>>296 ありがとうございます。
見てみます。
質問です。 class X { vector<int> v; public: void show() const; ... }; void X::show() const { for(vector<int>::iterator i = v.begin(); i != v.end(); i++) { cout << *i << endl; } } みたいなコードを書いたらコンパイルエラーになりました。それでiteratorをconst_iteratorに するとエラーでなくなります。それは、たぶん、showがconstだからかなとも思うのですが、 ちょっと納得がいきません。この解釈でよいのでしょうか。 v自身はconst vector<int>ではないので、const_iteratorでなくてもいいような気もするのですが。
>>308 constメンバ関数中では、変数はすべてconstと見なされる。
それが嫌なら、mutableと宣言すべき。
↑変数とは、メンバ変数の事ね。ローカル変数には適用されない。
312 :
デフォルトの名無しさん :2005/10/22(土) 20:52:26
つ[ImageMagick] つ[LeadTool] つ[google.com]
314 :
初心者 :2005/10/22(土) 22:16:15
最近、C++で一つのプログラムを書きました。実行するときDOSの状態で日本語を入力 したいですが。どうすればいいですか?知ってる方是非教えてください。
スレ違い
ALT+半角/全角
317 :
初心者 :2005/10/22(土) 22:18:40
最近、C++で一つのプログラムを書きました。実行するときDOSの状態で日本語を入力 したいですが。どうすればいいですか?知ってる方是非教えてください。
config.sysを書き換える
319 :
初心者 :2005/10/22(土) 22:24:50
デフォルトの名無しさん 、ありがとうございます。
うほっイイ初心者
#include <iostream> #include <vector> using namespace std; class Base{ public: Base(const string& s) {} }; class Derived : public Base{ public: Derived(const string& s) : Base(s) {} }; int main(){ vector<Base*> data; data.push_back(new Derived("D")); } をBorlandC++でコンパイルすると警告がでます。(上は全角空白を使ってます) 警告 W8030 vec_test.cpp 18: '__x' パラメータ(vector<Base *,allocator<Base *> >: :push_back(Base * const &))のために一時変数を使用する(関数 main() ) どうしてだかわかる方いますか?頭が変になりそうです。
そのままの意味だと思うが。
323 :
321 :2005/10/22(土) 23:06:02
>>322 すみません。確かに一時変数を使っているのでそのままですが、
data.push_back(new Base("B"));
では警告がでません。また、コンストラクタを引数無しのものに変えると警告が消えます。
ということで何がなんだかわからないのです。
324 :
321 :2005/10/22(土) 23:07:23
すみません。それで、一番知りたい事は、push_backの引数に一時変数を使うことが 警告されるような悪いことかということなんです。
data.push_back( static_cast<Base*>(new Derived("D")) ); とか? でもそれをsortとかしたらスライシングされるからやめとけ。
328 :
321 :2005/10/22(土) 23:12:19
>>325 レスありがとうございます。
でも、キャストしても警告は消えません。動作に問題ないようなので警告を無視してもいいのかも
しれませんが、なんだかものすごく嫌なんです。
それとsortでスライシングってどういう意味でしょう。スラインシングの意味がわからないのですが。
329 :
321 :2005/10/22(土) 23:16:42
>>326-327 ありがとうございます。
Borlandの警告のバグということでしょうか。
>>326 の下の752の「原則」は誤りだと思います。
一時変数をconst参照に渡しても問題ないと思うのです。
325は知ったかだから
じゃたぶん v.push_back(static_cast<Base*>(static_cast<void*>(new Derived("hoge")))); かもしくは vector<Base*> v(0); //初期化 のどっちか、そんでv.sort()でスライシングってのは間違い、 だけども delete v.back(); ってやるとスライシングが起きる。 つまりBaseのデストラクタとBase用のdeleteが動くので、 new Derived で確保したデータが残ったりデストラクタが行うプロセスとか無視されたりする ような気がする、、、
336 :
332 :2005/10/22(土) 23:30:40
ちくしょうメモリはかいされろ。
総叩きワロス
ワロタw
339 :
321 :2005/10/22(土) 23:34:33
仮想デストラクタがないという話だったんですね。すみません。
(でも、
>>321 ではデータメンバがないので、問題ないような。
そうとも言えないのかな?)
それはそれとして、BorlandC++のバグということで寝ます。
みなさんありがとうございました。
問題ないってw
>>329 過去スレのほうはもうちょっと先を読め。
W8038 定数メンバー 'member' は初期化されていない コンパイラ警告 (この警告の表示抑止用コマンドラインオプション = -w-nci) この C++ クラスには定数メンバー member が含まれていますが,member は初期化子を持っていません。 定数メンバーの初期化は可能ですが,定数メンバーへの代入はできない点に注意してください。
int n; string s; cin >> n; getline(cin, s); とすると、2行目の入力で3行目まで行っちゃう。 それは、cinで拾えなかった改行がgetlineで拾われるから? その対策に、getlineの前に、cin.sync();を入れてみたんだが、それでいい?
×2行目の入力で3行目まで行っちゃう。 ○3行目の入力で4行目まで行っちゃう。
>>343 「(入力が)3行目まで行っちゃう」の意味がわからない。
>>345 cin >> n;
で入力待ちになるが、そこでint値を入力すると、次のgetlineで入力待ちにならない。
その対策にcin.sync();って、どこかのホムペで見たことがある。
プログラムが長くなってきて修正がしんどいので ソースファイルを複数に分けたいのですが 定義をメインのソースでして、中身を別のソースファイルに書いて g++ メインのソース 別のソースって感じでいけますか?
>>347 キーワードを教えてやるよ。あとは自分で考えな。
宣言と定義
分割コンパイル
ヘッダファイル
C言語のスレかと思ったぜ
勉強不足な貴方のためにスライシングの話を軽く。 struct Base { int val1; virtual ~Base(){} }; struct Derived : public Base { int val2; }; ※sizeof(Base) == 8、sizeof(Derived) == 12 とする Base * p = new Derived[5]; ++p; 上記がスライシング。 ++p だと、p から 8Byte しか進まないので、 p が指している場所は、次の Derived ではなく、 Derived の中途半端な位置を指していることになる。 std::vector< Base > vec(5) に対して、 vec.push_back( vec.begin() + 1, Derived() ); をやると、Derived の Base 部分しかコピーされないので、 これもスライシングの一種。 std::vector< Base * > vec2(4); に対して、 vec2.insert( vec2.begin()+1, new Derived() ); とするのは安全。
ワロタ
乙
>>350 元々は後者をスライシングと言い出したような気がするが俺の勘違い?
部分的に切り出すことをスライシングっていうから、後者のほうが本来の意味だと思う。
で、その心は?
前者って、単にオブジェクトのsizeofが違うだけじゃないの? 別に継承は関係ないだろ。ま、ポインタを代入する時にエラー出るが。
m9(^Д^)プギャー
>>356 配列をポリモーフィックに扱うなってことだよ
>>358 それは誰でもわかる。そのためにboost::ptr_vectorなんかがわざわざ
用意されたんだろ。
>>350 前者はスライシングとは言わない。
勉強しろよ。
んなことわからなくても、仕事は出来るから別にいいや。
m9(^Д^)プギャー
C++なら素直にstd::vector使っとけと言う事だよな……
yes
C++ではstructとclassは、デフォルトのアクセス権がpublicかprivateかの違いだけです。 そこで質問というか、他人はどう書くのか聞いてみたく。 1. 全メンバがpublicのとき イ) struct X { int member; }; ロ) class X { public: int member; }; 2. 一部メンバがpublic、その他はprivateのとき イ) struct { int pub_mem; private: int pri_mem; }; ロ) class { public: int pub_mem; private: int pri_mem; }; ハ) class { int pri_mem; public: int pub_mem; }; 大学の研究室向けコーディング規約を見直しているところで、 そこそこC++コード書いてる他の人はどうか知りたいのです。
とりあえずデータメンバに対してpublicとprivate混ぜるのは非常に気持ち悪い もちろん状況によるが
より基底クラスかつ初期化と代入以外のメンバ関数を 定義しなさそうなやつはstructの傾向がある。
templateでenumハックするときはstruct
Cの時と同じようにデータをまとめる場合はstruct 何かをカプセル化する場合はclass
ファンクタはstruct。あとはclass。
>>366 private/publicの例示として書いたのでそこは無視していただきたいところです。
けっこうclass/structは意味で分けるのかな。
クラス定義の先頭には公開メンバーを書き、次にprotected、最後にprivateと
隠蔽するにつれて後ろにする書き方があって、そうすると定義の最初は
常にpublicということになる(2-イの書き方)。
こういう書き方の人はいないのかなあ?
もっともこの書式だと、ほとんどclassを使うことがなくなるのだが。
classとstructのコード上の違いは確かにそれだけでしかないが、 意味としてのクラスと構造体は天と地ほどの差がある。 抽象データ型やポリモーフィズムを行うものにstructはおかしいし、 = {}の形式で初期化をするようなものがclassでもなんだか不自然。 まあ、関数オブジェクトや368のようなものはstructでも定石のようなものだから良い。
>>372 >意味としてのクラスと構造体は天と地ほどの差がある。
おまえが勝手に異なる意味を見出してるだけだと思うが。
先行宣言に便利なように、どっちかに完全に統一するのがいいと俺は思う。
よしわかったこれ使え #define class struct 俺は使い分ける。
オブジェクトならclass、データ構造でもコンストラクタ/デストラクタ以外の公開メンバ関数を持ったらclassにしている。 蔭でこそこそやるだけのデータ構造ならstruct。 例えば、↓はstruct。 struct foo { int x; int y; foo() : x(0), y(0) {} }; そして↓はclass。 class bar { public: int x; int y; bar() : x(0), y(0) {} void set(int tx, int ty) {x = tx; y = ty;} }; 今悩んでいるのは、オペレータを持つデータ構造をclassにするかstructにするか。 例えば↓みたいな。 struct fooz { int x; int y; fooz() : x(0), y(0) {} operator double() {return hypot(x, y);} }; #あくまで例なのでコード内容への突っ込みは勘弁。
>>374 お前が使い分けるのは自由だが、そのルールを他の人も守ってるとは思わないでくれよ
俺はほとんど全てのメンバが公開されたとき意味を持つものを struct にして ほかは class にしてる
ほとんど全てとはまた曖昧だな
ところで上のほうにあったスライシングだが、 class Base{ int val1; }; class Derived : public Base { int val2; }; で、 Derived d; Base b = d; ←これだけだろ。 なんだかご苦労さんって話だよね。
>>379 のBaseに仮想デストラクタがないのはいいのか?
いい
382 :
デフォルトの名無しさん :2005/10/26(水) 00:38:41
>>381 もちろん
>>379 のコード内で問題はない。
しかし、派生クラスを作る以上、仮想デストラクタを書いておくべきではないのか、ということだが。
べきではない。こんな下らんクラス1個につき4バイト多く消費する
384 :
デフォルトの名無しさん :2005/10/26(水) 01:03:37
>>382 基底クラスのすべてに仮想デストラクタをつけるべきではありません。
基底クラスのポインタで派生クラスのオブジェクトを扱う場合にのみ必要となります。
>384 C++ Coding Standardsにそのネタあるな。 基本クラスのデストラクタはpubilc仮想かprotected非仮想にする だって。
あのさ、独習C++第3版でC++の勉強してるんだけど、 438ページに template <class T, class Allocator = allocator<T>> class vector ってあるんだけど、 class Allocator = allocator<T>の部分の意味がわからないんだけど・・・ Allocatorはクラス名で、allocator<T>ってのは何者? クラス名(Allocator)にallocator<T>を代入?
>>386 テンプレートvectorの第二パラメタAllocatorのデフォルトをallocator<T>に指定している。
このallocator<T>はstd::allocator<T>のこと。
allocator<T>っていうのはクラス名?
うん
あ、なるほどわかった、トンクス!
>>385 >基本クラスのデストラクタはpubilc仮想かprotected非仮想にする
そう言った端から、「そうでないこともある」と書いてあるような。
マレなケースとか書いているが。
ちなみに、Effectiveの方はもっとマイルドに、ポリモルフィックな
基底クラスには仮想関数を付ける。ポリモルフィックでないときは、
メモリ損するから考えろみたいに書いてある様子。英語なんで、
自信ないが。というか、読める奴の受け売りだが。
んで、
>>383 が正解な希ガス。
392 :
デフォルトの名無しさん :2005/10/26(水) 15:00:42
>>373 この流れからすると、どう考えても
「異なる意味を見出す」という所行は
>>372 の勝手なものではないね。
どう言い訳する?
393 :
_ :2005/10/26(水) 15:52:06
はじめまして、こんにちわ。 ニューラルネットネットワークのバックプロパゲーションの プログラムってどんくらい難しいですか?? どなたか何か情報を教えてください。 よろしくお願いします。
>>392 俺が「勝手に」と言ったのは
「一般の慣行から離れて」という意味じゃなく
「処理系や言語仕様から離れて」という意味だから、
間違ってるとは思わない。
誤解を招く言いかたスマソ
396 :
デフォルトの名無しさん :2005/10/26(水) 21:35:00
初心者なのですが プログラムを起動させることってできるのでしょうか たとえばテキストエディッタなどを起動するようなプログラムを 作りたいのですが。 お願いします。
>>396 <cstdio>のstd::system関数。
398 :
デフォルトの名無しさん :2005/10/26(水) 21:42:22
C++での質問です void hoge(int i, char *str,...); というプロトタイプ関数があるのですが strの後ろの「...」とはどんな意味があるのですか?
>>398 そもそもここでC++以外の質問されても困るけどな。
可変長引数でググレカレー
可変長引数なんて捨てれ。それはCだ。 と言ってみたりみなかったり。
402 :
385 :2005/10/26(水) 23:50:01
>391 >そう言った端から、「そうでないこともある」と書いてあるような。 どこに?この前出版された和訳本はそんなことないけど。 ちなみに要旨は 「オブジェクトをどうやって破棄するかを考えてデストラクタを定義しろ」 つうことですな。
javaにも採用されたし、まあアレだ
404 :
363 :2005/10/27(木) 00:24:44
>401 C++なら素直にstd::vector使っとけと言う事だよな……
406 :
363 :2005/10/27(木) 01:12:09
>405 関係なくはないよ。
たまたまメソッドのみのクラスがあった時、コンストラクタ、デストラクタ はやはり空関数として実装しておかないといけませんか?
>>409 自分で宣言しなかったときはコンパイラが勝手に
空のコンストラクタ、デストラクタを定義する。
なので、必要ない。
>407-408 へ?可変長の引数を渡すときは、可変長引数使わずにstd::vector使え つうことだけど、なんで関係ないの?
>>411 union types { int i, char c, double lf, std::string s; };
vector<types> args;
printf("%lf %d %c %s", args);
みたいにしろってこと?
恐らく
>>411 が言いたいのは、
void func(...); の代わりに、
void func(std::vector<type> args);
こうしたらどうか?ってことなんじゃないかと。
実際やってみれば分かるけど、
これじゃ可変長に出来てもvectorに積める型が1種類だから、
>>412 みたいにいちいちunionでラップしなきゃならなくなるのに気が付くはず。
こんなのいちいちやるのアホクサイ。
でも実際に可変長引き数に積めるのはint, longとlong long, double, long doubleにポインタだけだがな。
boost::ptr_vectorに、boost::anyへのポインタでも入れて渡せばいいだろ。
要するに void* args を C++ でどう書くのが綺麗かって話になるんだな
boost::formatみたいに演算子ーオーバーロードして繋げればええやん
419 :
デフォルトの名無しさん :2005/10/27(木) 10:51:48
News 2005-10-24: C++ Standard Core Language Issues List (Revision 38) is available News 2005-10-24: The C++ Standard Library Issues List (Revision 39) is available
>>413 ユニオンなんて古代のCだから捨てろ。その発想がすでにだめなんだよ。
君はC++に向かない。と言うか、C++の勉強が足りない。
と言ってみたりみなかったり。
>>420 反論できない->とりあえず煽る->予防線を張る
そんなビクビクするくらいなら黙っとけよ(笑
実行ファイルのヘルプ表示(--helpオプションなどで表示する説明文書)について質問です。 ヘルプ表示はたいていの場合固定の(static constな)文字列で、かつ複数行から成り立ちます。 これをC++流で書くと(coutかcerrはともかく) std::cerr << "hage program\n" << "usage: hage [option] target\n" << "options:\n" << " --ratio N scalp hair density" << std::endl; のように書き連ねることになります。これを、perlのように print <<END_OF_HELPTEXT hage program usage: hage〜 〜 END_OF_HELPTEXT; と改行を含めて書きたいのです。 テキストファイルをリソースとして取り込む方法も検討しましたが、Win32限定なら 容易にできるものの、標準C++だけでやる方法がわかりません。 こうしたテキストデータをうまく扱う方法はありませんか?
>>422 無理。
素直に書き連ねるか、外部ファイルから読み込むか、プリプロセッサを自前で作れ。
>418 promotion が入るからってことじゃね? C++ でも確かにそうなってる。(5.2.2/7) 多分、C との後方互換性のためじゃないかと。
>>420 C++ でも union は必要になるケースはある。例えばアラインメント解決やメモリをケチりたい場合など。
何の条件付けもせずに捨てろというあなたのほうがよっぽど C++ に向いてないとおもうが。
union { _m128 v; float vec[4]; }; バリバリ使いますなぁ。
そんなシビアな状況ならそもそもC++使わんだろって言う話なら分かる
いや、C++はそういう状況でも使えるように作られている。
C++でユーザープロセスソースを一から書くならunionなんかまず使わないでしょ
機種依存の話をしてるのか。 それにしてもx86-64の64bitインラインアセンブラ禁止やめてくれ・・・・・ fp87の使用禁止もあり得ねー。
class A { static int m_counter; int m_num; A(){ m_num = ++m_counter; } } int main(){ A arr[100]; } --- このとき、arr[0] == 1、 arr[1] == 2、 arr[2] == 3、、、 って保障される? arr[99]の方から初期化される可能性もあるのかな?
>>422 std::cerr << "hage program\n"
"usage: hage [option] target\n"
"options:\n"
" --ratio N scalp hair density" << std::endl;
ではいけないの?
>>431 クラスオブジェクトの配列の初期化は添字順に行われることが決まっていたはずだから、
その場合は恐らく保証されている。
デストラクタは逆順。
>>434 そうですた。やっぱり定期的に見ないとあやふやになってていかんなぁ。
補足トンクス
>>432 それでコンパイル通るんだ。g++3.4.2だと通るね。知らなかった。
>>436 ちょいまちー。この書式はANSI-C89の時代から使えるぞ。
文字列リテラルの連結はCからあるね
439 :
406 :2005/10/28(金) 01:00:53
>413 そもそも可変長引数て、型安全て考慮されていたっけ? 手軽に逃げるならvoid*のvectorで、boost使えるならboost::anyか boost::variantなんかが使えると思う。
片瀬雪希とぽけっとチュッチュ♪
今月は何月なのかを取得したいんですが、 どうやればいいのですか。
>>441 boost::gregorian使うと
date today(day_clock::local_day());
cout << today.month() << endl;
>422 std::cerr << "hage program usage: hage [option] target options: --ratio N scalp hair density" << std::endl; これは?
>>441 これだと標準じゃないのかな?
#include <iostream>
#include <ctime>
using namespace std;
int main ()
{
time_t now_ (time (NULL));
tm now;
gmtime_r (&now_, &now);
cout << now.tm_mon << endl;
return 0;
}
>>445 ×time_t now_ (time (NULL));
○time_t now_ (time (0));
>>446 NULLじゃダメなの?
glibc-2.3.5では以下のようになってんだけど
time_t
time (t)
time_t *t;
{
struct timeval tv;
time_t result;
if (__gettimeofday (&tv, (struct timezone *) NULL))
result = (time_t) -1;
else
result = (time_t) tv.tv_sec;
if (t != NULL)
*t = result;
return result;
}
boolをint等の整数型に代入した場合trueは1、falseは0になったのですが これは言語で保証しているのでしょうか?
してる
ありがとう
451 :
411 :2005/10/28(金) 10:25:55
型キャストに関する質問です。 別のコンパイラで使っていたコードを VC++.net に持ってきたんですが、 型キャストで warning がでまくってしまいます。 void cHoge::Init( void *start ) { unsigned int st; st = (unsigned int)start; } : warning C4311: '型キャスト' : ポインタを 'void *' から 'unsigned int' へ切り詰めます。 こんな感じです。 C++自体、使い始めて日が浅いのでいまひとつ解決の仕方が見えてきません。 初歩的な事かもしれませんが、ご助力お願いします。
>>452 本当はスレ違いなんだが一応答えておくと、
VC.NETではデフォルトでポインタが64bitサイズと仮定されてコンパイルされるから
unsigned intにキャストすると情報落ちが起こるぞ、とWarningを吐く。
押さえたければ、プロジェクトのプロパティのC/C++→全般にある
「64ビット移植への対応」を「いいえ」にすればいいはず。
454 :
452 :2005/10/28(金) 11:44:01
>>452 即レスありがとうございます。
解決いたしました。
ポインタ類は 32Bit であると疑いもしなかったので・・。
スレ違いの質問でしたが、お答えいただきありがとうございました。
C++的には、型のサイズは実装依存だから、void*を整数型にキャストするのは あまりよくない希ガス。実際には多くのコードがやっていることだが。 可能ならば、クラス情報を持たないvoid*も使わない方がよいのでは。
>>425 union使うとどうしてメモリけちれるの?
具体的に書いてみてちょ。
>>426 自分のコードを一度unionなしで書き直してごらん。
(1)できない → ヴォケ
(2)struct使いまくり → 無理せずC使えよ
(3)条件分岐だらけ → ここは爺さんの来るところじゃないよ
>>456 もちろん426のコードが何を意図しているか理解したうえで煽ってるんだよな?
可変長引数に対してアレルギーみたいなのを感じている人もいるようだけど、 boost::is_base_and_derived や、Loki::SuperSubClass は、 可変長引数がないと実装不可能だよ。
>>456 簡単にかけるものをわざわざ面倒に書き直してなにがうれしいのボク?
まあまあ落ち着こうよ。 煽りあっても何も得るもの無いよ。
可変長引数もユニオンも一切禁止ってのはないけど、 C++では無用の長物と化していることは事実でしょ。 妙なこだわりを持ってる奴は、なんちゃってCプラプラマ。 そんなことよりオブジェクト指向くらい理解しろよと。 それが無理なら引退しろよと。俺は愛を持ってそう言いたいっすよ。 「おじいさん。ご苦労様でした。次は僕たちの時代ですから、 どうぞ安らかに」
煽ってどうするかなぁ。 union嫌厨はどうも、自分ができないものに蓋をしているようにしか見えないよ。 使いたい香具師は使えばいいし、使いたくない香具師は使わなければいいというレベルのものでしょうが。 まぁ、unionを含むような構造体はできれば公開して欲しくない(≒ラッパを公開して欲しい)とは思うけど。
>>462 「無用の長物と化している」のはぜんぜん事実じゃあない.
boostやVC7のSTLとか見れば union が必要とされていて,きちんと使われてるのがわかる.
>>462 君の中ではオブジェクト志向と共有体が相反する概念なのか?
まあ可変長引数が不要(C++の仕組みでは使えない)というのには同意する。
C++ の仕組みでは使えないからこそ使われる(boost::is_convertible)という皮肉
ここの少し痛いプログラマの卵をどうにかしる
>>469 内容がほとんどまだ無いサイトみたいだけど、どこが痛いの?
具体的には何をすれば?
私怨乙
私怨じゃない。
だれも見てる人いないのに助けてとか言ってるから
ここの住人で並みのプログラマにしてやろうではないかと。
まぁ本人にそのような意志があったらの場合だが・・・。
>>471 言い方悪かった。スマン。
宣伝乙
ブログには興味ないので、このスレに引っ張り出せばいいのでは? ここがまずいんなら初心者スレとか。
まず本人にやる気はあるかどうかでは? だれか潜入してくれる香具師はいないですかね…。
なぜわざわざそのような事をする必要があるのかワカラン。 このスレのURLでも貼っとけ。
477 :
431 :2005/10/28(金) 23:52:17
>433-434 おおお、保障されてたのかー ありがとうございました
478 :
406 :2005/10/29(土) 00:45:49
>458 可変長引数の関数は実体化もされませんから!
くあしく
間違って宿題スレに一度出してしまったが、スレ違いなのでこちらに 出させてください。 あるソフトのバグ?を追求している過程で、問題を純化していったら 以下のC++コードの合法性が焦点となることがわかったのですが、規格書 見てもよくわかりません。誰か、これの規格合致・違反・未定義性を 指摘できませんか? <規格合致か違反か?> struct foo {} とした場合、foo::foo としてその型(struct foo)を 表記してよい(foo でできるのは当然だが、foo::foo はありか?) 別の見方をすると namespace foo { void hi(); } class foo { static void hi(); } があるとき、両方の hi() が共存することは可能か?それともエラーか? どのコンパイラで通るって話ではなく(g++ で foo::hi() と foo::foo::hi() で共存するのは確認済)、規格書の第何項の どういう解釈によって合致・違反と定まるのか、という点で知りたいです。 そうじゃないと単なるコンパイラのローカル拡張とも思えるので。 規格上はクラス名は名前空間定義とほぼ等価なのだが、じゃあ それなら上の foo::foo って foo class-scope の中の foo という 解釈になって、それは型名ではなくコンストラクタではないのかとか、 g++ が通しても本当に正しいのかちょっと悩んでます。
>>480 一点目は残念ながら規格書ではないが。
プログラミング言語C++第3版 5.7 構造体(手持ちではP.141):
> Cの時代に遡る理由から、同じスコープに同じ名前のstructと非構造体を宣言することは可能になっている。
> たとえば、次の通り。
>
> struct stat { /* ... */ };
> int stat(char* name, struct stat* buf);
そして、規格書3.4 Name lookupの3:
> Because the name of a class is inserted in its class scope (clause 9), the name of a class is also
> considered a member of that class for the purposes of name hiding and lookup.
とあるので、class fooはfoo::fooとして参照できる。
よって、合法だと思う。
482 :
デフォルトの名無しさん :2005/10/29(土) 03:27:10
質問お願いします。 #include <iostream> using namespace std; class Kitty { public: Kitty(bool , char *); }; Kitty::Kitty(bool bo , char *str) { if (bo) cout << str << '\n'; } int main() { Kitty obj[3] = { Kitty(true , "Kitty on your lap") , Kitty(false , "Card Captor Sakura") , Kitty(true , "Di_Gi_Gharat") }; return 0; } ってコードを見つけたんですけど、これはいいのでしょうか。 Kittyには引数を取るコンストラクタがないので、 Kitty obj[3]; とはできないわけですよね。 それなのに、上みたいに、初期値を与えて配列を作ってもよいのでしょうか。
483 :
482 :2005/10/29(土) 03:28:42
すみません。書き忘れです。
>>482 のKittyにはデータメンバがないんですが、それと何か関係あるんでしょうか?
>482 暗黙のコピーコンストラクタ
>Kittyには引数を取るコンストラクタがないので あるじゃん。
486 :
482 :2005/10/29(土) 08:49:02
>>485 すみません。
「引数を取らないコンストラクタがないので」の間違いです。
だから、「Kitty obj[3];」はできません。
それなのに、配列を作っちゃっていいのかってことなんです。
>>484 すみません。わかりません。
>>482 コンストラクタとデストラクタとコピーコンストラクタはユーザが書いてない場合コンパイラが勝手に定義する。
>>486 コンパイラは暗黙のうちにKitty::Kitty(const Kitty&)を定義している。(クラス内にこれが宣言されていない場合)
そしてobjの初期化では各要素毎にKittyの一時オブジェクトを作り、それを上記のコンストラクタに渡しているということになる。
>>481 ありがとう!
結局 struct foo {} ってあったとき、
struct foo *v = new struct foo();
foo::foo *v = new foo::foo();
のどちらも有効なんだね。ということで hi() 問題も
foo::hi(); // namespace foo の hi()
foo::foo::hi(); // struct foo の hi()
で規格合致な形で識別可能ですね。
自分の手元には第二版しかないが、そのあたりがさっぱり見当たらない・・・
ページ構成から完全に違うし、さすがに買いなおすかな。
複数種のクラスのメンバ関数のアドレスを格納する関数ポインタ配列を作ろうとしています。 メンバ関数の引数と戻り値の型は統一されています。 メンバ関数がstaticだったらうまくいくのですが、static以外だとコンパイルエラーになってしまいます。 staticではないメンバ関数を格納することは出来ないのでしょうか?
multisetやmultimapでソートキーが同じものがinsertされた場合、どこに入れられるかは決められているのでしょうか? 例えば struct A { A(int x, int y) : a(x), b(y) {} int a, b; bool operator<(const A& r) const { a < r.a; } }; std::multiset<A> hoge; hoge.insert(A(1, 10)); hoge.insert(A(1, 20)); とした場合、後から追加されたA(1, 20)はA(1, 10)の前と後ろどちらに入るか、ということです。
>>490 通常のポインタでstaticでないメンバは指せず、代わりにメンバへのポインタというのがある。
もちろんメンバへのポインタはクラスごとに別個の型。
というわけで490のようなことをやるのは結構面倒くさい。
普通はboost::functionの配列にboost::bindを使って格納することになると思う。
>>493 ありがとう。
正直言うと、2, 3回ググって面倒臭くなって訊いてしまった。
495 :
490 :2005/10/29(土) 11:52:32
>>492 Thank!
と言うことは、boost::を使うか、staticメンバの引数にthisのポインタを渡して誤魔化すか
どっちかか。
496 :
482 :2005/10/29(土) 11:53:01
>>487-488 ちょっと難しいですが、結論としては、
>>482 のコードに間違いはないということですね。
Kittyとかあるんであやしいと思ったのですが。
ありがとうございます。
>>496 それはそのコードを書いた人がアレなだけだから気にしなくて良い
>>497 あれとは失礼だぞ仮にも本を出版しているのだから
「アレ」は中立表現に一票
カタカナだから他意があるに一票
他意があっても無問題に五票
areと書けば無問題
>>480 namespace foo と class foo は同じスコープに存在できないよ。
504 :
デフォルトの名無しさん :2005/10/30(日) 05:32:16
こんなコードを書いてもよいのでしょうか。 struct MyData { int x, y, z; }; MyData mydata[2] = {{1, 2, 3}, {4, 5, 6}}; うまくいっちゃうのですが、MyDataにコンストラクタはいらないのかなあと。 よろしくお願いします。
>>504 いいよ。
その例だと、コンストラクタを作ったら初期化が面倒になるだろう。
上のほうにあるレスですが、
>>445 と
>>446 むしろ、time_t now_ (time (0)); がわからないんですが。
NULLは0でよいんでしょうか?だったらNULLなんかいらないような。
それともCとC++で違ってるのでしょうか?
>>506 time(NULL)でいいよ。教条主義者と勘違い野郎は0にするかもしれないけど。
>>506 C++でNULLは0と同じ。
Cだと(void *)0になっていることがあるのだが、
C++ではvoid *から他のポインタ型への変換にはキャストがいるので単に0となっている。
で、いっそのこと0使えやということになって、
それを実践しているが507のいう教条主義者ということになる。(含む俺)
C++で敢えてNULL使う派もいるなんて初めて知った orz
NULLを使う波。 NULLならヌルポインタを関数に渡していると一目でわかる。 0を渡すと数値渡してるのかポインタ渡してるのか判らん。
昔はNULLだったがその後禿に合わせて0にするようにしたなあ
>>511 のように引数に使うと見分けをつけやすいけど、
結局エラー時にコンパイラには補足されない点では同じだし
int *p = NULL;
よりは
int *p = 0;
の方が自然かな、というところで最近は0派。
どっちを使ってても実務で問題になったことはないし、好みの問題だろ。
NULLと0の議論は別スレ立ててやれやう゛ォケ共
>>515 いや、別スレ立ててるほどのものでもないでしょ。
過去スレみれば腐るほど議論がされているような気がするのだが?
分かったから出てけ
つまりどっちでもいいでFA。
好きな方使えばいーじゃん
俺は
>>514 みたらNULLの方が分かりやすいなとも思うし人それぞれ
ところでC++/CLIにはnullptrキーワードが導入され、 通常のポインタに対しても使えるようになる。
void f(int n); f(NULL); ていう恐らく意図とは違うコードが f(nullptr); でエラーとして捕らえられるってことか。 便利やも。 でもC++/CLIじゃなぁ(´A`)
522 :
デフォルトの名無しさん :2005/10/30(日) 14:48:44
>>521 C++って、いつからコマンドラインインタフェースになったの?
Common Language Infrastructureだっけ?
524 :
デフォルトの名無しさん :2005/10/30(日) 18:07:47
#include <iostream> using namespace std; int foo(struct null_ptr*) {cout << " null po " << endl;} int foo(int i){cout << " int " << endl; } int main() { foo(0); foo(static_cast<null_ptr*>(0)); } ってなかんじのコードなら見たことがある。
最前画面のウィンドウにマウス左クリックしたメッセージを流したいのですが hWnd = GetForegroundWindow(); SendMessage(hWnd,WM_LBUTTONDOWN,0,1); SendMessage(hWnd,WM_LBUTTONUP,0,1); では動きません、どうすればよいですか?
>>526 先ずはスレ違いということを認識することから始めよう。
NULL を使うこと自体は構わないが、 <cstddef> とかのインクルードをせずに 予約語のごとく使う奴は許さない。
何かしらのライブラリをインクルードすれば#define NULL 0がついてくるんだけどな。
インクルードで思い出したが、size_tやらptrdiff_tにstd::をつけるべきか否かでいつも迷う。
<cstddef>のほかにC由来のヘッダでは<cstdio> <cstdlib> <cstring> <ctime>でNULLが定義されることになっている。
>>531 <c〜>のヘッダを使っていればもちろん必要。
<〜.h>のヘッダでは内部でusingされているということになっているから、
規格通りの処理系ではstd::size_tなどとしても使えるはず。
535 :
デフォルトの名無しさん :2005/10/31(月) 23:46:06
C++で実装するときでC標準ライブラリを使うとき、 <*.h>を使う奴はいないよな?
536 :
デフォルトの名無しさん :2005/10/31(月) 23:49:13
勘弁してくれ。
538 :
デフォルトの名無しさん :2005/11/01(火) 12:43:55
メンバ関数のポインタ配列を順次実行しようとしています class CTest { private: void func1() {}; void func2() {}; public: static void (CTest::*fpTable[])(void); }; void (CTest::*CTest::fpTable[])(void) = { &CTest::func1, &CTest::func2, NULL, }; void func() { CTest test; void (CTest::**pFList)() = test.fpTable; for (; *pFList; pFList++) { (CTest::*pFList)(); } } 関数コールするところで、error C2059: 構文エラー : '<tag>::*' が出てしまうんですが(VC6) なにか対策無いでしょうか?(俺に聞けスレからの誘導です)
>>538 (CTest::*pFList)();
↓
(test.**pFList)();
というか、あまりメンバ関数へのポインタについて理解してないようだから
無理にそういう書き方をしないで、boost::functionとboost::bindを組み合わせて使っておくのが無難かと
理解してないなら理解すればいいだろ
>>539 サンクスです
今の仕事場、boostはおろか、STLも禁止なんです
正直、関数ポインタはあまり使わないんで、勉強し直すつもりです
>>541 禁止キター
その仕事場、逃げたほうが良いんじゃないか。
Boostはともかく(うちでは使ってるけど)としてSTL禁止とかワロス
古い処理系で既に作られているプログラムのエンハンスなんかでは よくある話なんでないの?
エラトステネスのふるいを書こうとしてます.Python で言うところの def sieve(xs): if (len(xs) == 0): return [] else: return [xs[0]] + sieve([y for y in xs[1:] if y % xs[0] != 0]) print sieve(range(2,1000)) というコードは,C++ ではどれくらい簡単に書けますか? # Pythonではリストの加算はリストの隣接を表します. # xs[1:] はリストの二番目の要素から後の部分リストです.
>>545 #include <list>
#include <iostream>
#include <functional>
#include <iterator>
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
namespace lambda = boost::lambda;
template<typename Out>
void seive(std::list<int> xs, Out out)
{
while(!xs.empty())
{
int p = xs.front();
*out++ = p;
xs.pop_front();
xs.erase(std::remove_if(xs.begin(), xs.end(),
lambda::bind(std::equal_to<int>(), 0, lambda::bind(std::modulus<int>(), lambda::_1, p))),
xs.end());
}
}
int main()
{
std::list<int> x;
for(int i = 2; i <= 1000; i++)
x.push_back(i);
typedef std::ostream_iterator<int> oii;
seive(x, oii(std::cout, " "));
}
547 :
545 :2005/11/01(火) 18:24:57
>>546 remove_if が algorithm のほうの remove_if なので,せっかく list を使っていても,そのメリットがありません.
(algorithm の remove_if は普通は内部で remove_copy_if を呼ぶので,コピーが発生してしまいます)
あと,一応結果を保持しておきたいです(で,できればそっちでもコピーは発生させたくない).
コピーをたくさん発生させてもいいなら,イテレータを回して↓な感じなんですが.
vector<int> primes(2000);
int k = 2; generate(primes.begin(), primes.end(), var(k)++);
vector<int>::iterator it, last;
for (it = primes.begin(), last = primes.end();
it != (last = remove_if(it+1, last, _1 % *it == 0)); ++it);
primes.erase(last, primes.end());
548 :
546 :2005/11/01(火) 18:42:13
>remove_if が algorithm のほうの remove_if なので,せっかく list を使っていても,そのメリットがありません. その通り。 >あと,一応結果を保持しておきたいです(で,できればそっちでもコピーは発生させたくない). それだと標準アルゴリズムでは扱いきれないはず。 手でループを回すのが一番かと。
>>535 なんで駄目なんだ
<windows.h>
<stdio.h>
って風に.hで揃えたいじゃないか。
<vector.h><map.h>
そもそもヘッダに.hが無いのって名前空間を考慮してないコードと.hがついた ヘッダと互換性を残すためなんだっけ?それだったらstdioくらいは良さそうなもんだが。
Borland Turbo C++ 1.01だとiostream.hにしないと怒られたお(;^ω^)
554 :
デフォルトの名無しさん :2005/11/01(火) 23:34:03
>>539 っていうか、
玄人は**pFListなんてやらないで、*pFList[]にするよ。
今更ポインタできまつ!おらできまつ!流行んない。
555 :
デフォルトの名無しさん :2005/11/01(火) 23:39:13
class CBase{ public: int x_, y_; CBase(int x = 0, int y = 0){ x_ = x; y_ = y; } }; // 上のクラスはめっちゃ適当です。 // ソート用に演算子のオーバーロード bool operator < (CBase &a, CBase &b){ return a.x_ < b.x_; } std::list<CBase *> ObjectList; CBase* BB = new CBase(100, 20); CBase* BBA = new CBase(200, 20); CBase* BBB = new CBase(150, 20); ObjectList.push_back(BB); ObjectList.push_back(BBA); ObjectList.push_back(BBB); // ここでソートしたいがうまくいかない ObjectList.sort(); CBaseクラスのx_の値でソートしたいのですがうまくいかないんですができないんでしょうか? std::list<CBase *> ObjectListをstd::list<CBase> ObjectListにして実体渡せばソートできるみたいなんですが どなたか回答お願いします。
556 :
デフォルトの名無しさん :2005/11/01(火) 23:42:55
>>555 ソートしたければSTLのソートアルゴリズムを使え。
>>555 リストのソートは比較の関数オブジェクトを渡すことができる
'ex' 内の 'test' へのアクセスがあいまいです。 とエラーがでるのですが、何がいけないのでしょうか? template <typename T> struct base {static void test(T){}}; struct ex :public base< int >,public base< int* > {}; int main() { int a; ex::test(a); ex::test(&a); }
test(int) と test(int*) が衝突している。 ……ってあれ? コレで良いんだっけ?
560 :
558 :2005/11/02(水) 00:27:50
>>559 どうも。
using base<int>::test;
using base<int*>::test;
usingしたらVC7.1で通りました。(VC6だとだめぽ)
>>558 そのエラーメッセージおかしいね。
gccでは
error: `test' is not a member of `ex'
error: `test' is not a member of `ex'
と出る。規格ではどうなってるんだっけか。
>>555 -ObjectList.sort();
+struct Local {static bool Dereference_Less (const CBase *lhs, const CBase *rhs) {return lhs->x_ < rhs->x_;}};
+ObjectList.sort(&Local::Dereference_Less);
bool operator < (CBase &a, CBase &b)
は
bool operator < (const CBase &a, const CBase &b)
に
> 10.2/2 > (前略) > If the resulting set of declarations are not all from sub-objects of the same type, > or the set has a nonstatic member and includes members from distinct sub-objects, > there is an ambiguity and the program is ill-formed. 隠蔽を考えた上での member name lookup の結果が、 1) 同じ型の sub-objects 由来のものではない場合 2) 非静的メンバを持ち、かつ別個の sub-objects 由来のものを含む場合 のいずれかである場合、曖昧であり ill-formed である、そうな。 オーバーロードの解決はこの後(結果が曖昧でなかった場合)だそうで。 D&E (日本語訳) p.534 にも(非静的メンバだけど)例があった。
>>563 解説サンクス。
>>561 で生じたエラーは、base<int>::test と base<int*>::test はあるが、
ex::test はないために生じたのだと思う。VC7.1は、これらをまるでex::test
のように扱うために、外部からアクセスした時に曖昧エラーが出ているが、
本来は gcc のように、not found エラーとして処理すべきかと。
m_cell &= m_cell ^ rhs.m_cell; と m_cell = m_cell & (m_cell ^ rhs.m_cell); は同じではないのですか?
>>565 どういうこっちゃ。演算子のオーバーロードとかは無しという方向で?
567 :
デフォルトの名無しさん :2005/11/03(木) 03:56:11
class base{ } class parent:public base{ } class player{ void inc(base*){ for(int i=0;i<10;i++){ (base+i)->XXX(); } } main(){ parent a[10]; player p; p.inc(a); } のように,基底クラスのポインタを扱う関数incに派生クラスの配列のポインタを与えると エラーが出てしまいます.(実行可能ですが値が破綻します) そもそもクラスの配列自体がナンセンスなのでしょうか?
>>565 後者は一時オブジェクトがよぶんに生成される可能性がある。
m_cellが何かによって、同じ効果のある文かどうかは変わる。
>>567 baseと、baseから派生されたparent(ふつうはderivedと名付けた方がわかりやすいと思う)のサイズが
まったく同じでない場合、結果は不定になる。baseのサイズを元にしてポインタ演算が行われるからである。
たいていの場合は派生クラスの方にメンバが追加されているなどで大きさが異なるので
(何をしているかが分からない限り)配列をポリモーフィズム的に扱うことは避けた方がよい。
570 :
デフォルトの名無しさん :2005/11/03(木) 04:27:59
エディタ等が入ってないPCで Visual C++で作られた dllファイルを一行追加したいんだけど、 サクラを入れてみたけど、文字化けで指定のところが編集できませんでした。 なにで編集すれば文字化け解消できますか?
572 :
デフォルトの名無しさん :2005/11/03(木) 04:46:05
>>571 570です。釣りではなく、まじでした。
ご存知でしたら誘導先に建てましたのでお答えいただけません?
573 :
567 :2005/11/03(木) 04:48:58
>>569 助言を参考にしますと,上記の例ではplayerクラス関数に
inc(derived*){}
を作り直すか,テンプレートを使用する必要があるということですね.
ありがとうございました.非常に良くわかりました.
parent* a[10]; って風すれば要望みたすんじゃないの?
575 :
565 :2005/11/03(木) 10:40:37
565です。 m_cell, rhs.m_cell 共に bool です。 だから、&=, ^, =, & は全てデフォルトの演算子ですよね?
>>575 その2つの式が同じバイナリを吐くか、もしくは違うバイナリを吐くかは、
コンパイラにより、さらに最適化レベルにもよる。
一般的に言って、上の式の方がより最適化されたバイナリを吐く可能性
が大きいが、規格では何も決められていない。
577 :
567 :2005/11/03(木) 15:02:15
>>574 指南いただいた内容より,ポインタの配列を使用しても,実体はparentクラスのサイズ分が確保されるので,
baseクラスのポインタのインクリメントは不可能(不定)なのではないでしょうか?
気が向いたらご返信願えればと.
>>577 sizeof(base) != sizeof(parent)であってもsizeof(base*) == sizeof(parent*)
厳密には実装依存か?
>baseクラスのポインタのインクリメントは不可能(不定)なのではないでしょうか?
>>574 の例では、実際にインクリメントするのはbaseへのポインタのポインタだから、
問題ない。
580 :
567 :2005/11/03(木) 20:12:33
>>578 >>579 なるほど,そのようにインクリメントすればOKなのですね.
これで派生クラスごとに場合分けをしなくてすみそうです.
皆様の適切なアドバイスありがとうございました.
581 :
デフォルトの名無しさん :2005/11/03(木) 22:31:46
テンプレートクラスで template<class T> class CHandleAaa というのがあったときにTがあるクラスCAaaを継承したクラス限定 という制限をかけるにはどうすればいいですか? TがCAaaの派生クラスで無い場合コンパイルで怒られたいです。
>>581 boostのtype_traitsのis_base_ofとBOOST_STATIC_ASSERTを組み合わせればいい。
そういやtype_traitsは標準入り決定だけど、STATIC_ASSERTとかはどうなってるの?
585 :
デフォルトの名無しさん :2005/11/04(金) 18:51:15
メンバ関数へのポインタの配列をメンバ変数として持たせたいのですが、 class TestClass { public: typedef void (*LPFUNC_VOID_VOID)(); LPFUNC_VOID_VOID m_lpFunc[3]; …(略)… void Draw00(void); void Draw01(void); void Draw02(void); …(略)… }; とし、コンストラクタの中で m_lpFunc[0]=&TestClass::Draw00; と代入するとcannot convert〜というエラーが出ます。TestClass::LPFUNC_VOID_VOIDとしてもエラーが出ます。 また、メンバ関数から呼び出そうと (this->*m_lpFunc[1])(); とするとこれもエラーになるようです。 VC++6.0の時はこんな感じの記述でいけたのですが、VC++2003ToolkitとVC++2005Expressではだめでした。 このように、メンバ関数のポインタをメンバ変数として持ちたい場合、どのようにすればよろしいでしょうか?
>>585 メンバーへのポインターに成ってないからじゃない。
>typedef void (*LPFUNC_VOID_VOID)();
>LPFUNC_VOID_VOID m_lpFunc[3];
void (TestClass::*m_lpFunc[3])();
>564
>
>>561 で生じたエラーは、base<int>::test と base<int*>::test はあるが、
> ex::test はないために生じたのだと思う。VC7.1は、これらをまるでex::test
> のように扱うために、外部からアクセスした時に曖昧エラーが出ているが、
> 本来は gcc のように、not found エラーとして処理すべきかと。
言わんとするところをちゃんとつかめてないが、その解釈と↓の挙動は矛盾しない?
メッセージの違いは name lookup 段階での曖昧性に対する表現が違ってるだけなんじゃないかな?
#include <iostream>
struct A { static void func(void) { std::cout << 'A' << std::endl; } };
struct B : public A {};
struct C : public A {};
struct D : public B, public C {};
struct E : public A { static void func(void) { std::cout << 'E' << std::endl; } };
struct F { static void func(void) { std::cout << 'F' << std::endl; } };
struct G : public A, public F {};
struct H : public A, public F { static void func(void) { std::cout << 'H' << std::endl; } };
int main(void)
{
B::func(); // A
D::func(); // A
E::func(); // E
// G::func(); // error: `func' is not a member of `G'
H::func(); // H
return 0;
}
588 :
585 :2005/11/05(土) 00:44:05
>>586 回答ありがとうございます。おかげでちゃんとエラーが出ずに動作するようになりました。
「関数のポインタ」じゃなくて「voidのポインタを返す〜」になってたんですね。
質問です ちょっと気になったことなんですが ポインターの参照を返してみたいとふと思いついて ↓のようなものを書いてみたんですが、戻り値のところが int*& のような見慣れない形になってるにもかかわらずコンパイルできました。 これって、大丈夫なんでしょうか? int* a;//どこかで定義 int*& 関数() { return a; }
>>589 大丈夫。
ついでに、そういうことは習慣じゃなくて論理を基に考えるべきだと思う。
でも毎回論理で考えると時間がかかるからそれも習慣にいれとけ
#include <cstdio> using namespace std; int main (void) { int i=15,*p; p = &i; printf("%x %x %x %x %x\n",p,*p,&p,*&p,&*p); } 実行結果 22ff74 f 22ff70 22ff74 22ff74 当然だね
>>590 >>591 早い回答ありがとう
なるほど、大丈夫ですか。
安心しました。
論理か・・ プログラムって意外と奥が深いんだなあ
594 :
デフォルトの名無しさん :2005/11/05(土) 05:41:29
displayInt(int value){ printf("INT: "); printf(" %d", value); printf(" (%08X)", value); } displayDouble(double value){ printf("DOUBLE: "); printf(" %f", value); printf(" (%16X)", value); } displayString(char *value){ printf("STRING: "); printf(" %s", value); printf(" (%08X)", value); } こういった感じの関数を、各組み込み型すべてについて作りたいのですが、テンプレート、あるいはオーバーロードなどをどういう風に書いたら、コードを短くできるでしょうか? displayInt/Double/UCharなどと、String/WStringは別物と考えた方がいいのかもしれませんが・・・
>>594 引数の型を表す名前は関数名に含めずに、オーバーロードを定義すればいい。
iostream を使うと、フォーマット文字を型ごとに変えてやる必要は無くなる。
INT, DOUBLE, STRING なんてのは、それぞれ書かないと無理だろうな。
各関数の3行目は意味が不明瞭なので手がつけられない。
一行目はこんな関数を作り、displayでは最初にstd::cout << TypeName(x) << ": ";とすればいいだろ。 template<typename T> inline const char *TypeName(const T& x) { return typeid(x).name(); } char *をchar *と表示させたくなければ特殊化すればいい。 3行目は各値のビット表現を出力したいということだろ。 こんなものを考えたが駄目だった。 std::cout << std::hex << '(' << reinterpret_cast<const boost::uint_t<sizeof x * CHAR_BIT>::least&>(x) << ')';
>>595 >INT, DOUBLE, STRING なんてのは、それぞれ書かないと無理だろうな。
typeid(int).name()でいけないか?
>>596-597 nameが何を返すかは処理系依存だし、実際gccは「i4」だとか一見意味の分からない文字列を返すから使えない
#include <cstdio> // use <boost/format.hpp> if boost is available #include <iostream> #include <iomanip> #include <sstream> #include <typeinfo> template <typename T> struct type { inline static const char* name() throw() { return typeid(T).name(); } inline static const char* format() throw() { std::stringstream ss; ss << "%0" << sizeof(T)*2 << "X"; return ss.str().c_str(); } }; template <> struct type<int> { inline static const char* name() throw() { return "INT"; } inline static const char* format() throw() { return "%08X"; } }; template <> struct type<double> { inline static const char* name() throw() { return "DOUBLE"; } inline static const char* format() throw() { return "%16X"; } }; template <> struct type<char*> { inline static const char* name() throw() { return "CHAR*"; } inline static const char* format() throw() { return "%08X"; } }; template <typename T> inline void display_type(const T& value) { using namespace std; cout << type<T>::name() << ": " << value << " ("; printf(type<T>::format(), value); // OMG cout << ")"; }
600 :
599 :2005/11/05(土) 14:21:41
int main() { int i = 12345678; double d = 1234.56; char* c = "test"; unsigned int j = 12; display_type(i); display_type(d); display_type(c); display_type(j); return 0; } 問題を難しくしただけの希ガス(´д`) 「型」と「型の名前」、「型」と「型の出力フォーマット」を プログラマが思うとおりにしなければならないなら、そのいちいちについて列挙するしかない。 template〜とか書くのがめんどくさい場合、マクロを使う: #define TYPE(T, NAME, FORMAT) \ template <> struct type<T> { \ inline static const char* name() throw() { return NAME; } \ inline static const char* format() throw() { return FORMAT; } \ }; TYPE(int, "INT", "%08X") TYPE(double, "DOUBLE", "%16X") …… 糞コードだな(鬱
俺はconst std::type_info&をキーにしてstd::mapに格納できないかと考えた。 それは無理だろうけど、適当にラッピングすればキーに出来るのではないかと思う。
602 :
:2005/11/06(日) 01:37:03
ファイルからたくさんデータを読んでクラスのメンバ変数に保存してるんだけど。 (デフォルト値はある。ファイルで入力が無かった変数にはそれを使う) で、質問なんだけど、その変数をpublic変数にしていつでも読めるようにしたい、 でも左辺値にはしたくないって時にどうやってる?
>>602 「左辺値にする」の意味がよくわからないが、
それが「代入の対象となる」という意味なら、
public な const 参照メンバを置けばよさそう。
>>603 レス、サンクス。
const参照メンバ?
public:
const int var1;
const double var2;
const string var3;
みたいな?
デフォルト値があって、入力があった時だけはメソッドで読み込んで値を変えたい。
外部で使用するときは参照するだけ。値の変更は許さない、みたいな使い方。
でも、上だと値そのものが変更できないんじゃないのかな?
本来は、単にprivate変数にすれば良さそうだけど、 参照したい変数がすっごく多くて、そのつど、その変数の値を返す だけのメンバ関数を書きたくないんですよ。 だから、public変数にしたい。でも、値は好き勝手に変更できるようにしたくはない、って訳です。
>>605 まとまったデータとして、struct などにまとめてはどうだ?
>>604 class C
{
private:
int v;
public:
int const& rv;
C() : rv(v) {}
};
すっごく多いってことなら、これも不味いんだろうな。
606 の言うように構造体にまとめて、
この方法と組み合わせるといいかもしれない。
それでも、奇妙なことせずに値参照用のメンバ関数を
用意するのが最善なのに変わりは無い。
>>607 > 値参照用のメンバ関数を用意するのが最善なのに変わりは無い。
ああ、それ、いい方法があったら知りたい。
一つ一つの変数ごとに関数を用意するんじゃなくて、なんか汎用に使える方法ないのかな。
#define READONLY(t, n) private: t n##_; public :const t& n() const {return n##_;}
>>608 設計を見直すのはどうだろう。
折角クラスを設計しているのに内部データを曝け出すのは設計が悪い。
曝け出したいものが一括りにできるのならそうするべき(≒>606)だし、
条件付で曝け出す(≒>607)もいいが、本当に曝け出すべきかどうかも検討してみるべき。
パフォーマンスを犠牲にしてもよければ、プロパティクラスを使う手はあるけど そもそも変数の数が膨大という時点で設計を見直した方がいいかもしれない。 private: T ID_; public: const T& ID() const { return ID_; } を書けばいいということなら、これをマクロにして: #define readonly(T, ID) \ private: \ T ID##_; \ public: \ const T##& ID##() const { return ID##_; } というのはどうだろう? class b { readonly(int, value) }; 試してないので間違いあるかも。
考えることはみんな同じだなw
クラスが一枚岩になってそう 一つの機能に絞ってまずは分割汁
privateメンバに対するgetメソッドを自動的に作るようなスクリプトでも書けばすむ話じゃないのか?
>>614 そんなことしたくなる場面では設計を見直すほうがいい。
参照型は使い回しって出来ますか?
使いまわしの意味がわからんが 初期化したら最後、変更はできない
> 初期化したら最後、変更はできない constの話じゃなくって? だったら詳しく
>>618 T& r を一度初期化したら &r は変更できない、ってこと。
それとは別に、 r = x という式は T が const 付じゃない限り有効。
> T& r を一度初期化したら &r は変更できない、ってこと。 ごめん。意味がわからない。 int i,j; .... int& k = i; ... k=j; これができないって意味じゃないね?
× これができないって意味じゃないね? ○ これができないって意味じゃないよね?
やってみたらいいのに
Moreか無印のEffective C++呼んだ方が早いな
>>620 ポインタとの対比で、
int i, j;
int *p = &i;
int &k = i;
p = &j; /* pの参照先を変えることはできるが */
&r = &j; /* もちろんこんなことはできないし、 */
r = j; /* こうしてもrはiを参照し続ける */
>>622 馬鹿はだまってろ
>>624 まあ餅付けよ
実際に自分で試すのは大事なことだと思うぞ
>>625 同意。自分で試さないからrなんていう未定義変数を使っちゃうんだよな。
あ、r経由でrの参照先を書き換えることはできないって言ってるのか。 失礼しました。
628 :
616 :2005/11/06(日) 21:02:39
>>617-624 EffectiveC++買ったは良いけど読んでませんでした・・・。
みなさんこんな質問してすいません。でも、良くわかりました。ありがとうございます。
>>628 EffectiveC++は一種の思想書だから、他の本の方がいいかも
C++って今のところ正規表現サポートしてないですよね? このあたり、厳しいかと思うのですが、標準サポートの 動きはないのでしょうか。
とっくの昔にあるにょ 次の規格改定で入る予定だにょ それまで待てないんだったらboostでググってみろにょ
632 :
デフォルトの名無しさん :2005/11/07(月) 02:31:09
x |= 0x01 これと逆で、あるビットを0にする演算子なにですか?
x &= ~0x01
x &= ~0x01
x &= ~0x01
>>633 ,634,635
ありがとうがざいます。
637 :
デフォルトの名無しさん :2005/11/07(月) 03:36:57
C++でプログラム書くとなんであんなにバイナリがでかくなっちゃうの?
-D_RTLDLLを指定しているかい?
delphiとかvbに比べたら小さいと思うが
641 :
デフォルトの名無しさん :2005/11/07(月) 06:16:06
逆に言えはなんでCはあんなにバイナリが小さいのか。 やっぱりCこそ最強にバランスの取れたプログラミング言語なのか。
>>637 ,641
「あんなに」って言われてもわかんねぇぞ。
STLつかうと一気に実行ファイルサイズが10倍に?!
>>644 > vc7.1は普通にjを参照するけど。
それがほんとで assert(&r == &j) が通るなら VC7.1 は盛大にバグっていることになるが、
そんな話は聞いたこと無いのでおそらくお前がバグってるんだろう。
646 :
デフォルトの名無しさん :2005/11/07(月) 08:17:11
>>643 STL使って実行ファイルの サ イ ズ が増えたとしても
何の影響もない。今時ハードディスクでヒィヒィ言う奴なんていないだろ。
それよりも開発が楽になることの方が素晴らしい。
STLマンセー
>>644 値とオブジェクトを取り違えてないか?
int i = 1, j = 2;
int& r = i;
std::cout << r << std::endl; // rの参照先はiで、iは1だから1が出力される
r = j; // rの参照先はiのままで、jの「値」である2が代入される
std::cout << r << std::endl; // だから、ここで2が出力される
std::cout << i << std::endl; // これも2
r = 3; // rの参照先はiのままだから、この文はiに3を代入する
std::cout << r << std::endl; // 3が出力される
std::cout << i << std::endl; // これも3
std::cout << j << std::endl; // jはrとは無関係、従って2が出力される
649 :
644 :2005/11/07(月) 10:43:07
>>645 ,648
ごめんアホでした。言い訳をしたいけど止めときます。(´・ω・`)ショボーン
>>649 どうせだから聞かせてくれ。参照を理解できない香具師に教えるヒントになるかも知らん。
>>650 いや、たいした理由じゃないけど勘違いしてた。それも、まじめに。
int& r=a;
は初期化するときaの参照先を受け取るから
r=b;
代入してもそれはbの参照先を受ける
というよなプロセスで勘違いしてた。
>>652 レスTHX。
なるほど、ありがちとは言え、判っている人間は思いつかないような落とし穴だね。
int& r = &a; こういう方が直感的に?
つくづくCのポインタ表記はまぎらわしいと思うな。 引数と宣言と代入で意味が混ざる。 int instance; int* pointer = &instance; int& reference = instance; void function(int by_value, int* by_pointer, int& by_reference) { int instance_by_value = by_value; int instance_by_pointer = *by_pointer; int* pointer_by_pointer = &by_pointer; int instance_by_reference = by_reference; }
>>656 訳の分からんPascalのポインタよりマシだろ
658 :
デフォルトの名無しさん :2005/11/07(月) 15:24:08
テンプレートライブラリを使うとなんであんなにバイナリがでかくなってしまうのか。 アセンブリソース眺めて調べないと。マンドクセ。
>653 それは、判ってないんじゃないかと思う。 実際、r=b;がどちらが参照するかは状況による。 俺も、判っているとは言えない。
判ってないからこそ、必ず、直後にアドレスを確かめる、 元の値をホーチしたまま、アドレスが変わったほうが参照した側だ。
個人的にはポインタの宣言する時に int *pとかではなく int* p、もしくは、(int*)pとすると 気持ち見やすいと思う
>>661 それすると int *ptr, var;としたいときに
int* ptr, var;となってわかりにくくなる
それはそうだが、その前にそんな宣言しないよなぁ
一行一宣言
すくなくともintとintのポインタの宣言は分けるべきだろう
>
>>661 (int*)pは文法違反。(int (*p)は問題ない)
ちゃんと統一的な規則があるんだから、宣言を
型名 変数名;
と考えるのはやめた方が合理的だと思う。
LPINTでいいじゃん
int* p; のほうが合理的のような気がする。。。
LPINT<=>int* であることを考えると、 int* p; だな。 int *p; だと*pが変数名?みたいな感じでキモイ。
ここでお約束のこれ int *p;と書くと式の中で*pと書けばint値が得られると読める。
int * p;
int * p ;
int* ^p^;
実際exeバイナリのサイズが問題になる状況でC++なんて使ってられるのか?
>>646 はWin32環境の事しか考えてなさそうだが。
>>675 C++の方が可読性を維持したまま実行モジュールサイズを削減できる可能性が高いと思うが。
#コンテナクラスやstd::stringを使いまくったらワヤだけど。
>>671 >*pと書けばint値が得られると読める。
そう読むと、既にメモリが確保されているかのような誤解を招く。
それは型と値の区別ができていないわけで。
恋愛と結婚の区別ができません
>>675 バイナリのサイズが問題になるような使い方をしなければ
C++でもまったく問題無いでしょう。
C++はそう作ろうと思えばそう作れる言語ですから。
(それができないのは、できない人間の能力の問題ですし)
関数にデータを渡すときに func(const std::vector<XXX> & data) みたいなコンテナむき出しの渡し方はダサイですか(´・ω・`) <algorithm>のようにイテレータで渡したいんだけど・・・
>>682 > <algorithm>のようにイテレータで渡したいんだけど・・・
それならイテレータで渡せばいいんじゃないかな?
684 :
デフォルトの名無しさん :2005/11/07(月) 19:53:46
>>653 おめー、ム板のマルチスレッドスレにも居ただろ?
ここでも丸投げかよ。
#define iVector std::Vector<int> とかでもいけるんでないの?
>>686 詳細ってtypedefがわかんないの??
それより682で言ってるようにイテレータでわたしゃいいじゃん
>>687 いけるいけない以前になぜtypedefでなくdefineなのかと?
それからなぜVが大文字なのかと?
>>687 せめて
typdef std::Vector<int> iVector;
イテレータで渡すなら: template <typename Iter> void func(Iter first, const Iter& last) { while (first != last) { ++first; } } みたいにすればいいんじゃないの。 コンテナがよければ: template <typename Container> void func(Container& c) { typedef typename Container::iterator Iter; }
未だにイテレータの有効期間が分からない俺ガイル。 コンテナの要素に対して変更が行われない限りは使い回していいのかな?
693 :
682 :2005/11/07(月) 21:03:40
皆さんありがとう。大変勉強になります (・ω・)シャキーン
>>691 682は普通の関数作りたいだけじゃないのか?
すいません、ちょっとアイデアを頂きたいのですが・・・ int型整数をLPSTR型文字列に変換する手順てなにかないでしょうか?
>>695 そのint型の変数をnとするとboost::lexical_cast<std::string>(n).c_str()とすればよい。
標準ライブラリだけでやりたいのならstd::ostringstreamを活用する。
まあstd::sprintfもなくはないけど……。
LPSTR型って何?
LPINT型整数
>692 vector/dequeはコンテナに対して要素の追加時と削除時に無効になる。 list/map/setはイテレータの指す所が削除されたときに無効になる。 unordered_map/setはどうなるんだろうね?
typedef CHAR* LPSTR;
>>696 回答ありがとうございました
なるべくなら標準ライブラリでやりたいのですが・・・
その先の活用の仕方が思いつきません orz
どうか教えていただけないでしょうか?
>>704 めんどくさいから、char buf[20]; int num = 100; std::sprintf(buf, "%d", num);とでもしとき。
>>704 俺もよく分かってないから間違ってるかも知れんが
ostringstreamに出力させた後で、一時的なstringオブジェクト作って
そいつにostringstream.str()で移して、c_str()使えばいいんじゃね?
>>704 #include <sstream>
int num = 12345;
std::ostringstream oss;
oss << num;
oss.str().c_str(); // ←これを使う。
sprintfの方が高速だからこっちのがいいと思うが・・
CBaseClassから派生したCMyClassを作っています。 両方ともテンプレートでCMyObjクラスを指定してあげます。 CBaseClassはLibにして、CMyClassはAPのほうで実装します。 しかしCBaseClassのメソッドを呼び出すとリンクエラーになります。 よく見るとLibファイルにCBaseClassのメソッドが出力されてません。 ソースは以下のようです。 ライブラリを使うアプリ //App.cpp template <class T> CMyClass : public CBaseClass<T> { }; CMyClass<CMyObj> m_MyClass; m_MyClass.Foo(); ライブラリ //BaseClassLib.cpp template<classs T> CBaseClass { public: CBaseClass(){}; ~CBaseClass(){}; void Foo(){printf("foo\n");} }; というつくりなのですが、CBaseClassのメソッドはBaseClassLib.libに出力されないのですか?
>>709 テンプレートは型が確定しないと実態を作れないので、ライブラリ化できません。
>>709 キーワードを教えてやるよ。
テンプレート リンクエラー 定義
あとは自分で考えな。
>>710 ありがとうございます。やっぱりそうなのか。。
713 :
デフォルトの名無しさん :2005/11/08(火) 03:19:56
class A{ B obj_b; C obj_c; }; class B{ int hogehoge; } class C{ int gehogeho; } というAがクラスBとクラスCのオブジェクトをもつとします。 Aの要素としてBからC、CからBのようなアクセスをしたいんですがどうしたらいいでしょうか。
設計を見直す。
>>713 B、Cそれぞれのpublicメンバなら普通に触れるでしょ
なにが問題なの?
716 :
デフォルトの名無しさん :2005/11/08(火) 04:14:12
obj_bからobj_cのメンバ変数ってどうやって指定するのですか?
717 :
デフォルトの名無しさん :2005/11/08(火) 05:05:39
>>710 .NET2.0だとテンプレートのままライブラリ化できるんだっけ?
>>716 何がしたいのかよく判らんのだが
無茶なことを考えているらしいということだけは判った
あきらめて寝ろ
目が覚めたら一から勉強しなおせ
class B内にclass Cへのポインタをメンバに含めればいいでしょ class C; class B{ public: int hogehoge; C* lp_obj_c; }; みたいにして、lp_obj_cを介してobj_cのメンバ変数にアクセスする 当然だがあらかじめlp_obj_cにclass A内のobj_cへのポインタを代入しとかないとだめ
リング形式?のコンテナクラスってありますか? イテレータを++していって最後まで行ってら自動的に先頭まで戻って、 使う側からしたら永遠にデータを取り出せるような奴。
とりあえず標準にはないですな。
>>720 それって標準コンテナの要件満たすのか?
end で何を返すの?
というか if (it == hoge.end()) it = hoge.begin(); をループに入れるだけで実現できると思うんだが
end()が意味を為さないね。
リングバッファはしばしば使うけど、固定長だから自力で実装しているなぁ。
>>720 大した手間じゃないから、標準コンテナのI/F見ながら自分で作ってみよう。
725 :
720 :2005/11/08(火) 10:31:23
一般的なものはないというのはわかりました。ありがとう。
>>723 それをいれないでグルグルアクセスできたら少しきれいになるかなと
思ったので。
>>725 だからそれをやるクラスを作ればいいじゃん。
>724は非コンテナって言ってるけどvectorで実装すれば>723をそのまま内部で持てばいい。
単なるリングバッファならend()も要らなきゃbegin()も要らぬ。operator[]があればいい。
>>692 ローカル変数の使いまわしはバグの基
基本に返って関数分けを考えたほうがヨロシ
>>726 >
>>725 > だからそれをやるクラスを作ればいいじゃん。
別に作りたくないとは言ってないけど、何か誤解されてる?
720 が言ってるのはそういうものでスタンダードなのがあれば教えてくれってことでしょ
730 :
デフォルトの名無しさん :2005/11/08(火) 12:12:37
あの。質問です。下のコードがコンパイルエラーになるのですが・・ ローカルクラスオブジェクトは std::for_each() などのファンクタに 指定することはできないのでしょうか? #include <iostream> #include <vector> int main( void) { struct F { void operator()(const int & i) const { std::cout << i << std::endl; }; }; std::vector<int> vec; vec.push_back(100); vec.push_back(200); std::for_each(vec.begin(),vec.end(),F()); return EXIT_SUCCESS; }
>>730 ローカルに拘るんだったら以下のようにどうぞ
int main( void) {
- struct F {
- void operator()(const int & i) const {
+ struct Local {
+ static void F (const int & i) {
std::cout << i << std::endl;
};
};
std::vector<int> vec;
vec.push_back(100);
vec.push_back(200);
- std::for_each(vec.begin(),vec.end(),F());
+ std::for_each(vec.begin(),vec.end(),&Local::F);
return EXIT_SUCCESS;
}
733 :
730 :2005/11/08(火) 12:28:30
無理でした。orz
>14.3.1 Template type arguments
>2 A local type, a type with no linkage, an unnamed type or a type compounded from
>any of these types shall not be used as a templateargument for a template
>typeparameter.
>>731 ありがとうございます。
734 :
730 :2005/11/08(火) 12:37:16
>>732 なるほど・・トリッキーな手法ですね。勉強になります。
ありがとうございました。
>>709 一応、標準にはある仕様ってことで
ライブラリ側のクラス定義にexportキーワードを指定すればいいことになってるおw
>>700 >unordered_map/setはどうなるんだろうね?
今の予定では insert メンバが呼ばれると無効化されるかもしれない,という仕様です.
ただし要素への参照やポインタの有効性は,その要素が削除されるまで常に維持されます.
また,load factor と bucket count の値から iterator が無効化されるかどうかを
事前に知ることができますし,rehash や max_load_factor を用いて
iterator が無効化されるタイミングをある程度調節することが可能です.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf >>720 >>720 boost-sandbox に circular buffer があります.参考までに.
>>732 これはあくまで関数ポインタ経由のコールバックなので,関数オブジェクトに比べて
インライン化が効きにくくなるという状況はあるでしょうね.
template<class T>struct Hoge { T* t; Hoge(int n){ t = new T[n]; } }; assert(Hoge<int>(10).t[0] == 0); ↑Tにプリミティブ型を入れたときにtの各要素を初期化する方法ってありますか? T()を代入するのは非プリミティブ型のときにコストがかかるし・・・ 全てのプリミティブ型に対して特殊化するのはスマートではないし・・・
>>737 すぐ思いつくのは、
・std::uninitialized_fillを使ってT()で初期化する
・boostのtype_traitsで組み込み型を判別する
>>738 ありがとうございます。
いずれもtype traitsですね。パクってみます。
740 :
デフォルトの名無しさん :2005/11/09(水) 12:17:21
->* .* これらはどういうものなんでしょうか?
743 :
デフォルトの名無しさん :2005/11/09(水) 16:33:52
newって何のためにあるんでしょうか? 「newで生成したオブジェクトはポインタのスコープに関係なく存在するから」 みたいな説明がありますが、スコープに関係ないってのよくないですよね? 理解に苦しみます。
>>743 >スコープに関係ないってのよくないですよね?
いいや。
auto_ptr
newが無かったら 不定値な領域を確保したいときはどうするんだ?
>>743 vtblがあるようなオブジェクトを実体化させる時困る。
なくても困らないよ。newなんてシンタックスシュガーだよ。
なんだか甘そうだな
>>747 おそらく743はmallocとの違いを聞いているのではないと思う。
( ゚д゚)マローク
いや743はなんでポインタは全部スマートポインタじゃないんだって言いたいんだろ
('A`)カローク
(゚Д゚;)リアローク
(・∀・)ラグナローク オンライン
<`д'>アロカ
758 :
デフォルトの名無しさん :2005/11/09(水) 22:35:26
現在、C++で構造化記述されたコードをオブジェクト指向記述でリファクタリングしています。 が、どのようにクラス設計すればいいのか、見当がつきません。 例えば、以下のようなコードがあります。(細かい文法ミスは勘弁してください。) GUIのグリッドコントロールからデータを取得する処理、入力範囲をチェックする処理、 構造体の各メンバに突っ込む処理です。 3コのメソッドで似たような条件分岐があり、これを取り除こうと思うのですが、 どのようにしてよいかわかりません。 最初は各メンバをクラスにしようかと思ったのですが、 そうすると30コくらいの小さいクラスができてしまいます。 また、各メンバの型も異なります。 新規メンバが追加されたりしても、修正個所が少なくてすむような クラス設計するにはどうしたらよいのでしょうか? ご教授いただけませんでしょうか。
759 :
その2 :2005/11/09(水) 22:36:16
//グリッドからデータを取得(GUIクラスに記述) void GetData( int nField, CString& Val ) { switch( nField ) { case 1:// Val = m_Grid.GetText( ROW_1, COL_DATA ); break; case 2: Val = m_Grid.GetText( ROW_2, COL_DATA ); break; case 3: Val = m_Grid.GetText( ROW_3, COL_DATA ); break; // 以下略 30コくらい }
760 :
その3 :2005/11/09(水) 22:37:04
//入力範囲をチェック(GUIクラスに記述) int CheckData( int nField, CString Val ) { switch( nField ) { case 1: if( ( -10 > atol( Val ) || ( 10 < atol( Val ) ){ return -1; }else{ return 0; } break; case 2: if( ( 0 != strcmp( "A", Val ) ) && ( 0 != strcmp( "B", Val ) ) ){ return -1; }else{ return 0; } break; case 3: if( ( 0 > atoi( Val ) || ( 5 < atoi( Val ) ){ return -1; }else{ return 0; } break; // 以下略 30コくらい }
761 :
その4 :2005/11/09(水) 22:37:27
//取得したデータを構造体に設定(GUIクラスに記述) void SetVal( int nField, CString Val ) { switch( nField ) { case 1:// stData.Field1 = atol( Val );// long型 break; case 2: stData.Field2 = Val;// 文字列型 break; case 3: stData.Field3 = atoi( Val );// int型 break; // 以下略 30コくらい }
caseの値に対応する内容をTraitsクラスにして、 GetData(), CheckData()とSetVal()があるクラスを クラステンプレート(Traitsクラスを引数に取る)にしてしまうのをまず思いついた。
763 :
758 :2005/11/09(水) 23:38:53
お世話になります。
>>762 即レスありがとうございます。
すいません。
私の力量不足の為、いまいち理解できておりません。
もしよろしければ、参考書籍、参考URL等を教えていただけませんでしょうか?
DDXみたいなのを実装すればそれで終わり?
stDataは何処から出てくるの? それから、何故にこれだけ stData.Field1, stData.Field2, stData.Field3 みたくなってるの?
>>761 stData の構成自体から考え直した方が良い気もする
768 :
758 :2005/11/10(木) 00:37:22
>>766 ありがとうございます。
早速、購入してみます。
>>767 この構造体は多数のタスクが参照しており、
構成を変更することは無理なのです。
オブジェクト指向に書き直さなきゃならないけどクラス設計が皆目わからないってんなら、デザインパターンの本でも読んでみてはどうだろう
771 :
766 :2005/11/10(木) 01:44:46
>770 いや、多態も使えてない様だから、もう少し基礎的な所から始めた方がいいと思う…… そういや、デザインパターン本で基礎的な所をカバーしたやつって見たことないなぁ
772 :
766 :2005/11/10(木) 01:56:50
>768 >この構造体は多数のタスクが参照しており データの管理がうまくいっていないような気がする…… まずは >767の通り、stDataの抽象化からかなあ。 さっきの本の「フィールドのカプセル化」を行って、「メソッドの移動」「クラスの抽出」 あたりを検討する……かな? 『今のコードはプロトタイプ』と割り切って再設計する手もあるけど。
773 :
デフォルトの名無しさん :2005/11/10(木) 05:15:08
プリプロセッサはCとC++ではまったく同じ仕様? 違うとしたらどこが違うの?
>>773 コメント記号 // の扱いが違うだろ。
775 :
デフォルトの名無しさん :2005/11/10(木) 13:05:26
>>743 遅レスだが、newを使う効用には「大きなオブジェクト」の確保ってのもあると思う。
関数内で大きなオブジェクトに対して自動変数を使うとオーバーフローしてしまうことがあるから。
ところで、関数用のスタックの大きさってどうやって調整すんだろう?>>誰か
>>758-761 せっかく書き直してるんだから、その恥ずかしいcase文を
ダラダラ書いてるところから見直そう
関数用のスタックって何よ?
779 :
デフォルトの名無しさん :2005/11/10(木) 13:45:55
匿名掲示板で変な勘ぐりすんなよ
関数の仮引数やローカル変数用に用意されるメモリ領域のことだと思われ
関数用のスタックという言い方が成立するなら"関数用*でない*"スタックが存在することになるな。
std::stackとか
784 :
779 :2005/11/10(木) 16:38:26
すみません、g++でCソースコードを ジェネレートすることってできるんですか? 昔のC++コンパイラはCのソースコードを 吐き出していたと聞きます。 今でもそれができるかどうかを教えてもらえませんか?
>>785 昔のって、禿のcfrontのことか
comeauなら今でもそんな感じ(バイナリコード生成をするコンパイラを別途用意しなければならない)
>>787 ありがとうございます。
調べてみます。
しかしcomeauって発音がよくわからないな・・
コミュー?
カミーユ
791 :
デフォルトの名無しさん :2005/11/10(木) 21:45:26
void foo(const char* i){ std::cout << i << std::endl; } int main(){ boost::bind(&foo, _1)("3"); return 0; } ↑は正しくコンパイルされて動くんだけど、 ↓(引数がint)はコンパイルエラーになるのはなぜですか? void foo(int i){ std::cout << i << std::endl; } int main(){ boost::bind(&foo, _1)(3); return 0; } gcc3.4.4 boost1.33.0です
なんだ、男か。
>>793 ありがとう! constじゃないといけないんですね
boost::lambda::make_constを使ってうまくいきました
795 :
616 :2005/11/10(木) 23:11:17
("3")チュイ
C++ Coding Standards p157に、 「std::string の実装は、時代遅れの最適化手法である書き込み時コピーを放棄しつつある」 ってあったんですが、COWって時代遅れなんですか?もっといい方法があるんですか?
>>796 なんかCOW(というかリファレンスカウント?)はマルチスレッドで都合が悪いらしい。
そんで、いまは愚直にコピーしまくる代わりにアロケータを賢くすることで
パフォーマンスを稼ごうって流れだっけ?
>>796 More Exceptional C++(英語) P118〜
COWはマルチスレッド時のパフォーマンス低下が甚だしいので、
従来の参照カウント方式を使わない方向の方が望ましいような
事が書いてある。
COWは遅延評価の一種であるため、mutexなどを使ってスレッド・
セーフにしないと、バグる理由が説明してある。
但し、シングル・スレッドで走らせるならば、50%程度のパフォー
マンス向上が望めるとも書いてある。
これ早く和訳されないかね〜
Effectiveみたいに訳者が変わって悲惨なことにならないでくれるといいけど・・・
>>799 俺そのために、More Effective C++は英語版も買ってしまった('A`)
こいつらを付き合わせて読まないと、意味が通らない所があるんで。
>>800 漏れもだ('A`)
C++FAQとMoreEffectiveC++は原著を読んだ方がいい
どこに書いたらいいか分からなかったのでここで質問させて頂きます。 少々長文になってしまいますが。 自分の環境は、WindowsXP SP2、P4 2.6G HT コンパイラはBCC 5.5.1です。 単なるローカル変数として宣言したもの同士の割り算、 100万回ループに掛かる時間が int型同士 約0.769ms、float型同士 約16.763ms、double型同士 約54.38ms (int a / int b 等) なのですが、あるクラスのメンバー変数の場合、上記と同じ計算をすると、 int型同士 約22.725ms、float型同士 約16.581ms、double型同士 約16.649ms (class a.a / class b.b 等) と、int型が鼻糞な程遅くなります。 使ったコードはクラス、変数の宣言とループと時間計測に必要なコードのみの 単純な物でQueryPerformanceCounterで計測しました。 メンバー変数の場合、色々状況を変えて計測してみても、 ループに掛かる時間の変化はあってもintが絡む場合intだから早いという事にはならず、 結果としてはfloat型の変数が一番高速に計算できるという結果に。 クラスのメンバー変数になったとたんにint型だけが超低速になってしまうのが どうしても納得いかないのです。 この辺りの事に詳しい方がいましたら、 どういう事でこうなってしまうのか教えて頂きたいのです。 (メンバー変数のint型が遅くなる理由とか) 宜しくお願します
環境依存スレチガイ
class A{ public: void ff(const char* c){} }; class B{ public: void ff(const char* b){} void foo(){ std::vector< const char* > v; A a; std::for_each(v.begin(), v.end(), boost::bind(&A::ff, &a, _1)); // (1) std::for_each(v.begin(), v.end(), boost::bind(&B::ff, this, _1)); // (2) } }; (1)はOKですが(2)はコンパイルがとおりません。 自分のメンバ関数を呼ぶときはどう書くんでしょうか? VC7.1 boost1.31
>>804 VC7.1 boost1.33でコンパイル通ったけどなぁ
boost::bind
途中で送信してもた orz boost::bind(boost::mem_fn(&B::ff), this, _1) にしてみては
>>804 g++ 3.3.5 boost1.32でそれ通りますね
808 :
804 :2005/11/11(金) 11:50:56
あ、すみません。 class B が関数内クラスになってました。 class A{ ... }; void XXXX(){ class B{ ... }; ... } class Bを外に出したらうまくいきました。 (が、なぜ関数内だと駄目なのかは理解していない・・)
>>810 笑い終わったら理由を教えてくれないか
俺もわかんねぇぞw
>808のネタが分からない奴がいるとは悲しいことだ
↑説明たのむ
815 :
デフォルトの名無しさん :2005/11/12(土) 19:52:22
バイトオーダがネットワーク型、intが4バイトとしてとして int i = 12345; (i >> 12) & 0xffff みたいに任意の場所を2バイト整数として取り出すことができますが(プログラム正しいか?) 逆に値を設定するときはどうするの?
バイトオーダー関係ないとおもう
>>816 ビット演算ってバイトオーナ関係なかったのか
定番の方法ってないんですね
とりあえず内部的には個別に整数でもってビットパターンがほしいときに(a<<32)|(b<<14)ってして返すようにした。
バイトオーナ?
ニー
つーかC++スレならbetset使えよ。
betset?
そんなにいっぱい賭けられません><
誤字で会話するスレはここですか
>>815 int i=12345;
int mask= 0xffff<<12;
i&= ~mask; /*更地*/
i|= mask&(0xabcd<<12); /*セット*/
829 :
デフォルトの名無しさん :2005/11/14(月) 05:00:02
#include<cstdio> template <class U> U operator+(U i, U k){ return i + k + 2; } int main(){ printf("%d\n",2+2); } これでコンパイルすると"4"と表示されてしまうのですが、 演算子オーバーロードを有効にするには何が足りないのでしょうか?
>>829 組み込み型の振る舞いを変えることは出来ない
operator+のパラメータのうち最低一つはユーザー定義型でなくてはならないから、
Uはintにはなりえない
>>830 >operator+のパラメータのうち最低一つはユーザー定義型でなくてはならない
なるほど。試しに以下のようなコードをにしたら演算子オーバーロードが機能しました。どうもです。
#include<cstdio>
struct CLASS{};
template<class T, class U>
U operator+(T t, U k){
return sizeof(t) + k;
}
int main(){
CLASS cls;
printf("%f\n",cls+2.5);
}
あれ、どうでもいいけど上のコードが $gcc foo.cpp でコンパイル実行できちゃっってた。なんでんだろ・・・
コンパイルできない理由がないだろ。
c++ライブラリを使ってないから。l
835 :
デフォルトの名無しさん :2005/11/14(月) 08:37:59
char c[]{ 0xff }; c == 255; このcの大きさが任意、例えば10バイトとかでも10進表現の文字列に変換したいんだけど どうすればできる?
>>835 頼むから初心者スレに行くか、問題を整理して書くかしてくれ。
多倍長整数の表示ルーチンをつくりたいって話か?
>>837 多倍長整数っていうのか。検索してみたけどある程度コードかかないとダメっぽいね
g++3.4.4 で以下のコードがコンパイルできないのは何ででしょうか? また,以下みたいな generic な template-class の中で map の全要素を舐めたいときはどうすればよいのでしょうか? template <class T> struct X { std::map<T,int> map_; void func() { for (std::map<T,int>::iterator itr = map_.begin(); itr != map_.end(); ++itr) { cout << itr->first << " " << itr->second << endl; } } };
error: dependent-name `std::map<T, int, std::less<_Key>, std::allocator<std::pair<const T,\ int> > >::iterator' is parsed as a non-type, but instantiation yields a type note: say `typename std::map<T, int, std::less<_Key>, std::allocator<std::pair<const T, in\ t> > >::iterator' if a type is meant コンパイルエラーくらい嫁よ。
どうせtypenameだろ エラーメッセージぐらい書け
intellisenseってどんな仕組みでパラメータヒントを表示しているんですか? インクルードしていないヘッダの定義を勝手に表示してくれたり 逆にインクルードしてても表示してくれなかったりわけがわかりません mfc使ってないのに定義とか表示されると邪魔でしょうがないです vs2003です
確かファイルに吐き出してたはず ビルドした時点でそのファイル更新して 新規追加したヘッダーのも追加してるんじゃね? 詳しい解説は↓よろ
書こうかと思ったがスレ違いなのでやめておく。
おい、書いてくれよw
vs2003 は知らないけど vc6 なら ncb ファイルを見てるんじゃなかったっけ
ncbファイルってどうやって修正するの?
PODについて調べていたのですが、PODである要件の中に、仮想関数をメンバに持たないというのがないようなのですが、 これは何かの間違いですよね?(集成体の要件には仮想関数を持たないというのがありましたが)
調べてみたらncbファイルを編集するツールとかは無いらしい 不便なままでいろってこと?w
POD-StructはAggregateだって書いてあるようにみえるんですが?
できるかしらんが、同名の空ファイル作って読み込み専用にしてみたら?
>848 仮想関数にはvtblが要るじゃあないか。PODとは言えんよ。
>>852 そう思ったのですが、ISOのドラフトやJISでさえ仮想関数があってはならないとは書いていないです。
>>854 すいません。見逃していました。
ありがとうございます。疑問ははれました。
>>857 どういう理由でそう思ったのかわからんが外れだ
スマートポインタのbool値変換として、メンバポインタ typedef T * (this_type::*unspecified_bool_type)() const; typedef T * this_type::*unspecified_bool_type; が使われているけど、もっと単純に、 不完全型のポインタ struct unspecified_bool_type_tag; typedef unspecified_bool_type_tag *unspecified_bool_type; や、関数ポインタ typedef void (*unspecified_bool_type)(void); なんかじゃ駄目なのかな。 どこかに穴がある?
void *にしてしまったら型が違うポインタ同士の比較が出来てしまう
たとえばの話ですが, 1234という入力を,2バイト分ずつ(12, 34)というように読みたいときに, aとbをそれぞれ2バイト変数として定義して, cin >> a >> b; とやってもa=12, b=34とはならないんですが, どうやったらうまくできますか? cin >>の形ではできないんですか?
>>861 1234って16進数での話だよね?
というかその例だと1バイト分ずつだけど・・・
リトルエンディアンとして、
int tmp;
cin >> tmp;
a = tmp & 0xFF;
b = (tmp >> 8) & 0xFF;
じゃだめなん?
863 :
861 :2005/11/16(水) 12:52:23
すいません. 入力は,あるフォーマットされたファイルなんですが, そのファイルのヘッダ部分だけ一気に読みたいんです. ヘッダには10個くらい項目があるので, operator>>を定義して cin一個で綺麗に読めないかなと思いまして.
>>863 std::getline()で一度std::stringに読み取っておき、boost::lexical_castで
切り出して変換する。
まあヘッダを読み取るだけのために専用クラスを作ってもいいけど、 何かもったいない気がしたので。やろうと思えばできない事もないが。
ありがとうございます. ついにboostを使うときが・・・. いやよいやよと避けてきましたが,やってみます.
嫌なんなら適当に書けば言いジャマイカ template <class Target, class Source> inline Target lexical_cast(Source source) { std::stringstream ss; Target t; ss << source; ss >> t; return t; } 素人が適当に書いてみるテスト 普通はどう書くんだろう…
別に無理してboost使わなくても、atoi() or atof() + std::string::c_str()でも オケ。
869 :
デフォルトの名無しさん :2005/11/16(水) 15:10:07
Cの関数の引き数としてC++のメソッドのポインタを渡したいんですが。 無理でつか
超FAQな質問だな
>>869 Cの関数に、vtblを解析できる能力と、thisを受け取る能力があればな。
POD vtbl Aggregateって何ですか?
18禁の単語だから聞いちゃダメ!
そうなんですか、失礼しました
PODはPlain Old Dancerつまり古き良き時代の踊り子 vtblはバーチャルリアルリアリティの世界に登場する机 Aggregateは睾丸だ
間違えたがどうでもいいや
>>869 無理。
でもWinAPIみたいに追加の引数を渡せるようになっていれば何とかなる。
WNDPROCに追加の引数はない
仮想関数のテーブル書き換えるのってどうやるの?
>>880 ウィンドウハンドルに好きなだけデータを関連付けられるから、そっちで何とかすればいい。
>>881 実装依存だし、できたとしてもやっちゃダメだ。
>>882 ウインドウをサブクラスして、あるクラスに処理させたいときはどうするの?
SetPropでウィンドウにクラスへのポインタを関連付けて GetPropでそのポインタを拾ってクラスに処理させればいい ウィンドウを閉じる前にRemovePropするのを忘れずに
VC++でCOMのインターフェイスとクラスの関係についてです。 IStream ← CStream(IStreamの実装) ↑ ↑ IFile(Open追加)← CFile(IFile::Openの実装) class CStream : public IStream interface IFile : public IStream class CFile : public IFile, CStream これだとIStreamの各関数が定義されていませんとエラーが出てしまいます。 IStream ← CStream(IStreamの実装) ♂ IFile(Open追加)← CFile(IFile::Openの実装) class CStream : public IStream interface IFile : public CStream class CFile : public IFile IFileの派生元をCStreamに、CFileの派生元をIFileにすれば エラーは出ないのですが、何かしっくり来ません。 こういうモノなのでしょうか?
ATL風に IStream ← CStream<IStream>(IStreamの実装) ↑ IFile(Open追加)←CStream<IFile>(IFileのIstream部分を実装)←CFile(IFile::Openの実装) とでもすれば?
>>887 CFileの中でIStreamのメソッドそれぞれに対していちいち次のように親のメソッドを呼ぶ方法もないわけではない。
STDMETHODIMP Read(void *pv, ULONG cb, ULONG *pcbRead)
{
return CStream::Read(pv, cb, pcb);
}
ただ、そもそもIFile::Openの存在意義がわからない。何故必要?
890 :
887 :2005/11/17(木) 19:23:56
>>888 おぉ、ありがとうございます。
こんなかんじで出来ました。
template <class TYPE> class CStream : public IStream
interface IFile : public IStream
class CFile : public CStream<IFile>
ただ、IStreamからの派生物が増えてくると、お腹いっぱいになりそうです。
それとQueryInterfaceでIFileインターフェイスの取得が上手くいかなさげ??
>>889 その方法は面倒臭そうだったので止めました。
> ただ、そもそもIFile::Openの存在意義がわからない。何故必要?
え゛? 他にもIBufferとかICompressとか作って
IStreamでの一括管理がしてみたいから、としか…
COMに拘る理由は無いんですが、勉強にもなるかなと。
>890 ×class CFile : public IFile, CStream ○ class CFile : public IFile { private: CStream foo; } 理由もなくprivate継承するな。 めんどくさがらずに、いちいち実装しろ。
891のは>887とするべきだったか もひとつ >890 ×template <class TYPE> class CStream : public IStream ○template <class TYPE> class CStream : public TYPE テンプレートを使うとなると、 実装をモジュールに封じ込めるために別のクラスが欲しくなる罠。
893 :
889 :2005/11/17(木) 20:10:48
>>890 template <class T> class CStream : public T
おそらく888はこうすることを考えていたはず。
ところで俺はIFile/CFileなどを作らずともSHCreateStreamOnFileとかで十分ではと思った。
894 :
887 :2005/11/17(木) 20:51:42
>891 > 理由もなくprivate継承するな。 こ、これはバグです。 >892 >893 public TYPE これで出来ました。何故なのかは後で考察します。 で、妄想を膨らませたらこうなりました。 template <class TYPE> class CStream : public TYPE template <class TYPE> class CFile : public TYPE CFile< CStream<IFileStream> > > SHCreateStreamOnFile 更に悟りを開いた結果、これが全てを物語ってる気がします。 タイヤの発明 ('A`)
895 :
887 :2005/11/17(木) 21:23:56
ああ、なるほど。 template <class TYPE> class CStream : public IStream だと >888 IStream ← CStream<IStream>(IStreamの実装) 固定になってしまうのか。
896 :
887 :2005/11/18(金) 15:21:10
> template <class TYPE> class CStream : public TYPE でも、これって複数のinterfaceを継承する時どうするんだろ? IArchive IStream ↑ ↑ IArchiveStream CStream<IArchiveStream> (IArchiveStreamのIStreamの実装) CArchive<IArchiveStream> (IArchiveStreamのIArchiveの実装) だとすると template <class TYPE> class CArchiveStream : public CStream<TYPE>, public CArchive<TYPE> CArchiveStream<IArchiveStream> または template <class TYPE> class CArchiveStream : TYPE CArchiveStream< CStream< CArchive<IArchiveStream> > > 前者はIStreamが未実装、後者はIUnknownの変換があいまい、てエラーが出る。
>896 正直なところ、 CArchiveStreamの実装が単純なCArchiveとCStreamからの横流しで できるようなものなのかが疑問だが(それ故の多重継承じゃないのか?) 1.いちいち定義 class CArchiveStream : public IArchiveStream { private: CArchive<IArchive> a; CStream<IStream> s; } 2.多重継承なインターフェイスが悪い interface IArchiveStream { virtual IArchive &GetIArchive() = 0; virtual IStram &GetIStream() = 0; }
CArchiveStreamからIUnknown*への変換を必要とするところすべてに、 ちゃんとしたキャストを実行すればよろし。 static_cast<IUnknown*>(static_cast<IArchive*>(this));か、 static_cast<IUnknown*>(static_cast<IStream*>(this ));かどっちかだろうが。
899 :
887 :2005/11/19(土) 03:19:58
>>897-898 レスありがとうございます。
> 多重継承なインターフェイスが悪い
なんとなくそんな気はしてました。
(887の最初のところも含めて)COMの理念にそぐわない設計なんだろーな、と。
キャストに関しては、テンプレートの利点を生かせるように試行錯誤してましたが
やはり明示的に指定してやらないとダメみたいですねぇ。
もうしばらくは色々な文献を漁ってみることにします。
900 :
デフォルトの名無しさん :2005/11/19(土) 03:46:01
>>898 キャスト使う時点で設計ミスだ。static_castだとしても。
901 :
デフォルトの名無しさん :2005/11/19(土) 08:01:49
すいません。教えてください。 C++用のlint は存在するのでしょうか?
>>897 > > 多重継承なインターフェイスが悪い
>COMの理念にそぐわない設計
実際、COMのインターフェイスは単独継承しかできない仕様。(だからIArchiveStreamは存在できない)
(それを実装するときは好きなだけインターフェースを継承して実装できるがそれはCOMの世界でないから)
複数のインターフェイスをサポートしたければQueryInterfaceで対応することになる。
>>901 ない。仮にあったとしたらそれは既にlintではない。
904 :
デフォルトの名無しさん :2005/11/19(土) 12:25:21
903>> ありがとうございました。納得です。
過去ログって見れないの?
●買えばみれる
908 :
デフォルトの名無しさん :2005/11/19(土) 23:45:11
Modern C++ Designのポリシーっていうやつなんだけど、 あれについてもう少しいろんな具体例が書かれているような本とかってある?
アレはまさにLokiの解説本って感じの本だった。 サパーリ活用してないが。
>>906 ●買ったらID:???の板とかでも全部ID見えるって本当?
hontou
>908 ポリシーってアレだろ。 単に、テンプレート引数で与えられるクラスに「処理」を任せるようにして、 「処理」の中身を選択したり、自分で作ったりできるようにした。 ってだけの事じゃないのか?
908は多分、そこんとこはわかった上で 機能をポリシーに分解する具体例をたくさん見たいんだと思う。
Lokiの実装を見るのが一番だと思うなぁ。 ModernC++Designで触れられてないコンポーネントもあるし。 他のライブラリでポリシーを前面に押し出したやつってあるかな?
boost
boostライブラリっていつ標準化されるんすか?
919 :
デフォルトの名無しさん :2005/11/20(日) 20:18:15
マジかよ
ΩΩ Ω<ナ、ナンダッテー
>915 STLコンテナ(のアロケータ)
dbx形式のメールを、eml形式に変換するにはどうすればいいのでしょうか。
>>923 ここではスレ違いだから、頑張れとしか言えない。
>923 頑張れ
928 :
923 :2005/11/21(月) 08:01:43
自己解決しました、お騒がせしてすみませんでした
>>908 ATL のソース読んでみ。
Loki よりもだいぶ昔にかかれたものだけど、
スレッドモデル選択や、ウィンドウスタイル選択などは
Loki のポリシーに通じるものがある。
>>929 ATL。MFCよりいい出来なのに、マニアックすぎて人気がいまいちなのが悲しい。
日本語の資料が少ないのも原因かと。 <ATL
質問なんですが、変数に値を代入する時に、例えば、 a=10,b=15; とするのと、 a=10;b=15; とするのとでは違いというのはでるものなのですか?
コンパイラに聞いてください
>>932 「副作用完了点」でぐぐってみ。上の式しか右辺値になれないし。
C++では左辺値にもなれるんだっけ。変態仕様だな。
>>932 上は式が一つ。下は式が二つ。
実行結果に違いは無いので、下のほうが見た目に違和感が無くて好ましい。
式が一つしか書けない所では上を使うことになる。
basic_ostream に、バイナリデータを書き込みたい場合、 // n は出力する文字数 basic_ostream::write(const char_type *s, streamsize n); を利用して出力すると思うのですが、basic_ostream< char > ならば、 n == 出力するバイト数になるので問題は無いのですが、 basic_ostream< wchar_t > の場合、sizeof(wchar_t) >= 1 のため、 バイナリデータをキッチリ出力するのは難しいような気もします。 basic_ostream< wchar_t > にバイナリデータをキッチリ出力する 上手い方法はないでしょうか。
ない。
938 :
932 :2005/11/22(火) 15:46:08
Hoge::Hoge() //コンストラクタ : m_var(0) { ... } というメンバの初期化法を知ったのですが、これは Hoge::Hoge() { m_var = 0; ... } と同じことなのでしょうか?
>>940 ありがとうございます
皆さんよく使われる方法なのでしょうか?
今まで私はコンストラクタ内にずらずらと代入してきましたが…
可能な限り使うよ
そうですか、参考になりました
>>939 constオブジェクトとか、オブジェクトのリファレンスは前者の初期化法しか
使えんよ。というか初期化忘れのコンパイルエラーが出る。
>>939 初期化と代入の違いは大丈夫かい?
int i = 0;
と
int j;
j = 0;
は別物。可能な限り前者を使う。
初期化って必ずしないといけないものでしょうか。 特に自動変数の時。
>>946 かならず値を代入することが分かっていて、かつ最初の代入が
行われるより前に参照されることはないと分かっているのなら
しなくてもいい
定義と同時に初期化を済ませるのがC++の流儀。 初期化しない自動変数はバグの温床。
時と場合によるが「初期化は必ずしないといけない」で 全ておkなんでクセ付けときな。
for(;;){ int val; // valを使った処理・・・ } と、 int val; for(;;){ // valを使った処理・・・ } って、やっぱ後者のが早淫すか? それともおんなじ?
>>950 意味が違う。
後者がブロックの外でvalを使わないなら一般的には、全く同じコードを吐くと思われる。
#つーか、何で後者の方が速いと思うんだ? 最適化が蛸なら寧ろ前者の方が速くなることが期待できるぞ。
>>950 初期化しない int なら同じ可能性がまあまあ高い。もちろんコンパイラ依存だけど。
>>950 とはちがうけど、
STL等の走査で、iterator の終端の判定用にインスタンス別に作ったほうが早いのかな?
1.
for(list<int>::iterator it = hoge.begin(); it != hoge.end(); ++it);
2.
list<int>::iterator end = hoge.end();
for(list<int>::iterator it = hoge.begin(); it != end; ++it);
前者のほうがソースとしては楽&見た目すっきりだけどどうなんでしょ?
endが無効化したらどうするんだこのスカタン
いや、もちろんそういったものがないって前提で
早いに決まってんだろこのド低脳が
決まってはいないよ。質問は「STL等」についてだし、処理系も指定していないからね。
>>956 不満事を書いた瓦を頭で割ってるCMの、
ナレーターの台詞を思い出した
相当要素数が多くないと有意差は出ないよ. 実用的にはよほど効率を切り詰めたい部分でもなければ,毎回 end 呼んで構わないと思うけど.
>for(list<int>::iterator it = hoge.begin(); it != hoge.end(); ++it); この例だと、実質同じコードになる希ガス。
>>960 試したのか? 俺の環境では g++, cl, bcc32 のどのコンパイラでも異なるコードを生成したぞ?
Metrowerks CodeWarrior for Windows v8.3では全く同じコード。
963 :
デフォルトの名無しさん :2005/11/26(土) 02:35:46
C++もそろそろネタ切れだな
>>963 お前にとってはな。ということでさようなら。
話は戻るけどswitch文の一部でしか使わない、しかも複数の箇所で使う変数はどうしてるの? switch(c){ case 0: int i = 0 ;return i; case 1: int i = 1; return i; case 2: return 2; } 面倒だからいい加減なサンプルだけどこれだとコンパイルエラーになる。 iをswitchの外側で定義すると初期化できないし。 case文の所を{}で囲めばいいんだけど正直見た目が悪いような。
>965 変数の使いまわしなんかするくらいなら、多少見た目は悪くとも >case文の所を{}で囲めば これ一択だと思いますけど。
Windowsのメウィンドウプロシージャなんかだと、 メッセージクラッカーを使うから半強制的に各caseの中身が関数に切り出されて、 そんな心配が要らなくなる。あくまで結果的にだけどね。
「Windows限定」の話ならスレ違い
>967 を「スレ違い」と認識するのは、理解力が足りない。
970 :
デフォルトの名無しさん :2005/11/26(土) 10:14:00
参照って言うのは実態はなんですか? たとえばWindowsでSendMessageで文字列をスレッド間で引き渡す場合、 ポインタだったらサブスレッドのスタックにある文字列を指していても、 SendMessageでWPARAMやLPARAMに乗っけてメインスレッドに渡せるじゃないですか。 参照は無理ですか?
これはいいのか?
うん
> 参照って言うのは実態はなんですか? ポインタ > 参照は無理ですか? 無理ではないがどっちかに統一したほうがいい win32apiだとかを呼びまくる場所ではポインタのほうがいい 抽象化が十分になされた、アプリケーションロジックが主体のレイヤでは 参照のほうがいい 混ざってるのはたいへん見苦しいしバグの温床
975 :
デフォルトの名無しさん :2005/11/26(土) 12:24:23
C++って、以下のようなコードで例外を出してくれないのでしょうか。 struct test *p = NULL; int val; try{ val = p->member; } catch(...){ std::cout << "例外をキャッチ" << std::endl; } またtryのなかを val = 100/0; とかに変更してみても、例外を投げずにアプリケーションエラーとなりました。 そういうものなんでしょうか? WinXPでmingwを使用しています。
catch(...)でWIN32構造化例外が取れるかどうかはコンパイラ依存
979 :
デフォルトの名無しさん :2005/11/26(土) 13:06:38
関数example1からexample2にmultimapのtestMapを引き渡したいのですが どうしたらうまくいくでしょうか? 以下のような感じなのですが void example1 (){ MMAP testMap; testMap.insert(Mvalue([配列])); } void example2(MMAP map){ for(MMAP::iterator i=testMap.begin(),end=testMap.end(); i!=end; i++){ cout << *i << endl; } }
>>975 Windowsには構造化処理例外(SEH)というのがある。
SEHではヌルポインタへのアクセスも例外となる。(その名称がNullPointerExceptionでないのが残念)
Winodws用のC++コンパイラは大抵C++例外の実装にこいつを使っているので、
そういう風にヌルポインタアクセスはcatchできる。
すみません。もうひとつ。 参照とポインタが実態としては同じと言うことは どうにかコンパイラを騙せばポインタを渡す関数に参照を渡しても、その逆をやっても動きますか?
>>980 具体的にはどのようにしたらよいのでしょうか?
そんなことするくらいなら、Javaなりドトネトなりに行けよwwwww
986 :
975 :2005/11/26(土) 14:12:06
ありがとうございます。
VC8 Expressのコンパイラで__tryと__exceptを使用してみると、確かにキャッチできました。
C++が勝手に投げてくれるのは、標準例外
http://www.02.246.ne.jp/~torutk/cxx/exception/stdexceptions.html にあるものだけ、という認識でよいのでしょうか。
しかし、newで失敗してもbad_allocを投げないコンパイラがあったり(VCのことだと
思うのですが)するようですので、C++における標準例外の
位置づけがいまいちわかりません…
以下本題とは逸れるのですが。
書籍「.NET&Windowsプログラマのためのデバッグテクニック徹底解説」の記述によると
> catch(...)はC++例外を補足するだけでなく、SEH例外も捕捉することになっているのです
ということでした。
VC6+MFCのプログラムで、NULL参照をcatchしていたのを見て、てっきり
C++の機能で面倒見てくれているのだと思っていました。
# ただ、VC8で
>>975 を走らせても、やっぱり例外を捕捉してくれない…
# 記憶違い?
>>986 newがNULLを返すか例外を投げるかは規定されてなかった希ガス
この2通りの内どちらかになるのは規定されてるが、どっちかはシラネ
>>986 newが失敗してbad_allocを投げないのは規格違反。
VC7以降ならちゃんと投げるはず。
>>986 規格上C++のcatchで受け取れるのは下に書いたのとあとはthrowされたもの。
bad_cast(dynamic_castで参照型のキャストに失敗したとき)
bad_typeid(動的なtypeidでヌルポインタが渡されたとき)
bad_exception(例外指定に合わない型の例外を投げようとしたとき)
>>953 >前者のほうがソースとしては楽&見た目すっきりだけどどうなんでしょ?
for(list<int>::iterator it = hoge.begin(), end = hoge.end (); it != end; ++it);
とか
次スレ立てられなかった。誰かよろしこ。
// ちょっとここをお借りしますよ。 class CTest1; class CTest2; class CTest1 { public: CTest2 *pCTest2; }; class CTest2 { public: CTest1 *pCTest1; };
997
998
999
!!!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。