1 :
デフォルトの名無しさん :
02/02/21 00:04
2 :
デフォルトの名無しさん :02/02/21 00:06
3 :
デフォルトの名無しさん :02/02/21 00:08
v(^・^)v
v(^・^)v
v(^・^)v
6 :
デフォルトの名無しさん :02/02/21 00:16
7 :
デフォルトの名無しさん :02/02/21 00:19
newしたオブジェクトを参照で受け取るときに Class *const &cls = new Class; のように*constを入れなくてはいけない理由はなんですか? Class &cls = new Class; でもいいじゃないかと思うんですが。
8 :
デフォルトの名無しさん :02/02/21 00:26
>>7 なぜ”*”ではなくconstが必要と思ったのかなぞだが、
Class *&cls = new Class;
or
Class &cls = *(new CLass);
だろー。しかしなんつー使いかただ・・
ハァ?
10 :
デフォルトの名無しさん :02/02/21 00:37
class内でのconstメンバ変数の初期化ってどうやるんですか?? class A{ int const aa; A(){aa=123;}; }; ではエラーになってしまいます。
A():aa(123);
>>10 A():aa(123){};
基本だろ、キホンッ!
v(^・^)v
>8 Class&* で受けるんなら const 要るみたい(g++3.0.3) っつか,どーゆー時にこーゆー使い方が必要なんだ? >7 よ
×Class&* ○Class*&
v(^・^)v Class&* v(^・^)v Class*&
17 :
デフォルトの名無しさん :02/02/21 22:04
あるクラスの演算子[]をオーバーロードするとき b = a[0]; と a[0] = b; で、違う関数が呼び出されるようにすることは可能ですか? また、可能ならばどのように宣言すればいいのでしょうか?
>>17 C C::operator[](int) const;
C& C::operator[](int);
19 :
デフォルトの名無しさん :02/02/22 01:13
struct S { static const int I = 12345; // O.K. static const int* const Ptr = &I; // O.K. static const int& Ref = I; // N.G. }; ↑の S::Ref でコンパイルエラーが出ます。 参照は実体(メモリ領域)が必要になるようです。 Ptrの様にコンパイル時解決で済む静的参照を定義することはできませんか? 言語仕様としてこれをNGにした理由がわかりません。
>>19 「宣言」と「定義」は違うだろ。
struct S
{
static const int I;
static const int* const Ptr;
static const int& Ref;
};
const int S::I = 12345;
const int* const S::Ptr = &S::I;
const int& S::Ref = S::I;
>>20 ???
S::I と S::Ptr はよくて、 S::Ref だけダメなのがなぜかという質問ですが。
ちなみに、gcc です。
22 :
デフォルトの名無しさん :02/02/22 01:52
>>19 その形で初期化出来るのは定数(constなもの)だけ。
const int&はconst int型の値への参照を表す普通の変数なので
そこでは初期化できない。
ためしてないからわからんけど、
const int const &ならそうやってできると思われ。
嘘書きまくってた。無視しといてくれ。
24 :
v(^・^)v :02/02/22 02:01
>v(^・^)v なんすかコレ?
boostの使い方とか説明してる、いいサイトない?(日本語で) googleとかで探してもいまいち見つからんのだが・・・
>>24 C++相談室のキャラクター。
かわいがってあげてください。
29 :
ひよこちゃん :02/02/22 10:28
最近coutとcinで文字を表示させることができたひよこです 今度は、structureとenumを勉強してるんですけど enumってcinつかえないんですか? これでカラー選んで入力させられるようになりたいんですけど 誰かヒントくださ〜い enum ColorList {white, black, blue, green}; struct boatlist{ char name[50]; ColorList color; float age; };
30 :
デフォルトの名無しさん :02/02/22 13:17
void (Class::*pfunc)() = &Class::func; こんな感じにメンバ関数のポインタを取得できることは 分かったのですが、これをクラスの外で呼び出そうとする ことはできないのでしょうか? 普通に*pfunc();と呼び出そうとするとエラーになってしまいます。
環境はg++.3.0.3です。 エラーメッセージは以下です。 pointer to member function called, but not in class scope
>>30 メンバ関数を呼び出すには、オブジェクトが必要。
Class *p;
Class c;
void (Class::*pfunc)() = &Class::func;
(p->*pfunc)();
(c.*pfunc)();
33 :
デフォルトの名無しさん :02/02/22 13:50
>>32 どうもありがとう。
でもどうも疑問が残るのは
Class* cls;
(cls->*func)();
としたときに実際のメンバ変数の領域がないはずなのに
なぜか関数func内でアクセスできてしまうんですよね。
どうしてなんでしょうか?
コンパイルエラーを出すべきところではないのでしょうか?
>>33 > なぜか関数func内でアクセスできてしまうんですよね。
> どうしてなんでしょうか?
C++ だとポインタは、実際には(実装依存だけど、ふつーは)単なるアドレス値
だから。
> コンパイルエラーを出すべきところではないのでしょうか?
そのぐらいの簡単なケースなら、警告レベルを上げれば警告してくれると思う
けど(変数を初期化せずに使用しています、とか何とか)。
ただ、一般論としては難しい。
void foo(Class* p)
{
p->func();
}
これで p が有効なオブジェクトを指しているかどうかを毎回チェックすると、
無視できないコストが発生するから。Java のように GC 前提の言語なら
null check だけで済むけど。
>>34 ご丁寧に本当にありがとうございます。
g++では-Wallをオプション追加しても
警告は出ませんでした。
でも良く考えてみれば当たり前ですね。
Cでアロケーションした(つもりの)領域へ
確認無しに書き込むようなものですからね。
それがメンバ関数内で行われているという
違いだけで。
この辺は本当はアセンブラが読めれば
もっとC++の動作原理が分かるのでしょうか?
上のは、 なんでもない戯言です。 アセンブラ勉強します。 すみません。
>>35 g++ だと、最適化をかけないと未使用変数のチェックができななかった気がする。
g++ -O -Wuninitialized
でどう?
>>37 でました!
: `class Class * cls' might be used uninitialized in this function
こんなの初めて知りました。
最適化かけて初めて警告が出たりするんですね。
ホントに勉強になります。。。
>37 うぉ!漏れもそれ初めて知った!!感謝age!! # っつーかそーゆー知識ってやっぱマニュアル熟読してたりするわけ?
間違えて sage ちまった・・・鬱氏
g++の全てを知りたい。
どうぞ。
C++のコンソールアプリのサンプルコード集なんてどこかにないでしょうか? 人のコードを読んで勉強したいっす。
>>39 私は、
マニュアル読んだり
本を読んだり
プログラミング言語 C++, Generic Programming, Exceptional C++, Effective C++,
More Effective C++, Effective STL, Modern C++ Design,
Inside the C++ Object Model (以上、目の前の書棚に並んでるヤツ)
ソースを読んだり
STLport, boost, ATL/WTL, gcc
メーリングリストを読んだり
って感じですが。隅々まで知ろうというのは無理なんで、最初から放棄してます。
メーリングリストは C++ 関係のをチェックしてもいいですが、意外と UNIX の開発
者が集まってるようなメーリングリストを読んでると、コンパイラやらネットワークや
らの面白い話が拾えることが多いです。freebsd-arch とかね。
>>44 色々とやられているんですねぇ。
自分の不勉強を反省。
>44 うーむ,やっぱそのくらいしないとダメか. 一応C++自体の知識に関してはそれらの本は一通り読んだから それなりにあるつもりだけど,やっぱ英語の ML とか読まんとダメか. boost や STL のソースはちょこちょこ読んだりするんだけどね. まだまだだな,ヲレも.
19が流れませんように、age
49 :
デフォルトの名無しさん :02/02/23 01:19
>19 そもそも static な参照って使い道あるか?
>>49 たとえば、メモリマップドI/Oの抽象化なんかはどうですか?
ポインタで -> にするのがいやなだけだったりしますが。
v(^・^)v
52 :
デフォルトの名無しさん :02/02/23 10:05
NestedClassとかLocalClassって なんか使い道あるんでしょうか? これが言語的に含まれるようになった 理由が良くわかりません。NestedClassは まだなんとなく分からないでもないですが、 LocalClassのほうはさっぱり。 実際のプログラムで使ったことってありますか?
>>52 C 言語の時点でも nested struct や nested class は存在したから、まぁ自然な
拡張だと思うけど。
私は nested class, local class 両方とも、実際に使ってます。local class の代表
的な使い方としては、変数スコープに合わせて何かを処理するというのがありま
す。
struct MutexHolder
{
MutexHolder() { GetMutex(); }
~MutexHolder() { ReleaseMutex(); }
};
こんな感じの class/struct を関数内で定義して使うとか。もちろんグローバル
にい定義してもいいのですが、それだとグローバルな名前空間を汚してしまい
ますから。
nested class は、たとえば実装を Bridge パターンを使って隠す場合に
class Foo
{
struct Impl; // nested class
const std::auto_ptr<Impl> pImpl_;
public:
Foo();
~Foo();
// 他にメソッドいろいろ
};
と公開ヘッダで書いておいて、実装側で struct Foo::Impl を定義するとか。
別に nested class にせずに FooImpl というクラスを定義しても良いけど、
この方が関係が良く分かって良いかな、と。
Command Pattern を使う場合にも、各コマンドを操作対象のクラスの nested
class にしてます。
class TextSurface
{
public:
class SetTextCommand;
class SetFontCommand;
...
};
>>53 分かりやすい説明どうもです。
今までNestedクラスはクラス内に
ずらずら書き込むところを想定して
いました。
>struct Impl; // nested class
なるほど、classbodyは別にする訳ですね。
これなら分かりやすいです。
とてもいいことを教えていただいて
ありがとうございます。
MutexHolder!
羽暮らせて頂きます!!
感謝!
55 :
デフォルトの名無しさん :02/02/27 11:05
まだ定義していない enum型 Foo を、 enum Foo; のようにして先に宣言しておくことは、C++ の標準規格的に可能でしょうか。 VC++ 6 なら通るんですが、g++ 3.0.2 だとエラーになります。 g++ で通らないということは、99%、標準じゃないとは思われますが……
56 :
角度 -180..180 :02/02/27 11:10
与えられたあらゆる角度を -180 から 180 に収めるためのコードを探してます。 これ、一行でかけますか?
fmod()
C++ ではメンバ関数のアドレスは絶対に取得できないんでしょうか? 構築が終わったインスタンスのメンバ関数のアドレスは確定してますよね? 処理系依存でもいいので方法はないでしょうか? VC++6.0 を使ってます。 Delphi なら出来るというのは無しでお願いします。(事前にぐーぐるで調べたらその事についてのDelphi賛美ばっかりですよioi)
&Hoge::method
>>59 &Hoge と method に分かれて解釈されてしまいました。
method はグローバルスコープのメンバじゃないと言われ
&に左辺値がないと言われてしまいました。
とここまで書いて自分の間違いに気づいたのですが、
クラス名を書けという事ですね。
this ポインタを通しては無理でしょうか?
いや、まアドレスを返すメンバ関数を作ればよさそうなので一応なんとか
なりそうです。ありがとうございます。
>>56 いまいち意図のわからない質問だが angle -= 180; じゃ駄目なノリなのか。
62 :
デフォルトの名無しさん :02/02/27 13:15
C++で、string型からint型へキャストする方法がわかりません。 すみません。教えてください。
>>62 文字列をint型の配列に変えたいということですか?
C++で、string型からint型へキャストする意図がわかりません。 すみません。教えてください。
>>62 C++はCと同じく、文字列は文字型の配列だよね?
それをキャストするの?
文字列を整数値にしたかったらatol,strtol,strtoulを使え。
66 :
デフォルトの名無しさん :02/02/27 13:45
>>56 arg = (arg%360)-180; かな?
ちなみに私はCしか分からないので、もしも文字列の定義が違ったらごめん。
いや、全然違う。スマソ。
>>65 > C++はCと同じく、文字列は文字型の配列だよね?
それでも使えるが、ふつー STL の std::string or std::wstring 使う。
i %= 180; f = fmod(f, 180.0);
>>61 すみません、やりたい事というのは、type float の値 (-∞...∞) を与えて、
それを -180 から 180度の間の値に修正したいのですが、良い案がおもいつきません。
>>66 % は float には使えません。。。
>>70 ありがとうございます!!!! fmod() を知りませんでした。感謝感謝です!
>>70 と思ったら。。。うまく行かない。
f = 194.3
f = fmod(f, 180.0);
で f = 14.3 になりますが、実際は -165.7 が欲しいのです。
たとえば、string型変数 a を int型にキャスト変換し 3という値を文字列ではなく数値として扱いたい場合 String a = "3"; int b = 1; b = b + a; このやり方がどうしてもわかりません。 atoi()等は使えないですよね?
>>66 arg = 194.3
arg = fmod(arg,360)-180
で arg が 14.3 度になってしまい、×です。 194.3度は-165.7度になってくれないと
76 :
デフォルトの名無しさん :02/02/27 14:14
newを使ってクラスオブジェクトを配列で動的作成したときに それぞれのコンストラクタに引数(一定の値ではなく0,1,2,〜という感じで) を渡すことって可能なんでしょうか? class hoge { hoge(int a); }; だとして hoge *p_Hoge; p_Hoge = new hoge[4] = {0, 1, 2, 3}; これじゃダメでした・・・(当たり前? アドバイスお願いします〜
>>74 stinrg::c_str()
string::at(sstring::size_type index)
を使えば、atoi()も使える。
>>76 私も初心者だけど、
ループで回すしかないと思います。
>56 arg = (fmod(arg,360) > 180) ? 180 - fmod(arg,360) : fmod(arg,360); か?無理矢理一行で書くとすれば. >76 そーゆーの出来ないよ.init(int i) みたいなメンバー関数作って for で回すとか, for で回しながら一個ずつ vector に push_back するとかすればよろしいのではないかと. それ以前に hoge *pHoge; じゃぁ new hoge[4] は格納出来ないけど・・・
58で質問した者です。とりあえずメンバ関数のアドレスは取れたのですが、 メンバ関数のポインタを void* に格納する事は不可能なのでしょうか? (キャストできないと言われる) なんとかしてメンバ関数にコールバックさせたいのです。 どなたか教えてください。よろしくお願いします。
>>56 >>79 と似てるけど
arg = arg > 0 ? fmod(arg + 180, 360) - 180 : fmod(arg - 180, 360) + 180;
あるいは、2行になるけど
#define sgn(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : 0))
arg = fmod(arg + sgn(arg) * 180, 360) - sgn(arg) * 180;
58はなんか変な作り方してそう
>>80 static_cast
では、不可能でしたか?
reinterpret_cast
なら、可能だと思いますけど、
危険ですよね。
>>80 void* pF = reinterpret_cast<void*>( mem_fun );
でもダメか?
つーか、void* じゃなきゃ渡せないようなライブラリ相手だと、
メンバ関数のアドレス渡しても this ポインタが解決できないから
マトモに呼び出されんと思うけど。
>>79 なるほどーーー。ただ、arg=-194.3 の時に答えが -194.3 になってしまいます。ここは165.7にならないと
>>81 すごい!!!!完璧です。答えもバッチグーでした。多謝 ::::))))
>>83 reinterpret_cast でも駄目でした。というかエラーメッセージに
この変換が可能なコンテキストはありません。
と出ているのですが…、そうなんでしょうか。
>>84 呼び出し元も自分で書いてるんです。
>>82 スレッド(Win32)をラップしたクラスを作ろうとしているのですが、
スレッドのエントリー関数(実際には本物のスレッドのエントリーが呼ぶ)
をメンバ関数にしたいのです(staticな関数の場合はうまくいきました)
この作り方は変でしょうか?
>>76 まず、組み込み型 (int, long, ... ) を除いては、配列を動的に確保するのはやめた
方がいい。とくにデストラクタが仮想だったりすると、面倒なバグに出くわす可能性
が高いし、iterator がらみのアルゴリズムが使えなくなる。
C++ の流儀だと back_inserter を使って、こんな感じで書くのが良いんじゃない?
ほんとは template を駆使すると hoge::creator は generic な書き方も出来るんだ
けど、下準備がいろいろいるから hoge 限定ってことで。
---
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
#define NELEM(x) (sizeof(x) / sizeof(x[0]))
using namespace std;
class hoge
{
public:
hoge(int n) { cout << "hoge " << n << endl; }
struct creator
{
hoge* operator()(int n) { return new hoge(n); }
};
};
int
main(void)
{
const int param[] = { 0, 1, 2, 3 };
vector <hoge*> v;
transform(param, param + NELEM(param), back_inserter(v), hoge::creator());
return 0;
}
---
>>86 自分で書いてるなら、わざわざ void* にしなくても
そのままメンバ関数へのポインタ型で扱えばいいのでは?
>>80 > メンバ関数のポインタを void* に格納する事は不可能なのでしょうか?
無理です。
というか、そもそもメンバ関数でなくとも
- 関数ポインタ
- 変数ポインタ (void* を含む)
は全く互換性がないことになってます。規格上 sizeof(void *) と sizeof(void(*)()) が
違うこともあり得ることになってるし。
>>86 > スレッドのエントリー関数(実際には本物のスレッドのエントリーが呼ぶ)
> をメンバ関数にしたいのです(staticな関数の場合はうまくいきました)
無理。ふつーはスレッドのエントリ関数にパラメタを渡せるようになってるから、
1. static なメンバ関数を呼ぶ
2. そのメンバ関数で、引数から this を取得して、非 static なメンバ関数を呼ぶ
の二段構成にする。Win32 のウィンドウプロシージャのようにパラメタを渡す
領域がない場合には thunk を使って細工するとか、いろいろ。
90 :
スーパー初心者 :02/02/27 15:39
タグ無しのユニークなクラスのコンストラクタはどうすればよいですか? できないんでしょうか?
>>88 呼び出し先は固定にしたくないんです。
>>89 > - 関数ポインタ
> - 変数ポインタ (void* を含む)
>
> は全く互換性がないことになってます。規格上 sizeof(void *) と sizeof(void(*)()) が
> 違うこともあり得ることになってるし。
知らなかったです…。関数ポインタ版 void* みたいなのはないんでしょうか?
> 2. そのメンバ関数で、引数から this を取得して、非 static なメンバ関数を呼ぶ
あぁ!なんでこれに気づかなかったんでしょう!
static な関数内で偽 this ポインタを使う所まではやっていたんですけど
この偽 this でメンバ関数を呼べばよかったんですね。
とりあえず解決しました。
(本当はこれを応用して本物のダブルディスパッチとかできないかなぁ?とか考えていたので、そっちはポシャリましたが)
ありがとうございました。
>>90 ごめん。タグって何ですか?
私も初心者なんで、ベンキョウのために。
>>92 > 関数ポインタ版 void* みたいなのはないんでしょうか?
一般的な関数に関しては、キャストして OK ってことになってます。
void (*pf)();
とでも宣言しておいて、これに「あらゆる型の関数ポインタ」を格納しても
大丈夫(呼び出すときに、元の型にキャストし直すのを忘れなければね)。
ただし、メンバ関数になると仮想関数の扱いがあるので、難しくなります。
たとえば
struct IObject { virtual void foo() = 0 };
とあるときに &IObject::foo は何を返すかと考えると「関数のアドレス」では
NG ですよね(なにしろ、純粋仮想関数なのでアドレスが存在し得ないわ
けだし)。
C++ での関数の抽象化には関数ポインタも使われますが、主役は関数オ
ブジェクト (functor) になります。mem_fun や Boost.org のライブラリ bind
あたりを調べておくと、将来、役に立つかもしれません。
95 :
スーパー初心者 :02/02/27 16:21
例えばこんな時です。 class { char *p; public: (){p = new char[256];} //無名なのでコンストラクタ名がつけられない!(エラーになる) virtual ~(){delete[] p;} //同上 }c;
virtualは忘れてください(;_;)ミスッタ
名前くらいつけてやれよ。
98 :
デフォルトの名無しさん :02/02/27 17:11
初歩的な質問で申し訳ないんですけど、 unsigned char でどうして数字が扱えるのかわからないので教えてください。 charって文字変数しかあつかえないんじゃないんでしょうか?
>>98 > charって文字変数
C, C++ は char, short, int, long は全て「整数」型です。扱える数字の範囲が
違うだけ。
>与えられたあらゆる角度を -180 から 180 に収める double Hoge(double d) { return (double) (short) (unsigned short) ((d * 65536 + 180) / 360) * 360 / 65536; } 思わずこんなコードを書いてみるテスト……。
>>98 補足しとくと、半角文字は乱暴に言うと0〜127の128種類しか無いから、
その種類をブチ込んでるだけ。
0〜255のunsigned charや
−128〜+127の signed charだと、無駄が無いのさ。
基本的にunsigned char 又は BYTE を使っておく事を勧める。色々面倒有るから。
int c = 'A';
printf("%d\n", c);
putc(76);
以上を実行してみたらわかるかも。わかんないかも。
102 :
デフォルトの名無しさん :02/02/27 21:07
データメンバを value で初期化したい時に、 Hoge h( value ); とするのか、 Hoge h; h.Init( value ); とするのか、いつも悩みます。 前者だと、 class Hoge { private: int m_value; Hoge(); public: Hoge( int value ); }; とした時に、value の渡し忘れを防ぐメリットが、 一方、後者だと value の結果(戻り値)が得られるメリットがありそうです。 こういう場合は戻り値が必要/不必要だけで判断していいんでしょうか?
>>102 コンストラクタも多重定義できるから両方使い分ければいい。
ただ、
結果を得たいだけなら別のメンバ関数用意した方がいいのでは?
104 :
デフォルトの名無しさん :02/02/27 22:26
コンストラクタでのエラーを通知するのにJavaは例外を使うけどなぁ。 C++ではどうするのが定跡なんでしょうか?
>>104 例外が発生するような処理は、極力、コンストラクタに書かないようにすべきだと思うが。
いやそんなことはないでしょ。 例外は例外。 善悪もなく、必要であれば使えばよいだけ。 て、どういう例外のことを行ってるかわからんけど、 例外っていうくらいだから例外なんだよな。
>>107 > 善悪もなく、必要であれば使えばよいだけ。
そのとおりだが。ただ C++ だと「コンストラクタで、あまりヘビーな仕事をさせない
方が良い」っつーのも、一理ある。
この前見つけたドキュメントを一つ。あとは (More) Effective C++ あたりにも、例外
に関するトピックがあったと思う。
Error and Exception Handling
http://www.boost.org/more/error_handling.html > When should I use exceptions?
> The simple answer is: ``whenever the semantic and performance characteristics
> of exceptions are appropriate.''
109 :
激しくリロード (Class) :02/02/27 23:27
classの勉強中です。 数字ならうまく逝ってます。 下のソースはdoubleだけど、d1、d2を文字にするには どうしたらいいんですか? #include <iostream.h> class cls{ double d1, d2; public: double out(); }; double cls::out(){return d1 + d2;} void main(){ cls c; double* p; p = (double*)&c; *p = 1.1; p++; *p = 2.3; cout << c.out(); }
>>109 > cls c;
> double* p;
> p = (double*)&c;
おいおい。
cls 型のインスタンスを、無理やり double にキャストしたらダメだって。とりあえず、
しばらくキャストは忘れましょう。キャストしなければ動かない場合には、何か自分
が間違ってると思った方が良いです。
> 下のソースはdoubleだけど、d1、d2を文字にするには
そもそも cls のメンバ変数 d1, d2 を、クラスの外から
- 設定する
- 取得する
拾ってくる方法がないじゃない。まずは、そのメンバ関数を作るところからスタート。
>>109 マテマテマテマテマテマテマテマテマテマテ
すげー無茶を(藁
せめてd1&d2をpuclicにして c.d1 = 1.1 ってするか、普通は
void cls::dataSet(double one, double two){
d1 = one; d2 = two;
}
として、 cls.dataSet(1.1, 2.3); なんて感じでやりゃいい。
で、文字って、charでなく文字列?
それならCString使ってみ。簡単だから。
>>111 > それならCString使ってみ。簡単だから。
std::string 薦めるだろ、ここ VC++ スレじゃないし
113 :
激しくリロード (Class) :02/02/27 23:47
マテマテ マテマテ マテマテ マテマテ マ・テ・マティ〜カ♪ 初心者です。 難しい話はまだ分かりせん。 書いたソースはあれでも動いてます。 数字ならできるけど、文字列ならどういうソースに すればいいか分かりませんか?
>>113 > 書いたソースはあれでも動いてます。
おいおい、動けば良いってもんじゃないぞ。たとえば仮想関数を一つ追加
した瞬間に、多くの処理系だと即死することになる。
先を急がずに、ちと調べろ。
> 書いたソースはあれでも動いてます。 ワケもわからず適当に書いてみてたまたま動けばいいってもんじゃないののの!
116 :
激しくリロード (Class) :02/02/27 23:54
文字列にできないの?
117 :
激しくリロード (Class) :02/02/27 23:58
キャストって p = (double*)&c; でしょ。 ここではキャストしないとコンパイルエラーだよ。 上級者なら分かるはず。
>>116 できるが、それ以前の問題だ。
あと「文字列」って何をさして言ってる? C++ だと文字列といっても
- char[]
- wchar_t[]
- string
- wstring
といろいろあるんだが。VC++ だと、さらに
- CString (MFC)
- CString (WTL)
- CComBstr
- _bstr_t
- BSTR
なんつーのもアリだぞ。
しまった。ネタだったのか>激しくリロード (Class)
ネタなら他所でやんな。
class cls{ double d1, d2; public: cls(a,b) : d1(a),d2(b) {} frend ostream &operator << (ostream &os, const cls &c) { os << d1 + d2; return os; } }; こんなもんコレで十分だ。 void main() { cls c(1.1, 2.3); cout << c; }
122 :
激しくリロード (Class) :02/02/28 00:02
char[]型です。 数字なら、intでも成功した。 でも、char[]ではうまくいかない。 あの初心者的なソースの原型をできるだけ保って d1、d2 をchar[]型でやりたいです。
123 :
激しくリロード (Class) :02/02/28 00:05
>>121 ありがとう。でも難しくて分からなかった。
char[]型だとそう簡単にはいかないと思う。
C++では長さの決まってない文字列にはstringを使う。 class clss { string s1, s2; public: clss(const string &a, const string &b) : s1(a), s2(b) {} friend ostream & operator << (ostream &os, const clss &c) { os << s1 + s2; retun os; } }; void main() { clss c("ひげ", "もじゃ"); cout << c; } 型をテンプレート化して template<class T> class cls { T s1, s2; public: cls(const T &a, const T &b) : s1(a), s2(b) {} friend ostream & operator << (ostream &os, const cls &c) { os << s1 + s2; retun os; } }; void main() { cls<string> cls_str("ひげ", "もじゃ"); cls<double> cls_dbl(1.1, 2.3); cout << cls_str << endl; cout << cls_dbl << endl; } 精進せいや
・・・あがってるから期待したのに。
>>19 はあきらめるしかないのか。
126 :
激しくリロード (Class) :02/02/28 00:14
ありがとう。今からソースをじっくり見るぞ。
os << s1 + s2 を os << c.s1 + c.s2 になおしてちょんまげ。 コンパイルしてないから他にもエラー有ると思う。 誰かなおしてニャンマゲ
>>125 言語仕様として NG なのは確定っつーことで、何をやりたいのか書いたほうが
良いと思うが。目的がはっきりすれば、良い代替案が出てくるかもしれないし。
129 :
激しくリロード (Class) :02/02/28 00:22
原型壊れて分かりません。 #include <iostream.h> class cls{ char d1[50], d2[25]; public: char out(); }; char cls::out(){return strcat(d1, d2);} void main(){ cls c; char* p; p = (char*)&c; *p = "1.1"; p++; *p = "2.3"; cout << c.out(); } これ直せる?
>>129 だから、ネタは他所でやれと…
本気ならば、まずは入門書から読み直したほうが良い。キャスト使ってどうこう
しようって時点で、C++ プログラマとしては終わってる。
>>125 C++ってそんなことできるんだ。
Cだと確実にエラーになるんだけど。初期値なんて設定できないし、メンバーを個別にstaticにできないし(staticは変数を宣言するときに使うものだもの)。
>>125 struct S
{
static const int I;
static const int* const Ptr;
static const int& Ref;
};
const int S::I = 12345;
const int* const S::Ptr = &I;
const int& S::Ref = I;
つーか、何がやりたいんだ? ちなみにVC++6.0では
>>19 はIの時点で蹴られるが。
>>131 VC++では純粋仮想関数の宣言であるとみなされた上でエラー。
ネタなら論外だし、マジ初心者としても人の言う事聞いちゃいねー。 ほっとこーぜ、もう。
>>132 なるほど。C++ではstructは構造体だけを表すわけではないんだ。
Cを使うのはやめてC++を勉強しようかな・・・・文字列型なんてのがあるみたいだし。これはかなり魅力的。
135 :
激しくリロード (Class) :02/02/28 00:34
で、結局、ソース書ける人いないのね。 がっかり。 原型が保たれてない。
#include <iostream> #include <cfloat> using namespace std; class cls { char *tbl[2]; public: operator char ** () { return tbl; } double out() const { return atof(tbl[0]) + atof(tbl[1]); } }; class cls2 { char *tbl[2]; public: operator char ** () { return tbl; } string out() const { return string(tbl[0]) + string(tbl[1]); } }; void main() { // 数値計算 cls c; char **p; p = (char **)c; *p = "1.1"; p++; *p = "2.3"; cout << c.out() << endl; // 文字連結 cls2 c2; char **p2; p2 = (char **)c2; *p2 = "1.1"; p2++; *p2 = "2.3"; cout << c2.out() << endl; } できないこたないが こんなコード書くやつがいたらクビだ。
>135 原形がそもそもプログラムとして不完全過ぎるんだから それを保って書こうってのがどうかしてる. だから「ネタ」って言われるんだよ. もーちっとC++勉強してみ. キャストしてインクリメントっつーのが如何に無茶苦茶か良く分かるから.
138 :
デフォルトの名無しさん :02/02/28 00:37
メニューに画像が張り付いてるのを見ることが あったり、メニューの背景をオーナードロウ してたり、メニューの文字列の色を変更してたり するんですが、どのようにやってるんですか? ヘルプは見たんですが、ずばり答えてくれてなくて、 よろしくお願いします。
>138 VCスレなりなんなり他のとこ逝け. スレ違いだ.
140 :
デフォルトの名無しさん :02/02/28 00:41
>136 良く頑張った!感動した!!
141 :
激しくリロード (Class) :02/02/28 00:48
ありがとうございます。 文字列が数字に見えたのがいけなかった。ごめんなさい。 文字列でいいんです。 #include <iostream.h> class cls { char d1[50], d2[25]; public: string out() const{ return strcat(d1, d2); } }; void main(){ cls c; char **p; p = (char **)c; *p = "abc"; p++; *p = "def"; cout << c.out(); }
strcatするならstring out() constの const修飾子は外しておけ。 ついでに cout << c.out(); を二回実行したらどうなるか考えておけ。
143 :
激しくリロード (Class) :02/02/28 01:00
まだだめね。 #include <iostream.h> class cls { char d1[50], d2[25]; public: char out(){return strcat(d1, d2);} }; void main(){ cls c; char **p; p = (char **)c; *p = "abc"; p++; *p = "def"; cout << c.out(); }
これやるから、とっとと失せろや。 #include <iostream> using namespace std; class cls { char d1[50], d2[25]; public: char *out(){return strcat(d1, d2);} operator char**(){ static char*table[] ={d1,d2}; return table;} }; int main(){ cls c; char **p; p = (char **)c; strcpy(*p , "abc"); p++; strcpy(*p , "def") ; cout << c.out(); }
146 :
激しくリロード (Class) :02/02/28 01:09
じゃお前がいいかげんにソース書けや。 どや?無理だろ? 初心者のお前には目を細めれば寿司のネタに見える無い様だ。 初心者は豆腐食べてなよ。
147 :
激しくリロード (Class) :02/02/28 01:13
最初に書いた数字のやつのソースはいろいろ文句言われたけど コンパイルはエラー無しだ。 145は<静的変数>を含む関数はインライン展開できないだな。 operatorってのを使わずに書けないの?
>>146 > じゃお前がいいかげんにソース書けや。
124 に書いてもらったソースが分からなかったんだろ… 処置無しだよ。
149 :
激しくリロード (Class) :02/02/28 01:15
でもよー。145はえらいよ。できてるよ。 operatorを使ってないのも教えてほしいよ。 初心者な俺はoperatorなんて初めて見たもんだから。
一体何を求めてるの?
原型崩すな、とか言うから145さんはoperator出してきてんじゃねーのか?
自分が何を逝ってるか分かってるの
>>149
>149 この機会にoperatorについても学ぼうという向学心はないのか?
152 :
激しくリロード (Class) :02/02/28 01:26
#include <iostream.h> class cls { char d1[50], d2[25]; public: char *out(){return strcat(d1, d2);} }; int main(){ cls c; char *p; p = (char *)&c; p = "abc"; p++; p = "def"; cout << c.out(); } 文字化け。 operatorについても学ぼうという向学心あるよ。 でも、今はoperatorなしでやってみたいんだ。
これ以上「激しくリロード」に餌を与えないで下さい>各位 しかし 100 前後はわりと良スレだったのに、一気に荒れたな。
154 :
激しくリロード (Class) :02/02/28 01:28
>>153 場かは言ってよし。
そんなにじゃまならソース書け場か。
書けねーだろ。だから豆腐食べろってんだ。
荒らす気が無いなら、頼むからバカは放置してくれ>おーる こんなバカの為に有るスレじゃないんだから。
ほんとに荒れてらあ。最悪。さげ。
(最近の小学校では、2chでスレ立てて対決しろ、とかいういぢめが流行ってるのかな・・・)
厨房は放置で逝く事にケテーイで。
159 :
激しくリロード (Class) :02/02/28 01:37
今は分かる人いなさそうだね。 俺も今から豆腐食べるから、俺と同じ場かは 無い知恵絞って考えようね。 #include <iostream.h> class cls { char d1[50], d2[25]; public: char *out(){return strcat(d1, d2);} //operator char**(){ static char*table[] ={d1,d2}; return table;} }; int main(){ cls c; char *p; p = (char *)&c; *p = (char)"abc"; p++; *p = (char)"def"; cout << c.out(); }
もう、放置だな。
145にお礼も言わないわ、態度がどんどんでかくなるわで
厨房街道一直線だな。
>>151 こんな他人任せの奴に、そんなものはありません。
やりたいことかきます。 メモリマップドI/Oなハードで、コンパイラはgccを使います。 んで、ハードウェアのモードによってI/Oレジスタのメモリアドレスが変わるんですが、 変わるといってもその値はすでにわかっています。 #define MODE0_HOGE_REGISTER_ADDRESS (0x????????) #define MODE1_HOGE_REGISTER_ADDRESS (0x????????) で、レジスターの内容ビットをビットフィールドによって 操作可能にするための構造体を定義しました。 これは上記のモードが変わっても変わらないとします。 struct HogeRegister_t { unsigned X_IN:1; unsigned X_OUT:1; }; ここまでで、アクセスするためのコードはCで書くと、 void X_Out( BOOL signal ) { (*(volatile HogeRegister_t*)MODE0_HOGE_REGISTER_ADDRESS).X_OUT = signal; } って感じです。 泥臭い上にモードも決め打ちになるのでもっとかっこよく書こうとして、 以下のようなコードを書きました。 enum MODE { MODE_0,MODE_1, }; template< enum MODE > struct RegisterMap { }; template<> struct RegisterMap< MODE_0 > // モード0レジスターマップ { static volatile HogeRegister_t& Hoge = *(volatile HogeRegister_t*)MODE0_HOGE_REGISTER_ADDRESS; }; template<> struct RegisterMap< MODE_1 > // モード1レジスターマップ { static volatile HogeRegister_t& Hoge = *(volatile HogeRegister_t*)MODE1_HOGE_REGISTER_ADDRESS; }; 想定していた使いかたは、 const MODE theMode = MODE_0; // 以下のプログラムで使うモードを設定 typedef RegisterMap< theMode > theRegister; void X_Out( bool signal ) { theRegister::Hoge.X_OUT = signal; } ここまでソースに書いて、(・∀・)イイ! とおもってたのですが、コンパイルしてみたら、、、 今のところの代替案は static volatile HogeRegister_t* const pHoge = (volatile HogeRegister_t*)MODE1_HOGE_REGISTER_ADDRESS; theRegister::pHoge->X_OUT = signal; です。 なんかくやしいです。
162 :
デフォルトの名無しさん :02/02/28 01:45
ときに何故 class X : public int {}; って駄目なんだ?
ビットフィールドって、読み出し、書き込みの回数に保証は無いはずだから、 メモリマップドI/Oに使うのはどーかと思うけど。
#define MODE0_HOGE_REGISTER_ADDRESS (0x????????) なら、 volatile HogeRegister_t* hoge_regs[] = { (CAST)MODE0, (CAST)MODE1}; するとか、 #define MODE0_HOGE_REG \ (*(volatile HogeRegister_t*)MODE0_HOGE_REGISTER_ADDRESS) にするとか、何もテンプレートとかつかわなくてもいい気がするけど。
>162 そうしたら、何かうれしい? つか、その親仮想クラスint(class)がもつ、 intなvalueにどうアクセスする気? 素直に、IntClassを定義して始めたほうが…
>>162 それは俺もオモタ
>>165 実際にやりたいとかで無く、ただ単に疑問に思っただけでしょう。
実際にやれたとしたら、嬉しくない上に、ヤな問題とか、 C++の文法/予約語の追加とかが待ってるから、 駄目だ、という話ですが。
>>167 でもtemplateとからめて考えたら,
そういうこと (class X : public int {};) ができたなら
わざわざtraitsクラスを作ったりせずに済むかもね.
class dt : public int ,private int , protected int, int { //困った、このintの区別をどうつけてやろうか... }
>>163 あ、そうか。危ないですね。気をつけます。
あー、、、なるほど。
>>164 配列にするのは、メモリ領域が必要になるので、いただけません。
そのマクロなら結構自然な形で書けますね。
妥協案としていただきます。
ほんとは class Time : public time_t {}; って書きかけて疑問に思ったわけさ 上のクラスの批判は無しね
>>165 *this
でいいんじゃない?
int value(){
return *this;
}
>>169 それはINTでなくても駄目でしょ?
>172 func( TIME & ); class TIME : public time_t, public double { TIME() : *this( 4400) , *this( 2.5 ) {} method() { func( *this ) ; }//AGGGGGGGGGG. }
組み込み型で多重継承か。 class X : public void (*func)(int n) { }; 対抗して関数を継承してみた。
よーし、パパ、メソッドや配列、予約語も継承しちゃうぞー class IHoge { virtual void method(int)=0; }; class Y : public (void IHoge::*(int)), int [50], char [128], public new {...};
class AString : "もうね、アホかと。馬鹿かと"{};
まぁ素人はヘッダでも継承してなさいってこった。 class Io : public #include <cstdio>{};
class D: public C++ {};
class D: private C++(~機能(all)) {};
激リロードがいくらCが出来る人だとしても あいつを見る限りおれはC++とCを一緒に勉強しといて よかったなと思ったよ。
>>180 > 激リロードがいくらCが出来る人だとしても
そんなわけないって。
滅茶苦茶なキャストやポインタ演算見れば、C も使えないことは明らか。
継承した関数って 実際やるかどうかは別として、 アクセス制限は自由にかえることは できますよね?
183 :
デフォルトの名無しさん :02/02/28 13:30
質問です。クライエントサーバーでデータをやり取りする際、 javaにあるObjectOutputStreamのようにオブジェクトをそのまま送る っていうことはC++ではできないんでしょうか?全部char*型にいったん 直さないといけないんですか?
185 :
デフォルトの名無しさん :02/02/28 13:37
ごめんね。
で、C++でシリアライズって使ってる人いますか?
標準的な方法がないので, クラス毎に自分で実装するか ツールを使う(ObjectStore, MFC の CArchive など)しか方法がない。 面倒だし、やってる人は少数派だと思う。素人には略
188 :
デフォルトの名無しさん :02/02/28 14:04
MFCのCArchive、ObjectStoreですね、VC++に標準でついているの かな。探してみます。とにかくオブジェクトを文字列に直して、送って、 またオブジェクトに変換しなおすっていう作業が時間がかかって いやなんです。
189 :
デフォルトの名無しさん :02/02/28 21:26
>>188 簡単にいうと言語レベルでのサポートはないですよ
データがほしいだけなら
::write(fd,this,sizeof(*this))
でいいんじゃない?
190 :
デフォルトの名無しさん :02/02/28 21:33
言語レベルでサポートすべきことなのか? シリアライズって。こういったことは共通の ライブラリを使うことで解決すべきだと思うが。
>>190 どこまで言語や標準ライブラリがやるべきかは、難しいところだな。
ただ、C++ はリフレクションなどの機能を言語レベルでサポートしていないので、
シリアライズを実装しようとすると、Java などと比較すると余計な手間がかかる
のは確かだ。
(自分で書くと、わりとめんどい)
#define NULL 0 に代わる新たな NULL を考えてみた。 仕様: 整数型に変換できないこと。 あらゆる型のポインタに代入できること。 あらゆる型のポインタと等価比較できること。 class NullPointer{ private: NullPointer(const NullPointer&); const NullPointer& operator=(const NullPointer&); void* operator&(); public: NullPointer(){} template<typename T> operator T*()const{ return 0; } }; NullPointer nullPointer; template<typename T> inline bool operator==(T* p, const NullPointer&){ return p==0; }; template<typename T> inline bool operator!=(T* p, const NullPointer&){ return p!=0; }; template<typename T> inline bool operator==(const NullPointer&, T* p){ return 0==p; }; template<typename T> inline bool operator!=(const NullPointer&, T* p){ return 0!=p; }; #include <cstddef> #undef NULL #define NULL nullPointer
193 :
デフォルトの名無しさん :02/02/28 22:41
>>192 先生!ウチの職場では
memset(buf,NULL,sizeof(buf))←こんなコードが蔓延しています
(0で初期化したいらしい)
それ使えません。
>>189 そんなやりかたできますか?調べてみます。
いままでどうやってたんだ?
196 :
Java暮雨 :02/02/28 23:01
つーかポインタをぬるで初期化するのって なにか問題あるの?
197 :
Java暮雨 :02/02/28 23:01
上のはぬるじゃなくてゼロの間違い、訂正
できても環境依存じゃない?
NULL は 0 じゃない派と NULL は 0 だ派の戦争が勃発するのでやめまっしょう。
200 :
Java暮雨 :02/02/28 23:06
それを参照する段階でゼロかそれ以外か判断できれば 問題ないんじゃねの?
>>194 ただし単純なクラスにしかつかえませんよ
ポインタをメンバにもってるクラスとかだと駄目ですよ。
ポインタにゼロを代入したりゼロと比較するのは全く構わないんだけど、193 みたいに整数ゼロの代わりに NULL を使う困った輩がいるので、防止策として考えてみた
203 :
Java暮雨 :02/02/28 23:12
>整数ゼロの代わりに NULL を使う困った輩 これって何のためにそうするんですか?
>>201 浅いコピーってやつね。
あれって英語でなんていうんだっけ?シャローコピー?
>>203 全ての型に共通する初期値としてNULLを
考えてるのがいるんだよ。
先生! スモールトークではNULLのインスタンスは1つしかありません。 (UndefindObjectの唯一のインスタンスだったかな?)
>>206 シングルトンに改造してやってくださひ・・・
208 :
仕様書無しさん :02/03/01 01:42
ここでよいのかどうかわからないのですが、出来ればご教授下さい。 現在TCPのパケットダンプツールを作成しています。 そこで拾ってきた数値・・例えば 45 00 00 28 64 f8 40 00 3d 06 a5 04 d3 13 a0 10 E..(d.@.=....... c0 a8 00 07 00 6e 11 09 d6 を整形(人が識別出来る形)して表示する為にはどのようにすればよいのでし ょうか・・・ このスレにお分かりになる方はいらっしゃいますでしょうか・・・ 情報のポインタだけでもお教え頂くだけでもかまいません。 あわれな漏れにご教授下さい。 C++BuilderVer5.0UP1 Win2000です。
人が識別できる=16進表示ってこと?
210 :
仕様書無しさん :02/03/01 02:02
>>209 さん
例えば「プログラマ」とか「プログラム」とかの文字への変換です・・・
日本語下手ですいません。。。。。
>>208 sprintf(結果を入れる変数, "%s", バッファ);
じゃ駄目なのか?
あらゆるプロトコルのテンプレートを与えといて、類推するのでわ? 80番なら、httpのルーチンにでもまわせばいいし。 ftpのまわりは面倒だけど、できないこともなかろう。
213 :
仕様書無しさん :02/03/01 02:09
すいません。もっと簡単に言います。 VIGILのようなLAN上に流れているTCPを取得して、その情報を分かりや すく表示するソフトを作成しています。 ※VIGILとはまた別方向ですが・・・ その為、208で記載したような情報を取得したのですが、Winsock2.0で 取得したのですが漏れにはTCPDUMPを文字数値に変換出来ない (わからない)のです。 あうーーー。どうすれば・・・
バイナリエディタみたいな表示にしたいんじゃない? 左にダンプリスト、右にその ASCII 表示てな。
IPヘッダの構造解釈 TCPヘッダの構造解釈 とかってところから始めないとだめでそ
216 :
仕様書無しさん :02/03/01 02:12
>>212 SMTPとPOP3のみのデータのみを取得し、表示したいのれす・・・
上記は208を解析出来れば実現出来ると考えたのれす・・・
ごみん、IPは関係なかった
結論 RFC を見れ!
結論 ネットワークプログラミング相談室へどうぞ!
220 :
仕様書無しさん :02/03/01 02:16
>>217 さんへ
いえいえ。ありがとうございます。
Source AddressとDestination AddressさらにSource PortとDestination Port
等は取得できているのれす・・・
ただ解析がどうしても・・・・出来ないのれす・・・知恵を貸してくらさい・・
それはRFC読んでアプリケーション層での やりとりされるデータを知らないと。 やっぱりネットワークプログラミング相談室かなw。
222 :
仕様書無しさん :02/03/01 02:23
>>221 ありがとうございます。その「ネットワークプログラミング相談室」とは
どこにあるのでしょうか・・・
お教え頂けないでしょうか?
223 :
仕様書無しさん :02/03/01 02:24
ってこれってdatオチしてませんか?
225 :
仕様書無しさん :02/03/01 02:27
あううーーーありがとうございます。即ここで聞いてみます。 ありがと。ありがと。
v(^・^)v
228 :
デフォルトの名無しさん :02/03/01 03:09
>>226 いえいえ。一瞬でもお考え頂いたのです。ありがとうございます。
すいませんでした。
229 :
デフォルトの名無しさん :02/03/02 15:44
namespace 関係で質問です。 windows.h をインクルードしたいのですが、BYTE という名前が 別に(ちゃんとした名前空間の中に)宣言されているので あいまいなシンボルです と言われてしまいます。global namespace を荒らすヘッダをうまく インクルードするコツみたいな物はあるのでしょうか? よろしくおながいします。
>>229 試さないで言ってるけど
namespace win32 {
#include <windows.h>
}
とかダメ?
ってゆーか
> 別に(ちゃんとした名前空間の中に)宣言されているので
それなら、そっちのBYTEとグローバルのBYTEはあいまいにならない気がするんだけど…。
ソースの先頭どころか、ヘッダの中に using namespace std; を入れちゃう人だったりして。
そんなやつ銃殺
>>229 typedef char BYTE;
namespace A{ typedef char BYTE; }
この2つは
::BYTE
::A::BYTE
で区別できると思うけど?
ん、まず勘違いしてたです。
小さなクラスだったので、.h と .cpp に分けてなかったファイルに BYTE が
宣言されてました。
>>230 それは試してみましたが駄目です。
>>231 今回はそうなってました^^;
>>232 殺されてしまうのですか?
>>233 namespace A に属する方を全部 A::BYTE と書かないといけないんですよねぇ…?
(windows.h とそれに引っ付いてくる山ほどのヘッダの中の BYTE を全部 ::BYTE に書き換えないかぎりは)
私なんか勘違いしてます?こういうもの?
using namespace xxx; はやめるべき。 せいぜい、 namespace hoge { class hage {}; } using hoge::hage; 程度にしておく。
>>235-236 クラスなら型名がそんなに頻出しないのでいいのですが、
BYTE とか(Javaでいうプリミティブ型、.NET でいう値型)に対応する物なので
あちこちに出現しまくりです。
C 言語用のヘッダを C++ で使うことにやっぱり無理があるんですね…。
C99 は名前空間サポートするんでしたっけ?
早く世の中のすべての言語に名前空間がサポートされる日がこないかな…。
238 :
デフォルトの名無しさん :02/03/03 06:50
class A{ public: int const a[2]; }; としたときのa[2]の初期化ってどうやるのでしょう?
コンストラクタの初期化リストで
すまん意味不明だった 初期化リストで。
>>237 #define BYTE XXX::BYTE
で逃げるという手も無くはない
242 :
デフォルトの名無しさん :02/03/03 17:02
クラスのメンバ関数のアドレスを別の関数に渡したいのですが どうしたらいいでしょうか? どうもコンパイルできない。
そんなことできたっけ?
できるよ。C++第三版だと15.5メンバポインタ に出てる。
別の関数って まったく関係ない別のクラスでもいいの?
VC++ではできませんか? C++のバージョンできまるんですかね。 クラスの外の別の関数に渡したいのです。
double f(double (*g)(double)) のような関数があったとき、メンバ関数を引数にして呼び出したいのですが・・・ コンパイルできませんでした。 できないということは別の抜け道があるのでしょうか?
メンバ関数ポインタは、関数ポインタの型の要素として所属クラスも含まれるので 仮引数もそれを受け入れられる型になっていれば受け取れる。 staticメンバじゃないなら、それを呼ぶときは->*演算子でその所属クラスのオブジェクトを隠れ引数thisに渡す必要がある。 つーか、本嫁
>>247 とりあえず今どう書いて動かないのかをここに書け。
>>247 出来ませんな。メンバ関数は呼び出すためには、関数のアドレスの他にインスタンスのアドレスも必要と理解すれ。
class MyClass { public: double func1(double); double func2(double); typedef double (MyClass::*MyClassFuncPtr)(double); friend double mona(MyClass *p, MyClassFuncPtr); }; double MyClass::func1(double d) { return d - 1.0; } double MyClass::func2(double d) { return d + 1.0; } double mona(MyClass *p, MyClass::MyClassFuncPtr funcp) { return (p->*funcp)(1.0); } int main() { MyClass obj; MyClass::MyClassFuncPtr p = obj.func1; double d1 = mona(&obj, obj.func1); double d2 = mona(&obj, obj.func2); return 0; } こんなんだろ? さあ、次々
レスありがとうございます。 248-251をもう一度よくよんで考えてみます
>>246 「C++第三版」っつのは C++ のバージョンのことじゃないぞ…
254 :
デフォルトの名無しさん :02/03/05 11:21
純粋仮想関数にするメンバが特にないけど抽象クラスにしたい場合って どうすればいいんでしょう? 皆さんはどうしてますか?
デストラクタを仮想に
>デストラクタを仮想に それだけじゃだめだろ。純粋仮想にした上でデフォルト実装を提供しなきゃ。
機能を継承してはいけない、というのが最近の定説です。 インタフェースを継承して、インタフェースとその実装は分離しなさい。
基本的には同意だが、それだけではすまない場合もある。 256 もその一つ。
あ、ごめん、ようやく意図がわかった。 メンバに void force_pure() = 0; をおまけで一個だけ付けときゃーいいんでないの? 継承する側に void force_pure() {} を付けとくひつようあるけど。 class Interface { };
下のは気にせんといてーな。
>>254 コンストラクタを protected に。
>>257 何だと!同じコードを何度も書けというのか。
継承はやめて移譲にしときなさい。 class 262が使い回すと便利だと思っている機能クラス { public: 262が使い回すと便利だと思っている機能(); }; class 262のバカクラス1 { private: 262が使い回すと便利だと思っている機能クラス foo; }; class 262のバカクラス2 { private: 262が使い回すと便利だと思っている機能クラス foo; };
264 :
デフォルトの名無しさん :02/03/06 12:23
C/C++ の経験浅いんですけど #define UNTIL(x) while(!x) ってやっちゃ駄目ですか?やっぱりご法度? 理由も沿えてお願いします。
とりあえず #define UNTIL(x) while(!(x)) ってツッコミは却下?却下?
>>265 > > C/C++ の経験浅いんですけど
って言ってあるじゃん(汗)。言いたいことは伝わったでしょ?
ご法度かどうかは知らんけど #defineを Cでインライン関数書くとか 定数宣言以外の目的に使うヤツって嫌い。
>>264 わかりにくいソースになるからダメ。
趣味で個人的に作ってるヤツとかだったら別にかまわんけど。
例えば
#define loop for(;;)
void func(){
loop{
…
}
}
とかやられて読みやすいですか?
>>268 それはわかるんですけどねぇ。
while があってなぜ until がないのか、カーニハンとリッチーを小一時間問い詰めたいです。
さらに付け足すチャンスのあったストラウストラップとか Sun の人(誰だっけ?)
とかヘジルスバーグとかも小一時間問い詰めたいです。
でも Perl はやりすぎだよねと思う今日この頃です。
untilってあるのはどの言語だっけ?
271 :
デフォルトの名無しさん :02/03/06 15:50
みんなは釈由美子が嫌いだというのですが、ぼくは釈由美子が 好きなので、釈由美子を共用PCの壁紙にしてよいですか? 理由も沿えてお願いします。
よい。大いにやれ
273 :
デフォルトの名無しさん :02/03/06 17:06
BCCでWin32APIを使って簡単なGUIアプリを作りたいのですが (ウインドウが開くだけでもいいから) 参考になるサイトなどありましたら、教えていただけないでしょうか?
275 :
デフォルトの名無しさん :02/03/06 17:32
>>274 ありがと。ページの存在は知ってたけどVC++を使ってるみたいだったから
詳しくは見てなかった…
やってみます。
>>271 釈由美子がなんなのかわからんが、
あんまりオタな壁紙は張るなよ。
新入社員が引くからな
277 :
デフォルトの名無しさん :02/03/06 20:59
STLのstringに対してsprintfみたいなことをしたいのですがこの場合 普通はどうするのでしょうか?ポインタだけでも教えていただけるとうれしいです。 あと余談ですがstring::sprintfみたいなメンバー関数(クラスメソッド?)が存在しないのは何故なんでしょうか? よろしくお願いします。
>>276 釈由美子ってグラビアアイドル(?)だったような…
オタな壁紙しか張らない人にはわからないかもしれませんが。
アイドルオタだろ
やめとけ、グラビア壁紙にして女性社員に影でボロクソに言われてる人 知ってるから。
>>277 stringstream を使うか、適当な char[] に sprintf した上で string::assign() で書き
込む。
sprintf が存在しないのは、型安全性を重視してのことと思われ。
std::string ssprintf(const char*, ...) を自作するとか
283 :
デフォルトの名無しさん :02/03/07 16:18
swich 内の各 case ラベルの後で変数宣言するとエラーになる(VC++)ので ラベルから break までを {} で囲ったのですが、このコードは移植性に 問題はないでしょうか?
>>283 問題ない。
ちなみにどんなエラーがでるんだ?
>>285 後ろにさらにcaseラベルがあるときに、constructできないから
問題あるって話やないかね。
>>284-285 大丈夫なんですね、ありがとうございます。
>>286 多分そうです。
srcfile.cpp(次のラベル行) : error C2360: '変数名' の初期化が 'case' ラベルによって行われませんでした。
srcfile.cpp(変数宣言行) : '変数名' の宣言を確認してください。
というヤツです。
288 :
デフォルトの名無しさん :02/03/07 17:14
UNIXで使える無料のC++のlintないでしょうか? g++ -Wall -W... より五月蝿い事言ってくれるのをキボンヌです。
289 :
デフォルトの名無しさん :02/03/07 19:02
stringクラスのメソッドにremove()が無いんですがどうしてですか? Visual C++ 5.0 です。
>>290 std::vectorとかの実装に使われてます。mallocとかで確保しただけの未初期化メモリエリアにコピーコンストラクタでオブジェクトを構築するために使うんだと思います、たぶん。
>>289 removeってeraseのこと?
>>291 本当だ、ありました。本にはremove()と書いてあったので・・・。ありがとうございました。
293 :
デフォルトの名無しさん :02/03/07 22:32
int array[2000] // arrayに値を入れる deque<int> a_deque; ここで、a_dequeにarrayの中身を移したいのですが、 for文を使わずに済む方法ってありますか?
deque<int> a_deque(&array[0], &array[2000]);
295 :
デフォルトの名無しさん :02/03/07 22:49
>>293 std::copy(array, array + 2000, std::back_inserter(a_deque));
とか?
>>295 なぜにback_inserter???
deque.assign 使えばええのんちゃうかい
298 :
デフォルトの名無しさん :02/03/07 23:12
>>295 なるほど。copyとback_inserterですか。
ありがとう!
>>294 コンパイルできませんでした。(VC6)
ありがとう!
299 :
デフォルトの名無しさん :02/03/07 23:20
>269 駄目? >297 そうですね。
300 :
デフォルトの名無しさん :02/03/08 04:07
(ΦωΦ)フフフ・・・
301 :
デフォルトの名無しさん :02/03/08 12:19
>> 277 >STLのstringに対してsprintfみたいなことをしたいのですが こんなのどう #include <string> #include <vector> #include <cstdarg> using namespace std; int strprintf(string& s,const char *format,...) { va_list va; va_start(va,format); vector<char> buf; int k, n = 63; while (true) { buf.resize(n+1); k = _vsnprintf(&buf[0],n,format,va); if (k > 0 && k < n) break; n = n*2 + 1; } va_end(va); s.assign(buf.begin(),buf.end()); return k; }
302 :
デフォルトの名無しさん :02/03/08 13:22
コンストラクタが仮想メンバ関数を呼び出したら(コンストラクタによるテンプレートメソッドとでも言うのでしょうか)どうなりますか? vtable がいつ初期化されるのかというのは C++ の規約に決まっているのでしょうか?
決まってない
>>303 ダウト。ANSI C++ の規格書では
12 Special member functions
12.6 Initialization
12.7 Construction and destruction
この項目 3 で明確に規定してある。
>>302 コンストラクタ中で仮想メンバ関数を呼び出した場合には、派生クラスではなく、
そのクラス、もしくは規定クラス中の最も外側で定義された仮想関数が呼ばれ
る。
class Base {
public:
virtual void foo();
Base() { foo(); } // この foo() は常に Base::foo() を呼び出す
};
class Deriv : Base {
public:
virtual void foo();
};
vtable はコンストラクタが実行される直前に初期化されます。
Deriv d;
は仮想的な C++ コードで書くと、次のような処理に展開できる。
d.vptr = Base::vptr; // まずは Base クラスの vtbl が設定される
d.Base(); // Base クラスのコンストラクタが呼ばれる
// vptr == Base::vptr なので foo() は Base::foo() を呼び出す
// ここまでで基底クラスの構築は完了、次に派生クラスの構築を行う
d.vptr = Base::vptr; // Deriv クラスの vtbl が設定される
d.Deriv(); // Deriv クラスのコンストラクタが呼ばれる
// 作成完了
d.foo(); // vptr == Deriv::vptr なので foo() は Deriv::foo() を呼び出す
// 実際には d が Deriv クラスのインスタンスであることをコン
// パイラは分かっているから、vptr を介さずに直接 Deriv::foo()
// を呼び出すコードを作成するけど。
したがって、デザインパターンの Template Method っぽい処理を行いたい場合に
は、コンストラクタは使えません。
>>304 わかりやすい解説ありがとうございます!!
よくわかりました!!
306 :
デフォルトの名無しさん :02/03/08 19:14
boostのregexで、 static const boost::regex reg("^([a-e]){1,5}([^a-e].*)$"); などとした場合に、最初の括弧の部分を1〜5個、全部あとで得ることはできないでしょうか。 boost::regex_match だと、例えば"abc_"を与えると、"c" "_" の2つしか 得られません…。
307 :
デフォルトの名無しさん :02/03/08 20:37
ofstreamとstringを同時に使うにはどうしたらいいんですか?
>>307 #include <string>
#include <fstream>
309 :
デフォルトの名無しさん :02/03/08 20:59
>> 308 それだけだとstringを認識しないんですけれども。
ひょっとして
311 :
デフォルトの名無しさん :02/03/08 21:07
s
312 :
デフォルトの名無しさん :02/03/08 21:09
td::
か?
314 :
デフォルトの名無しさん :02/03/08 21:30
いくら連係プレーしても
>>307 には伝わらないという罠。
315 :
デフォルトの名無しさん :02/03/08 21:35
stdって using namespace stdの事ですか? ってかそれしか知らないのでそれとして受け取ります。 でもusing namespace std使うと今度はofstreamが使えないんですけれども。 そこが一番聞きたい所なのです。
316 :
デフォルトの名無しさん :02/03/08 21:41
>315 ofstreamが使えなくなるってのも不可解だが、それなら using std::string; と書くか、stringを使う時、 その前にいちいちstd:: をつければ (string ではなく std::string と書く) いいとおもうよ。
317 :
デフォルトの名無しさん :02/03/08 21:44
#include <fstream.h> と書いているなら <fstream> にしてみよう >315
318 :
デフォルトの名無しさん :02/03/08 21:57
>>316 とても為になりました。
でもstd::stringってやったら<<が使えなくなりました。
何が違ってるのでしょう?
>>317 <fstream>に変えてみたらofstreamが認識されませんでした。
319 :
デフォルトの名無しさん :02/03/08 21:59
>318 <fstream>ヘッダは、中身が namespace std { #include <fstream.h> } されてるんですよ。 名前空間の勉強をしないとこれ以上は無駄なように思われ…
320 :
デフォルトの名無しさん :02/03/08 22:02
あ、エラー消えました! 助けてくれた方々ありがとうございました。
321 :
デフォルトの名無しさん :02/03/08 22:03
omedetou
322 :
デフォルトの名無しさん :02/03/08 23:47
C言語では、半角スペースとchar c=" "は同義なんでしょうか?
324 :
kenta :02/03/09 00:11
>>322 ダブルクォーテーションで囲んだらヌル文字が付くと思われ。
っつーか、char c は整数なので文字列リテラルは代入できません。
326 :
デフォルトの名無しさん :02/03/09 00:39
char *c=" "
>326 ネタか?
>>306 ^([a-e]{1,5})([^a-e].*)$ 括弧の範囲に注意。
329 :
デフォルトの名無しさん :02/03/09 19:33
仮想関数について質問です、 class A { public: virtual int foo(int a); } class B:public A { public: virtual int foo(int a,int b); }; のように、仮想関数の 引数の違うオーバーライドって、オブジェクト指向設計上問題あるのでしょうか? どうしても、使いたいときがあるので気になっています。 使いたいときがあること自体問題あるのでしょうか?
システム設計上は問題ないだろうけど、記述ミスの可能性をどうコンパイラが解釈するかの、 言語設計上の問題はある。なんつったり
オーバーロードにしかならないような
>>329 それはオーバーライドではなく、単に違う関数(オーバーロード)。
THE PROVING GROUND OD THEMAD OVERLORD
つーか、ベースクラスの関数を隠しちゃうね。
the proving ground of the mad overlord じゃんかよ
the proving ground of the mad overlordパターンですね。
つーか、突っ込み入りすぎ&かぶりすぎ
B内でusing A::foo; すればベースクラスのfoo(int)も見えるようになり、両方が呼べてしまうね。
なるほど、参考になりました。 ちなみに、the proving ground of the mad overlord にはどういう意味があるの? 調べたらウィザードリとしか分からないです。
次はkod'sを調べましょう
341 :
デフォルトの名無しさん :02/03/10 01:33
class A{ public: const int a[10]; A():a(){}; }; の配列メンバイニシャライズが謎です。何故でしょう?
staticにしなさいというお告げです
template様の深みに ズブズブはまっていってしまうんですが、、、
良い事です。テンプレートはC++の真の力です。大いに活用しましょう。
先ずは行き着くとこまで逝っちゃいなさい。 で、Modern C++を読んで、ああ、まだ行き着いてはいなかったんだ。 でも、ここまでやったら馬鹿だな、と反省しなさい。
346 :
デフォルトの名無しさん :02/03/10 14:03
いま、More Effective C++ や Exceptional C++ に 書いてある 「リソースの獲得は初期化」っていうイディオムの実装方法を考えてます。 CFile file;// not MFC 自作クラスのCFileです if(file.Load("test.txt") == false) return ERROR; string str = file.ReadOneLine();// 一行読み込み みんなこんな感じのコードを書いてると思うんですけど。 「リソースの獲得は初期化」を実装すると、こうなるんじゃないかと。 if(CFile::IsExist("test.txt") == false) return ERROR; CFile file("test.txt"); string str = file.ReadOneLine();// 一行読み込み CFileはファイルを処理するクラスなんですから、CFileのインスタンスが 存在するときには、いつでもそのインスタンスでひとつのファイルを 処理できなくちゃいけない、というのがこのイディオムの意味だと 思います。だから、逆に言えばいつでも処理できるという状態を基準にして、 インスタンスを生成しなければならないんじゃないかと。そのために、 1.常に「コンストラクタでリソース確保」&「デストラクタでリソース解放」 2.Open,Load,Read,Createなどの関数での、リソースの途中確保はさせない。 3.Close,Release,Destroyなどの関数での、リソースの途中解放はさせない。 というのが、「リソースの獲得は初期化」ってイディオムを実装したスタイル なんじゃないかと思います。 「リソースの獲得は初期化」って、リソースリークが激減し、かつ効率も 良さそうで素晴らしいイディオムだと思ったんですが、グーグっても一件しか 出てこなったのが不安でなりません。それに、どっかで「コンストラクタで なんでもかんでもやろうとするな」とか書いてあったのを見かけたのが 気になって、これを実践するのを躊躇しています。 どなたか、このイディオムを実践されてる方はおられませんか? 実践されてる方がおられましたら、このイディオムでクラス設計をするときの 注意点などを教えて欲しいです。
その例の場合に限っていうと、 IsExistをやった直後に別プロセスからファイルを削除されちゃったり権限が更新されちゃったりして CFileコンストラクタで失敗しちゃう可能性あるよね。 そういうとき例外を投げればいいとは思うんだが、ファイルのオープンの失敗みたいなありふれたことで いちいち例外をハンドルしなきゃいかんのかと思うと、鬱になるよね。 ファイルI/Oに関して言えば fstreamの実装みたいな柔軟性(コンストラクタでオープン、もしくは別メソッドでオープン)があれば どっちでもいいんじゃねえの?というのが、俺様の感想。 それ以外のクラスは、やはりそれに応じてコンストラクタでやるか、別メソッドでやるか、 どっちでもできるようにするか、考えなきゃ移管よね。
例外でもいいけど、それをするなら わざわざExistで判別する意味ないよね、といってみるテスト。
クラスのあずかり知らぬところで状態が変化するようなオブジェクト(たとえばファイル)をクラスで管理する場合、 実行と、実行の前提条件のテストを別処理にするのは、うまいやり方ではない、といってみるテスト。
逆にすべてがそのクラスに責任があるオブジェクトは、 処理を分けようが一つにしようが勝手にしろといってみるテスト。
>>349 もちろんそうだね。それは削除して、例外でやってもいいと思うってこと。
同じ条件なのにタイミングによってエラーの処理が違うのはアホ(笑)
353 :
デフォルトの名無しさん :02/03/10 14:54
C++ で 自分の別のコンストラクタを処理したい場合は どうしたらいいのでしょうか?
逝ってることがよく若ランけど class A : public B { A(); } A::A() : B() { } みたいなことを逝っているのか?
ひとつのクラスにコンストラクタを複数持たせて 使い分けたいって言うならoverload使う
>>347-352 いちおう、この例の場合、CFileのコンストラクタで例外を投げることを
想定しています。CFileは、CGraphicやCTextのメンバ変数として使われることが
多いでしょうから、戻り値でエラーを返すよりも、例外を返した方が取り扱い
しやすいんじゃないかと思います。それで、戻り値でエラーが欲しい場合は、
その前にIsExistで確認すればいいんじゃないか、という意味でチェックを
入れてます。
>>352 ぎゃふ。アホですか。すんません。例外を投げる以上、もうエラーチェック
しない方がいいですか。ていうか、いわれてみれば確かにそのとおりですね。
まだ例外の扱いになれてない…っていうか、使ったことない厨なので。(^^;
>>350 >クラスのあずかり知らぬところで状態が変化する
この一言、心に留めておきます。
とりあえず、例外を勉強してきます。
気になったので、ついでに。
class A{
A(int);
A(int,int);
int a_,b_;
};
A::A(int a,int b) :
a_(a),
b_(b)
{
}
A::A(int a)
{
this->A(a,a*2)
}
>>353 は、こんな感じで、コンストラクタのひとつから別のコンストラクタを
呼び出すことで処理させたいけど…って話のような気がします。
解決策は…覚えてないけど。(^^;
あ、かなり言葉足らずでしたね。 class A{ public: A(int); A(int, int); } A:A(int a1) { A:A(a1,100)したい; } A:A(int a1, int a2) { 処理; } したいんです。
>>359 C++ のコンストラクタは、メソッドとは扱いが根本的に異なるので、無理。
private な共通初期化メソッドを用意して、コンストラクタから呼び出すのが
一般的。
class A{ public: A(int, int=100); } じゃダメなのか?
たぶんそれで解決(藁
placement newを使って出来ないことはないが ややこしいエラーを招くので使うべきではない。 ・・・というのをExceptional C++あたりで読んだ気がする。
なるほど…引数を元に変更する必要があったので、プライベートなメンバ関数にしました。 ありがとうございました。
365 :
デフォルトの名無しさん :02/03/10 19:04
質問です。 std::string って使ってる? その場合日本語の扱いってどうしてるの? wstringでunicodeで作るのが良いのかと思ったんですけど でもstring<->wstring変換の関数って無いですよね?
mbstowcs
367 :
デフォルトの名無しさん :02/03/10 19:47
text file からfinとか使って情報を読み取りたいんですが、 どうやってeofって認識させられるんですか? text file に書き込んでる時に行の一番最後に<<endl;って入れてるんですが そんなのお構い無しにどんどん空白を読み込んで行ってしまうのですが? って俺の言ってる意味分かりますかね?
>>365 std::basic_string<_TCHAR>を多用している。
VCなら全然問題なし。
汎用キャラクタマッピングには慣れといた方がいいよ。
って、これもVCだけか。
複数の文字コード(例えばSJISとEUCとか)を扱う場合はどうするの?
日本語だけならnkfでSJISに変換するのが何かと便利かも。
>>369 内部で同時に扱うって話だったら、
内部コードはひとつで入出力時にそれぞれ変換する
372 :
デフォルトの名無しさん :02/03/11 03:10
const class CA{ public: void func(void){cout<<"func"<<endl;}; void foo(void){cout<<"foo"<<endl;}; }; classの頭についているこのconstは一体何の意味が・・・? エラーも警告も出ないと言う事は、ちゃんとした文法ですか? VC使ってます。
unixのtypescriptと同じログを記録するコマンドって windowsのコマンドプロンプトにはないんですか?
375 :
デフォルトの名無しさん :02/03/11 13:37
>>374 VC++で書け
、、、としかこのスレでは言えねえわな(わら
376 :
デフォルトの名無しさん :02/03/11 18:53
質問です。↓って OK なんでしたっけ?ちゃんとスタックからスタックへコピーして返してくれてるのでしょうか? そして移植性にも問題ないんでしょうか?(VC6とBC5ではちゃんとコンパイルできました) #include <stdio.h> struct A { int elem1; int elem2; int elem3; }; A func() { A a; a.elem1 = 0; a.elem2 = 1; a.elem3 = 2; return a; } void main(void) { A a; a = func(); printf("%d %d %d", a.elem1, a.elem2, a.elem3); }
ok
>>376 問題ないけど、できるなら、
A a = func();
ってやったほうが、効率がよい。元のやつだとコンストラクタが3回、
コピー代入が1回呼ばれるけど、上のやり方ならコンストラクタが
2回呼ばれるだけ。
>>377 , 378
ありがとうございます。特に問題はないんですね。
> 元のやつだとコンストラクタが3回、コピー代入が1回呼ばれるけど、
> 上のやり方ならコンストラクタが2回呼ばれるだけ。
あー struct にもコンストラクタってあるんですか…。
C → Java → (今)C++ やってる(Cやってた頃はあんまり気にしなかった)ので。
ところで A a = func(); ではコピー代入(ってコピーコンストラクタの呼び出しみたいなものですよね?)が起こらないんですか?
メンバーをコピーしてくれるコンストラクタが自動生成されるのでしょうか?
あと、こういう関数を見ないのは引数で参照渡しの方が効率がいいからですよね?
>>379 Effective C++ あたりをいっぺん読んでみるといいかもよ。
>>379 > あー struct にもコンストラクタってあるんですか…。
いちど synthesize constructor, trivial constructor で検索して、違いを良く
理解しとくと良い。書籍なら Inside the C++ Object Model が詳しく解説して
る。
>>379 「メンバーをコピーしてくれるコンストラクタ」ってのがコピーコンストラクタ。
定義されていない場合は、コンパイラが勝手に生成してくれる。
A a = func();
って書くと、ふつうは、
A a( func() );
と同じように扱われるはず。で、func() の末尾の
return a;
のところで、コピーコンストラクタが呼ばれる。ついでに書くと、
struct A にもコンストラクタを定義してやって、
return A(0, 1, 2);
としてやると、コンストラクタの呼び出しは1回で済んじゃう。
このあたりの詳しいことは、
>>381 の本に詳しいんだけど、訳本はトッパン
だったから、今は絶版?
383 :
デフォルトの名無しさん :02/03/11 20:42
structとclassの違いって、 デフォルトのアクセス属性の違い以外は まったく同じですよね?
>>385 ウィザードリィというコンピュータ RPG のルーツとなるゲームがあるんだが、
その第一作目のタイトル。邦訳は「狂王の試練場」だったかな。
基底クラスの関数を隠してしまうという「トチ狂ったオーバーロード」(使うな
よ、そんなもん)と「mad overload」をかけたんでしょ。
>>386 その洒落の初出はどこですか?
良い情報源になりそうな気がする。
389 :
デフォルトの名無しさん :02/03/12 00:30
C++ でクラスの継承を禁止するにはどうしたらいいでしょうか?
そういうコーディング規約をつくる
馬鹿なコーディング規約スレに行け。
とりあえず、コンストラクタをprivateにすれば?
>>392 コンストラクタを private にしたら、static 関数で生成する以外に方法が浮かばないんですが、そうするしかないですか?
今、ただのフラグ群なんだけど、いちいち取り出すのが面倒くさいので
ビットごとに取り出すインラインメンバ関数を持ったクラスを作ろうと
思ってるのですが、継承される可能性があると、仮想デストラクタを作らなければいけないので、仮想関数テーブルを持ちますよね?
そうするとサイズも大きくなるし、重くなるし困ります。
常にスタックに積むような使い方をしたくて、最適化コンパイルされた時に
ただの unsigned int になるようにしたいのです。
どうしたらいいでしょうか?
俺なら // 継承したら殺す class A { };
というか デストラクタがvirtualでないのは継承することを考えていないのだと、 周知徹底しとくだけでよいのでは?
396 :
デフォルトの名無しさん :02/03/12 01:16
派生のオブジェクトを基底のオブジェクト スライシングして問題を起こしてみるレス。
アフォがアフォなコードを書くことを禁止するような言語は作れません。
1. 何となく便利そうだからと継承はしない。 2. 継承する必要性が生じるまでは継承しない。 3. そもそも継承が必要な場合以外に継承はしない。 これらを守れば デストラクタを virtualにしなきゃいかんかどうかで悩む必要はなくなる。 性能を重視してるなら、「継承はしない」という前提で作ってよし。 デストラクタがvirtualでなければ一目瞭然だが、世の中にはバカもたくさんいるので コメントとドキュメントを書いておけ。
399 :
デフォルトの名無しさん :02/03/12 01:49
g++で、-fno-exceptionsでコンパイルされたライブラリを使う時、自分の書く コードで例外投げても平気ですか?
400げっとー・・・
ってああ!!!!
すっかり忘れてた!!
今日こそはGCCをISDN回線で落とそうと思って挑んだのに
スカーリ忘れてたYO!!
ありがとう
>>399 さん
g++って書いてくれなかったらわからなかったス
色々面倒くさくなったので
>>394 さんの案でいく事にします。
もともとこういう趣旨のクラスって邪道だし、スマートに禁止できないなら
しょうがないですね。
みなさんありがとうございました。
ていうか、C++の言語として、継承禁止を明示できるような キーワードがあれば便利なのにね。 unsucceed class A { }; ってな感じで。造語をキーワードにしちゃまずいかも知れんが。
他言語のちょっと便利な機能を 何でもかんでも取り入れる必要はないでしょ。
404 :
デフォルトの名無しさん :02/03/12 10:54
継承禁止を明示することがどれだけ便利な機能なのか俺には想像がつかない。 現場に必要なのは安全カミソリじゃない。 よく切れて、いつでも研げるカミソリなんだ。
自分の手首を切りつけるのも カンタン♪
>>404 「効率をまったく犠牲にすること無く、コンパイラに禁止事項を伝える」
って意味で、constと同じレベルの価値があると思うんだけどなぁ。
安全カミソリが嫌いなあなたは、constで安全性を確保したりは
されないんですか?
>>406 窓の場合で言うと、Java にある last のような機能がなくても、
もしそのクラスが DLL からエクスポートされるものなら、
protected メンバやコンストラクタをエクスポートしないでおくことによって、
事実上、派生クラスが作れなくなる。
(インスタンスは専用のグローバル関数で作る)
漏れはこの方法で「設計上の安全性」とでもいうかな、一応、間に合っている。
>>406 constはもちろん使うよ。
安全性確保と最適化のためにね。
だが、Javaでいうところのfinalなんてもんが言語仕様的に
必要とは思えないんだ。
constとfinalではキーワードとしての重みが違う。
constは必要だが、finalはなくても良いし、なくても困らない。
くだらない言語仕様を追加されてもなあ..と思っただけよ。
いろいろ考えてみたが、設計無しでいきなりコードを書き始めて、 昔使ったXXとYYを合成したらどっちも使えて便利だなあ、などの 思いつき中心で事を進めるアホPGでもなければ、そんなキーワード いらんよな。 バカよけは全くの不要だとは思わないが、そういうレベルのPGは もっとくだらないレベルで、もっとくだらない間違いを犯すだろう。 GCが欲しいだのポインタがわからないだのいう連中は、 そういうものから解放された、別の言語を選べばよいのだと思う。
interfaceとimplementationのclassを分離して、 pure virtual base classしか見せなければ、ほぼ自動的に finalみたくなるとおもうがどうか。
>>409 そのアホPGを見分ける洞察力と、事前にプロジェクトから外す政治力があるなら
要らないな。
412 :
デフォルトの名無しさん :02/03/12 16:59
inline キーワードが任意な事はわかっているのですが、 「ここに inline つけても絶対インライン展開されない気がする〜」という状況なので、リンカの働き、オブジェクトファイルの内容等について詳しい方にお聞きしたいのですが、 .h ファイルに宣言だけされていて、 .cpp ファイルに実装が書いてあって 全ての .obj を最後に一括リンクするような事をした場合、 どうやっても .cpp 内の関数はインライン展開されないですよね? それとも .obj 内の情報からインライン展開してくれるものなのでしょうか?
>>412 リンクという動作が実際にはどんなことをするのか、ちゃんと理解した方がよいと思う
ふふふふふ、VC.NETのリンカは コンパイル単位越えてインライン展開してくれるよ〜ん と人心を惑わせる情報を出してみるテスト
416 :
デフォルトの名無しさん :02/03/12 21:45
時間のかかる処理(検索など)でループを回している最中に キャンセルボタンが押された 処理が一定の量に(検索結果が一定数に)達した 等で中断したい時、 例外を投げてループを抜けるのは邪道ですか? 例外を使わないなら、ループの最中に毎回フラグを見ることになるし 中断か全終了かの判断も返り値で見る事になって面倒くさいんですが。 (ボタンが押されたかどうかは、結局フラグを見なければいけないけど)
>>415 どれくらいのものか知りたいんだけど・・・発売まで待ちかな
419 :
デフォルトの名無しさん :02/03/12 23:06
412と同様にtemplate関数も.hに宣言のみ、.cppに実装のやり方では リンカエラーが出ますが、これも回避する方法はありませんよね? 413が気になるのですが・・・ リンカの動作についての詳細な説明は、どこを見ればいいでしょうか? 後、STLのクラス群は継承されることを想定しているのでしょうか?
なんで継承するの?
>>418 inline関数(実体があるもの)は展開できる
templateは実体が無いから展開できない
>>419 継承の目的による。
- unary_function のような関連型定義のクラスは、継承すること前提。
- basic_string や vector などのコンテナクラスは、デストラクタが virtual でない
時点で何かを感じてくれ。
ありがとうございます。
>>420 ,422
はい、所有することにします。
コンテナに独自のメソッドを追加するために継承しようとしてました。
デストラクタの定義を見ようとしたんですが、
どこを見ればいいのか分からなかったんです。すいません。
424 :
デフォルトの名無しさん :02/03/13 05:26
int *p = new int(0),*p2 = new int(1); を開放するとき delete p,p2; ではだめですか? deleteにコンマを付けるとコンマ演算子として働くのですか? それとも変数宣言のコンマのようにただ区切るだけでこれは大丈夫ですか?
425 :
デフォルトの名無しさん :02/03/13 05:29
だめ。
それじゃ書式的にnew と対になってないでしょ
>>424 君の new に対応する書き方はこうだ。
delete p, delete p2;
単なるカンマ演算子。
>>425 さん、ありがとうございます。
コンマ演算子だからp2しか開放してませんね。
逝って来ます(TT)
いやdeleteは演算子だから delete p,p2; はpだけ開放か・・・鬱だ死のう
p2だけ解放だろ
>>426-429 どっちだっていいだろ。そんなこと覚えてたってしょうがない。
どうせそんなアフォな記述はしないんだから。
>>430 delete p, p = 0;
とか書いたりするよ…
#include <stdio.h> int main() { int i=4; printf("result%d\n", (i, i=0) ); return 0; } --- result:0
>>431 悪いことは言わん、auto_ptr の reset() メソッドを使え。
434 :
デフォルトの名無しさん :02/03/13 15:31
past-the-end値ってなんなんですか?よく聞くけど
>>434 配列のような順序付けられたデータ構造で、要素数 + 1 (最後の有効な要素の次)
を指す値。
たとえば int n[10] なら &n[10] が past-the-end 値だし vector<int> v(10) なら
v.end() が past-the-end 値。
436 :
デフォルトの名無しさん :02/03/13 19:47
437 :
デフォルトの名無しさん :02/03/13 20:05
>>436 is.clear() の呼び忘れでした。
(・∀・)ノ ハーイ
>>435 先生わかりました。
439 :
デフォルトの名無しさん :02/03/14 11:57
うまく説明できないので, 簡略化したソースをのせます. class A { class B { int *ptr; public: B(int *p) : ptr(p) {} int& bar() { return ptr[1]; } int bar() const { return ptr[1]; } } ; int x[3]; public: A() { x[0] = 7; x[1] = 8; x[2] = 9; } B foo() { return B(x); } B foo() const { return B(x); } } ; void hoge(const int v) { printf("%d\n", v); } void fuga(const A& a) { hoge(a.foo().bar()); } int main() { A a; fuga(a); return 0; } このソースを g++ 2.95.2 でコンパイルすると >test2.cc:15: passing `const int *' as argument 1 of `A::B::B(int *)' >discards qualifiers とエラーが出ます. この場合どういう風にコードを書きなおすのが, いいのでしょうか ? ちなみに, class B のコンストラクタ, メンバ ptr の const 版を追加したバージョンも試したのですが, bar() だけ const じゃない ものが呼び出されてしうので, うまくいきませんでした. そういうものなのでしょうか ?
>>439 return ptr[1];
という無茶苦茶なアクセスが本当に意図したものであるのなら、
クラス設計が根本的におかしい。「コードを書き直す」でどうにかなる
レベルじゃない。設計から見直すべし。
class A { class B { const int *ptr; public: B(int *p) : ptr(p) {} B(const int *p) : ptr(p) {} int& bar() { return const_cast<int*>(ptr)[1]; } int bar() const { return ptr[1]; } } ; : :
class A:Bの意味というか、位置づけがよくわからん。 要するにconstをよく分かってないタコが書いたクラスに constなオブジェクトを見せようとしコンパイラにはじかれたってだけだろ。 class A { class B { int x_[3]; public: B(const int *p) { std::copy(p, p+3, x_); } int GetSecond() const { return x_[1]; } } b_; static int initial_b_[]; public: A() : b_(initial_b_) {}; friend fuga(const A & a) { return a.b_.GetSecond(); } }; int A::initial_b[] = { 7, 8, 9 }; int main() { A a; fuga(a); return 0; }; アホ草
アドバイスありがとうございました. コンパイルエラーは 441 の方法で解決できることを確認しました.
444 :
デフォルトの名無しさん :02/03/14 15:43
デストラクタで例外投げるのは違法ですか?
>>444 違法だよ。つーか、それを聞くってことは、More Effective C++ か
Exceptional C++ あたりを読んだんじゃないの?
デストラクタは、だまってthrow()指定。
いや、投げると黙ってabortするので…。 2冊とも手元にあるので読みます。ありがとう。
デストラクタが例外なげると、下手すると多重例外になるやん。 どないするっちゅうねん。 func(){ ThrowOnDestructObj obj; throw "some exception" }
>>447 ~Foo::Foo(){
if(!std::uncaught_exception()) {
throw .....;
}
}
とか?いやまぁ、throw()指定にしときますけど。
449 :
デフォルトの名無しさん :02/03/14 21:45
Oracle Objects for OLE C++ Class Libraryの日本語ヘルプって無いんすか?
450 :
デフォルトの名無しさん :02/03/14 22:01
>>448 どうでもいいけどFoo::~Fooな。
451 :
デフォルトの名無しさん :02/03/15 14:19
いつもお世話になっております(藁)質問です。 singleton を作ろうと思っています。 GoF には Singleton::Instance() で 静的メンバが NULL かどうかチェックする と書いてあるのですが、実装ファイル内の静的メンバ初期化で new Singleton() するのは、別の Singleton との初期化の順序を指定できない以外に問題は ないですか? あと、 Singleton の初期化中に、その Singleton を必要とするオブジェクトを作成する必要があるので Singleton のコンストラクタの一番初めに インスタンスを格納する静的メンバ変数を this にする事は問題ないでしょうか? よろしくお願いいたします。
>Singleton の初期化中に、その Singleton を必要とするオブジェクトを作成する必要があるので 逆じゃないか? ふつうはsingletonを必要とするクラスが必要になった時点でsingletonを作成する。
453 :
きしべしろーと :02/03/15 14:50
>デストラクタが例外なげる 自己破産したやつが再度、自己破産しようとしているようなもんやね
>>452 いえ、逆じゃないんです。
あるクラスのコンストラクタで、対象 singleton にそのインスタンスを登録
するのですが、singleton の初期化中に、番兵要素として、その管理されるクラスのインスタンスを生成しているのです。
つまり
1.管理されるクラスのインスタンスをはじめに作成しようとする。
2.管理されるクラスのコンストラクタが Singleton::Instance() を呼び出す
3.Singleton コンストラクタが 管理されるクラスのインスタンスを(番兵要素として)生成する
4.番兵要素インスタンスが Singleton::Instance() を呼び出す
という流れで、4の時に Singleton::Instance() が Singleton::Singleton を
呼び出すと
「時の流れに身をまかせぇ〜♪」という感じでスタックオーバーフローか、
new が失敗するまで無限地獄…じゃなくて無限ループです。
そこで Singleton::Singleton() のはじめの仕事として静的メンバ変数 instance に this を代入すると、
(とりあえず) うまくいっているように見えるのですが…。
すごく心配です。
>4.番兵要素インスタンスが Singleton::Instance() を呼び出す
クラスのデザインとして、ここが一番問題アリっぽいね。
『Null Objectパターン』つって、「オブジェクトが存在して、
普通に振る舞っているように見せかけつつ、実は何もしてない」
というクラス設計手法があるんよ。
http://www.hyuki.com/dp/dpinfo.html#NullObject Null Objectを、番兵要素インスタンスとして生成すれば
いいんじゃないかな?
ごめん、ちょっと言葉足らずだった。 Null Objectを番兵要素インスタンスとして生成することで、 番兵がSingleton::Instance() を呼び出すことがないようにすれば いいんじゃないかってこと。
ストラウストラップ先生が書いたプログラミング言語C++第3版 デカくて1000ページもあってビビタヨ!
(;´Д`)ハァハァ、例外、すごくいいよ…… こんなにスリムなコードになるなんて…… (;´Д`)ハァハァ ……うっ。
出すもん出したら例外安全が保証されてるかどうか調べ直しとけよ。
460 :
デフォルトの名無しさん :02/03/15 19:57
例外中立モナー
>>460 例外安全は守るべき項目として納得できるけど、例外中立って守る価値あるの?
全部の例外を呼び出し側に伝えるのって、そんなに大事?
例外中立について詳しい解説キボン。
ヽ(。´Д⊂)゜。ウワァァァン!!! 『例外中立』ってGoogleでも3件しか出てこないよ〜。
例外安全と例外中立を理解するまで、 実は怖くて例外使えませんでスタ。 こういうひと、他にいる?
受け取った例外を正しく処理できないオブジェクトは、 その例外を正しく、呼び出し側に伝える必要がある。 ってだけだけど。 かってに途中のクラスで例外が消えたり 例外の種類が変わったりしたら、困ると思うんだがなあ。 管理しきれんよ。
464 :
デフォルトの名有さん :02/03/15 20:54
VC++.NET(単体)ってインストーラー作成ツールついてる?
>>455 やはりそうですかぁ。絶対に登録されていないオブジェクトを作りたくないので
番兵も対象クラスを継承したクラスにしたのですが、Java のインターフェイス
みたいなベースクラスを作るしかないですかねぇ…。
あぁ、C++ 難しいです。いま operator= まわりで悩んでいます。
サブクラスで operator= をオーバーライドする時の戻り値は
ベースクラスの型で問題ないのでしょうか?(というかそうしないとコンパイルエラーなのですけど)
あと、ポインタを通してオブジェクトを扱う事が多いのですが、
ちがうサブクラスどうしを代入した場合で左辺値が右辺値を許容できない型だったり
する事を考えると operator= はベースクラスで private 宣言して使わせないようにしてしまおうかと
思うのですが、継承を前提にして、フリーストアにオブジェクトを確保するような
使い方をしていて operator= を適切に使いこなす事なんて本当に可能なのでしょうか?
たぶんお前の継承は間違っている。
>>462 オレもだよ〜。Exceptional C++ と More Effective C++ の例外に関する
項目を熟読して、ようやく例外を扱えそうな気になってきたから、
昨日から例外を使いはじめたよ。
>>463 あ、それが「例外中立」の正しい定義?
すまん、オレ激しく勘違いしてたよ。
Exceptional C++ の28ページには、「すべての例外を呼び出し側に伝える」
って説明してあったから、てっきりcatchした例外はぜんぶ再throwするんかと
思ってた。
Exceptional C++ に書いてあったのは、コンテナテンプレートクラスで、
どの例外もこのテンプレートクラスじゃ正しく処理できないから、「すべての
例外を呼び出し側に伝える」ってことになるわけか。なるほど。
468 :
デフォルトの名無しさん :02/03/15 21:39
>>462 俺そう。
だから敢えて例外には一切触れないコードしか書いてない。
厨房でスマヌ
うん。 exceptional C++の記述はコンテナクラスに特化してるからね。 コンテナが一番難しいからなんだろうけど.。。 職場においといたら、「クイズ形式?」とかいわれて鼻で笑われ申した。 ウワーン馬鹿にしるなー。
10年くらい前のなあ、BBS時代になあ、C++は曖昧な、ツーか、すっきりしない部分がある んだよって書いたんだけど、具体的に何が?って聞かれても、すぐにはでてこなかったんだよね。 あのころの疑問は氷解した。
471 :
デフォルトの名無しさん :02/03/16 00:40
VC++で sizeof(!0.0)==4になります。 また、 void f(int i){} void f(bool b){} で f(!0.0); だとintの方が呼ばれます。 なぜですか?
bool型以外の値に ! 使う奴いるのか...
今だ!3ゲットオォォォォ!!  ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ズザーーーーッ ∩) (´´ (´⌒(´ ∧∧ノ つ ズザーーーーーッ(´⌒(´ ⊂(゚Д゚⊂ ノ ∧∧≡≡)ズザーーッ(´⌒;;;≡≡ ∧∧(゚Д゚⊂⌒`つ∧∧≡(´⌒;;;≡≡≡ ∩) ⊂(゚Д゚⊂⌒`つ≡⊂(゚Д゚⊂⌒∧∧≡≡)(´⌒;;;≡≡ ∧∧ノ つ ズザーーーーッ∧∧(´⌒(´ ⊂(゚Д゚⊂⌒`つ≡(´´ (´⌒(´ ⊂(゚Д゚⊂ ノ ∧∧≡≡)⊂(゚Д゚⊂⌒`つズザーーッ(´⌒;;;≡≡ ∧∧(゚Д゚⊂⌒`つ∧∧≡(´⌒;;;≡≡≡ ⊂(゚Д゚⊂⌒`つ≡⊂(゚Д゚⊂⌒`つ≡(´⌒;;;≡≡≡  ̄(´⌒(⌒;;∩) (´´ ∧∧(´⌒)ズザーーーーッ ∧∧ノ つ ⊂(゚Д゚⊂⌒`つズザーーーーーッ(´⌒(´ ⊂(゚Д゚⊂ ノ ∧∧≡≡)ズザーーッ(´⌒;;;≡≡ ∧∧(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡ ⊂(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡  ̄ ̄ (´⌒(´⌒;;
f(!"今だ474ゲットズザー");
>>472 C の頃から使われてますが、何か?
(使った事ない奴もいないだろうけど)
>>471 試したところ、BCC 5.5.1 と gcc 2.95.3-6 (mingw special) では f(bool) が呼ばれます。
…でも double に ! は使いたくないな…
>>476 試していただいてありがとうです。
>…でも double に ! は使いたくないな…
ただのネタですので。
478 :
デフォルトの名無しさん :02/03/16 11:27
演算子オーバライドなんですが・・・ あるクラスのコンストラクタの演算子()←コレをオーバライドする方法は ないでしょうか? 具体的には、 class A{}; main(){ A a=10; return 0; } とやりたいのですが。
コンストラクタのアレは演算子か…?
違うのですか? ()だからてっきり演算子かと・・・
operator()?
コピーコンストラクタでしょ
というか、オーバーライド? オーバーライドとオーバーロードの違いもわかってないし、 代入演算子とコピーコンストラクタのこともわかってないんじゃない? もう少し、用語に対する理解を深めてから、正しく質問してくれよ。
コピーコンストラクタは、、、 class A{.....}; main(){ A a(); A b=a; return 0; } ですよね。 そうではなく、 main(){ A a=100; }; とやりたいのです。 房な質問でごめんなさい。
struct A { int val; A(int i) : val(i){} }; int main() { A a = 10; }
>>485 をを、そんなやり方が・・・
有難うございます。おかげさまでなんとか窮状を脱しました。
ご恩は忘れません〜〜。
暗黙の型変換ってやつだな
488 :
デフォルトの名無しさん :02/03/16 15:12
LzhやZipについて圧縮・解凍の仕方を知っておられる方はおられますか? (DLLを使わずに) おられましたら、方法またはページなどを教えてください。
491 :
デフォルトの名無しさん :02/03/17 03:39
仮想継承してるとダウンキャストできないのは何故ですか?
493 :
デフォルトの名無しさん :02/03/17 03:47
今テンプレートにはまりこんでます、 クラスメンバーのテンプレート関数の 関数ポインタを取得するのってどうやるんでしょうか? class a { public: template<typename T> T* func(T* p){return p;} }; void* (a::*pfunc)(void*) = a::func<void>; これだと「内部コンパイラ エラー」ってのになっちゃいました
gccだと class a{ public: template<typename T> T* func(T* p){ return p; } }; main(){ void* (a::*pfunc)(void*)=&a::func<void>; } これで取れたが。
VCでは出来ないようだ。
496 :
デフォルトの名無しさん :02/03/17 15:33
priority_queue を要素の低い順に扱いたいのですが、どうしたらいいでしょうか? 中身の演算子を反対に変更しないですむ方法はないでしょうか?
>494 >495 レスありがと コンパイラで分岐させてから MSCのときだけほかのメンバー関数経由で 呼び出すことにしますね (う、、、呼び出せない・・・・・ 明示的に型を指定できないのかな?)
498 :
デフォルトの名無しさん :02/03/17 15:55
>>496 not2( less<T> ) とかなんとかで順序づけ?
>>496 int d[] = { 5, 3, 1, 4, 2 };
priority_queue<int, vector<int>, greater<int> > pq(d, d+sizeof(d)/sizeof(int));
while (!pq.empty()) {
cout << pq.top() << endl;
pq.pop();
}
こんな感じ?
>>498 よ、よくわかりませんでした。
>>499 うまく逝きました。std::less と std::greater ってのがあるのですね。
C++ は色々覚えることが多いです。
(今も提示してもらったサンプルのコンパイル中に >> でエラーになってびっくりしました)
みなさんありがとうございました。
関数オブジェクトはおもしろいよ
>>498 > not2( less<T> ) とかなんとかで順序づけ?
not2()はオブジェクトを取るんじゃなかったっけ?
less<T>は型だよね。文法的におかしいと思う。
あと仮にオブジェクトの形にしてnot2(less<T>())としても、
operator<()の代わりにoperator>()を使いたいって話だと思うから、
operator>=()じゃまずいよね。たぶん。
priority_queueの場合はあまり副作用なさそうだけど。
オブジェクトの形でソート順が指定できるかどうかはわかんないや。
503 :
デフォルトの名無しさん :02/03/18 17:53
すいません、 struct { int type; void* ptr; }; というような配列を作って、typeの値によって type=0の場合はデータ、1の場合は関数Aへのポインタ 2の場合は関数Bへのポインタ・・・というように ptrのキャスト方法を変えたいのですが どう記述すればできるのでしょうか?(そもそも出来ますかね??) 厨質問で申し訳ないですが、よろしくお願いします。
504 :
503:訂正 :02/03/18 17:56
【誤】 struct { int type; void* ptr; }; というような配列を作って、typeの値によって 【正】 struct { int type; void* ptr; } ptrList[]={ {0,pData1}, {1,pFuncA}, {2,pFuncB}}; というような配列を作って、typeの値によって
>>503 そういう時こそ、滅多に使われないunion様の出番ではなかろうか。
>>503 struct DamnIt {
int type;
void *p;
};
int n = 1;
struct C { int num; C(int n) : num(n) { } } c(2);
void foo() { cout << "3" << endl;}
void bar(int n) { cout << n << endl;}
DamnIt di[] = {
{ 1, &n },
{ 2, &c },
{ 3, foo },
{ 4, bar },
};
int main()
{
for (int i=0; i<sizeof(di)/sizeof(DamnIt); i++) {
switch (di[i].type) {
case 0:
break;
case 1:
cout << *(int*)(di[i].p) << endl;
break;
case 2:
cout << ((C*)(di[i].p))->num << endl;
break;
case 3:
((void (*)())(di[i].p))();
break;
case 4:
((void (*)(int))(di[i].p))(4);
break;
}
}
}
こういうこと?
507 :
デフォルトの名無しさん :02/03/18 19:07
>>503 C++ ならテンプレートを使うのはどう?
>>503 void *ptr
って宣言してるんだから、使うときにtypeの値を見て、それで
その場でキャストするしかないんじゃねーの?
てか、それをどういう風に使うのかを書いたほうがいいと思うぞ。
関数オブジェクト使ってみた。
struct Base {
virtual void operator()() { }
};
struct A : Base {
const int num;
A() : num(1) { }
};
struct B : Base {
int num;
B(int n) : num(n) { }
};
struct C : Base {
void operator()() { cout << 3 << endl; }
};
struct D : Base {
int num;
D(int n) : num(n) { }
void operator()() { cout << num << endl; }
};
int main()
{
Base* d[] = { &A(), &B(2), &C(), &D(4) };
for (int i=0; i<sizeof(d)/sizeof(Base*); i++) {
if (dynamic_cast<A*>(d[i]) != NULL)
cout << (dynamic_cast<A*>(d[i]))->num << endl;
if (dynamic_cast<B*>(d[i]) != NULL)
cout << (dynamic_cast<B*>(d[i]))->num << endl;
if (dynamic_cast<C*>(d[i]) != NULL)
(*(dynamic_cast<C*>(d[i])))();
if (dynamic_cast<D*>(d[i]) != NULL)
(*(dynamic_cast<D*>(d[i])))();
}
}
だからどうと言われるとちょっと困る。
>>507 テンプレートは型覚えるから、ちょっと細工しないとだめかも。
よく考えたら、キャストして使っちゃ意味無いね。 まあもともと意味なんぞ無いと言われればそれまでだけど。
>>510 C++なら仮想関数にして呼び出すだけでいいんじゃないの?
int typeが型情報に内包(?)されることになるし。
>>509 の場合だと
int main(){
Base* d[]={&A(),&B(2),&C(),&D(4)};
for (int i=0;i<sizeof(d)/sizeof(Base*);i++){
d[i]->operator()();
}
}
みたいに。
>>511 > C++なら仮想関数にして呼び出すだけでいいんじゃないの?
> int typeが型情報に内包(?)されることになるし。
うん。そうなんだけどね(^^;;
もう一度チャンスをくれ!
struct Data {
Data() { }
virtual Data* func() { return this; }
};
struct FuncA : public Data {
FuncA() : Data() { }
Data* func() { cout << "FuncA" << endl; return NULL; }
};
struct FuncB : public Data {
FuncB() : Data() { }
Data* func() { cout << "FuncB" << endl; return NULL; }
};
int main()
{
Data* d[] = { &Data(), &FuncA(), &FuncB() };
for (int i=0; i<sizeof(d)/sizeof(Data*); i++) {
Data *dat;
if ((dat = d[i]->func()) != NULL) {
// データだったときの処理
}
}
}
あとはfunc()を適当に変えたり。
514 :
デフォルトの名無しさん :02/03/19 02:45
friend な演算子がコンパイルエラーになってしまいます。何故ですか? クラス内で friend ostream& operator<< (ostream& out, const Int& rhs); と宣言していて、 ostream& operator<< (ostream& out, const Int& rhs) { out << rhs.m_Value; return out; } と実装しているのですが m_Value <- こいつがプライベイト変数なのですが、 プライベートだと怒られます。 なぜか operator<< ではなくて、通常の関数にすると大丈夫なのです。 何故演算子だとコンパイルエラーになるのでしょうか? VC6 を使っています。よろしくお願いします。
515 :
C++初心者 :02/03/19 02:55
質問です C++でnewされたインスタンスが自分自身をdeleteすることは 可能でしょうか。それをすることは問題ないでしょうか? よろしくお願いします。
>>515 私もそれ考えた事あるんですが、多分可能な気がします。
delete することでメンバ関数がメモリから消え去るわけではないですから。
でも、 new[] で確保されていた場合とか、auto 変数だった場合とか
色々ありそうなので、結局怖くて、自分自身で delete するのはやめました。
多分自己解決しました。VCのバグらしいです(英語のページだったので、多分ですけど)。 SP3 で直ってるって、そういえばこの間 OS 入れなおした後, VS に SP 当ててなかったです。 鬱だ…。
518 :
C++初心者 :02/03/19 03:46
>>514 さん
ご回答ありがとうございます〜m(__)m
>でも、 new[] で確保されていた場合とか、auto 変数だった場合とか
はい。スタック上に積まれていると困ります…。スコープが管理してますから…。
インスタンスの生成と解放って所有者がいないようなクラス構造では
誰がやって良いのかわからないので難しいです。
こういう方針(自分の消滅は自分で管理する)はたして正しいのか…。
>>518 delete this;
は常套句。判って使う分には問題ないぞ。
>>519 さん
なるほど…常套句なんですね。迷っていましたが
このやり方でやってみることにします。
大変参考になりました、ありがとうございます〜 m(__)m
521 :
デフォルトの名無しさん :02/03/19 04:20
自作クラスから組み込み型へ代入したいときはどうしたらいいんでしょう? 普通にやろうとすると、代入演算子って事になるんですが、既に戻り値が自分の型になってしまっているので、オーバーロードできません。 以下のようなのをコンパイルできるようにしたいのです MyClass m; m.lowByte(100); m.highByte(20); // この行の代入が OK になるようにしたい int a = m; lowByte(), highByte() は例え話なので、実際にそういう事をしたいのではなくて、 別の型への代入をしたいのです。 よろしくお願いします。
operator int
関係ないけど int a = m; で呼ばれるのは代入演算子じゃないぞ
>>522 ありがとうございます。できました〜!
文法レベルはマスターしたつもりでしたが、まだまだ知らない書法が…。
ちょっと鬱でげす。
>>523 ですね(.asm)
これじゃ初期化ですもんね。
ということは int のコピーコンストラクタが呼ばれるのですか?
キャストを定義したという事は MyClass が int に変換されて、
もし int がクラス型なら int( const int&) みたいなコピーコンストラクタが
呼ばれるのでしょうか?違うかな…?ちょっと自信ないです。
深いなぁ。
>>518 コンストラクタをprotectedにして、専用の関数でのみ生成できるようにすれば、とりあえずauto変数には出来なくなるぞ。
デストラクタをprivateに、とか言う手も。
template<class C>struct ST{ public:template<class U>class INA{public:U val;INA(U u):val(u){};U REF(void){return val;};}; INA<C> ina; ST(C c):ina(c){}; C Ref(void){return ina.REF();}; };
528 :
デフォルトの名無しさん :02/03/19 22:14
>>527 教えて君で申し分けないが、何をやってるの?それ。
>>527 インデントめちゃくちゃで読みにくい上に
無駄なセミコロンが4つあるな。
空文ということで見逃してくれるけど。
読んでみると・・コンストラクタで与えた値を非const関数 Ref()で返すだけのテンプレートクラスか。
なんだこりゃ。
縦 に 読 め
531 :
デフォルトの名無しさん :02/03/20 00:34
言 っ て み た だ け
な ん か ワ ラ タ
534 :
デフォルトの名無しさん :02/03/20 08:55
お楽しみの所申し訳ないのですが質問です。 実行中に ランタイムエラー:純粋仮想関数の呼び出し みたいなメッセージ(本当は英語)が出て止まってしまいました。 そんな事言われても…。という感じで今ソースを追っているのですが まだ原因が掴めていません。 純粋仮想関数が呼び出される可能性について考えてみたのですが、 スライシングが起こった時はそういう可能性があるような気がするのですが、 やはりそういう事ってあるのでしょうか? あと、他の可能性が考えつかないのですが、他にはどういったときに そういう事が起こりますか?
>>530 了解。直ちに任務に就く。
連絡ご苦労。
>>534 > 実行中に ランタイムエラー:純粋仮想関数の呼び出し みたいなメッセージ(本当は英語)が出て止まってしまいました。
この部分がとても大事だと思うんだけど、きみはどう思う?
まずはそこからだ!と思ったけど、試してみたよ。
struct A {
virtual void foo() = 0;
virtual ~A() { }
};
struct B : public A {
void foo() { }
};
int main()
{
A* a;
a = &B();
a->foo();
}
これ実行したらどうなる?うちのbcc32では問題なく動くけど、
g++では実行時エラーでcore吐く。
> pure virtual method called
> Aborted (core dumped)
ちなみに
> $ g++ --version
> 2.95.3-5
仮想デストラクタ取っ払ったり、&B()をnew B()に変えるとちゃんと動く。
なぜかはわかんないけど、この辺から攻めてみたらどうだろう。
コンストラクタの中で仮想関数を呼び出してないかな。 vtblの初期化はコンストラクタが終わった後じゃないっけ?
>>537 > vtblの初期化はコンストラクタが終わった後じゃないっけ?
そう書くと、微妙に語弊があるな。
class Base {};
class Deriv : public Base {};
この場合 Deriv クラスのインスタンスを作ると
1. メモリ領域が確保される
2. Base クラスに関する初期化(vtbl の初期化など)が行われる
3. Base クラスのコンストラクタが呼ばれる
4. Deriv クラスに関する初期化(vtbl の初期化など)が行われる
5. Deriv クラスのコンストラクタが呼ばれる
という順番になる。だから、基底クラスのコンストラクタから(純粋)仮想関数を
呼び出すと、基底クラスで定義されたメソッドが呼び出される。
つまりそのとき、baseが純粋関数を持っていてBaseのコンストラクタの中でそいつを呼び出そうとすれば、 vtblの中身が空なんだよね。
540 :
デフォルトの名無しさん :02/03/20 21:10
stringstreamの質問す。 strstreamの場合だと////////////////// using namespace std; char buf[10]; strstream str_stream(buf, 10, ios::out); str_stream << 10 << ends; ってやるとbufの中がかわるのに stringstreamの場合/////////////////// using namespace std; string s; stringstream string_stream(s,ios::out); string_stream << 10; ////////////////////////////////////////// ってやってもsの中がかわらないんだけど。 これってどうしようもない? string_stream.str()で持ってくるしかないのかな。
541 :
デフォルトの名無しさん :02/03/20 22:06
下のように相互にキャストできるようにしたいのですが、 class A a; class B b; a = b; b = a; 下のように定義するとコンパイルが通りません。 class A { public: operator B () { return B(A) } } class B { public: operator A () { return A(B) } } なにか良い方法はないでしょうか。
継承
>>541 先行宣言をやってない…ってオチじゃないよな?
544 :
デフォルトの名無しさん :02/03/20 23:27
>>543 先行宣言って何ですか?
先頭にclass B;と宣言することはやっていますが、
インラインにすることが前提ですので、それでは駄目なんです。
class A { public: #ifdef B operator B () { return B(A) } #endif } class B { public: #ifdef A operator A () { return A(B) } #endif } とすることで一応解決できたのですが、 A classとB classが同じヘッダファイル内にないとうまくいきません。 もっとエレガントな解決方法はないでしょうか。
//------ A.h ------- class B; class A { operator B(); }; //------ B.h ------- class A; class B { operator A(); }; //------ AandB.h ------- #include "A.h" #include "B.h" inline A::operator B() { return ***; } inline B::operator A() { return ***; } つーか。 いまいち想像つかんがどうしてもinlineにしなけりゃならんような 相互依存してるなら、class A と B は同じヘッダに入るべきだろう。
>>541 はっきりと一言で言うと、
>>541 のクラス設計が根本的におかしい。
class Aとclass Bが変換演算子で相互に変換可能なほど密な関係なら、
その二つは同じヘッダで提供すべきだ。
逆に、「別のヘッダで提供しなければエレガントではない」と設計者自身が
感じるということは、それは、その二つのクラスが実は疎な関係にある
ということ。
設計を最初からやり直したほうがいいんじゃないのか? 二つのクラスを
密な関係にしたいのか、疎な関係にしたいのか、はっきりさせたほうがいい。
参考資料として、ム板の推薦図書 Exceptional C++ の第5章を挙げておく。
548 :
デフォルトの名無しさん :02/03/22 14:22
class A{ public:void func(void){....} }; main(){ A* pa=new A; delete pa; pa->func(); return 0; } これが動くのが理解出来ない。deleteした時点paは消滅するはずでは?
>548 消滅はしたけど、跡地に前の情報が残ってるから たまたま動いてるように見えるってだけ。 deleteしたものにアクセスしちゃ遺憾。 { { int n = 3; } { int n; cout << n << endl; // n=3かもしれない } }
550 :
デフォルトの名無しさん :02/03/22 14:37
>>549 なるほど、理解できました。サンクスです。
551 :
デフォルトの名無しさん :02/03/22 15:06
メンバー関数の引数に同じクラスのメンバー関数のポインタ を入れたいのですがうまくいきません. この場合もクラスのアドレスが必要なのでしょうか よろしくお願いします.
ああ! cのコードをクラスに書き換えていたのですが cのときは関数のポインタ与えるのに&演算子いらなかったのですが c++になるとクラス名と&演算子をつけないといけないんですね なんとかなりそうです 勉強不足でした.すいません.
>>553 C++になると、でなくて、メンバ関数だと、だな。どっちかと言うと。
555 :
デフォルトの名無しさん :02/03/22 22:15
C だと、標準ライブラリが stdioとかstdlibとかにあるから strcpyとかprintfとか あんまり気にせず使えますが C++ だと標準ライブラリというのはあるんでしょうか?
>>555 沢山ある。標準入出力ならiostream。
つーか、stdio.h、stdlib.hもC++の標準ライブラリだよ。
#include <cstdio>
#include <cstdlib>
という具合に使う。
557 :
デフォルトの名無しさん :02/03/22 22:18
>>556 ああ、ありがとうございます。
ではBCBをダウンロードしてきます。
558 :
デフォルトの名無しさん :02/03/22 22:39
今socketを使ったプログラムを作っているんですが、 sockfd = ::socket(AF_INET, SOCK_STREAM, 0); なんて処理のところで implicit declaration of function というエラーが出ます。 同じようにbindやlistenにも出てしまします。 g++2.95.4を使っているのですが、何かコンパイルオプションが 必要なら教えて下さい。お願いします。
関数宣言が見つからないという意味だから #include するヘッダをあなたの環境で確認して頂戴 いわゆるunixなら man socket で出てくるはず あとスレ違い
>>558 その::をやめてusing namespace std;をインクルード宣言文の
後ぐらいに書いたら動くかも。
#include <hogehoge>
using namespace std;
int main (...)
{
:
というように。試してないんで動かなかったらスマソ
562 :
デフォルトの名無しさん :02/03/22 22:56
563 :
デフォルトの名無しさん :02/03/22 23:00
C++を勉強するにはCを理解してないと無理ですか?
564 :
デフォルトの名無しさん :02/03/22 23:01
>>561 関係ないです。
socket関係はstd名前空間に入っていませんから。559が正解。
565 :
デフォルトの名無しさん :02/03/22 23:01
そんなことはありません。
皆さんどうもありがとうございます。 #include <sys/socket.h> #include <netinet/in.h> なんかを入れて上手くいきました。 sysのところがlinuxとなってたのが間違ってました。 どうも済みません。 ちなみにC++の本にはC用のヘッダーファイルは <stdio.h>を<cstdio>と書くようにって書いてあったのですが、 これだとコンパイラを通せないヘッダーファイルもあるみたいですね。 例えば<cunistd>とか。規則とかあるんでしょうか? gccの話になって申し訳ないのですが、よろしくお願いします。
>>567 C++標準じゃないなら
#include <chogehoge>
と書くのはいただけないな…
570 :
デフォルトの名無しさん :02/03/22 23:48
>>568 >>569 ありがとうございます。
もう一つだけお願いします。
Javaのようにクラスにスレッドを割り当てたいのですが、
staticなメンバ関数を用意してそこで自身のオブジェクトを作成するって
やりかたはC++的に正しいやり方なのでしょうか?
571 :
Alexandrescuマニア :02/03/23 00:33
Loki使えるよ
572 :
デフォルトの名無しさん :02/03/23 17:49
あの本誤植多いけどな
573 :
デフォルトの名無しさん :02/03/23 18:15
>>563 俺はCじゃなくてC++から始めてるよ。
最近かなりつまづいてるけどね。「はじめてのC++」とかいう本がよかった。
574 :
デフォルトの名無しさん :02/03/23 19:13
Javaのinterfaceのように継承したらそこで規定するメソッドを 実装しないといけないようなものはどうやって宣言したらいいんでしょうか?
575 :
デフォルトの名無しさん :02/03/23 19:15
576 :
デフォルトの名無しさん :02/03/23 19:18
純粋仮想関数だな。
virtual void XXX() = 0; これが一つでもあるとJavaのabstractclass。全てならinterface。 継承した子クラスを実体化しないとエラーは出ないから注意。
アホな質問。 これ実行したらhogeのデストラクタ呼ばれないんだ。 デストラクタ呼ばれるようにするにはどうするの? class hoge { private: int *p; public: hoge() throw(exception) { p = new int; throw exception(); } ~hoge() { delete p; } }; //////////////////////////////// int main(int argc, char* argv[]) { try { hoge h; } catch(exception &e) { cout << e.what() << endl; } } あーというか、ききたいことは コンストラクタで例外を起こしても、デストラクタ呼ばれるようにするにはどうすんの?
>>580 コンストラクタで例外が発生したと言うことは、
オブジェクトが作成が完了してないと言うことだから、
有効なオブジェクトではないのでデストラクタは呼ばれない。
>>580 デストラクタが呼ばれないのはC++の仕様だから覆せない。
メモリリークが起きなければいいんだろう?
int *p;
を
auto_ptr<int> p;
にすれば解決。
あとは Exceptional C++ でも読んで勉強しなはれ。
レスどうも。
>>582 なるほど
それもそうかぁ(ι´ー`)
>>583 勉強して出直してきまーす。
参照回数計測の実装方法がわからん〜〜〜〜(藁
586 :
デフォルトの名無しさん :02/03/24 18:58
class aaa{ aaa(); } これを生成するとき、 aaa bbb; と、 aaa bbb(); てどう違うの?
587 :
デフォルトの名無しさん :02/03/24 19:00
aaa bbb; // bbbという名のaaaのインスタンスを作成。コンストラクタを呼ぶ。 aaa bbb(); // bbbという名の引数をとらないaaaを返す関数の宣言。
>>589 そうなんですか。bbb()の実装部分の
aaa bbb(){
...
}
の記述は必要ないんですか?
591 :
デフォルトの名無しさん :02/03/24 19:18
>>590 「宣言」と「定義」の違いを勉強してから戻って来るよーに。
aaa bbb(); は宣言なんで、定義である aaa bbb(){ ... } は別に書くってことですよね?初歩的でスイマセン。
594 :
デフォルトの名無しさん :02/03/24 20:07
Output,Inputっていうインターフェースつくったんですよ。 で、Input には Input::Null っていう何もしない実装が用意されてます。 こんなかんじで、 struct Input { int Interface() = 0; struct Null; }; struct Input::Null : public Input { int Interface() { return 0; } }; ほんでそのインターフェースでなんか仕事する関数があるわけですよ、 int DoSomething( Output& out , Input& in = Input::Null() ); そしたらそのデフォルト引数のところで gcc におこられたんで、 調べたら一時オブジェクトは右辺値だから非const参照には渡せないそうで。 ちょっと考えて、思いつきで関数もう一個並べて、 inline int DoSomething( Output& out ) { Input::Null dummy; DoSomething( out , dummy ); } ってしたんです。そしたら gcc も通してくれたんで素通りしかけたんですけど、 元の奴と書き直した奴って、本質的には何も違わないような気がするんですよ。 なんか見落としてますかね? ちなみに、元の奴をVC++6に食わしたら何にも言われませんでした。
>>594 namespaceを認識してないだけだろ
596 :
デフォルトの名無しさん :02/03/24 20:37
bcc5.5.1で以下のコードが通らないのですが、どうしてでしょうか? std::auto_ptr<int> a; a = std::auto_ptr<int>(new int); memory.stlファイルには、 auto_ptr<X>& operator= (auto_ptr<X>& rhs) _RWSTD_THROW_SPEC_NULL { reset(rhs.release()); return *this; } とあるので、オペレータ自体は定義されているようなのですが。 エラー E2285 a.cpp 44: 'std::auto_ptr<int>::operator =(std::auto_ptr<int>)に一致するものが見つからない です。 他の箇所でも、関数宣言時に仮引数に参照を指定してテンプレートクラスを渡すと 同様のエラーが出て、実体になおしたりしたのですが。 原因がわかる方、おねがいします。
597 :
デフォルトの名無しさん :02/03/24 20:53
>>596 C++Builder6では通るよ。Borland-C++5.5.1のバグじゃないの?
>>595 initialization of non-const reference .....
っていうエラーメッセージだったんですけど、 namespace なんすか?
599 :
デフォルトの名無しさん :02/03/24 21:12
>>596 bcc5.5.1のバグっぽいけど、ふつうは
a.reset(new int); とするんじゃないの?
a = std::auto_ptr<int>(new int); は冗長すぎ。
>>594 > int DoSomething( Output& out , Input& in = Input::Null() );
こっちのNullは、その場で生成してその場で消滅する、
「テンポラリオブジェクト」もしくは「一時オブジェクト」ってやつ。
> Input::Null dummy;
> DoSomething( out , dummy );
こっちのNullは、dummyという「名前つきオブジェクト」。
どちらも人間の感覚では一時的なオブジェクトとして
違いはなさそうに思えるけど、これがコンパイラにとっては
大きな違いになるらしい。テンポラリオブジェクトの方が
最適化されやすかったりするし。
詳しいことは、 More Effective C++ の項目19,20あたりを読んで
勉強しましょう。
>>599 いや、ほんとは
class A{
std::basic_string<TCHAR> s_;
public:
A(std::basic_string<TCHAR>& ref) : s_(ref) { }
};
std::basic_string<TCHAR> str;
A a(str);
だったんだけど、くどいので簡単な例を出しただけです。
で、バグでしたか。それなら納得です。
ありがとうございました。
>>600 あのー、「コンパイラにとって大きな違いになる」ということですが、
gccがエラーでvcが黙って通してくれるのはやっぱりもしかしてvcバグってるんですかね?
一時オブジェクトの扱いはコンパイラによるだろうから 明らかにバグでない限りは、別にそれでもヨイのでは。 ふるい規格のままだったり多少の規格との差は、 おれとしては許容範囲内。 #ifdef程度のコードで回避できるならね。
>>601 A()のコンストラクタの引数だめじゃん。
そういう場合の参照引数はconst付けるの常識っす。
A(const std::basic_string<TCHAR>& ref) : s_(ref) {}
>>604 そういう問題なのかなと思い、const-referenceにしてみたら、見事解決しちゃいました。
thxです。
じゃ、やっぱりバグではなかったということですか?
>>603 規格はどっちか定めてないんでしょうか?
まぁとりあえずMoreとか読んで出直してきます。
607 :
デフォルトの名無しさん :02/03/24 23:22
↓これ、Borland-C++5.5.1でエラー出ませんけど? #include <string> #define TCHAR char class A{ std::basic_string<TCHAR> s_; public: A(std::basic_string<TCHAR>& ref) : s_(ref) { } }; std::basic_string<TCHAR> str; A a(str); main() {}
class A{ std::basic_string<TCHAR> s_; public: A(DWORD d, std::basic_string<TCHAR>& ref) : s_(ref) { } }; std::vector<A> v; v.push_back(A(1, std::basic_string<TCHAR>("str"))); あ、ちょっと違った。上のような感じです。 元のクラスがでかすぎるので、切り分けるのにミスをしてました。
610 :
デフォルトの名無しさん :02/03/25 00:52
>>609 本当ですね。constを付けないとエラーになるけど、結局一時的に生成されるオブジェクト
のリファレンスを取るのは問題があるのでしょう。
プログラミング言語C++第3版のどこかにそういう章があればいいのですが。
>>608 あ、vcの警告レベル上げたら「非標準の拡張機能」って出る。
つまりは標準ではないと。
でも拡張で通してもいいくらい、たいした理由のないきまりだと、、、
>>610 ARM あたりに書いてあったような気がする
613 :
デフォルトの名無しさん :02/03/25 22:44
template<class type>struct ST{ type data; ST(type val):data(val){} ST<type>operator+(const ST<type>& rhs){return data+rhs.data;} }; main(){ ST<int> const a=10; ST<int> b=0; b=a+a;←---------------これをエラーにならずにやる方法はないでしょうか? return 0; }
>>613 operator+ を、非メンバ関数にしましょう。メンバ関数だと、
暗黙の型変換での問題が発生するから推奨されていません。
もしくは、 operator+= をメンバ関数として実装して、
b += a;
b += a;
と書くことを考えましょう。
参考資料
Effective C++ 項目19
More Effective C++ 項目22
Exceptional C++ 項目20
非参照型の引数を取るコピーコンストラクタって、 無限再帰が起こり得るんじゃなかったっけ?
>>613 そりゃconstなオブジェクトでconstでない面罵関数は
呼べんわな。
みなさま、御手数をおかけしました。
>>616 さま、クリティカルです。
618 :
デフォルトの名無しさん :02/03/26 21:30
g++ 3.0.4 で std::wstring が使えないんですが、そういうもんですか? ヘッダーファイルを grep してみると、 <stringfwd.h> #ifdef _GLIBCPP_USE_WCHAR_T typedef basic_string<wchar_t> wstring; #endif <bits/c++config.h> // Define if code specialized for wchar_t should be used. /* #undef _GLIBCPP_USE_WCHAR_T */ といった記述が見つかりました。これは、c++config.h で #define _GLIBCPP_USE_WCHAR_T 1 とかやればよいということなんでしょうか。
> #define _GLIBCPP_USE_WCHAR_T 1 これをやってみたけどいろいろ undefined エラーとかが出ますね。 wstring だけなら basic_string<wchar_t> で typedef してやれば よさそうだけど、typedef basic_ostringstream<wchar_t> wostringstream; とかを使おうとすると、やっぱりいくつか undefined が出る。うーん。
620 :
デフォルトの名無しさん :02/03/26 23:39
CRC計算のクラス作ってるんだけど 誰か作っている人いないかな? ソースみせてほしいんだけど よろしくお願いします。
なんでこの手のバカは全角英数使うんだ?
624 :
デフォルトの名無しさん :02/03/26 23:51
vectorにvectorを入れたいのですが、 vector<vector> vec; こういった書き方は出来ないのでしょうか? vector<vector<int> >とか何らかの型を指定しないと やっぱりダメですか?
長いんだけど見てください class CRC16 { private: word init; word poly; bool refin; bool refout; public: CRC16(); void SetInit( word value ); void SetPoly( word value ); void SetRef( bool in, bool out ); word GetInit(); void Citt( byte data[], UINT size ); void CalcL( byte data[], UINT size ); void CalcR( byte data[], UINT size ); }; CRC16::CRC16() { init = 0; poly = 0; refin = false; refout = false; }
626 :
デフォルトの名無しさん :02/03/26 23:54
void CRC16::Citt( byte data[], UINT size ) { init = 0xFFFF; poly = 0x1021; refin = false; refout = true; CalcL( data, size ); } void CRC16::SetInit( word value ) { init = value; } void CRC16::SetPoly( word value ) { poly = value; } void CRC16::SetRef( bool in, bool out ) { refin = in; refout = out; } word CRC16::GetInit() { return init; } void CRC16::CalcL( byte data[], UINT size ) { UINT i, j; if ( refin == true ) init = ~init; for ( i=0; i<size; i++ ) { init ^= data[i] << 8; for ( j=0; j<8; j++) if (init & 0x8000) init = (init << 1) ^ poly; else init = init << 1; } if ( refout == true ) init = ~init; } void CRC16::CalcR( byte data[], UINT size ) { UINT i, j; if ( refin == true ) init = ~init; for ( i=0; i<size; i++ ) { init ^= data[i]; for ( j=0; j<8; j++) if (init & 1) init = (init >> 1) ^ poly; else init = init >> 1; } if ( refout == true ) init = ~init; } おねがいします。
624はなんでそんなことがしたいの?
>>628 推測だが
vector2<int>
で vector<vector<int> > に展開されるようなコードを書きたいんじゃないのか?
C++で無限タイプリストがあつかえないものかなーとか思ってみたりして、、 template<class A,class B> struct Typelist{typedef A H;typedef B T;}; とかいう今流行りのあれです。
だから上の奴は例えが悪いです。 typedef vector<vector> vecvec; とやりたいですって言えばよかったと思います。
632 :
デフォルトの名無しさん :02/03/27 01:49
というか良く考えたら、 typedefの再定義はできないからそれは不可能かもね。 有限のデータ構造をしたから積み上げるだけがC++の全てかも。
#define vecvec(type) vector< vector<type> >
634 :
デフォルトの名無しさん :02/03/27 02:12
635 :
デフォルトの名無しさん :02/03/27 02:52
boost::anyはどうか vector<vector<T> >なら #include <vector> using namespace std; template <typename T> class vector2 : public vector<vector<T> > {}; int main(int argc, char *argv[]) { vector2<int> v2; v2.resize(3); v2[0].push_back(0); v2[0].push_back(1); v2[2].push_back(2); return 0; } でどうよ
636 :
デフォルトの名無しさん :02/03/28 00:01
メンバー関数で同じクラスのメンバー関数は どうやって呼び出したらいいの? それとこのやりかたはよくないですか?
this->method();
639 :
デフォルトの名無しさん :02/03/28 00:10
>>637 >>638 すばやい回答どうもありがとうございます。
test::aaa() {
this.bbb( 123, 456 )
}
int test::bbb( int a, int b) {
return a+b;
}
これでいいの
それともこっちのほう
this->bbb( 123, 456 )
>639 thisはポインター
>>639 自分のオブジェクトのメンバ関数を自分のオブジェクトの
メンバ関数から呼ぶ場合は何も指定しなくてもOK。
上の例だと
test::aaa(){
bbb(123,456);
}
でOK。
thisは自分のオブジェクトへの参照を返すときなどに
使用する。
>自分のオブジェクトのメンバ関数を自分のオブジェクトの >メンバ関数から呼ぶ場合は何も指定しなくてもOK。 仮想関数だと話が変わってくるがどうか。
637はJava?C#?
646 :
デフォルトの名無しさん :02/03/28 08:42
長い文字列を途中で改行するにはどうしたらいいのでしょう。 ど忘れしてしまって "今日はいい天気です。外で元気に$ あそびましょう"
648 :
デフォルトの名無しさん :02/03/28 09:05
>>646 "今日はいい天気です。外で元気に"
"あそびましょう"
じゃないのか?連続する文字列は一つになります。
>>646 要するに、『長い文字列を、ソース上で見やすくするための改行』を
したいんだよね? 『出力時に文字列を改行』したいなら
>>647 が
答えてるけど、そんなの度忘れしたりもしないだろうし。
char a[] =
"今日はいい天気です。外で元気に\
あそびましょう";
行末に \ を入れればいいよ。
って、
>>648 の方法でもイケるんだね…。知らなかったよ。
>>648 の方は、分割した後のインデントが出来るから、
そっちがよさそうだね。
650 :
デフォルトの名無しさん :02/03/28 10:48
K&Rの47ページにしっかりと 「文字定数はコンパイル時に連結することもできる」 と書いてあります。 けっこうK&R読んでない人いるのね。
652 :
デフォルトの名無しさん :02/03/28 16:02
Cなんて知るか!
653 :
デフォルトの名無しさん :02/03/28 16:11
これからはRubyだ!
> Cなんて知るか! 『プログラミング言語C++ 第3版』の127ページには 「隣り合う文字列はコンパイラによって結合されるのえ」 って書いてある。誤字ってるけど。
Javaだと使えないので注意。演算子 + で繋げよう。
strcat strcat strcaaaaaaaaaaaaaaaaaaaaaaaat
>>654 本当だ。誤植ですね。でもこれはANSI-Cでも使われていた記法ですよね。
>>654 あの本の誤植には、「参考演算子」ってのもあったな。
template<class T>class Ct{ friend void func(int a){cout<<a<<endl;} }; という風なフレンド関数に何故かアクセスできません。 何故なのでしょうか?
>>659 クラスのなかでフレンド関数を「定義」するのは無意味だと思いませんか?
661 :
デフォルトの名無しさん :02/03/28 20:38
フレンド関数って一言でいうとなんですか?
そいつにはすべてをみせちゃうわけだ
友達はたよりになることもあるが トラブルをひきおこすことのほうが多いのだよ
665 :
デフォルトの名無しさん :02/03/28 20:45
それじゃセフレ関数になっちゃいます。 フレンドでも見せられないものとはなんでしょうか?
フレンドはメンバーではありません。
田代メンバーでも稲垣メンバーでも辻元メンバーでも鈴木メンバーでも(以下略
669 :
デフォルトの名無しさん :02/03/30 06:32
以下のコードの 「struct ::n::s」の部分は文法的に間違いなのでしょうか?
vc6,g++(cygwin)でコンパイルも実行も出来たのですが。
namespace n {
struct s;
}
struct ::n::s {int x;};
int main() {
::n::s v;
v.x = 1;
return 0;
}
The C++ Programming Language(3rd)の巻末のgrammarのクラスの定義の部分は、
>class-head:
> class-key identifier(opt base-clause(opt
> class-key nested-name-specifier identifier base-clause(opt
> class-key nested-name-specifier(opt "template" template-id base-clause(opt
>
>class-key:
> "class"
> "struct"
> "union"
また、
>nested-name-specifier:
> class-or-namespace-name "::" nested-name-specifier(opt
> class-or-namespace-name "::" "template" nested-name-specifier
となっており、クラス名またはクラス名の前のネームスペース名には "::" を
付けられないというように読めるんです。
正誤表には載ってないので、コンパイラ独自拡張ですか?
http://www.research.att.com/~bs/3rd_errata.html
頭の::は simple-type-specifier: ::(opt nested-name-specifier(opt type-name の、スコープはずしになってるんでないのかな?
すいません。言ってる意味がよくわかりません。スコープはずしって? ので、確かなことは言えないですが、クラスの定義はsimple-type-specifierでなく class-specifierのほうではないのですか? (反語じゃないですよ。実はBNF?よくわかってないので)
スマートポインタについて考えているのですが 参照カウントをポイント先のアドレスをキーにした hash に入れて管理する という方式はまずいでしょうか?
>>671 定義だろうと、式の中だろうと、先頭につく::はグローバルスコープを意味するんじゃないの?
>>672 作ってみれば?
まずかったらまずかったでやり直せばいいんだし。
どうせ車輪の再発明なんだから、割り切ってやるとよし。
>>673 やっぱりよくわからない…。
ので、自分の言いたいことだけ書くと、
struct ::s{}; とか struct ::n::s{};という書き方が出来るためには、
>>669 のclass-headはclass-keyの次に "::"(opt が必要ではないのか?
ということです。
あ、
>>669 のmain()は試しに実行したい人がコピペだけですむようにっていう
粋な計らいにすぎないので、本題とは関係ないです。
>>669 訳者あとがきに長尾さんのメアドが載っているから、直接聞いてみるの
がいいかもね。迷惑かもしれないけど(^^;;
もし答えが返ってきたら、ここにも報告よろしく。
>>677 英語版のほうなんですがいいのですかね?
日本語版でも書いてあることは同じですか?こっそり変わったりはしてないですか?
英語版は持ってないので、もし原著者のメアドが載っているなら原著者 に聞いてみる方が確実かも。日本語版にも同じことが書かれています。 こっそり変わったりしてません。 良心の問題ならば、日本語版買いましょう。
メアドが見当たらんが、これから学校なので、
とりあえず、Bjarneへのメールのテンプレよろしく
>>681
>>669 メールの作成も自分でやってね、ってつもりで書いてたんだけどね。
春休みなしですか。学校行ってらっしゃい。
>>669 comp.lang.c++ で聞けよそのくらい。
テンプレいっぱいあるからさ。(nntpd の上に)
683 :
デフォルトの名無しさん :02/03/31 03:23
すなおにアンチパターン嫁て感じな。
初心者にはきつすぎる、、、(涙)
686 :
デフォルトの名無しさん :02/03/31 10:24
最近テンプレートに手を染めたばかりの若造です。 テンプレートクラスのテンプレート引数型を含むスタティックメンバー変数の実体をどうやって定義したらいいのかわからずに困っています。 ヘッダで template < class T> class TemplateClass { private: static map<T, int> StaticMemberVariable; } このように宣言して 実装ファイルで map<T*, int> TemplateClass::StaticMemberVariable = 0; としているのですが、 T ってなんぞや というエラーになってしまいます。 とりあえず map<TemplateClass::T*, int> TemplateClass::StaticMemberVariable = 0; とも書いてみたのですが、やはり駄目でした このような場合、どこでどのように宣言すれば良いのでしょうか? よろしくお願いいたします。
>>686 template<class T>
class TemplateClass
{
private:
static map<T, int> StaticMemberVariable;
};
template<class T>
map<T, int>
TemplateClass<T>::StaticMemberVariable = 0;
>>687 ありがとうございます。
今読み返したらちょっと間違った質問だったのですが、
的確なお答えを頂けて嬉しいです。うまくいきました!!ありがとうございました。
689 :
デフォルトの名無しさん :02/03/31 17:36
int型をchar*(文字列)に変換したいんですがどうやったらいいでしょう? 誰か教えてください。
691 :
デフォルトの名無しさん :02/03/31 17:49
ああそれか。知ってたのに。ありがと。
692 :
助けてください :02/03/31 18:13
どうやっても思いつきません。どなたか助けてください。 もう2CHだけが頼りです。 コマンドライン引数に指定されたファイルすべてに対して、 改行文字以外の各行を、逆さまにして表示するプログラム を書いてください。 このプログラムを a.out とすると実行結果としては、 以下のようになります。 % cat text text1 text2 text3 % ./a.out text 1txet 2txet 3txet 逆さまに表示する部分は、以下のようにすると簡単にできます。 1.文字列の最後に改行文字があれば、そこに「\0」を代入 2.文字列の最後の文字から先頭に向かって、順に 1 文字ずつ表示 3.1で改行文字があったならば、改行文字を表示
694 :
助けてください :02/03/31 18:21
どこ逝けばいいですか?
#include<stdio.h> char *push(void); void pop(c); int main(int argc, char *argv[]) { int c; int i; FILE *fp_in; if (argc < 2) { fprintf(stdout, "USEGE: filenames\n"); } for (i = 1; i != NULL; i++) { if ((fp_in = fopen(argv[i], "r")) == NULL) { fprintf(stderr, "File Open Error.\n" } while((c = getc(fp_in)) != EOF) { if (c == '\n') { while(putchar(push()) != NULL) ; } else { pop(c); } } } } 雨で帰れないから作っちゃったYO! でも提示された方法使ってないYO!
>>694 教えてクン逝って良し。せめてスレッド一覧を表示して、宿題で検索ぐらい
かけろよ。
だれか
>>695 に脳漿ぶちまけるほど突っ込んでやれよ。
698 :
デフォルトの名無しさん :02/03/31 19:03
皆さん、C++でハッピーハッキングしてますか?(w ところでBoostに代わるライブラリを探しているのですが 経験豊富な皆さんのお気に入りライブラリを教えていただけない でしょうか?簡単な利点欠点の説明がついてると嬉しいです。 よろしくお願いします。
最初の一行で答える気が失せた
700get!!!!
>>699 それはなぜでしょうか?
ハッピーじゃないからですか?
>>695 ぜんぜん仕様と違うじゃん…
大体宿題教えて君に教えてやるのは罪だぞ。
しかも関数の定義がないし…
#include <stdio.h>
int main(int argc, char *argv[]) {
char b[256];
for (int i=1; i<argc; ++i) {
FILE *fp = fopen(argv[i], "r");
while (fgets(b, 256, fp) != 0) {
int p;
for (p=0; 32<=b[p]; ++p) ;
while (p > 0) putc( b[--p], stdout);
puts("");
}
fclose(fp);
}
return 1;
}
これは
>>692 さんが列挙していた方法とは違うし、
細かい部分の仕様も違うけど、大方うまく動きます(VC++で確認、わらぃ)。
でも決してこんなコードを書いてはいけません。
もしもこんなコードを課題の解答として提出しようものなら、
たとえ 692 さんが他の面では優秀だとしても落第決定です。
仮に私が 692 さんの担当教官なら、2、3発は殴るかもしれません。
なぜこんなコードを書いてはいけないのかは 692 さん自身で考えて下さい。
とにかく、書いちゃだめです。
C++相談室だしな。ここはC++やっとかないと。 #include <algorithm> #include <fstream> #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { for(int i=0;i<argc;++i){ ifstream f(argv[i]); string s; getline(f, s, '\n'); reverse(s.begin(), s.end()); cout << s; } }
書き込んでから色々抜けてるのに気付いた・・・鬱だ。 でも面倒だからもぉいいや・・・
706 :
デフォルトの名無しさん :02/03/31 22:20
std::cinを使って、 while (!_kbhit()); _getch(); に匹敵する「空の入力待ち」をするにはどうしたらいいのでしょうか? 不可能ですか?
>>706 つまりEnter打つまで待つんじゃなくて、キーを押した瞬間に
動作してほしいっつーことだな。
そういうのは環境依存ってのが定説だと思っていたが。
ファイルシステムを抽象化するクラスを作りました。 はじめは一般的と思われるcompositeパターンで実装していたのですが、 最適化をしていくうちにnamelistとdirectoryオブジェクトで構築する COMのITEMIDLIST+IShellFolderのクローンができちゃったのですが、 もっとうまい構造はないでしょうか? ITEMIDLIST+IShellFolderをそのまま使うのは、速度の点で納得できないのと、 Windows以外では使えないので。
とりあえずどこかにソースupきぼんぬ。
>>708 そういえば Boost でもファイルシステムをラップするライブラリを
作ってたような気がする。そっちも見てみたら?
我が友人が、 「javaのようにc++の全ての機能をclassにするんだ!!」 と叫びながら姿を消しました。その後、彼から変数宣言を class化(?)したものがメール届きました。そのclassは 一応動きますが、分からないのはC++でjavaみたいなモノを作るのに 何か意味があるんでしょうか? 重いだけのような気が・・・
712 :
デフォルトの名無しさん :02/04/01 02:29
.NETで追加されたテンプレートパラメータって機能は C++標準なんですかね? なんかあやしいんですけど・・
713 :
デフォルトの名無しさん :02/04/01 02:35
こんな機能 template<class Type> class Type { } template<template<TemplateType> class Type> class Class { public: Type<int> type; } Class<Type> class;
715 :
デフォルトの名無しさん :02/04/01 03:13
今年高校生になる男子です。 超FAQだとは想いますが、質問させてください。 プログラミングを勉強しようと想って、C++を考えているんですが、 初めての言語がC++というのは無理でしょうか? やはりCから始めるべきでしょうか? 教えてください。
>>715 > 超FAQだとは想いますが、質問させてください。
ダメです。検索してください。
(っつか 4/1 に 2ch で質問するとは、人生捨ててるとしか思えんが)
C++からやりなさい 挫折しそうになったころにCをやれば十分です。
718 :
デフォルトの名無しさん :02/04/01 03:25
>>715 高校生なら頭柔らかいからC++から入っても問題ないだろ。
でも多分学校の勉強よりも大変だぞ。
>>715 最近はGCCも積極的にC++を取り入れてるからな。
流れはC++の方じゃないか?
ちなみに処理系はPC UNIX入れてやるとさらに
勉強になるのでやってみれ。
>>716 4月1日、、、エイプリルフール???
そ、そんな。。。
講談社新書のブルーバックスで、コンパイラが付録で付いて来る
C++の入門書があったので、それを取り敢えず買おうと想ってます。
他に、初心者向けの入門書があったら教えていただきたいです。
>>721 ただでさえ虚実入り乱れている2ちゃんねるなのに、今日はエイプリルフールと
いうことでネタ度がアップしてるからな。どこまでネタなのか見切れないと、時間
を大幅に無駄にするぞ(w
>>715 =721
初めてだからって〜
覚えることの出来ない言語なんて〜
きっとありはしないのさ〜
必要なのは〜
やる気と時間さ〜♪
その点君は、今年から高校生ですから
時間はたくさんあるでしょう。がんばってください。
ただ、プログラミングに没頭するあまり
高校生活を通じて得られたはずの何かを
手にすることが出来ないかもしれないという諸刃の剣。
何事もバランスが大事。
と、一応マジレス。
漏れが手に入れられなかったものは・・・うぅあぁぁぁぁ!!!!!!
>>719 見てきました。ともっちが可哀想でした。
>>720 >ちなみに処理系はPC UNIX入れてやるとさらに
>勉強になるのでやってみれ。
僕のスキルでは、ちょっと難しいです。
一応デュアルブートでターボリナックスを入れてますが、多分そんな
レベルの話ではありませんね、失礼しました。
F1が終わったので、そろそろ寝ます。
レスしてくださった方々、ありがとうございました。
C++に挑戦してみます。
727 :
デフォルトの名無しさん :02/04/01 04:15
>>715 高校生なら、まずは規則正しい生活を送りなさい。
体力をつけないと、プログラマーにはなれません。
つか、やっぱりCの知識もあった方がいいよ。 C++だけじゃ相手にしてくれない企業もある。 それ以前にCがわかればC++へもJava、C#へもスムーズに移行できるだろうけど、C++だけがわかっても先は望めないと思う。 つか、C++は.NETからしてみると相手にされてないし…。マネージC++は対応するようだけど…。
漏れは小学生の時MSXでMSX-BASIC、中学生の時98x1でQB>TC++
>>728 >それ以前にCがわかればC++へもJava、C#へもスムーズに移行できるだろうけど
なわけねーだろ
>>728 言葉上そうしたまで
実際、C++は最難関と言われるだけあって言語の中では一番難しい。スムーズに以降ってのはCのソースを.cppとして保存してC++としてコンパイルできるでしょ?だから。
覚えるのはそりゃあ本人のやる気次第。馬鹿は馬鹿だ。)w
それ以前にCの知識ないと挫折するのは目に見えてるような気もしなくもない…。 難易度でいうと C(易しい)、C#(普通)、Java(やや難しい)、C++(かなーり難しい) となるが、Cを覚えてからだとJavaにもC++にも応用でき習得の難易度も下がるだろう。
またまた言うと、C++とJava(C#も)はCの発展系なんですよね。(知ってるとは思いますが…) で、C++が難しいのはCとの互換性を重視しすぎたため。完全上位(下位?)互換ですから。 Javaはオブジェクト指向に関係ないものは全て切り捨てたんじゃなかったかな。
早速エイプリルフールネタかよ
>>712 もちろん、標準機能。つーか、いままでつかえなかったんかい!
>>728 C++はCを含んでるだろ。わけわからんこと言うな。
>>739 まさかCとC++を似たものだと思っているのですか?
>>740 含んでると書いてるだろ。C++ができるようになったときには
Cができるようになってるってことだよ。
あながちそーとも…
>>742 ?細かい点で相違はあるけど、C++中のC的な部分とCはほとんど
同じだぞ?C++ができるようになるためにはCができないと
駄目だが、C++から勉強しても結局同じ道を通るんだから
同じことだと思われ。
C++ だとコンパイラが自動的にやってくれるところを C では 手書きしなけりゃならないとか。たとえば、vtbl みたいな。 C++ から入ると、関数ポインタのテーブルを作ってディスパッチ、 なんてテクニックはあまり使わない気がする。
クラスライブラリ、テンプレートライブラリがないと何もできない。それも問題。
746 :
デフォルトの名無しさん :02/04/01 22:44
そんなレベルのやつにはそもそもライブラリを使いこなせないという罠
あのさC++を知っててCを知らないってどういう意味? そんなことあり得るの?誰か説明して
昔MFCが使えることを「C++が使える」と称していた人の話を聞いたことがある。
あるんじゃない? C++で好き勝手書いてると、Cの制限忘れてエラー出まくる。
C++をある程度やってからCに行くと、C++では当たり前だったものが、 Cではことごとく使えない、って感じるやつもいるかも、つか実際見た。 C++から入ったやつが、Cとの差分をいちいち気にしてるとは限らないじゃん。
752 :
デフォルトの名無しさん :02/04/01 23:25
long(a+b)とlong a + long b の違いを教えていただけませんか?
>>752 前:文法変。
後:それに何の意味があるというのか?
754 :
デフォルトの名無しさん :02/04/01 23:29
正直、STLなくなったら辛い、というか時間かかりすぎる。 ということでCは書けないな、俺。
後者はキャストと解釈してどこがわからないの? 見たまんまの事しかやってないよ。 結果はaとbの型による。
よくわからないのですが、こう言う問題があって…
両方doubleと仮定して。 丸め(a+b)と丸め(a)+丸め(b)の差?
キャストって()必須じゃないんですか? (int)a;
>>753 前者はC++なら合法になると思うが。
a+bの結果の値が数値型にキャスト可能ならば。
ありがとうございます。 (a+b)と(a)+(b)の丸め誤差の違いということですね。 もう一つわからないことがあるのですが、 int a=15; a ^=0x27; このaの値はいくつになるのでしょうか? a ^=0x27; の意味が良くわからないんです。 よろしくお願いします。
えっ?何でこんな基本的なこと聞くのかって? それは本持ってないしネットで調べるのも面倒だから。 だってここに書き込んでおけば自動的に 答えが返ってくるので簡単便利だからね。 インターネットマンセーマンセー。
a = a ^ 0x27 0000 1111 0010 0111 xor 0010 1000
多分40
>>765 自己満足のために安易に答え書くのもどうかと。
育たなくなるぞ。この子。
宿題に答えてやるのはいかがなものか。
まあ、他人かもしれんが、宿題を教えるのはやめるか。
>>765 0x27=39でaとのXORを取るってことですか。
ありがとうございます。
こんな質問してすみませんでした。
772 :
デフォルトの名無しさん :02/04/02 16:00
コンストラクタに explicit をつけなければいけないのは引数が一つだけ時だけですか? それ以外のときで implicit にキャストが行われてしまう状況というのはあるのでしょうか?
ないんじゃないの? 『C++ 第3版』11.7.1 には、「デフォルトで、引数を1つ取るコンストラクタは、 暗黙の変換も定義する」と書いてあるけど。
class A { public: A(int a, int b = 0) {} }; void f(const A& a) {} int main() { f(5); return 0; }
げげー、これも暗黙に変換されちまうのか。しかし、 > A(int a, int b = 0) {} は、もはや型変換とは呼べない気もするがなー。
776 :
デフォルトの名無しさん :02/04/02 22:53
基本クラス+メンバオブジェクトとか追加メンバ変数=派生クラス となっているのですが メンバオブジェクトをもたせた派生クラスのポインタは 基本クラスのポインタに代入させられないのでしょうか?
>>776 public派生してるなら、代入できる。
public派生させているのですが… 基本クラスA、派生クラスB、Cとなっていて Function(A *a1,A *a2)という関数を作って 使うときに、BとCのポインタ渡すのですが Bはちゃんと渡せていて、Cは渡すと値がおかしくなります BとCの違いはCにはメンバオブジェクトを持たせたくらいなのですが… コンパイルエラーは起こりません
reinterpret_castとかしたらだめ。 そのまま渡せ。 class B : public A {}; class C : public A {}; B b; C c; Function(&b, &c);
781 :
デフォルトの名無しさん :02/04/02 23:21
>>778 メンバオブジェクト持たせて、それ使ってない?
cast等はしていません メンバオブジェクトの有無は関係ないようですね それしか考えられないと思っていたのですが ほかの違いを探して見ます
メンバオブジェクトは使っていません ソースは、ずいぶん長くなっちゃうんですけど・・・
>>783 要約したのでいいよ。もちろんテストして
ちゃんと動かないことを確認してからうpしてくれ。
キャストをしてないと言うなら…。。。関数の中で a2->~A(); new(a2) A(); みたいなエキセントリックなことやってるとスライシングが 起きて値が変になるけど、まさかそういうことではないよねぇ。
786 :
デフォルトの名無しさん :02/04/02 23:40
stringに変数を16進数に変換した文字の 入れたいんだけどどうすればいいの int a=0x1234; printf("%08X",a); こんな感じの結果をstringに入れる 方法教えてください。
>>786 sprintf して char[] に入れてから string に代入。
あるいは stringstream で。
>>786 787じゃないがstreamを使う場合はもうちょっと知識がいるが勉強してくれ。
要約したらとおってしまいました(汗 >785 関数の中で基本クラスのpublicにした変数にアクセスするだけで ポインタの値が飛ぶようです a1->v[0].x=a1->v[0].x; こうしただけでハンドルされてない例外・・・ もう別の方法とることにします
790 :
デフォルトの名無しさん :02/04/03 00:13
>>786 #include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main()
{
int i = 0x1234;
string s;
ostringstream os;
os << setw(8) << setfill('0') << hex << i;
s = os.str();
cout << s << endl;
}
要約したらうまくいくってのはありがちだな。 out_of_range例外じゃないだろうな… あと、データメンバをpublicにするのは禿しく糞なので するな。classの意味がない。
792 :
デフォルトの名無しさん :02/04/03 01:04
>>789 気になるので、classの宣言部分だけでもうpしてくれ。
検証するから。
結局publicにアクセスするとポインタが飛ぶ原因はよくわかりませんでしたが publicはたしかに糞なのでprotectedに変更 そしてデータ読み出し用の関数を作ったら成功しました お騒がせしてしまい、すみませんでした
コピーコンストラクタが定義されてないとかoperator=が無いとか そんなレベルの爆弾だと思われ。
796 :
デフォルトの名無しさん :02/04/03 06:16
class A{ public: void func(){cout<<"hahaha"<<endl;} }; void main(){ const A* pa=new A; pa->func()←----------------これがOKなのに delete const_cast<A*>(pa); const A a; const_cast<A>(a);←---------なんでこれエラー?キャストできない }
間違えた。 pa->func() じゃなくて、 const_cast<A*>(pa)->func()だった。
ハァ?
const_cast<A&>(a).func();
質問。 delete に const_cast って必要?
質問があるのですが、、、、 class CA{ public: void func(){} void hoge(){} }; というclassがあった時、 void main(void){ CA ca=new CA; ca->func(); ca->foo();ここでcaが不要になるとき、それを察知して自動で自分を } deleteするにはどうすればいいでしょう、、、?
>>801 そりゃ何言語だ?
CAにpointer to CAは代入できないぞ。
std::auto_ptr<CA> ca = new CA;
boost::shared_ptr<CA> ca = new CA;
お好きな方をどうぞ
void CA::foo() { delete this; }
す、すいません。間違えました、、、、。 STLは最後の手段なので、、、 void main(void){ CA* ca=new CA; ca->func(); ca->foo();この時点で自動でdeleteしたいんです 何かいい方法はないものでしょうか。 int a=10; int b=12; }
int main() { { CA ca; CA*pca = &ca; pca->func(); pca->foo(); } int a = 10 int b = 12; } どうだ?
上手い!!、、、でも違う〜〜〜。
あくまで
>>804 の書き方でというなら、不可能。
言語側で自動的に変数の寿命を決定するシステムや、
プログラムからプログラムが見れるLispの様な処理系でないと不可能だろ
foo2(CA *ca) { ca.foo(); delete ca: }
STLがなんで最後の手段なんだこのバカ。
一日開けてしまった・・・
>>773 なるほど、勉強になります。
>>774 試してみました・・・。怖いですね。
「デフォルトで、引数を1つ取るコンストラクタ」の引数は仮引数じゃなくて
実引数の数の事を言ってるって事ですね(試した VC++6 がこの部分で規格に準拠してればですけど)。
ちなみに代入演算子も使えてしまいました・・・。
聞いてみてよかった。ありがとうございます。
811 :
デフォルトの名無しさん :02/04/03 08:24
std::map について質問です。 あるエントリーの値を調べたいのですが、もしそのエントリーが存在しなければ、 エントリーを作成せずに「エントリーがない」という事をしりたいのですが どうしたらよいでしょうか? [] では見に行ったときにエントリーを作成してしまいますし・・・。 よろしくお願いします。
812 :
デフォルトの名無しさん :02/04/03 08:29
>>801 テンプレートを使わずに、CA 専用の auto_ptr を作る。
findつかえ。
>>810 >>774 の形の暗黙の型変換を許さないと面倒な場合もある。
class Complex {
Complex(double re, double im) {...}
};
Complex& operator +(const Complex& lhs, const Complex& rhs)
{...}
void f()
{
Complex c1(1, 2);
Complex c2;
Complex c3;
c3 = c1 + c2; //問題無し
c3 = c1 + 3; //
>>774 を許さない場合、オーバーロードしなければエラー
}
818 :
デフォルトの名無しさん :02/04/03 09:32
2次元配列で悩んでいます。 #include <iostream.h> void func(char[3]); main(){ char str[3][50] = {"はじめ","真ん中","おわり"}; func(str[1]); } void func(char[3] x[][50]){ cout << x[]; } 真ん中というのを表示させようとしているんだけど、 コンパイルエラーです。 これを直したソースを教えてください。
素直にfunc(char *)つかっときゃいいじゃん
820 :
デフォルトの名無しさん :02/04/03 09:44
リリータの画像アドレスを教えろ #include <iostream.h> void func(char*); main(){ char str[3][50] = {"はじめ","真ん中","おわり"}; func(str[1]); } void func(char* x){ cout << x; }
メールアドレス書き忘れてた。
822 :
デフォルトの名無しさん :02/04/03 09:59
ありがとうございます。 外出スマスマの件名で送りました。
>>816 なるほど、確かに。この場合は、
Complex(double re = 0, double im = 0) {...}
ってな感じで、どちらの引数にもデフォルト値を設定してしまって
かまわないわけですな。それでも、
c3 = c1 + 3;
の 3 に対しては暗黙のうちにコンストラクタが適用されると。
>void func(char[3] x[][50]) C++はこんなこともできるのかと思ってしまった。 構文エラー出てアアヨカタ
825 :
デフォルトの名無しさん :02/04/03 15:23
>>824 C++はデフォルト引数と参照引数が使える点が違うぐらいだヨ。
826 :
デフォルトの名無しさん :02/04/03 17:44
厨な質問ですまんす。 #include <string> って何? #include <string.h> とは違うの?
string.hはcのヘッダ stringはstdc++のヘッダ
828 :
デフォルトの名無しさん :02/04/03 18:52
STLみたいにあたりまえでもなく、コンパイル時に素数を求めるほど 奇抜でもない、テンプレートの楽しい使い方おしえろ ゴルァ
楽しいけど奇抜じゃないって・・・ ソース見る人の理解を阻害しない程度の、ってこと?
素数を求めるのはそれほど理解するのは難しくはないので、 とにかく役に立つかっこいい使い方 キボンヌ... Prolog
LispやMLなど関数型言語で書いて、それを移植すればお望みのコードにならないか?
832 :
デフォルトの名無しさん :02/04/03 19:32
>>828 ああ、それ俺もキボンヌ。
Effective C++ で、『コピーコンストラクタと代入演算子をprivate宣言して、
実装は行わない。これで、想定外の代入・コピーを防ぐ』ってのが
あったじゃん。クラス作るごとに宣言して行くのがめんどいんだよね。
テンプレートでどうにか楽に出来ない? 誰か教えて。
>>833 ぎゃっふーん! マジっすか。
んじゃさ、Exceptional C++ のpimplイディオムのためのポインタとかは?
auto_ptrでもいいんだけど、どうせ代入・コピーはしないんだから禁止して
あるといいし、コンストラクタで確保してデストラクタで解放するのも
確定だから、所有権フラグも要らないじゃん。
これはどうよ?
>>738 遅レスごめん
標準なのか。
じゃ、ガンガン使わなきゃ。
疑り深くなってしまってるけど他にも
メンバの初期値指定はスタティックでコンストで整数型でなければならない
とか変な制約あるんだよね・・。
おまえそれenumちゃうんかと。
>>834 > auto_ptrでもいいんだけど、どうせ代入・コピーはしないんだから禁止して
> あるといいし、
pimpl は shared_ptr で確保するケースもあるぞ。Win32 の「ハンドル」みたく、
中身を見せないであたいベースで受け渡しできるようにする場合、とかね。
>>834 auto_ptrでやるのは無理じゃないか?
deleteするときにデストラクタ呼ぶだろ?
auto_ptrよりも制限がきついやつはboostに入ってるよ。
scoped_ptrとか。
>>837 ふつうは auto_ptr ではなく const auto_ptr を使う。
boostインストールしたけど英語わかんねーよ ヽ(。´Д⊂)゜。ウワァァァン!!!
>>833 せめてそのクラス名を教えてくれー。
>>836 >>837 サンキュー。
>>839 その名も「コピー不可能」という名前のクラスだ。頑張って英訳せよ。
uncopyable?
つ、つらかった…。やっと探し当てたよ。 class名は noncopyable で、ファイルは utility.hpp やね。 noncopyable を private 継承すればOK、という使い方みたいだなー。 テンプレートだと思ってたけど、継承でいけたのか。そっかー。
やっぱりテンプレートはBTA後のPEをC++コンパイラにやらせる技法 ということでよいか?
どうもtemplateは他のコードの中で浮くから馴染みづらい。 もう少し回りのコードと親和性の高い文法にならんかったのかねえ。
847 :
デフォルトの名無しさん :02/04/04 07:46
プライベートなスタティックメンバ変数の初期化は どこで行えばよろしいのでしょうか? class A { private: static int a; ・ ・ ・
848 :
デフォルトの名無しさん :02/04/04 07:48
コンストラクタ():プライベート変数(値)
int A::a=xxx;
>>848 コンストラクタ内でやるしかないんじゃないの?
宣言のとこにできなかったっけ?
クラスの中には書けないから、宣言だけしておいて、 849のようにクラスの外でそれを初期化するしかないのかな?
あ、プライベートだからできないのか・・・
class A{ private: static int a; }; int A::a = xxx; これでいいみたい
v(^・^)voO(constの勘違いかなぁ・・・)
857 :
デフォルトの名無しさん :02/04/04 11:15
>>847 プログラミング言語C++第3版§10.2.4「静的メンバ」参照。
静的データメンバの初期化は一度しか行われないため、クラスの宣言部
では初期化できない。
>>849 >>852 >>855 さんの通り。
>>848 さんの書式はstaticでないメンバに適用する。これはメンバ初期設定
リストと呼ばれる。特にconstなデータメンバの初期化にはこれ以外に方法
がない。
858 :
デフォルトの名無しさん :02/04/04 11:18
おまけ: もしstaticなデータメンバにコンストラクタ内で代入すると、そのクラスのインスタンス が生成される度にstaticなデータメンバは上書きされる。
そうどうせ俺はアホなやつさ。 例えば名前がClaというクラスがあったらClaの中でClaと言う名前を見つけた時 コンストラクタとは気づかず小一時間悩んだこともあった。 ああ、鬱だ死のう。でも真でも死にきれないよえーん
>>859 C++に関係のない人生というものがあります
861 :
デフォルトの名無しさん :02/04/05 10:09
class hoge{ void set(unsigned char *yama); }; class dore{ public: unsigned char *get(){ return kawa } unsigned char *kawa; }; と宣言して hoge->set(dore->get); と使おうとしたら、 1 番目の引数を 'unsigned char *(void)' から 'unsigned char *' に変換できません。 とか言われちまいました。 何がおかしいかサパーリ分からん。 どっかおかしいですか?
862 :
デフォルトの名無しさん :02/04/05 10:22
文字列で渡された四則演算式を計算してくれるようなクラスって、 どっかにありませんか? Str = "3+4*(4/2)" Str.Calculate(); こんな感じで演算させたら、 Str == "11" になってくれてるようなやつ。
>>861 hoge::set()に渡したいのはdore::get()そのものではなくdore::get()の返値だから、
hoge->set(dore->get());
としなければ。
ああ漏れafoだ
>>863 産苦す(=難産?>IME)
今思ったけどPascalの影響かな? 少しやってたから
867 :
デフォルトの名無しさん :02/04/06 05:22
868 :
デフォルトの名無しさん :02/04/06 06:12
for(int i=0,int n=str.length() ; i < n ; ++i ) という書き方がVC以外だとエラーが出るのですが、 これは他のコンパイラが腐ってるからですか?
>>868 int i, int n っつのがダメなんじゃないの?
int i=0,n=str...
悪い。よく知らんけど…。
VC6は古いからな。
>>868 VCってそれ通るのか?その方が腐ってる気がしないでもないが。
てか、エラーが出るならエラーを書けって。
875 :
デフォルトの名無しさん :02/04/07 07:01
今、C スタイル文字列に別れを告げようと思っています。 しかし str::basic_string の使い方がよくわかりません。 std::basic_string の使い方( std::string としてでも問題無しです) をわかりやすく解説しているサイトなどをご存知無いでしょうか? どなたかよろしくお願いいたします。
STL関連のページを探せ。 STLって書いてある本を探せ。 STL絡みで糞本はあまり見たことないからどれを買ってもOKだ。
877 :
デフォルトの名無しさん :02/04/07 18:43
>876 STL絡みの糞本あったよ、、、 前に不注意にも中身をろくに見ずに買っちゃったことがあってね 『公開されているヘッダー』をそのまま貼り付けて ドキュメントも英語の原盤の単語を置き換えて語順を変え、 一度も人間が目を通さなかったみたいな文だった 本を買うときは十分に立ち読みしてから買いましょう さて、本題に、 演算子のdeleteでNULL初期化されないのは仕様でしょうか?
>>877 遠慮なく晒すべし>本
本題はよく分からん。
>>877 普通されるか?
ポイント先が無効になるだけっしょ。
realloc(ptr, newsize)やfree(ptr)で ptrが変数であるとは限らないので 勝手に代入されないのと全く同じだと思いますが。 Object *Container::SelectObject(int index) {...} 等の時に delete SelectObject(index); というような使い方をすることが稀にありますが、 こういう時にどうしろというのでしょうか。
>879 やっぱダメ? 参照になってるかと思ってた じゃ、 delete p; p = NULL; ってやらなきゃだめなのか、、、 なんかスマートじゃないな >878 ゴメン、棄てたか売ったか誰かにあげたか、処分済みたい (結局Web上のと英文のでなんとかした)
>880 >ptrが変数であるとは限らないので ・・・・う、ちょっと理解できなかった 変数以外の場合って?(const付きの場合?)
つか普通コンストラクタで Hoge::Hoge() : p_(new XXX) {} デストラクタで Hoge::~Hoge() { delete p_; } だからそんなくだらん後処理しない。
>>881 NULL初期化しないといけない場合、ってあるか?
s/初期化/代入/ 鬱
>884スマートポインタとか
887 :
デフォルトの名無しさん :02/04/07 19:29
ifstreamの、ファイル読み込みだけを自作することって できませんかね? 具体的に言うと、 ifstream file("c:\\Hoge.zip\\Hoge.txt"); ってすると、cドライブのルートにあるHoge.zipアーカイブから、 Hoge.txtを取り出して読み込んでくれるようなモノを創りたいのです。 同様に、出力のほうもやりたいと思ってます。 ifstreamをメンバ変数として持つクラスを作って、ファイル読み込み以外を 全部委譲してしまえば出来るんでしょうけど、それはあまりにも煩雑すぎる ので勘弁してください。ifstreamを継承して、ファイル読み込み部分だけを オーバーライド出来れば…と思うんですけど、出来ますか?
>888それを言っちゃあ(^^; えと、結論は ・初期化されない、自分でしろ ・再利用するような状況なんてほとんど無い で、いいんだよね >887 streambufをいじればいいらしいよ
892 :
デフォルトの名無しさん :02/04/07 19:48
>893 コンテナに入れてistream_iterator、ostream_iterator通して、etc,etc auto_ptrはつかえないよ
>>894 前提が良く分からんが、何をどうしたいんだ?
>895 話がややこしくなってきてる、、、 最初の質問は いろんな機能をつけたスマートポインタを作って (スマートポインタは大抵継承不可だし、 既存のものをコピペして書き足すのよりは自分で書いた方が動作が把握しやすいかな、と) デバッガでチェックしてたときに deleteしたあとにポインタの値がNULLになっていないのを見て ここに質問だしたの、(deleteはNULL初期化してくれると思いこんでたので) 881のはスマートポインタ内の処理、 894の発言は>893のを僕が作った方のスマートポインタの事について言ってると 勘違いしてだしたものでした。 (今から思えばこっちは自分でスマートポインタ(?)を作ってるとは一言も言ってない、、)
演算子は代入を伴なわない。 以上。
899 :
デフォルトの名無しさん :02/04/07 23:14
boostのshared_ptrなら、コンテナに入れても大丈夫です。そのために 作られたものだから。
⊂(ΦωΦ⊂ )⊃= sageながらもゲットフフフ・・・
>899 レスどーも、 そう気づいてさっき入れました、
902 :
デフォルトの名無しさん :02/04/08 00:35
同一オブジェクトかどうか調べるのにアドレスで比較してもいいですか? class C *a, *b; if ( a == b ) {....
903 :
デフォルトの名無しさん :02/04/08 00:41
class A{.....}; main(){ A* pa=new A; delete pa; return 0; } とした後に、OSにこのpaを使わせないようにする方法ってあるんでしょうか?
>903 ワケワカンネェヨ
906 :
デフォルトの名無しさん :02/04/08 00:49
>902 許可されるかどうかという意味なら大丈夫だけど その比較がtrueになった時にどんな意味を持つのかは 書いた人次第だと思われ
>>903 pa を「使う」の意味は?
new したときに前回利用したアドレスを渡したくないのなら、operator new()
をそのように定義すればいい。pa のアドレスにアクセスしたときに保護例外
を発生させたければ mprotect() とかでページ属性を変更、かな。
・・・すみません、言葉足らずでした。 いえ、deleteしたらpaが解放されるので、 アドレスがOSに返されてしまう(ですよね?曖昧なのですが)、 その後にOSがpaのあったアドレスをOSが使用することを禁じたい のです。
開放しなければいい。 デバイスドライバ作っているの? 仮想メモリのアドレスじゃだめだよね?
>開放しなければいい。 そ、それはアリなんですか? >デバイスドライバ作っているの? はい。しかし何処をどうすればよいのやらで悩んでおります。
デバドラはSDKがないと無理だとオモタ。 普通のプロセスじゃ出来ないんじゃないの?
その前に、OSは?
908が何をやりたいのかは今二つ謎だけど、 operator newとoperator deleteあたりをHogeればできるはず。 ただ、deleteしたあとのアドレスの挙動を、なぜ制御したいのか、 というあたりに、大きな疑念が残るが。
いや、だからデバドラを作りたいんでしょ。 WinAPIスレあたりで聞いたらどうですか? SDKを読めってレスが付くと思おうけど。 それとVC++でしか作れなかったと思うよ。 (記憶が古いかも)
> いえ、deleteしたらpaが解放されるので、 > アドレスがOSに返されてしまう(ですよね?曖昧なのですが)、 そうとは限らない
intは10桁、doubleは203桁(だっけか?)までしか計算できないが、 数億桁まで計算させるにはどのようなテクを使えばいいのか良いのでしょうか? ちなみに数学系のプログラムなので膨大な桁が必要なのです。 マスマティカとかJAVAで計算できるとは聞いたことはありますが、Cでもできるのでしょうか?
918 :
デフォルトの名無しさん :02/04/08 10:21
#include <ruby.h> でBignumもいいかもね。
>921 作るために本を買うって事でしょ
>数学系のプログラム
にも色々あって一概には言えないが、多倍長演算することが目的でなくて、
正確な計算結果が欲しいのなら、出来合いのライブラリを使うことを推奨。
自作して変なバグが混入したら面倒だ。
俺が使わせてもらってるのは、MIRACL というやつ。
ttp://indigo.ie/~mscott/ いくつかサンプルプログラムも入っているので、見れば分かるはず。
fstream使ってるんだけど、これってファイルの切り詰め出来んの? 100kぐらいのファイルのお尻10k程度を切りたいんだけど 新しくファイル作ってわざわざそっちに書き出して 元ファイル消して新しいのリネームして、禿げしく鬱なんだが・・・・
ファイルサイズを減らす関数というのは、C標準ライブラリにも無かった気がする。
>>924 たとえば、リネームするのにfstream使う?
truncateとか。
Windowsなら _chsizeかな。
924だけど、早速のレスありがd
>>926 使わないけど、漏れ元々BCBつかっててさ
TFileStreamのSizeプロパティで一発でできたんだけど
しかし、とある事情からVCで作ることになって
しかたなく似たようなfstream使ったわけよ。
>>927 truncateわからんので調べに逝ってくるよ
>>922 そです。ライブラリを1から作るととはワタシニは無理ですな
>>923 では使ってみます。みんなサンクス
>>928 ストリームからハンドルもってきて
_chsizeにぶち込んだら一行で逝けたーよ!あーりがと!
よかったね♥
933 :
デフォルトの名無しさん :02/04/09 23:38
template<class TYPE>class Auto{ public: TYPE* pt; Auto(TYPE* pval=0):pt(pval){} ~Auto(){delete pt;cout<<this<<endl;} template<typename VAL>Auto<VAL>&operator=(Auto<VAL>& rhs){ /*何かの処理*/ } }; と言うスマートポインタを作っている最中さんですが、 void main(void){ Auto<CA> a(new CA),b(new CA); a=a;//ここでオーバロードしたはずの処理が無視される } なんとか無視されないようにする方法は無いでしょうか?
> template<typename VAL>Auto<VAL>&operator=(Auto<VAL>& rhs){ この優先順位が、 a.default op = ( default Auto( ptr ) );よるも低いのが問題でわ? operator =(TYPE*)とか、 operator =(Auto<TYPE>をキチンと定義するとか、 暗黙の型変換を拒否するとかで何とかなるような気がするが。
935 :
デフォルトの名無しさん :02/04/10 00:02
template<class TYPE>class Auto{ public: TYPE* pt; Auto(TYPE* pval=0):pt(pval){} ~Auto(){delete pt;cout<<this<<endl;} Auto& operator=(const Auto& rhs){ int x = 0; /*何かの処理*/ return *this; } };
↑コピー演算子のAuto型特別化しなくていーの?
//すまそ Auto<TYPE>& operator=(const Auto<TYPE>& rhs){
いやこっちがごめん bccもg++もコンパイラ通ったね
939 :
デフォルトの名無しさん :02/04/10 00:55
struct Data { long a; int b; short c; char d; }; っていう構造体があって、こいつをメンバに持ったクラスのコンストラクタを struct Class { Data x; Class() : x( Data() ) {} }; ってやるとxのメンバ全部0が入るんですけど、この動作は言語仕様としては どう規定されてるんですか? int() が 0 だっていうのはプロ言C++に書いてありますが。
ヌゥ、VCだと未初期化だった。 「入るんですけど」は g++ 依存ですかね、、、。
int main() { struct Data { long a; int b; short c; char d; }; struct Class { Data x; Class() : x( Data() ) {} }; Class c; printf("%d %d %d %d\n", c.x.a, c.x.b, c.x.c, c.x.d); return 0; } --- 出力 --- 4235448 2147348480 -13128 64 ------------ struct Data { long a; int b; short c; char d; }; struct Class { Data x; Class() : x( Data() ) {} }; Class c; int main() throw(int&) { printf("%d %d %d %d\n", c.x.a, c.x.b, c.x.c, c.x.d); return 0; } --- 出力 --- 0 2 512 0 ------------ ?
禿げしくはずしてるかも。。 スタック上にDataが作られてそれがコピーされるから、 ぐろーばるなインスタンスでも0がハインナイのでは。 >int() が 0 だっていうのはプロ言C++に書いてありますが。 詳細希望
俺、こういう場合、struct Dataのコンストラクタ書くから、気がつかなかったよ。
944 :
デフォルトの名無しさん :02/04/10 06:18
forward decl.をなくして、 class Foo{ class Hoge *m; }; って書いちゃうのは標準に合ってるんですか?
あ、これがいけないと自己参照構造体が書けないか。 でもforward decl.の代わりに使っていい物なのか・・・
問題ない
thanx;
948 :
デフォルトの名無しさん :02/04/10 13:23
>>939 int だのポインタだの、組込型についてはデフォルトコンストラクタは
呼ばれない。C++ 第3版 10.4.2 に書いてある。(ここ、誤訳があるので
注意)
949 :
デフォルトの名無しさん :02/04/10 19:39
こういうC/C++を混在させる書き方ってあり? メンテは楽なんだが... #ifndef mylib_h #define mylib_h #ifdef __cplusplus extern "C"{ #endif /* Cのライブラリ */ typedef struct{ ... } mystruct; void mystruct_init(mystruct *I); void mystruct_done(mystruct *I); #ifdef __cplusplus // C++のラッパーライブラリ class MyClass: private mystruct{ ... } } // extern "C" #endif #endif
950 :
デフォルトの名無しさん :02/04/10 20:49
951 :
デフォルトの名無しさん :02/04/10 20:55
>>949 Cのソースに対してC++のコンパイラを走らせることが必須になってしまう?
ので、C側のコーディングが型チェックなど厳しくなって面倒くさいような
気がすると思うが。
なんか、のidlをコンパイル?した結果みたいやね。
>>948 組み込み型に対して明示的にコンストラクタを呼んだ場合は、
0 をその型に変換した値(静的変数のデフォルトと同じ?)になる、
ってな感じのことが書いてあった。(構文のコンストラクタのところだったかと)
で、それと、10.4.2 の記述をあわせて読むと、
コンストラクタを宣言していない構造体に対して明示的にコンストラクタ
を呼んだ場合もそれぞれ 0 になるとも読めるかと。
>>949 よくわからんからこんなんでラップしてデフォルトコンストラクタを
つくってやればよいかなとも思いました
>>949 とくに問題ないと思うけど。オレだったら、class MyClass の宣言は、
extern "C" の外でするかな。
俺だったらラッパクラスは別ヘッダに書くぞ
おーい痔スレ立てないとまずいぞってことでよろしくー
よーし、もうそろそろ次スレだぁ いっぱいあれ書くぞオ(ワクワク
v(^・^)v
⊂(ΦωΦ)⊃ <三瓶です
Λ_Λハッ! / ̄ ̄ ̄ ̄ ̄ ̄ ̄ __( ;´Д`)__< 9、961かっ…! | 〃( つ つ | \_______ |\ ⌒⌒⌒⌒⌒⌒\ | \ \ \ |⌒⌒⌒⌒⌒⌒| \ |_____________|
962 :
デフォルトの名無しさん :02/04/11 00:19
| | ∧ |_|▽・) |文|⊂) | ̄|∧| モウスグ1000・・・
963 :
デフォルトの名無しさん :02/04/11 00:23
@@@ (゚Д゚ ) <あらやだもうすぐじゃないの
@@@@ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ (゜д゜@ < あらやだ。同じ髪型じゃない。 ┳⊂ ) \__________ [[[[|凵ノ⊃ ◎U□◎ =3 キコキコキコ
965 :
デフォルトの名無しさん :02/04/11 00:31
@@@ (´д`) <そうね奥さん
( ´・∀・`)へー
Cの方は勃ったぞ。 そろそろこちらもたてんといかんな
次はあれをリンクしろ。
環境に依存*しない*C++の話題。
過去ログ、参考、関連スレは
>>2-10 あたり
立てすぎで立てられなかった
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
|
>>972 立てようとした、その心意気や良し!
\
 ̄∨ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧
( ´Д`)
/⌒ ⌒ヽ
/_/| へ \
(ぃ9 ./ / \ \.∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
/ ./ ヽ ( ´Д` )< 後は任せろ!(漏れ以外の誰かに)
( / ∪ , / \_______________
\ .\\ (ぃ9 | ビシッ!!
.\ .\\ / / ,、
> ) ) ./ ∧_二∃
/ // ./  ̄ ̄ ヽ
/ / / ._/ /~ ̄ ̄/ /
/ / / )⌒ _ ノ / ./
( ヽ ヽ | / ( ヽ、
\__つ).し \__つ
/~ヽ /~~ヽ ああ・・・ | |i _∧ゝ ノ まさか10分以上前に立ってたとは・・・。 ノ ノ;´Д`) / ( ノ ソ ヽ ヽ \ \ \ \ _ / .\ _ /ミ (⌒Y. / ̄.\ .\ ミヽ  ̄ \ ,_ _,/ \,_ _,ノ ̄
,, ,=、 ,, , =、 ff | }!、,、〃 / ″ハズカシー!! ,リ/ .ノ*´jコ`)'〃 {{ { ′ v' 《 ヾ.\. \ヾ _,,二、》 ; \. 三,_ (( ゙ー=、`″〃 \. \-‐' ,)) ゙ー=″ ゙' 一'
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| 今漏れに出来ることは、
\
 ̄∨ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧
( ´Д`)
/⌒ ⌒ヽ
/_/| へ \
(ぃ9 ./ / \ \.∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄
/ ./ ヽ ( ´Д` )< ナビゲート!!
( / ∪ , / \_______
\ .\\ (ぃ9 | ビシッ!!
.\ .\\ / / ,、
> ) ) ./ ∧_二∃
/ // ./  ̄ ̄ ヽ
/ / / ._/ /~ ̄ ̄/ /
/ / / )⌒ _ ノ / ./
( ヽ ヽ | / ( ヽ、
\__つ).し \__つ
C++相談室 part6
http://pc.2ch.net/test/read.cgi/tech/1018454705/
v(^.^)v 次スレ行ってね。
v(^・^)v
v(^・^)v
v(^.^)v
Σ(´Д`ズガーン
Σ(゚Д゚) ズガーン
(´・ω・`) ショボーン
( ´・∀・`)へー
(・∀・) イイ!!
(゚∀゚ ) アヒャ!!
(゚ε゚) キニシナイ!!
| | ∧ |_|Д゚) |文|⊂) | ̄|∧| 990ゲット
(゚д゚) ウマー
(;´Д`)ハァハァ
(´-`).。oO(・・・
( -_-)=○)'Д')
( ゚Д゚) フー /( へ)へ
v <(゚ω゚) <うっ! ( )\ /'>
v (゚ω゚)> <はっ! /( ) <'\
v <(゚ω゚)> <うっ! ( ) /'>
ずれた・・・やめよ。
くっくっくっ。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。