■過去ログ置き場に戻る■
1-
前250
次250
最新50
[memo]
"9999999999_00.html#R20"
という感じで、URLの最後に "#R
レスNo
" を追加すると幸せになれます。
C++相談室 part34
751
名前:
デフォルトの名無しさん
:04/08/24 19:46
質問です。
以下のコード(
>>752
)をコンパイルすると二つのエラーが出ます。
エラーの内容は下の通りです。
(1) エラー
request for member 'action' in 'sclass()', which is of
non-aggregate type 'SampleClass ()()'
(2) エラー
request for member 'doAction' in 'uc(SampleClass (*)())',
which is of non-aggregate type 'UserClass()(SampleClass (*)())'
この二つのエラーは同じ系統のものかと思いまして、一度に質問させて
いただきました。何かヒントか検索キーワードでも良いので、なぜ
これがエラーになるのか教えていただけないでしょうか。
特に(2)のエラーは納得できません。代替策はあるのでしょうか?
コンパイラ:g++ (GCC) 3.2.2 Red Hat Linux
752
名前:
>>750 からの続き
:04/08/24 19:46
----------------------------- コードここから
#include <string>
#include <iostream>
using namespace std;
class SampleClass
{
public:
SampleClass() {}
void action() {cout << "SampleClass::action" << endl;}
};
class UserClass
{
SampleClass sc;
public:
UserClass(SampleClass sc_) : sc(sc_) {}
void doAction() { sc.action(); }
};
int
main(int argc, char *argv[])
{
SampleClass sclass();
// SampleClass sclass; とすればエラーは出ないが、上記のように
// 宣言しても引数無しのコンストラクタが呼ばれると思ったのですが…
sclass.action(); // (1) エラー
UserClass uc(SampleClass());
uc.doAction(); // (2) エラー
}
----------------------------- コードここまで
753
名前:
デフォルトの名無しさん
:04/08/24 19:47
失礼
>>752
の名前間違えました。
正しくは「
>>751
からの続き」です。
754
名前:
デフォルトの名無しさん
:04/08/24 19:50
>>753
C++ の最も奇妙な解析にはまっちゃってるな
755
名前:
デフォルトの名無しさん
:04/08/24 19:53
なんか日本語だとむかつくな
756
名前:
デフォルトの名無しさん
:04/08/24 19:58
>>751
スレの書き方・質問の仕方から察するに、プログラマに向いてない。
それが一番の問題。巻き添えを食うであろう同僚PGが気の毒。
757
名前:
デフォルトの名無しさん
:04/08/24 20:02
>>755
なんだと
758
名前:
デフォルトの名無しさん
:04/08/24 20:09
>>751
こりゃまた強引なネタで C++ の話題に戻しにかかってきたねぇ・・・
もしネタじゃないなら、ネタじゃありません、とか書いておいた方が良いよ。
759
名前:
751
:04/08/24 20:18
>>754
そうなんですか?
なにがおかしいのでしょう。
>>758
C++の話題に戻すのが目的でもありませんし、ネタでもないのですが
なにがおかしいのか教えていただけませんか?
みなさんのレスから想像すると、何か変なこと聞いてます、俺?
760
名前:
デフォルトの名無しさん
:04/08/24 20:27
SampleClass sclass();
これは関数宣言
761
名前:
デフォルトの名無しさん
:04/08/24 21:02
>>756
この書き方は何が問題なの?
762
名前:
デフォルトの名無しさん
:04/08/24 21:06
Exceptional C++ 項目42参照
763
名前:
デフォルトの名無しさん
:04/08/24 21:11
>>756
のような態度を取る奴の同僚PGの方が、オレは気の毒だと思うな。
764
名前:
デフォルトの名無しさん
:04/08/24 21:12
省略時コンストラクタがないクラスで
operator new
std::get_temporary_buffer
どっち使うのが主流?
765
名前:
デフォルトの名無しさん
:04/08/24 21:20
>>761
756 じゃないけど「・・・と思った」とか「納得いかない」っていうのは、
自分でアレコレ調べてみる動機としては結構だけれども、
単に「・・・と思ったけど違った。納得がいかない」っていう質問はちょっとアレだろ、
訊かれたほうも困るだろ、ということでは?
>>751-752
ちなみにエラーの意味はだいたいこんなところ。
(1) エラー
非集合体の型 'SampleClass ()()' として定義された 'sclass()' に対して
メンバ 'action' が要求されました。
(2) エラー
非集合体の型 'UserClass()(SampleClass (*)())' として定義された
''uc(SampleClass (*)())' に対してメンバ 'doAction' が要求されました。
766
名前:
751
:04/08/24 21:31
レスしてくれたみなさんありがとうございます。
>>760
あ、言われてみればそうですね。
ということは
>>753
のいう奇妙な解析というのはこれのことだったのですね。
実引数の無い時は関数宣言と解釈されるから、そのときは特別扱いで
空の括弧はなし、と。
ということは(2)に関しても
UserClass uc(SampleClass());
SampleClass()という関数として解釈されてるということでしょうか?
しかし、次の行のuc.doAction()をコメントアウトするとコンパイル&実行
できます。ただし、SampleClass::SampleClass()は呼ばれていないようです。
こちらはどういうことなんでしょう。
>>762
(More) Effective C++なら持っているんですが、その本は持っていません。
明日大至急立ち読みしてきます。
767
名前:
デフォルトの名無しさん
:04/08/24 21:35
>>766
UserClass uc(SampleClass());
これは 引数 void、関数値 SampleClass の関数へのポインタを引数に取る関数の宣言だ
(More) Effective C++ 持ってるのに分からないなんて終わってるなお前
768
名前:
デフォルトの名無しさん
:04/08/24 21:36
>>766
uc っていう関数として認識されてる。この関数の型は UserClass()(SampleClass (*)())
SampleClass を返す引数無しの関数ポインタを引数とする、UserClass を返す関数。
型の記述を読めるようになった方が良いよ。
769
名前:
751
:04/08/24 21:43
>>765
エラーメッセージの意味ありがとうございます。
>>767
, 768
なるほど、やっと理解できたようです。
たしかに型の記述が読めてないですね、精進します。
770
名前:
デフォルトの名無しさん
:04/08/24 22:32
>>764
配置new…かな?
771
名前:
デフォルトの名無しさん
:04/08/24 22:34
>>764
何をするためにそいつら使うの?
772
名前:
デフォルトの名無しさん
:04/08/25 01:38
class Test
{
char a[10];
int b;
char c[5];
public:
func();
};
こんな感じのクラスがあったとします。
これのインスタンス class Test test;
を定義して、例えば char c[5]
の先頭アドレスを取得したいんですが、
良い方法はないですか?
773
名前:
デフォルトの名無しさん
:04/08/25 01:48
>>772
class Test
{
char a[10];
int b;
char c[5];
public:
func();
char* get_address(int i) { return c + i; }
};
Test test;
char* p = test.get_address(5);
774
名前:
773
:04/08/25 01:59
>>773
すまん、忘れて。
775
名前:
デフォルトの名無しさん
:04/08/25 02:24
>>772
C++のクラスでもoffsetofマクロがそのまま使える。調べてみるべし。
776
名前:
デフォルトの名無しさん
:04/08/25 02:32
>>775
先頭アドレスってそういうことだったのか?読みが深いな。
777
名前:
772
:04/08/25 02:41
>>773
>>775
ありがとうございます。調べてみます。
778
名前:
722
:04/08/25 03:13
offsetofの一定義例によると、求められたオフセット値はsize_t
にキャストされているマクロになってました。
>>772
のc[5]のアドレスを指定されてそこに書き込む関数、
を考えると
static Test test;
SetAAA(const char *str)
{
Test* p;
size_t offset;
char* dest;
p = &test;
offset = offsetof(Test, c);
dest = p + offset;
strcpy(dest, str);
}
のような事をしたいのですが、この場合、安全なキャスト
はどのようになりますか?
dest = (char*)(p+offset);
と強引にやってしまってよいでしょうか?
779
名前:
デフォルトの名無しさん
:04/08/25 03:32
>>778
C++を使うなら(char *)とやらずにreinterpret_cast<char*>(p + offset) と書くべき。
働きは変わらないが。
780
名前:
デフォルトの名無しさん
:04/08/25 03:35
しかしなぁ、メンバへのポインタを使った方が楽だと思うんだけど。
まあいいけど。
781
名前:
デフォルトの名無しさん
:04/08/25 04:04
>>780
メンバへのポインタはアドレスじゃないから、
>>778
への最適解にはならんな。
実際内部クラスへの委譲をするにはメンバへのポインタではなくoffsetofマクロ
を使ってアドレスを求める必要があるしな。ケースバイケースかな。
782
名前:
デフォルトの名無しさん
:04/08/25 07:32
offsetofを使ったこと無いやつばっかだな・・・実際、あまり使うこと無いけど。
offsetofを使ってメンバのアドレスを求めるときは、
まずchar *にキャストしてそれからoffsetを加え、さらに実際のメンバの型にキャストするから
えらい汚くなるのよん。
dest = reinterpret_cast<char*>(p + offset);
じゃ正しく動かないねん。
783
名前:
デフォルトの名無しさん
:04/08/25 09:09
for( iterator i = begin(); i != end(); ++i )
i->m_p = NULL;
これを「for_each」を用いた式に変更したいんですが
出来るでしょうか?
784
名前:
デフォルトの名無しさん
:04/08/25 09:13
関数オブジェクトを作って使う
785
名前:
デフォルトの名無しさん
:04/08/25 09:14
class Test
{
char a[10];
int b;
public:
func();
char c[5];
};
Test test;
char *p = test.c;
ところでこれじゃだめなのか?
786
名前:
デフォルトの名無しさん
:04/08/25 09:26
for_each(begin(), end(), bind(&T::m_p, _1) = NULL);
とかか?
787
名前:
デフォルトの名無しさん
:04/08/25 12:43
>>784
,
>>786
mem_func1をパクってmem_assignを作りました。
ありがとうございました。
788
名前:
デフォルトの名無しさん
:04/08/25 13:40
Class Hoge{
private:
int hage; //他メンバ変数が「20」個
public:
void func( int n ){
switch(n){
case CASE0: hage達に関する複雑な処理; break;
case CASE1: hage達に関する複雑な処理; break;
//以下延々と「30」個
}
}
};
case文が多いので、そこの処理だけを他クラスに切り分けたいと思ったのですが(Stateパターン?)、
切り分けたクラスからHogeのメンバ変数であるhage達にアクセスする良い手段は無いでしょうか。
・getter/setterを20個ずつ用意する
・friendを30行書く
・メンバ変数を全て構造体にまとめ、切り分けたクラス達に渡す
思いついたのは、どれもいまいち _| ̄|○
789
名前:
デフォルトの名無しさん
:04/08/25 13:52
内部クラスにしてfriend
790
名前:
デフォルトの名無しさん
:04/08/25 14:20
>>788
・必要なメンバ変数に相当するものを構造体にまとめ、切り分けたクラス達に(getter, setterで)渡す
に1票。インタフェイスが明確になるし。
791
名前:
デフォルトの名無しさん
:04/08/25 15:09
vimでvi使うのってどうやるの?
792
名前:
デフォルトの名無しさん
:04/08/25 15:12
:set compatibleじゃ内科?
スレ違い
793
名前:
デフォルトの名無しさん
:04/08/25 15:39
>>789-790
レスありがとうございます。
やはりそういうやり方(俺のより遙かに洗練されてますが)しか無いのですね。
リファクタリングの本なんか見ると、switch-caseは全てstateパターンに
しろと言いかねない勢いで記されていますが、こういう風に分けなければとなると、
かえって解りづらい気がしてしまいますねぇ・・・。
794
名前:
デフォルトの名無しさん
:04/08/25 15:43
stateパターンに移行できるようなinterfaceで設計しておけばいいんと違う?
795
名前:
デフォルトの名無しさん
:04/08/25 22:04
cygwinにgcc3.4.1が入ったので使ってみた。
「参照されないstatic変数・関数は削除される」という変更が入っているらしいので、
早速試してみたところ、たしかに削除された。
static int x = 0; // この定義に対する領域の確保は無い
ふと思い立って、無名名前空間に置き換えたところ、変数領域の確保が出力された。
namespace { int x = 0; } // この定義に対する領域が確保される
無名名前空間によるファイルローカルな変数・関数は、
staticと同様に参照されない場合に削除してはいけないのでしょうか?
796
名前:
デフォルトの名無しさん
:04/08/25 22:43
素人な漏れから見れば、static が削除されるのなら無名名前空間も削除されてしかるべきなように思えるが…
797
名前:
795
:04/08/25 23:50
調べてるうちに、この問題についての議論を拾ったので貼っておこう。
ttp://gcc.gnu.org/ml/gcc/2004-01/msg02323.html
ttp://gcc.gnu.org/ml/gcc/2004-01/msg02341.html
gcc開発者側の言い分を勝手に要約すると、
「無名名前空間がstaticのかわりに使えるようにしたかったのは分かるが、
現状の規格に従う限りそれらは意味的に違うものになってしまっている。
最適化のために規格に則ったプログラムを犠牲にするわけにはいかない。
今までどおりの"static"として扱って欲しいのなら、"static"と書け。」
という感じ。
gccの現在の実装を盾にしている感もあったのだが、
ソースを見ずしてそこを非難するわけにはいかない。
ついでに、標準委員会の関連する動きも貼っとく。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#223
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#167
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#174
cwg_active.html#223 ってのが最悪で、
「deprecatedだからどうなの?」っていう話が未だに決まってないらしい。
激しく萎えた。
798
名前:
デフォルトの名無しさん
:04/08/25 23:53
別に削除されてもされんでもどうでもいいとオモタ
799
名前:
デフォルトの名無しさん
:04/08/25 23:58
std::localeあたりに削除されてほしいstatic変数がいくつかあるが
きれいに消えるんだろうか?
800
名前:
デフォルトの名無しさん
:04/08/26 00:11
消えてもせいぜい50kBくらいじゃないの?
消えたからって特になんの効果もなさそうな気が。
801
名前:
デフォルトの名無しさん
:04/08/26 23:16
>>800
処理系によっては、いくつか main() 走る前にコンストラクタが動いて、
動的メモリ割当を行うオブジェクトがあったりする。メモリ管理に手を
入れる場合に、ひじょーに面倒臭い。
802
名前:
デフォルトの名無しさん
:04/08/26 23:32
>>801
そんなオブジェクトも削除されるのか?
803
名前:
デフォルトの名無しさん
:04/08/27 15:33
単なる関数ポインタ宣言なら「void (*pf)();」と書けますが、
「A」というクラスに「B()」というメソッドがあった場合の、
Bのポインタ変数の宣言を教えて下さいでつ。
804
名前:
デフォルトの名無しさん
:04/08/27 15:41
A::*B
805
名前:
デフォルトの名無しさん
:04/08/27 15:43
>>803
void B(); なら void (*A::f)();
806
名前:
デフォルトの名無しさん
:04/08/27 15:44
>>805
あ、*の位置間違えた、と思ったら
>>804
が書いてた。
807
名前:
デフォルトの名無しさん
:04/08/27 16:24
今更ながらの質問なのですが、効率的なincludeの仕方ってあるんでしょうか?
例えばhoge.cppとhoge.hが共に、stdhoge.hを必要とする場合
hoge.hの先頭に#include<stdhoge.h>する方法と
hoge.cppの先頭に、stdhoge.h>hoge.hの順で#includeする方法がありますが・・・。
後者は他でhoge.hを使う場合にも同順でやらなければと不便で、今まで避けていましたが、
世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
808
名前:
デフォルトの名無しさん
:04/08/27 16:35
普通両方でインクルードするんでは?インクルードガードしてないと
おかしなことになるだろうし、してあればコードの解釈は1回ですむ
からそこまで効率が落ちるってことはないだろうし。
809
名前:
デフォルトの名無しさん
:04/08/27 16:35
>>807
ファイルは単独で意味を持つ方が望ましいという観点から見ても、前者がいい。
>世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
標準ライブラリがそうでないように、そういう注文を付けるライブラリは怠慢だと思う。
810
名前:
デフォルトの名無しさん
:04/08/27 16:48
hoge.hをインクルードしたらstdio.hの関数が使えるってのは嫌な話だ。
811
名前:
デフォルトの名無しさん
:04/08/27 17:00
>>810
C++スレでそんな事を嘆くべきかな?
テンプレートが記述されたヘッダをインクルードする時に、
避けられないことだと思うけどなぁ。
812
名前:
デフォルトの名無しさん
:04/08/27 17:08
exportつかいてえ
813
名前:
デフォルトの名無しさん
:04/08/27 18:01
関数ポインタを引数に持つCライブラリ関数に、
C++のstatic宣言されていないメンバ関数を渡して、
実行させることはできますか?
staticでないC++のメンバ関数の実行には、仮想関数など
ランタイム時に決定される種類のものがある。だから、
Cライブラリ関数がそれを関知して動作することは不可能
→ゆえにstaticしか通らない。
と考えているのですが。
814
名前:
807
:04/08/27 18:10
皆さんレスありがとうございます。
とりあえず唯一解みたいのが無くて安心しました。。
>>808
私の使っている駄目なIDEだと、cppの方にincludeしてないと
入力補助が働かないので、実利の面からその考えは納得できます。
>>809
さんのレスが、最も同感です。
ちなみに私が悩んだライブラリの筆頭がWTLです。
>>810-811
それもまた、もっともですよね…。かなり嫌ではあります…が。
815
名前:
デフォルトの名無しさん
:04/08/27 18:18
>813
概ねその通り。
まあ、渡せない理由は
仕様的には、型が違う
実装的には、暗黙のthisが引数に含まれる
からだけどな。
816
名前:
デフォルトの名無しさん
:04/08/27 18:18
>>813
仮想関数などを使っていなくても、C 風の関数ポインタは
"this"が何であるのかっていう情報を持っていないので、
C風の関数ポインタを用いてメンバ関数を呼び出すことは出来ません。
817
名前:
デフォルトの名無しさん
:04/08/27 18:24
>>813
プログラミング言語C++ 第3版 15.5
> メンバポインタは、変数ポインタや関数ポインタとは異なり、
> メモリの位置を指すポインタではない。
> メンバポインタは、ポインタというよりも構造体オフセット、
> 配列の添え字に近い。
818
名前:
813
:04/08/27 18:41
みなさんすみません。
最初、スレッドの初期化等を抽象化する基底クラスを
用意し、派生クラスではrun()メンバ関数のみを実装
すれば、コンストラクタ内部で自動的に
pthread_create(..., run, ...);
が呼ばれてスレッドが生成される...みたいな
スレッドライブラリを考えていたのですが....
スレッド生成はWin32ならbeginthreadex_だし、
Linuxならpthread_createだしで、けっこう相違が
あるので、隠蔽したいんですよ...。
どういう設計にするのが妥当でしょうか?
いままでCだけで書いて来たので、実際に応用しようと
するといろいろわからないことが...
819
名前:
デフォルトの名無しさん
:04/08/27 18:47
>>818
スレッドで実行される関数に少なくともポインタが格納できるサイズのパラメータが渡せるはずだから、
そこに this を reinterpret_cast して渡してあげて、スレッドの開始関数 (static) では単に
static int ThreadProc(..., void* arg)
{
return reinterpret_cast<ThisClass>(arg)->run();
}
820
名前:
デフォルトの名無しさん
:04/08/27 18:47
>return reinterpret_cast<ThisClass>(arg)->run();
return reinterpret_cast<ThisClass *>(arg)->run();
821
名前:
デフォルトの名無しさん
:04/08/27 18:56
>>818
どうでもいいけど、スレッドのクラスによるカプセル化は止めた方がいいよ。
ま、C中心だったのであれば、潔癖なカプセル化はしないだろうけど、念のため。
822
名前:
デフォルトの名無しさん
:04/08/27 19:05
>>818
> スレッド生成はWin32ならbeginthreadex_だし、
> Linuxならpthread_createだしで、けっこう相違が
> あるので、隠蔽したいんですよ...。
差異の吸収はboostにやらせるのはどうでしょ?
823
名前:
デフォルトの名無しさん
:04/08/27 19:16
>821
そうなの?漏れけっこうガチガチにカプセル化しちゃたけど
特に不便を感じた事はなかったな。。。
>818
みたいに,いろんな場所で動かす事を考えると
大変になるって事?
それとも漏れのカプセル化がまだユルユルだったのかな。
824
名前:
813
:04/08/27 19:46
うう、819さんのおっしゃることが理解できないんです。
すみません。
reinterpret_castを使ったスレッド生成関数の
startup_routineを作っても、pthread_createや
親クラスへもっていく方法がわかりません。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
class Thread {
public:
virtual int run(void *) = 0;
protected:
pthread_t t_;
};
class TSub : public Thread {
public:
TSub();
int run(void *);
protected:
};
static void * stub_thread(void *pParam)
{
reinterpret_cast<Thread *>(pParam)->run(pParam);
return NULL;
}
(つづきます)
825
名前:
813
:04/08/27 19:47
TSub::TSub()
{
pthread_create(&t_, NULL, stub_thread, (void *)this);
}
int TSub::run(void *pParam)
{
sleep(3);
return 0;
}
我ながら....情けなくなるのですが、TSubのコンストラクタに
書いてある内容をThreadのコンストラクタかメンバ関数に
もっていきたいわけです。
826
名前:
813
:04/08/27 20:00
ちなみに今まではUNIX/Win32でほぼ1vs1になるように
スレッドAPIを#defineで再定義していました。返り値なども。
ただ、スレッドプログラミングを進めるにつれ、
スレッドが使うヒープなどを終了時に自動的に回収したいとか、
pthreadそのままなのでprimitive過ぎて使いにくいとか、
いろいろ不満がでてきたのです。
Boost、恥ずかしながら今初めて聞きました。
ドキュメントを読んでみようと思います。
827
名前:
デフォルトの名無しさん
:04/08/27 20:01
こうかな?
class Thread {
public:
int Start()
{
return pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this));
}
int Join(void** value_ptr = 0)
{
return pthread_join(t_, value_ptr);
}
protected:
static void * thread_func(void *pParam)
{
Thread *pThis = reinterpret_cast<Thread *>(pParam);
return pThis->run(pParam);
}
virtual int run(void *) = 0;
protected:
pthread_t t_;
};
class TSub : public Thread {
public:
TSub();
protected:
int run(void *) { sleep(3); return 0; }
};
828
名前:
デフォルトの名無しさん
:04/08/27 20:04
上の
return pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this));
の stub_thread は thread_func の間違い。
ただ、今から書くのならば
class IRunnable {
public:
int run() = 0;
};
みたいなのを単独でインタフェイスとして定義して、Thread クラス本体と run を実装する
クラスを分ける方がよいと思う (Thread::Start の引数として IRunnable* を取る)。
829
名前:
813
:04/08/27 20:35
>>828
キタ━━━━(゜∀゜)━━━━!!
最初思っていたことは上記のコードでできそうです。
ありがとうございました。
で。IRunnableの話なのですが、Thread I/Fとして
のclass Threadから、run()を追い出すとどのような
メリットがありますか?
まずThreadクラスのインスタンスを生成/管理する
ThreadFactoryとかThreadPoolとか作っておいて...
それらとは別に作っていたクラス
(例えばScreenManagerとか)で、値の監視的要素が
出てきたら、おもむろにIRunnableをくっつけて
run()だけ実装して、
ThreadFactoryに「スレッドにdispatchしてくれ」と
頼む、みたいな感じでしょうか。Start()が参加で、
Join()が脱退みたいな。
830
名前:
デフォルトの名無しさん
:04/08/27 21:37
ここは頻繁にカプセル化するな厨が現れるな。
831
名前:
デフォルトの名無しさん
:04/08/27 21:44
プログラムの規模によるんだよ
832
名前:
デフォルトの名無しさん
:04/08/27 21:45
ThreadとかWindowとか、OSの機関にかかわる部分や特有の機能はカプセル化するべきじゃない。
Socketとかコンソールとか、どのOSでも似たような機能を備えていそうなものだけカプセル化するべきだ。
833
名前:
デフォルトの名無しさん
:04/08/27 21:53
>>832
グローバル変数はアプリケーションインスタンスの
インスタンス変数って考え方でいいじゃん。
あとアクセス制御をどうするかって論点に絞るだけ。
834
名前:
デフォルトの名無しさん
:04/08/27 22:10
カプセル化の是非はOOスレでやれ。
ここはC++でどうやるのがいいか悪いかを論じる。
835
名前:
デフォルトの名無しさん
:04/08/27 22:35
>832
ポータビリティを重要視したライブラリを真っ向から否定ですか?
836
名前:
デフォルトの名無しさん
:04/08/27 22:48
>>832
プラットホーム間のポータビリティとは限らんでしょ。
スレッドやソケットはさすがに微妙だと思うよ。
もろシステムコールじゃん。明らかに他のジャンルと異質。
837
名前:
デフォルトの名無しさん
:04/08/27 23:07
>>835
ポータビリティはOSの特色を生かせない低賃金がする言い訳
個々のOSの特徴や性能を100%引き出してこそプロ
838
名前:
プッ
:04/08/27 23:14
CとかC++とかperlとか、
ポータビリティのある言語だからプロ向けじゃ(ry
839
名前:
デフォルトの名無しさん
:04/08/27 23:18
ハードディスクの性能をフルにいかすには、ファイルシステムなんて(ry
840
名前:
デフォルトの名無しさん
:04/08/27 23:20
移植性とか規格を隠れ蓑にしてる厚顔無知は確実に実在する
決して「切り込み隊長」的な仕事をしない
841
名前:
デフォルトの名無しさん
:04/08/27 23:21
公然オナニー迷惑な「切り込み隊長」も確実に実在する
842
名前:
デフォルトの名無しさん
:04/08/27 23:29
>>837
移植性を追及すべきか、アーキテクチャへの最適化をついきゅうすべきかを合理的に判断してこそプロ
843
名前:
デフォルトの名無しさん
:04/08/27 23:29
追求を「ついきゅう」なんて書いちゃう俺はアマ
844
名前:
デフォルトの名無しさん
:04/08/27 23:40
>>842
両立してこそプロ(の技量)
845
名前:
デフォルトの名無しさん
:04/08/27 23:42
移植性は追求しろと
846
名前:
デフォルトの名無しさん
:04/08/27 23:43
いやもうマ板の話の流れっつーか
847
名前:
デフォルトの名無しさん
:04/08/27 23:45
>>841
無能ですね
848
名前:
デフォルトの名無しさん
:04/08/27 23:49
何のかんの理屈つけては逃げ回るだけの敵前逃亡の専門家イラネ
849
名前:
デフォルトの名無しさん
:04/08/27 23:56
なんのかんの理屈つけて、カプセル化、抽象化から逃げる池沼もイラネ
お前が出来ないからって、他の人も出来ないと思うな
850
名前:
デフォルトの名無しさん
:04/08/28 00:27
なぜ荒れる(w
851
名前:
デフォルトの名無しさん
:04/08/28 00:55
ホイポイカプセル化しとけ
852
名前:
デフォルトの名無しさん
:04/08/28 01:42
夏休みが終わりに近づいてるから
853
名前:
デフォルトの名無しさん
:04/08/28 06:25
>>849
は、手段と目的を履き違える典型的な「切り込み隊長」(w
854
名前:
デフォルトの名無しさん
:04/08/28 11:00
stringクラスには大文字を小文字に変換するメソッドとか
その逆のメソッドはありませんか?
MFC CStringのMakeUpper()やMakeLower()みたいな感じの。
855
名前:
デフォルトの名無しさん
:04/08/28 11:33
ctype::tolower
856
名前:
デフォルトの名無しさん
:04/08/28 11:39
std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(std::tolower));
locale対応バージョンがうまく書けない。
857
名前:
デフォルトの名無しさん
:04/08/28 11:57
面倒でつね… なんでメンバに実装されてないのかな…
858
名前:
デフォルトの名無しさん
:04/08/28 12:10
>>857
派生クラス作っときゃええやん
使えるクラスができたら売るとか・・・
859
名前:
デフォルトの名無しさん
:04/08/28 12:12
>>857
そりゃ、localeのせいだろ。
860
名前:
デフォルトの名無しさん
:04/08/28 13:17
デストラクタで純粋仮想関数を呼び出したいのですがうまくいきません。
純粋仮想関数の中身を実装しないとコンパイル時に関数がないと言われるのですがなんででしょう?
↓ソースはこんな感じです。
#include <time.h>
#include <iostream>
class DyingMessage{
virtual void say1() = 0;
virtual void say2() = 0;
protected:
~DyingMessage(){
( time(NULL) %2 ) ? say1() : say2();
}
};
class JiipanKeiji : public DyingMessage {
void say1(){ std::cout << "なんじゃこりゃー"; }
void say2(){ std::cout << "おらぁ死にたくないよ、死にたくない、死にたくないよ・"; }
};
class RAOU : public DyingMessage {
void say1(){ std::cout << "我が生が(略"; }
void say2(){ std::cout << "我が生涯に一片の悔いなし!ウオァァァアア!"; }
};
int main(void){
JiipanKeiji jk;
RAOU r;
}
861
名前:
デフォルトの名無しさん
:04/08/28 13:22
>>860
~DyingMessage() が実行されるときには、ジーパンもラオウも既に死んでいる。
862
名前:
デフォルトの名無しさん
:04/08/28 13:31
>860
コンストラクタとデストラクタ内では、仮想関数が仮想になれない。
デストラクタを仮想にしてそこに書くしか。
863
名前:
デフォルトの名無しさん
:04/08/28 13:35
柴田望洋さんの、CプログラマのためのC++入門を買おうと思っているのですが
内容的に古いらしいのですが、大丈夫なのでしょうか?
864
名前:
デフォルトの名無しさん
:04/08/28 13:51
>>861
まじで
台詞はいてからじゃないと名シーンが台無しに・・・。
>>862
すみません、virtual抜けてましたね。
でもデストラクタにvirtualつけてもやはりコンパイル通らないっす
って仰っているのはデストラクタにvirtualつけろってことではない?
それで実験としてDyingMessageのsay1とsay2を
cout << "犯人はヤス"; と定義してみたらと、
ジーパンもラオウも「犯人はヤス」しか言わなくなりました。
な、なにゆえ?
865
名前:
デフォルトの名無しさん
:04/08/28 13:59
>>864
処理の順番はこうなる。
DyingMessage()→RAOU()→ラオウの生涯→~RAOU()→~DyingMessage()
~RAOU()のタイミングでラオウは天に還ってしまう。
866
名前:
デフォルトの名無しさん
:04/08/28 13:59
コンストラクタとデストラクタの中では、
関数呼び出しは(virtualであっても)「そのクラス」として行われるよ。
DyingMessageクラスではsay1, say2の中身は存在しないから、
コンパイラのメッセージは正しい。
実行時にヌルポ(pure virtual function call)を出す実装もある。
細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス
と渡るときに、vtblのポインタが書き換わる。
これ、Javaと逆だから、多言語を渡り歩く人は要注意ッス。
Java方式もまたそれで問題あるんだけどね・・・
867
名前:
860
:04/08/28 14:18
>>865
中身(インスタンス)はRAOUだから、say1、2はラオウのものを呼んでくれてもいいのに( ´Д⊂ヽ
>>866
>細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス
>と渡るときに、vtblのポインタが書き換わる。
まじですか。vtblのポインタが書き換わるんですか。
main関数内と ~DyingMessageでのジーパン、ラオウのインスタンスのメモリアドレスが一緒だったんで、
ジーパンとラオウのvtblのsay1、say2が呼び出されてうまくいくかと思ってたのですが納得です。
結局のところ、どうしよう。
~DyingMessage上でラオウのsay1が実行させたいのですが。なんか考えます。
ありがとうございました。
868
名前:
デフォルトの名無しさん
:04/08/28 14:31
>>867
> ~DyingMessage上でラオウのsay1が実行させたい
そうはいってもそのときにはもうラオウは居ないから、
ラオウに追加したメンバは触れないぞ。
生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
869
名前:
デフォルトの名無しさん
:04/08/28 14:59
>>867
~DyingMessageが実行される時には
「お前(ラオウ)はもう死んでいる」から
ラオウのメンバを無理矢理呼び出すのもダメだよ。
870
名前:
860
:04/08/28 15:01
>>868
できれば、
>>860
のラオウやジーパンクラスのソースのようにsay1、say2のみを定義するだけで他は何も手を加えず、
後は親クラスのDyingMessageがsay1、say2を使って処理してくれるようなのが理想なんです。
できるだけ子クラスは記述しなければならないソースを減らしたいんです。
でも、確かにラオウは破棄されてしまうわけだから今回の場合は無理っぽいですね。
>生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
それはいいアイデアかもしれないっす。ありがとうございます。
871
名前:
デフォルトの名無しさん
:04/08/28 15:02
C++のデストラクタは、リソース開放のためだけに使うと思ったほうがええよ。
872
名前:
デフォルトの名無しさん
:04/08/28 18:56
>>858
std::stringの派生クラスを作る奴は糞。
873
名前:
デフォルトの名無しさん
:04/08/28 18:58
class x : public std::string
{
public: ~x() { std::cout << "x::dtor" << std::endl; }
};
main()
{
std::string* p=new x();
delete p;
}
実行結果
x::dtor
問題なし。
874
名前:
デフォルトの名無しさん
:04/08/28 19:11
>>873
環境は?
875
名前:
デフォルトの名無しさん
:04/08/28 19:24
>>874
お前が気にするのはそこなのか?
この場合問題なのはデフォルトコンストラクタしか使えんことだろ。
876
名前:
デフォルトの名無しさん
:04/08/28 19:25
>>875
実行結果
877
名前:
デフォルトの名無しさん
:04/08/28 19:28
>>876
Oh! Me としたことが釣られてしまいましたNeー!
878
名前:
デフォルトの名無しさん
:04/08/28 20:03
VC++6で.cppと.defファイルをDLLにコンパイルする方法を教えて下さい
879
名前:
デフォルトの名無しさん
:04/08/28 20:06
VCのスレ行ってください
880
名前:
デフォルトの名無しさん
:04/08/28 21:18
>>872
> std::stringの派生クラスを作る奴は糞。
まぁ、作るなとは言わんが、この場合は
tolower(std::string&);
toupper(std::string&);
っつーフリー関数にしておいた方が、何かと幸せになれる気がする。
881
名前:
デフォルトの名無しさん
:04/08/28 22:13
boost/algorithm/string/case_conv.hpp
882
名前:
デフォルトの名無しさん
:04/08/28 22:52
std::ifstreamで
std::ifstream fin("somefile");
char str[1];
fin.getline( str, 256 ); // この結果勝手に256に拡張されるっぽい
などとできてしまうのですけどこれって仕様ですか?
883
名前:
デフォルトの名無しさん
:04/08/28 23:01
>>882
未定義動作です。
884
名前:
デフォルトの名無しさん
:04/08/28 23:04
>>882
拡張をしないまま暴力的に 256 byte 書き込んできてしまうだけ
道路の拡幅工事を立ち退き交渉も予告もせずにおっぱじめるようなもの
何が起きるのかは、おそらくご想像のとおり・・・
885
名前:
882
:04/08/28 23:26
一見ちゃんと動いてるようでもやっぱり危険なコードだったんですね。
今度から気をつけます。ありがとうございました。
886
名前:
デフォルトの名無しさん
:04/08/28 23:28
>>872
uppercase_traits作るんでもいーけどさ、
stringとの混用を前提とする場合、他にどーしよーもねーだろ
887
名前:
デフォルトの名無しさん
:04/08/28 23:33
>>886
>>880-881
888
名前:
デフォルトの名無しさん
:04/08/28 23:35
>>886
そのuppercase_traitsって、何してくれるの?
889
名前:
デフォルトの名無しさん
:04/08/28 23:44
>>886
>>880
でいいやん。
なんで継承したがる?
つうか良く考えろよ。今から分かりやすく説明するからな。
お前は機能XXXを追加したくなった。
機能追加は継承だという浅はかな考えからstringから派生することにした。
class MyString : public std::string{
public:
void XXX();
/* 他のメソッドは略 */
};
こうしちゃったらさぁ、機能XXXを使うには
必ずMyStringクラスを構築する必要が出来るよな
MyString mystr=std_string_variable;
mystr.XXX();
これってかなーりムダだよな。
890
名前:
デフォルトの名無しさん
:04/08/29 01:10
>>889
ちっとも解りやすくないぞ。何が言いたいんだ?
アップキャスト後に追加メソッドを使うコンテキストでへ来ちまったら
ダウンキャストが必要になるのはどんな作りのクラスでも一緒やん。
継承を全面否定したいのなら、同意はしないが理解はできる。
891
名前:
デフォルトの名無しさん
:04/08/29 01:28
>>890
馬鹿はスルーしろよ
892
名前:
デフォルトの名無しさん
:04/08/29 01:31
STLのコンテナクラス(ここではstd::string)のデストラクタが
virtual じゃないんじゃね?
>>889
はJava厨の釣りと見た。
893
名前:
デフォルトの名無しさん
:04/08/29 01:42
いや、機能追加したいがためだけに実装継承するぐらいなら委譲で何とかしろってのがセオリーじゃないのか?
894
名前:
デフォルトの名無しさん
:04/08/29 01:43
コンテナには委譲を使うのが基本だね
895
名前:
デフォルトの名無しさん
:04/08/29 01:44
public std::string
↑
メソッド追加するだけなのにpublic継承してる所が釣り
896
名前:
デフォルトの名無しさん
:04/08/29 02:02
>>893
機能追加つーたら継承そのものやんけ
なんで「異常」な手段に拘るんだよ
897
名前:
デフォルトの名無しさん
:04/08/29 02:04
それでこそ2ちゃんねら
898
名前:
デフォルトの名無しさん
:04/08/29 02:05
↓まだ釣られる気かよ
899
名前:
デフォルトの名無しさん
:04/08/29 02:34
継承に警鐘
900
名前:
900ズサーーー!!!
:04/08/29 02:35
∩___∩ |
| ノ\ ヽ |
/ ●゛ ● | |
| ∪ ( _●_) ミ j
彡、 |∪| |
>>899
/ ∩ノ ⊃ ヽ
( \ / _ノ | |
.\ “ /__| |
\ /___ /
901
名前:
デフォルトの名無しさん
:04/08/29 02:37
900!
902
名前:
デフォルトの名無しさん
:04/08/29 02:43
以下何事も無かったかのように再開
903
名前:
889
:04/08/29 02:43
あれ、叩かれてる。説明あかんかったか。
よし、じゃあXXXとか言わずにuppercaseで書いたるか。
struct MyString : public std::string{
void uppercase();
};
ほれ、出来た。これでMyStringの大文字化はラクショーさ。
ああだけど、std::stringを使ってる部分もあるんだった。
これも大文字化しないといけない。
継承で機能追加
MyString mystr=std_string_variable;
mystr.uppercase();
std_string_variable=mystr;
外部関数で機能追加
uppercase(std_string_variable);
これでどうやろう?
基本的に継承は仮想関数のオーバーライドのためか
protectedなメンバに触りたい時くらいにしか使うべきではない。
904
名前:
デフォルトの名無しさん
:04/08/29 03:03
>>903
ヘ(_ _ヘ)☆\( ̄なんでやねん!
>MyString mystr=std_string_variable;
おまえ追加機能つかうちゅーてる時に予めアップキャストしとくんかい
アフォ言いな、比べ方の条件がちゃうやないけ!
905
名前:
デフォルトの名無しさん
:04/08/29 03:06
このアホさ加減
Java厨っぽいな
継承悪
コンポジットサイコーみたいな
思考停止したデザパタ厨
906
名前:
889
:04/08/29 03:09
>>904
?
じゃあstd_string_variableを大文字化するにはあんたならどうするん?
てかさっきから気になってたんやけど、アップキャストなんてしとらへんよ
アップやないし、そもそもキャストでもない
>>905
オレのことじゃないよな。俺は外部関数使えいうとるし
907
名前:
889
:04/08/29 03:13
ていうか、マジに大文字化機能を追加するには
std::stringを継承して、そのサブクラスにメンバ関数追加するのが一番だと思ってるんか?
908
名前:
デフォルトの名無しさん
:04/08/29 03:13
>>906
ああ、確かにstd_string_variableの定義を隠したままだねw
909
名前:
デフォルトの名無しさん
:04/08/29 03:15
>>907
同じことじゃん、所詮はthisの渡し方
色んな書き方ができる中で今回はどれって選ぶだけ
910
名前:
889
:04/08/29 03:32
>>908
定義?
std::string std_string_variable;
これでいいのか?
>>909
いやいや同じじゃないよ。
継承メンバ関数追加バージョンのuppercaseはstd::stringに対しては使えないんだよ。
継承メンバ関数追加を他の2、3人の奴がやってみ
A君は大文字化を追加したUppercaseStringを作った
B君は最後の文字を取り除く機能を追加したChopStringを作った
C君はその文字列をurlエンコードする機能を追加したURLEncoderStringを作った
じゃあ、大文字化の機能と最後の文字を取り除く機能とurlエンコードする機能全部を使いたいとき
一体どれを使ったらいいんだい?
外部関数でその機能を作ればこんなアホな自体にならないと思うけど。
911
名前:
デフォルトの名無しさん
:04/08/29 03:39
>>910
>これでいいのか?
ああ、それでいい。
派生クラスで protected にアクセスできなくなるのと
同根の仮定を勝手に持ち込もうとしていることが判ったからな
また3人て新たな仮定を追加するのかよ、いい加減にしろや
色んな書き方ができる中で今回は継承を選ばないって場合の例ばかり持ち出しては
継承そのものを否定しようとする態度はよくわかった
912
名前:
デフォルトの名無しさん
:04/08/29 03:44
>>910
3人でよけりゃ仮想継承って手もあるなw
913
名前:
デフォルトの名無しさん
:04/08/29 03:49
別に外部関数の方がよりよく実装できるというあんたの主張にケチなんかつけてない
だから880には噛み付いてない
さっきも言ったがあんた自分の態度に思い当たるフシあるんじゃないの?
914
名前:
889
:04/08/29 03:50
>>911
>継承そのものを否定しようとする態度はよくわかった
あれ?継承そのものを否定なんてしてないけど?
というか、オレは継承しまくり人間だよ。
実装継承もよくするしね。template<class T> class A : public T とかもしまくり。
ただ今回のケース、(
>>854
ね
は継承してメンバ関数追加 (
>>858
ね
は愚の骨頂やん?
だからいってるんやけど?なんか気に障った?
ヘタな説明にイラついたんやとしたらあやまるわ。ゴメン。
915
名前:
デフォルトの名無しさん
:04/08/29 03:52
洋書の著者にありがちな態度でもある罠
916
名前:
デフォルトの名無しさん
:04/08/29 03:54
>は愚の骨頂やん?
あんたのキャラクタか
917
名前:
889
:04/08/29 03:57
>>913
じゃあなんでオレに噛み付いたんだよ。
>さっきも言ったがあんた自分の態度に思い当たるフシあるんじゃないの?
聞いてないし、フシも無い。
>>916
はは、関西弁なんて知らんからな。酷く疲れたぜ。
918
名前:
デフォルトの名無しさん
:04/08/29 07:36
919
名前:
デフォルトの名無しさん
:04/08/29 08:12
>>890
890 が ToLowerCase, ToUpperCase を追加した MyStringUL を作った。
俺が EUC, SJIS の相互変換できる MyStringES を作った。
で、両方の機能が使いたくなったらどうする? 気がつくと似て非なる
互換性のない文字列型がたくさん出来てることになりかねんぞ。
ねじ・くぎのような「部品」として使うクラス、プログラミング言語 C++ で
言うところの具象クラスは、可能な限り安易な仕様を早期に固めて、
安易な拡張はしない方が良い。まして継承は最悪の選択肢の一つだ。
920
名前:
デフォルトの名無しさん
:04/08/29 09:14
>>919
virtual で多重継承して、C++の繊細さを堪能するというのもアリだと思うぞ。
堪能ってのは、実質デバッグの堪能だけどな。
ま、無理ではない。
921
名前:
デフォルトの名無しさん
:04/08/29 09:21
ま、普通、自分で作るなら、
iterator使ったgeneric function書く。> toupper
922
名前:
デフォルトの名無しさん
:04/08/29 09:39
>>920
すでに MyStringUL 使って書かれてるコードが大量にあったら、MyStringES に
クロスキャストするの? それは死にそうだ。
923
名前:
デフォルトの名無しさん
:04/08/29 09:57
汎用ライブラリじゃないなら、普通はそのプロジェクト内だけで使う。
890 が ToLowerCase, ToUpperCase を追加した MyString を作った。
俺が EUC, SJIS の相互変換できる機能を、 MyString に追加した。
となるわな。インフラグループとかが、普通にやってることだ。
924
名前:
デフォルトの名無しさん
:04/08/29 10:17
std::string を継承する
フリー関数を作る
どちらかでしか実現できないことなら仕方ないが、どっちでも実現できて
一方にはかなり痛いデメリットがある場合には、選択肢は自ずと決まると
思うんだが。
925
名前:
デフォルトの名無しさん
:04/08/29 10:58
>>923
機能追加はなんでもかんでも継承だ、という安直な考えを持った、
オブジェクト指向習い始めて3日目くらいの奴がそのグループに多いとやっちゃうわな。
だけどそんなフツウを、世の中のフツウと勘違いしたらダメだ。
926
名前:
デフォルトの名無しさん
:04/08/29 11:14
>>924-925
とりあえずやってみたらって言うのをずいぶん調子に乗って拡大解釈してるな、おまえ
選択以前のことを言ってるところへあーしろこーしろと思考まで代行してくれなくていいんだよ
それとも最後まで代行をやり通す責任感があって言ってるのか?
人が自分で物事を考えるときに金切り声で騒ぎ立てるのがただうるせえんだよ
物作ってるより人に暴言吐いてる方が楽しい奴が何か憶えたのを使いたくてこっち来たのか?
927
名前:
デフォルトの名無しさん
:04/08/29 11:17
>>926
何切れてんだお前?
責任とって欲しいならそもそも2chに来るなよ。
928
名前:
デフォルトの名無しさん
:04/08/29 11:19
お前のプロジェクトには、カスタマイズされた文字列クラスもないのかよ。
文字列操作系のグローバル関数満載かよ。
どんなプロジェクトだよ(w)
929
名前:
デフォルトの名無しさん
:04/08/29 11:22
930
名前:
デフォルトの名無しさん
:04/08/29 11:24
現在激しい電波を受信しています。ご注意ください。
931
名前:
デフォルトの名無しさん
:04/08/29 11:25
932
名前:
デフォルトの名無しさん
:04/08/29 11:27
多重継承のメモリ解放で疑問があります
class A { ... };
class B { ... };
class C : public A, public B { ... };
A, B, C全て仮想デストラクタを持っている
C* pc = new C;
B* pb = pc;
delete pb;
デストラクタは正しく呼ばれるが、pbのアドレス(pc != pbは確認済み)でメモリが解放されておかしくなる
と思ったのですが、operator newとdeleteをオーバーライドしてトレースしてみたところ
operator deleteではpcのアドレスが来ました。
delete pb;ではpbが指すのがCのオブジェクトなのかBのオブジェクトなのか区別できないはずなのに
どうしてpcのアドレスが求めることができたのでしょうか?
933
名前:
デフォルトの名無しさん
:04/08/29 11:28
>>929-931
反論できないと荒しかよ(ゲラ
934
名前:
デフォルトの名無しさん
:04/08/29 11:28
>>932
Exceptional C++ 嫁
935
名前:
デフォルトの名無しさん
:04/08/29 11:38
>>926
浅はかな考えを指摘されたからって逆切れするなよ
>>928
お前の糞プロジェクトを中心にものごとを考えるなよ。
936
名前:
デフォルトの名無しさん
:04/08/29 11:39
937
名前:
デフォルトの名無しさん
:04/08/29 11:52
>>935
浅はかかどうかをお前が決めてやらなくていいんだよ
自分の設計に同意を求めたくて余裕なくしてるのはお前だろ
938
名前:
デフォルトの名無しさん
:04/08/29 11:54
939
名前:
デフォルトの名無しさん
:04/08/29 11:54
>>932
MSVCの例だが。
ttp://www.microsoft.com/japan/msdn/vs_previous/visualc/techmat/feature/jangrayhood/
940
名前:
デフォルトの名無しさん
:04/08/29 11:58
>>937
明らかに継承の方が劣ってたじゃん。
>自分の設計に同意を求めたくて余裕なくしてるのはお前だろ
この一文がどっから出てきたのかわからないけど、そっくりそのままお返しします。ノシ
941
名前:
デフォルトの名無しさん
:04/08/29 12:01
942
名前:
デフォルトの名無しさん
:04/08/29 12:17
>>940
>この一文がどっから出てきたのかわからないけど
じゃ、何を必死になってるんだよ
943
名前:
デフォルトの名無しさん
:04/08/29 12:20
>>942
必死なのはお前だw
なんだよ
>>926
は
文面が必死すぎ、余裕無さ過ぎ
944
名前:
デフォルトの名無しさん
:04/08/29 12:20
>>942
必死になっているのはあなた一人に見えます。
あなたが「必死だな」と判断したのはどのレスですか?
レス番で教えてください。できれば理由も添えてください。
945
名前:
デフォルトの名無しさん
:04/08/29 12:20
さっきからageてる人が、口調からしても必死に見える。
946
名前:
デフォルトの名無しさん
:04/08/29 12:22
どっちも必死だよ、外でやっとくれ
947
名前:
デフォルトの名無しさん
:04/08/29 12:22
かぶりまくったw自演認定されそう
948
名前:
デフォルトの名無しさん
:04/08/29 12:22
継承の美しさを追求するあまり、
工数が増えたりするのはアフォらしいってのは、
みんな賛成してくれるだろ?な?駄目?
949
名前:
デフォルトの名無しさん
:04/08/29 12:26
950
名前:
デフォルトの名無しさん
:04/08/29 12:30
>>944
>>944
(・∀・)ジサクジエーン
951
名前:
デフォルトの名無しさん
:04/08/29 12:46
継承って美しいか?
むしろ泥臭い。
最適解なら泥臭くても使う。
それは継承でもグローバル関数でも変わらない。
952
名前:
デフォルトの名無しさん
:04/08/29 12:54
>>928
STL はコンテナ系も便利だが <algorithm> も便利だよ。
953
名前:
デフォルトの名無しさん
:04/08/29 12:55
うわーい。こんな雰囲気なら漏れさんでも飛び込み参加できそうな予感。
class MyConstants
{
static const std::string TEST_TEST1;
static const std::string TEST_TEST2;
static const std::string TEST_TEST3;
}
こういうクラスから継承するときはどうするのが普通なの?
private virtualあたり?
class MyTest : public MyTestAbstract, private virtual MyConstants
{
}
教えてね♪
954
名前:
デフォルトの名無しさん
:04/08/29 12:56
>>953
ポリシークラスでググる。
955
名前:
デフォルトの名無しさん
:04/08/29 13:00
オブジェクト指向プログラミングでいうところの継承と、
C++でいうところのclassの継承は
似てるようで全然違うよ。
手段と目的を履き違えないようにね☆
956
名前:
デフォルトの名無しさん
:04/08/29 13:08
>>955
何が違うの?
C++のクラスはOOPLのクラスと同じように扱う事もできるのに。
957
名前:
デフォルトの名無しさん
:04/08/29 13:10
>>956
Java厨はスルーしろ
958
名前:
デフォルトの名無しさん
:04/08/29 13:12
>>C++のクラスはOOPLのクラスと同じように扱う事もできるのに。
扱うこと「も」できるのに。
この「も」が重要。
959
名前:
デフォルトの名無しさん
:04/08/29 13:17
似てるようで全然違うよ。
~~~~~
960
名前:
デフォルトの名無しさん
:04/08/29 13:17
templateと組み合わせたgenericな・・・というのは詭弁。
違いはせいぜいスタックに生成できる事と、デストラクタの存在くらいなもんだ。
961
名前:
デフォルトの名無しさん
:04/08/29 14:02
>>955
>手段と目的を履き違えないようにね☆
無粋なやっちゃな、そこを敢えて履き違えるのが粋ってもんだろ?
962
名前:
デフォルトの名無しさん
:04/08/29 14:07
Java厨はスルーね
963
名前:
デフォルトの名無しさん
:04/08/29 14:42
>>961
えーそれだと学生みたいでヤだ
964
名前:
デフォルトの名無しさん
:04/08/29 14:48
>>963
プロが敢えて履き違えるのが興
965
名前:
デフォルトの名無しさん
:04/08/29 15:01
>>964
上司がPGあがりのPMだったら、厨房扱いされて査定に響く怖れアリ。
966
名前:
デフォルトの名無しさん
:04/08/29 15:20
template <typename T>
class C{ ... };
を、T を省略して
template <typename>
class C{...};
と書く事って認められてます?
テンプレートパラメータに template 入れるときに省略したいんだけど…
967
名前:
デフォルトの名無しさん
:04/08/29 17:43
>>966
こんなの?
template <typename T, template <typename> class U>
struct Hoge {
};
968
名前:
デフォルトの名無しさん
:04/08/29 18:11
>>967
そうです
969
名前:
デフォルトの名無しさん
:04/08/29 18:32
>>966
文法上は問題ない。
970
名前:
マイク
◆yrBrqfF1Ew
:04/08/29 20:05
>>955
何が全然違うんだ?
971
名前:
953
:04/08/29 22:27
>>953
でMyConstantsからの継承方法について
質問した者ですが……
すいません、
>>954
さんの言われたとおり
「ポリシークラス」でぐぐったのですが、
関係しそうなのは見つけられませんでした。
もう少しだけ詳しく教えて頂けませんか?
972
名前:
デフォルトの名無しさん
:04/08/29 23:32
>>971
たぶん質問の意図を理解できた奴はいないと思われ。
973
名前:
953
:04/08/30 23:20
>>972
そ、そうですか。。。
定数だけ宣言・定義しているクラスを他のクラスに
継承させる場合、どういう風にするのが正しいのか
知りたいのです。
Javaではこういう場合 implements を使いますが、
C++ ではどうすればいいのかはっきりと分かりません。
private virtual でも動いてはいるのですが、(
>>953
)
きちんとした裏付けがあれば、、、と思ったわけです。
974
名前:
デフォルトの名無しさん
:04/08/30 23:32
>>973
そもそもそんなクラスは作らないのが普通。
975
名前:
デフォルトの名無しさん
:04/08/31 00:01
>>973
わざわざそんなクラスを使う場合には、定数を付け替える意図アリと見て、ポリシークラスとしてパラメータ化して
<template class T> class MyTest : public MyTestAbstract, T { ... };
などして、使う側では MyTest< JPY_YeildRate > とか MyTest< USD_YeildRate > するんデネーノ。
という気がします。
private 継承、 public 継承は別に適切な方を使えばヨシ。
976
名前:
デフォルトの名無しさん
:04/08/31 00:49
>>973
private継承、virtual継承の仕様を知らずに使ってるの?
仕様さえ知ってればそれで裏付けになるんじゃないの?
977
名前:
953
:04/08/31 01:10
>>974-975
普通はこういうクラスは作らないものなんですか。。。
せっかくなので今の状況を説明しておきます。
あくまでイメージとして見てください。
class MainManager {
void registFoo(Foo & foo) {
_fooByFooNameTable.put(foo.getClassName(), foo);
_fooByTypeNameTable.put(foo.getTypeName(), foo);
_fooByBarNameTable.put(foo.getBarClassName(), foo); }
Array<Hashtable> enumerate(type); // 外部API
Hashtable getvalue(type, hashtable); // 外部API };
class Foo {
enumerateBarList();
createBar(Hashtable);
getClassName();
getTypeName();
getBarClassName(); };
class Bar {
toHashTable();
getClassName(); };
FooAbstract : public virtual Foo;
BarAbstract : public virtual Bar;
MyFoo : public FooAbstract;
MyBar : public BarAbstract;
YourFoo, YourBar, HisFoo, HisBar, HerFoo, HerBar, ...
と、こんな具合のクラス群があります。(続く)
978
名前:
953
:04/08/31 01:12
MainManager ----------------|
--(uses)--> Foo --(creates/uses)--> Bar
外部からMainManagerが呼び出されると、対応するFooが呼ばれます。
MainManager::enumerate(type) -> Foo::enumerateBarList()
MainManager::getvalue(type, hashtable) -> Foo::createBar(hashtable)
Fooの側ではenumerateBarList()でvalueをどっかから
取り出してきて一つ以上のBarを作成するか、
createBar(Hashtable)で既存のhash tableから
一部を読み出してそれを元にBarを作成します。
で、Barの側ではtoHashTable()を呼ばれると
自分を元にhash tableを作ります。
Barは内部的にはさまざまなところで使われます。
内部的にはもっぱらBarのインスタンスをやりとりしますが、
外部のAPIのからみがあってhash tableの操作は必要です。
で、この場合 KEY_NAME_A, KEY_NAME_B とかの定数を
両方のクラスで共有しないとすると、たとえばBarクラスで
定義して、Fooクラスで使うときにはBar::*としなければ
いけなくなってしまいます。
979
名前:
953
:04/08/31 01:13
さらに、Fooのインスタンス (Single) はMainManagerクラス内に
hash tableで登録されていて、Fooのクラス名、Barのクラス名、
あるいは外部APIのtype名で呼び出せるようになっています。
(ここでクラス名は単に識別名の役目)。
そのためにFooでは自分のクラス名、Barのクラス名、type名を
定数として持っておきたいんですが、同時にBarでも自分自身の
クラス名(識別名)は知っておきたいのです。
この場合やはり両方のクラスで同じ定数を共有したいと思います。
さらにさらに、実はFoo、BarのほかにBazクラスなども出てきそうです。
となると、やはりMyConstans, HisConstants等があったほうが
便利だと思うのです。
さらにさらにさらに、My*, Your*, His*, Her* クラスたちの大枠を
XMLファイルから自動生成するCode Generatorを作って、
includeを活用して人力の部分を少なくしようという計画も進行中です。
なので (機械化を楽にするためにも) 多少クラスは増えても
各々がシンプルになればと思っています。
定数を共有するためにもっといい方法があればご教示ください。
>>975
さんの「ポリシークラス」は、当てはまる部分では役立ちそうな
情報だと思いましたが、今回のケースではそこまでする必要もなさそうです。。
980
名前:
デフォルトの名無しさん
:04/08/31 01:14
作成したexeファイルを、Windowsのエクスプローラから
実行してみると、コマンドプロンプトが一瞬表示されて
直ぐに終了してまうのですが、こうやれば
#include <stdio.h>
main() {
printf("Hello!");
rewind(stdin); //追加行:標準入力を初期化する
getchar(); //追加行:一文字入力を待つ
return 0;
}
一文字打つまで終了しないらしいのですが、一瞬で終了してしまいます。
何故なのでしょうか?何処か違っていたら訂正お願い致します。
981
名前:
953
:04/08/31 01:17
あ、なんかregistFooでポインタのはずがリファレンスを
書いちゃってますけど、あくまでイメージということで。。。
982
名前:
デフォルトの名無しさん
:04/08/31 01:19
ずれていたました、すみませんこうでした
#include <stdio.h>
main() {
printf("Hello!");
rewind(stdin); //追加行:標準入力を初期化する
getchar(); //追加行:一文字入力を待つ
return 0;
}
983
名前:
デフォルトの名無しさん
:04/08/31 01:46
>>982
rewind(stdin); が禿しく実装依存。標準ではファイルポインタを戻せない
コンソール入力に対しては未定義動作。ファイルにリダイレクトされて
いればいいが。
取り除いてやってみろ。それからC++ではなくCスレに行った方が幸せになれる。
984
名前:
デフォルトの名無しさん
:04/08/31 02:09
つーか、privateメンバしかないclass作って何が楽しいの?
985
名前:
デフォルトの名無しさん
:04/08/31 02:11
>>977-
何の因果か知らないけども、あまり正気の沙汰とは思えない状態だな。
定数を共有するいい方法があったとしても、その混沌ぶりの前では焼け石に水と思われ。
結局定数なんだったらアクセス指定緩くても安全なわけで、
namespace My/Yout/His/Her とかに定義してしまえば終了な気もする。
986
名前:
953
:04/08/31 02:20
>>984
だからあくまでイメージなのです。。。
書いてあるのはほとんどpublicと思ってください。
>>985
そんなに混沌としていますか。。。すごく不安です。
namespaceはなんだか増やしちゃいけない空気です。
YourFooからYourBarの一覧を取り出すのに
HisBarを呼んできたりとかしますから。。
987
名前:
デフォルトの名無しさん
:04/08/31 02:45
>>983
助言ありがとうございました。
Cで訊いてみます詳しくは
988
名前:
デフォルトの名無しさん
:04/08/31 02:55
>>986
(953) たぶん「今の状況」を把握できた奴はいないと思われ。
989
名前:
デフォルトの名無しさん
:04/08/31 08:33
>namespaceはなんだか増やしちゃいけない空気です。
そんな空気は無い。
990
名前:
デフォルトの名無しさん
:04/08/31 09:40
>>989
>そんな空気は無い。
あるよ。
namespaceとヘッダファイル・クラスを混同してしまう人がいる。
namespaceは少ないに越した事はない。
悪意を持って他人の仕事の邪魔をしたいなら別だが。
991
名前:
デフォルトの名無しさん
:04/08/31 09:42
少ないに越した事はない≠増やしちゃいけない
992
名前:
デフォルトの名無しさん
:04/08/31 11:12
>>990
アホかお前?
993
名前:
デフォルトの名無しさん
:04/08/31 11:27
>>987
漏れなら継承を利用して定数を共有するなんて中途半端なことしないで、
virtual void DoSaveLoad(Hashtable h, bool bLoad) {
base::DoSaveLoad(h, bLoad);
if (bLoad) m_ver1 = h["Ver1"]; else h["Ver1"] = m_ver1;
};
に展開される4つのマクロ:
BEGIN_PROPERTY_EXCHANGE
DECLARE_BASE_CLASS(base)
DECLARE_PROPERTY(m_ver1, "Ver1")
END_PROPERTY_EXCHANGE
とか作るけど。3行目のようなのは必要に応じて増やす。
定数を剥き身で使ってちゃミスの元だし。
994
名前:
デフォルトの名無しさん
:04/08/31 11:53
みんな!宿題はおわったかな?!
バグもちゃんととってくれよぉ!!
995
名前:
デフォルトの名無しさん
:04/08/31 20:04
>>990
>あるよ。
無い。
>namespaceとヘッダファイル・クラスを混同してしまう人がいる。
そんな超々低能を基準にバカいってんじゃねぇ。
>悪意を持って他人の仕事の邪魔をしたいなら別だが。
悪意を持って他人の仕事の邪魔をしたくないなら、そんなキチガイ発言は止めろ。
996
名前:
デフォルトの名無しさん
:04/08/31 20:08
namespaceってウンコだよね。
ライブラリ作ってる香具師がバカだとglobal namespaceになんでも詰め込みやがるから、
こっちで
namespace UnkoLib
{
#include <library.h>
}
とかやってもうまく動かないし。
997
名前:
デフォルトの名無しさん
:04/08/31 20:19
C++ はバカ前提に作られてません。自分の首を絞めるのに十分なだけの
強度のロープを提供してます。
998
名前:
デフォルトの名無しさん
:04/08/31 20:56
まんこまんこ
999
名前:
デフォルトの名無しさん
:04/08/31 21:03
次スレは〜?
1000
名前:
デフォルトの名無しさん
:04/08/31 21:05
>>996
その場合ライブラリ作ってる香具師がウンコだよ。
■過去ログ置き場に戻る■
1-
前250
次250
最新50
DAT2HTML
0.33f Converted.