■過去ログ置き場に戻る■ 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.