■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part26
751 名前:デフォルトの名無しさん :04/01/13 01:06
いやー面白かった。

>>747
マジお疲れ。

>>748
( ´,_ゝ`)プッ

752 名前:デフォルトの名無しさん :04/01/13 01:07
>>750
そんなこと言うなよ。
もっと逃げやすい状況にしてやれよ。

753 名前:デフォルトの名無しさん :04/01/13 01:08
そろそろ 釣れた(藁 が来そうな悪寒

754 名前:デフォルトの名無しさん :04/01/13 01:10
>>748
> 引数が組み込み型かどうか判定する機能がtemplateにないから
template <typename T> struct is_primitive_type { static bool const value = false; };
#define D_(type) template <> struct is_primitive_type<type> { static bool const value = true; }
D_(char); D_(signed char); D_(unsigned char); D_(unsigned short);
D_(short); D_(int); D_(unsigned int); D_(long); D_(unsigned long);
D_(float); D_(double);
#undef D_

#include <iostream>
struct foo {};
int main()
{
std::cout << is_primitive_type<int>::value << std::endl;
std::cout << is_primitive_type<foo>::value << std::endl;
}

ポインタかどうかを判定するのは、もっと部分特殊化で済むからもっと簡単。
この辺参照。

ttp://www.boost.org/libs/type_traits/index.htm


755 名前:デフォルトの名無しさん :04/01/13 01:13
釣れたの前に自分以外は自作自演だと言い張るパターンが多い。


756 名前:デフォルトの名無しさん :04/01/13 01:17
>>754
long double を忘れてるべ。

757 名前:デフォルトの名無しさん :04/01/13 01:17
・相手は一人症候群
・自分は間違ってない症候群
・自分の文章が悪いのではなく、相手の読解力が無い症候群
・自分が最後の発言にならないと気がすまない症候群

758 名前:デフォルトの名無しさん :04/01/13 01:25
【上級者です】知ったか厨の法則【たすけて】

759 名前:デフォルトの名無しさん :04/01/13 01:30
>>756
げ、long double も標準規格の範疇だったのか。あと bool, wchar_t も脳内で
補完しといてね。

760 名前:デフォルトの名無しさん :04/01/13 07:22
>>717
>>720
これってつまり
Cでは読み込みと書き込みのポインタを一つで扱うが
C++では読み込みと書き込みのポインタ(?)を別々に扱う
ってことでいいのかな?

761 名前:デフォルトの名無しさん :04/01/13 15:51
>>760
むしろCの方がそうなってなかったのが不思議。

762 名前:デフォルトの名無しさん :04/01/13 18:43
>>761
テープドライブを読み書きするときとか。

763 名前:デフォルトの名無しさん :04/01/13 18:49
>>762
ああ、そう言えばCの一番古い奴は1972年頃に生まれたんだな。
scanf()関数はその時代の名残りで、それをキーボード入力用
に使うといろいろ不都合が出るからできるだけ使うなと言うように
なったっけ。そうでなくてもバッファオーバーランの危険性があるし。

FORTRANもパンチカード時代の名残りがあるしな。


764 名前:デフォルトの名無しさん :04/01/13 23:29
テープに限らず、シーケンシャルな記録デバイスしか
無かった時代があったんだから仕方なかんべ。

765 名前:デフォルトの名無しさん :04/01/13 23:30
>>745
うーぬ。解決しません。
とりあえずレスありがとうございましたの言葉だけ。

766 名前:デフォルトの名無しさん :04/01/14 01:02
すみません配列を現そうとソース作ってたら挫折しますたヘタレです
#include <stdio.h>
main()
{
int a[5]={1,2,3,4,5};
for(a=0:a>5;a++){
a++;
}
printf("%d\n",a[5]);
}

はっきり言って自分何がやりたいのか意味不明です
頭がおかしいんでしょうか


767 名前:デフォルトの名無しさん :04/01/14 01:08
>>766
適当な入門書を一冊じっくり理解できるまで読むことをお勧めします。

768 名前:766 :04/01/14 01:09
なるほどキチガイでした
入門書を今日買ってきて読んでみます

769 名前:デフォルトの名無しさん :04/01/14 01:26
>>766=768

次くるときは、せめて>>766がC++のソースにすら
なっていないことはわかるようになってね。


770 名前:766 :04/01/14 02:27
>>769
そうですね何しろエラーが出て実行できませんから

771 名前:デフォルトの名無しさん :04/01/14 11:25
struct Foo
{
static const int i=0;
static const int j=1;
}foo;

と宣言した構造体にアクセスするとき、
Foo::i とする方法と foo.i とする方法があると思いますが、
何がどう異なるのでしょうか?

両者の文法上の意味はわかるのですが、
静的メンバ変数のみの構造体のインスタンスなど、想像も出来ないのです・・・。
デフォルトコンストラクタが暗黙のうちに作られて何もせずに終わりでしょうか?
しかもインスタンスから静的メンバ変数にアクセスできるのも意味不明ですし・・・。

772 名前:デフォルトの名無しさん :04/01/14 11:47
>>765
コンパイラは何を使った?BCC5.6.4ではちゃんとコンストラクタが
呼ばれるぞ。

773 名前:デフォルトの名無しさん :04/01/14 11:48
Foo *p = 0;
p->i = 0; // ← thisにアクセスしないので落ちない

ってだけ


774 名前:デフォルトの名無しさん :04/01/14 12:51
>>771
静的メンバ変数はクラスのインスタンスを持たなくても存在している。

775 名前:デフォルトの名無しさん :04/01/14 13:25
>>771
乱暴な言い方すると
Fooという名前空間の中のグローバル変数。

776 名前:デフォルトの名無しさん :04/01/15 00:31
>>774 >>775
お返事ありがとうございます
そこまでは分かるのですが、なぜクラスのインスタンスから静的メンバ変数に
アクセスできるのかが良く分からないのです。
静的メンバ変数はクラスのインスタンスを持たなくても存在しているのは理解しています、
でも、何でインスタンスから参照することが出来るのでしょう?
まったく別の概念で、別の場所にある変数ではないのでしょうか?
非常に危険極まりないことだと思うのですが・・・

インスタンスから静的メンバ変数にアクセス出来ないようにする方法はないのですか?
もし出来ないのなら、なぜ出来ないのでしょうか?
そして、どのようなイメージで理解すればよいのでしょうか?

777 名前:デフォルトの名無しさん :04/01/15 00:39
メモリ配置的には確かにその通りなんだが、
オブジェクト指向的にその方が有用なこともある。
たとえば

class fixed_square {
public:
static int size;
};

class variable_square {
public:
int size;
};

としたとき(実際にはアクセサはさむが)
どちらもインスタンスから同じインターフェイスでアクセスできる。

778 名前:デフォルトの名無しさん :04/01/15 00:48
776は、
なぜ、Class::Staticsだけではなく、instance.Staticsでも
アクセスできるんだ危ないじゃないか、といいたいのでは?

779 名前:デフォルトの名無しさん :04/01/15 00:54
>>776
危険を承知で静的メンバ変数が必要な理由があるから。
インスタンスから静的メンバ変数にアクセスできないとしたら、
そりゃメンバ変数じゃないでしょ。

例えばインスタンスを10000個作ったとしても、静的メンバ
変数の実体は1個だけで、どのインスタンスから参照しても
同じに見える。これを利用して今いったいいくつのインスタ
ンスがあるのかを常に記録しておける。他にもいくつか利用法
がある。

780 名前:デフォルトの名無しさん :04/01/15 00:56
>>778
あら、それだったら静的メンバ変数をprivate属性にしちゃえば
いいだけの話では。

781 名前:デフォルトの名無しさん :04/01/15 01:08
>>777
おおお!そういうことでしたか。
さらには

class unit_square {
public:
const static int size=1;
};

な〜んていうふうにやっちゃうわけですね。
即レスありがとうございます。

しっかし、何も考えずに静的メンバ変数のアクセスにクラス名とインスタンス名を混在して使うと
とんでもないソースコードが生まれるわけですね・・・くわばらくわばら。

ところで、sizeof演算子をクラスに対して使った場合の正確な定義ってどこかにありますでしょうか?
プログラミング言語C++を探しても見つからなかったもので・・・

782 名前:デフォルトの名無しさん :04/01/15 01:08
>>780
それでstaticな下駄雪駄を作ると。
そういう話じゃないわけだが。

783 名前:デフォルトの名無しさん :04/01/15 01:14
静的メンバ変数は静的メンバ関数だけからアクセスする
癖を付けるのもいいかも。事実Singletonのデザインでは
そのようにしている。

但し複雑さというのは避けられないもので、静的メンバ変数
が他の箇所からほぼ同時にアクセスされる環境、すなわち
マルチスレッド環境では何らかの同期が必要となる。

784 名前:776 :04/01/15 01:15
>>778
そのとおりです

>>779
その理由でしたらClass::Staticsだけでアクセスすればよいと思うのです

>>780
そしたら外から見えないし・・・

結局のところ>>777の理由からでしょうかね?

785 名前:デフォルトの名無しさん :04/01/15 01:20
>>784
外から見えるようにするってあーた、それじゃわざわざ
静的にしろメンバ変数にする意味ないじゃん。

786 名前:776 :04/01/15 01:23
>>783
>静的メンバ変数は静的メンバ関数だけからアクセスする癖を付けるのもいいかも。
>事実Singletonのデザインではそのようにしている。
そうですね。静的メンバ変数はprivateにして、
静的メンバ変数にアクセスするpublicな関数を用意するわけですね
しかし今度はClass::StaticFunctions()だけではなく、
instance.StaticFunctions()でもアクセスできる
という問題が発生してしまいまして・・・

まあ、幾分かましではありますが。

787 名前:デフォルトの名無しさん :04/01/15 01:24
結論を手短にまとめると、>>784さんは

・クラスの静的メンバ変数が欲しい
・しかしそれはインスタンスから参照できないようにして欲しい
・しかもClass::Staticsという形でアクセスできるようにして欲しい

って所かな。そしたら、基底クラスでprotected属性で宣言し、
それを継承したクラスでのみインスタンスを作成する、という
方法ではだめなのかいな。

788 名前:デフォルトの名無しさん :04/01/15 01:28
あーprotectedにするとClass::Staticsという形ではアクセスでき
ないか。

789 名前:デフォルトの名無しさん :04/01/15 01:46
staticメンバ関数でアクセス方法だけ制限してやりゃええ話なのでは

790 名前:デフォルトの名無しさん :04/01/15 01:52
>>789
詰まる所そうなりますね。それ以上はC++を使う人の責任で、
って事で。

791 名前:デフォルトの名無しさん :04/01/15 01:56
static メンバ関数に
インスタンスからアクセスできなくする法はちと無理。
static と非 static でオーバーロードもできないし。

792 名前:デフォルトの名無しさん :04/01/15 01:59
ああ、int型に限っては一つだけ方法がある。
クラス内 enum 値はインスタンスから参照できなかったはずだ。

793 名前:デフォルトの名無しさん :04/01/15 02:09
>>792
こういう事でなくて?どうやってアクセス禁止になるんだろう。

#include <iostream>

class A {
public:
 enum E {a, b, c};
};

int main()
{
 A a;
 std::cout << a.b << std::endl;
}


794 名前:デフォルトの名無しさん :04/01/15 02:18
無名でもできなかったっけ……
すまん、じゃあ勘違いだ

795 名前:デフォルトの名無しさん :04/01/15 02:25
それじゃこんなのはどうだろ?
コンストラクタを返り値のように受けるのは微妙な問題があるけど
見た目上は要求の物に近いんでない?
複数の異なった値が欲しければ int に関しては
template < int n > と typedef を組み合わせれば
簡単なフレームワークで出来るはずだ。

class A {
public:
struct value{
operator int() const {
return 0;
}
};
};

int main() {
int v = A::value();
A a;
v = a.value(); // ここでエラー
}

796 名前:デフォルトの名無しさん :04/01/15 02:35
テストコード。一応、gcc3.2(MinGW)で動作確認済み。

#include <iostream>

class Integer {
public:
friend struct setValue {
explicit setValue(int n) { n_ = n; }
};
friend struct getValue {
operator int() const { return n_; }
};
private:
static int n_;
};

int Integer::n_ = 0;

int main(void) {
Integer::setValue(4);
std::cout << Integer::getValue() << std::endl;
Integer i;
//i.setValue(4);
//std::cout << i.getValue(4) << std::endl;
}


797 名前:デフォルトの名無しさん :04/01/15 02:52
>>795>>796
クラスのメンバに変換演算子のみを持つとそれは
初期化の時しか参照できないんだね。初めて知った。
しかもそれは一時変数で、目的の変数に代入が終了
したら消滅する。よくできたもんだ。

しかし>>796は残念だな。VC7.1でコンパイルできない。

c:\Documents and Settings\**\My Documents\Visual Studio Projects\Conversion\Conversion.cpp(9) : error C2391: 'Integer::setValue' : 'friend' は型定義中には使えません。
c:\Documents and Settings\**\My Documents\Visual Studio Projects\Conversion\Conversion.cpp(12) : error C2391: 'Integer::getValue' : 'friend' は型定義中には使えません。
c:\Documents and Settings\**\My Documents\Visual Studio Projects\Conversion\Conversion.cpp(24) : fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。

798 名前:デフォルトの名無しさん :04/01/15 02:54
>>797
エラーメッセージ読んだ感じ
定義後に friend 宣言すれば問題ないんとちゃう?
(それできなかったら多くの内部型が困りそうだ)


799 名前:デフォルトの名無しさん :04/01/15 03:04
>>798
結果だけ書くと、VC7.1はfriend宣言取ってもコンパイルできた。
事後のfriend宣言でも通ったけど、gccと挙動が違う。

800 名前:デフォルトの名無しさん :04/01/15 09:55
>>784の件についてだが
コンストラクタをprivateとかにしてインスタンスを生成できなくすればいいんでないの?

801 名前:デフォルトの名無しさん :04/01/15 15:20
>>800
いや、インスタンスが生成できて、かつstaticなメンバ変数
にインスタンスからアクセス不可能にしたかったようです。

802 名前:デフォルトの名無しさん :04/01/15 16:46
a.b とか pa->b という記法で static member変数を参照できる、
というのがキモチ悪かったっていうことだと思います。

漏れも少しキモチ悪い。virtual static member variable なんてのが
あるならともかく。

803 名前:デフォルトの名無しさん :04/01/15 18:59
functionはともかくvariableはないだろw

804 名前:デフォルトの名無しさん :04/01/15 19:26
>>802
気持ち悪いか。感覚の違いだな。
俺はそう書けて当然だと思う。統一が取れてて。

805 名前:デフォルトの名無しさん :04/01/15 21:32
質問です。intやcharで定義する変数名は英語ならどんな名前でもいいんですか?

int ten;
int x;

char name;
char a;

are you ok?

806 名前:デフォルトの名無しさん :04/01/15 21:34
>>805
名前付けルールはそのコードを維持する人が良いと思えば
何語だってかまわんよ。使える文字を使ってさえいれば。

807 名前:デフォルトの名無しさん :04/01/15 22:02
>>806
thank you

808 名前:デフォルトの名無しさん :04/01/15 22:09
>>803
>functionはともかくvariableはないだろw

いや、こんな感じ。vtbl みたいなクラス毎の変数用ストレージ。
struct A {
 virtual static const int object_id = ID_A;
};

struct B : public A {
 virtual static const int object_id = ID_B;
};

A* pa = new B;
pa->object_id // ID_B になる

809 名前:超初心者 :04/01/15 22:51
プログラミングの仕方が全然わからないんですが○×ゲームでかならず引き分けるプログラムをどのようにプログラミングしたらいいか教えていただけませんでしょうか。

810 名前:デフォルトの名無しさん :04/01/15 22:56
「必ず引き分ける」なんて結果のみを期待されても答えられない。
その手の手数の少ない対戦ゲームなら
素直にMAX-MIN法を使ってゲーム木を探索して手を決定するとか。



811 名前:デフォルトの名無しさん :04/01/15 23:08
>○×ゲーム
3*3の三目並べのこと?
ならウォー・ゲームでも繰り返し鑑賞しなさい

812 名前:デフォルトの名無しさん :04/01/15 23:58
おながいします。
テンプレートの引数にテンプレートを指定することはできないのですか?
CList<CArray<CPoint,CPoint>> m_list;
みたいな。。。

813 名前:デフォルトの名無しさん :04/01/16 00:07
>>812
できます。

814 名前:812 :04/01/16 00:10
レスありがとうございます。
VC++6.0なのですが
error C2146: 構文エラー : ',' が、識別子 'm_list' の前に必要です。
みたいなエラーが出てコンパイルできないのですが...

815 名前:デフォルトの名無しさん :04/01/16 00:11
だまされないように。できません。

816 名前:デフォルトの名無しさん :04/01/16 00:18
×:>>
○:> >

817 名前:デフォルトの名無しさん :04/01/16 00:20
VC6ではテンプレートのネストはできない。
もっと新しいコンパイラを使え。

818 名前:デフォルトの名無しさん :04/01/16 00:25
できるっつーの

819 名前:812 :04/01/16 00:26
>>816
どうもありがとう(TT)
でも今度はリンクができなくなってしまったのですが・・・


820 名前:812 :04/01/16 00:30
できました。
教えてくださったみなさんどうもありがとう。。。

821 名前:デフォルトの名無しさん :04/01/16 00:51
すみません。また812です。
別件なのですが、テンプレートクラスを含んだcppファイルを
コンパイルはできるのですが、それを使用したcppをコンパイルして
リンクしようとすると、シンボル未解決でリンクエラーになります。
何か考えられる原因はあるでしょうか?

822 名前:デフォルトの名無しさん :04/01/16 00:57
>>821
エラーメッセージぐらい貼れよ

823 名前:921 :04/01/16 01:00
>>822
すいません。m(__)m
通常のマングリングコードが出てシンボルは未解決ですって
いうエラーです。
というか今解決しました。hとcppにわけていたのですがhにまとめたら
うまくいきました。でもなんでなんでしょう???

824 名前:デフォルトの名無しさん :04/01/16 01:00
あらゆるtemplateは定義までヘッダにおいとかないと
たいていのコンパイラで上手くリンクまでできない。

825 名前:921 :04/01/16 01:02
そうなんですね。知りませんでした。。。

826 名前:821でした :04/01/16 01:05
遅くにどうもありがとう。。。

827 名前:デフォルトの名無しさん :04/01/16 01:21
class CObjAddr{};
class CPtrA{public: operator CObjAddr() const { return CObjAddr(); };
class CPtrB{public: operator CObjAddr() const { return CObjAddr(); };
bool operator== (const CObjAddr& lhs, const CObjAddr& rhs) { return true; }
int main()
{
CPtrA a;
CPtrB b;
if (a == b);
return 0;
}

はコンパイルできるのですが

template <typename T> class CObjAddr{};
template <typename T> class CPtrA{public: operator CObjAddr<T>() const { return CObjAddr<T>(); };
template <typename T> class CPtrB{public: operator CObjAddr<T>() const { return CObjAddr<T>(); };
template <typename T>
bool operator== (const CObjAddr<T>& lhs, const CObjAddr<T>& rhs) { return true; }
int main()
{
CPtrA<int> a;
CPtrB<int> b;
if (a == b);
return 0;
}

になると途端に==演算子を見つけられなくなります。
正確に言うと上の方のコードのoperator==にtemplate <typename T>と付けた時点(型名にはTがかかっていない状態)で
既に==演算子を見つけられなくなります。
下の状態で a == b をそのままの形で(明示的にキャストせずに)コンパイルできるようにしたいのですが
何か方法はないでしょうか?よろしくおねがいします。

828 名前:デフォルトの名無しさん :04/01/16 01:29
エラーメッセージをよく読んで } の数を数えてみることを勧める。
つーか上のコードよく通ったな。

829 名前:827 :04/01/16 03:54
>>828
ここに載せられるように簡略化したときにちょっと失敗しました。
class CObjAddr{};
class CPtrA{public: operator CObjAddr() const { return CObjAddr(); }};
class CPtrB{public: operator CObjAddr() const { return CObjAddr(); }};
bool operator== (const CObjAddr& lhs, const CObjAddr& rhs) { return true; }
int main()
{
CPtrA a;
CPtrB b;
if (a == b);
return 0;
}

template <typename T> class CObjAddr{};
template <typename T> class CPtrA{public: operator CObjAddr<T>() const { return CObjAddr<T>(); }};
template <typename T> class CPtrB{public: operator CObjAddr<T>() const { return CObjAddr<T>(); }};
template <typename T> bool operator== (const CObjAddr<T>& lhs, const CObjAddr<T>& rhs) { return true; }
int main()
{
CPtrA<int> a;
CPtrB<int> b;
if (a == b);
return 0;
}
ですね。質問の本質的内容は変わりません。よろしくお願いします。

830 名前:デフォルトの名無しさん :04/01/16 05:34
たぶん暗黙の型変換とテンプレート引数の双方のマッチングが
絡み合って適用されないんだな。

キャストをしたくないのなら、
明示的にテンプレート引数を指定して実体化させるか、
別の関数を挟むかするしかないだろ。


831 名前:デフォルトの名無しさん :04/01/16 09:30
template <typename T_>
class CPtrA
{
public:
  operator CObjAddr<T_>() const { return CObjAddr<T_>(); }

  bool operator==( const CObjAddr<T_>& rhs ) const {
    return true;
  }
};
にするとか・・・。めんどいかね・・・。

832 名前:デフォルトの名無しさん :04/01/16 15:37
class A{
public:
 virtual ~A();
 virtual func()=0;
};

class B : public A{
public:
 virtual ~B();
 virtual func();
};

みたいなクラスがあって、生成・破棄を行っているスレッドとは別にバックグラウンドで
Bのメソッドfuncを定期的に呼んでる。
バックグラウンドのスレッドがfuncを呼び出す時に
pure virtual function calledとかいうエラーが出て終了することがある。
で、Aのfuncを普通の仮想関数に変えたら出なくなった。

で、不思議に思ったんだけど、仮想関数の関数のアドレスってデストラクタで書き換わってるの?

class Bのデストラクタ

funcのアドレスをclass Aのfuncのアドレスに書き換える

class Aのデストラクタ

という理解でいい?
ちなみにVC++6.0。

833 名前:デフォルトの名無しさん :04/01/16 15:57
破棄中のオブジェクトにアクセスすんな。

834 名前:デフォルトの名無しさん :04/01/16 16:01
>>832
書き換わってるはず。
でないと

class A {
public:
 virtual ~A() { foo(); }
 void foo() { bar(); }
 virtual void bar() { ... }
};

class B {
public:
 virtual void bar() { ... }
};

{ B b; }

で A のデストラクタから B の bar が呼ばれてしまう。

835 名前:デフォルトの名無しさん :04/01/16 16:08
つーか、それ以前の問題として何の同期処理もなしに複数のスレッドから
同一オブジェクト参照してるのか?

836 名前:832 :04/01/16 16:24
>>834
class Aからvirtualなbarを呼び出した時って、
barが純粋仮想関数じゃなくてもclass Bの関数が呼ばれるの知らなかった・・・。
ありがとうございます。

>>833,>>835
Bのインスタンスをvectorに入れてて、別のほうのスレッドはそこからとってる。
Aのコンストラクタでvectorに入れて、デストラクタでvectorから外してて、
vectorへの追加・削除とvectorへのアクセスは排他してる。

class Bのデストラクタ

funcのアドレスをclass Aのfuncのアドレスに書き換える

別スレッドからfunc呼び出し

class Aのデストラクタ

という感じでこけてた。

837 名前:デフォルトの名無しさん :04/01/16 16:32
>>836
> class Aからvirtualなbarを呼び出した時って、
> barが純粋仮想関数じゃなくてもclass Bの関数が呼ばれるの知らなかった・・・。
何のための仮想関数なのかと小一時間...。

> という感じでこけてた。
そういう感じでこけること自体に問題があるのじゃ。

838 名前:デフォルトの名無しさん :04/01/16 17:37
なんで破棄が始まってるオブジェクトに
別スレッドからアクセスするのかまったく理解できないのだが

839 名前:デフォルトの名無しさん :04/01/16 18:36
マルチスレッドにはmutex使えよお・・・・そんなん常識じゃんかよ・・・

840 名前:デフォルトの名無しさん :04/01/16 18:40
クリティカルセクションでもセマフォでもいいやん

841 名前:デフォルトの名無しさん :04/01/16 19:04
ついこないだ自分も同じ現象で悩んじゃったよ。

>>838
例えば、デストラクタ中にスレッドを終了させるような仮想関数を呼びたくなったりするのよ。
確か、Javaだと平気だったと思うんだけど。

842 名前:デフォルトの名無しさん :04/01/16 19:16
Java にデストラクタってあったっけ?

843 名前:デフォルトの名無しさん :04/01/16 19:26
>>841
その例は違う話だろ。

デストラクタ中のメンバ関数(メソッド)呼び出しは
なんらおかしくない。

破棄が始まっているオブジェクトに対して
別スレッドから並行してメンバ関数を呼び出そうとするのが
ありえないって言ってるわけで。

>>842
オブジェクト破棄はVMがやるからデストラクタはないけど
終了処理を行うファイナライザを記述することはできた(はず)

844 名前:デフォルトの名無しさん :04/01/16 20:42
複数スレッドからアクセスされるオブジェクトの廃棄は
特定のスレッドでやったほうがいいと思うズラ

845 名前:デフォルトの名無しさん :04/01/16 22:35
初学者にとってCではポインタが関門であったようにC++での関門はどこですか?
継承あたり?テンプレートあたり?
始める前に”ヤマ場”を知っておきたいです。

846 名前:デフォルトの名無しさん :04/01/16 22:38
>>845
いっぱいあり過ぎる。
ストリーム、STL、クラス、継承、デザパタ(OOP一般)・・・・
被虐的な人ほどC++にはまる。

847 名前:デフォルトの名無しさん :04/01/16 22:47
#include <stdio.h>
main ()
{
int tink,mank;
mank=5;
for (tink=0;tink>mank;tink++){
printf ("チンコはマンコより大きくないとやヴぁい")
}
if (tink<mank){
printf ("セクース");
}
else{
printf ("童貞街道まっしぐら");
}
return (0);
}



848 名前:デフォルトの名無しさん :04/01/16 22:52
>>847
if(tink > mank) printf("こんな大きいの、入らないよぉ・・・\n");

849 名前:デフォルトの名無しさん :04/01/16 22:53
いくら童貞でもここまで非科学的なアフォは珍しいな

850 名前:デフォルトの名無しさん :04/01/16 22:58
>>846
やる気うせた・・・ ○| ̄|_

851 名前:デフォルトの名無しさん :04/01/16 23:00
オーバーロードだけでいいよ

852 名前:デフォルトの名無しさん :04/01/16 23:06
>>850
負けるな一茶ここにあり。
俺も最初はめげたが、BBSなどでひつこく質問を繰り返し、
自分でいくつもぢっけんする事によってだいぶ理解できた。

C++の入門書はできるだけ易しいのにした方がいいよ。

853 名前:デフォルトの名無しさん :04/01/16 23:08
そしてテンプレートにはまっていくともう抜け出せない。。。

854 名前:デフォルトの名無しさん :04/01/16 23:21
ハマルってことは、勉強してて楽しいことかな?やりがいあることかな?ワクワク♪

855 名前:デフォルトの名無しさん :04/01/16 23:22
>>854
自分にC++で理解できない所があったら腹立たしく感じる事。
こうなるまで勉強したらもうやめられない。

856 名前:デフォルトの名無しさん :04/01/16 23:50

誰かタイピングの神挑戦求む!
1位強すぎ

http://cgi.f28.aaacafe.ne.jp/~arena/daken/


857 名前:デフォルトの名無しさん :04/01/16 23:56
わからない事があったら、面倒でも実験コード書いて確かめる。
俺はそうやって覚えた。

858 名前:デフォルトの名無しさん :04/01/17 00:51
PCないし・・・

859 名前:デフォルトの名無しさん :04/01/17 00:58
>>858
は?

860 名前:デフォルトの名無しさん :04/01/17 01:18
>>858 は脳から電波を発し、
2ch を閲覧し、書き込む事が可能です。
PC なんぞ不要なのです。

861 名前:デフォルトの名無しさん :04/01/17 01:21
>>858は電脳の持ち主です。むやみに攻撃すると彼の攻勢防壁によって脳を焼き切られます。


862 名前:デフォルトの名無しさん :04/01/17 01:35
もしかして>>858はA・Iが止まらないのサーティですか?

863 名前:デフォルトの名無しさん :04/01/17 08:09
>>862
なにかと思って検索しちゃったじゃないか。
漫画のキャラなのね。

864 名前:デフォルトの名無しさん :04/01/17 09:54
他の言語を使用してWindowsアプリケーションを作成する際、
わざわざC/C++で作成した外部DLLを呼び出すメリットを
教えてもらえないでしょうか?
今他言語で作成しているのですが
C/C++の方が優れている点が分かれば
適材適所に言語を使えるなーと考えています。
よろしくお願いします。

865 名前:デフォルトの名無しさん :04/01/17 10:08
C/C++で書かれたライブラリは質量共に圧倒的だから。

866 名前:デフォルトの名無しさん :04/01/17 10:57
パフォーマンスもいいし、DLL 越しに呼べばいいだけならそうした方が(゚Д゚)ウマー


867 名前:864 :04/01/17 12:10
>>865-866
レスありがとうございます。
それでは外部DLLを呼ぶことが許されている環境では
なんでもかんでもC/C++で書いたライブラリから
呼ぶに越した事は無いという理解で正しいでしょうか?

868 名前:デフォルトの名無しさん :04/01/17 12:33
>>867
なんか話が逆のような気がするんだがな...。

目的があってプログラムを作り、理由があってその一部をDLLとして切り出すなら、
そうすればいいし。
あるいは何らかのライブラリがスタティックリンク形式とDLL形式の両方で
提供されているとき、どちらを使うべきか?...なんていうことなら、
それはそれで話は変わってくるし...。

最初からいきなり"DLLありき"で考えるのは、話が逆なんじゃないの?

なんていうか、たとえば「大学に入るために受験する」みたいな、さ。
それって何かを達成するための手段なはずでしょ。
でも、それ自体が目的になっちゃってる...。

HowToばかり詰め込んでると、応用問題ができないよ。

869 名前:デフォルトの名無しさん :04/01/17 12:36
c++で書いたほうが、ライブラリが書きやすいってだけじゃね?
書くほうにメリットがあると。
呼び出すメリットは特に無いかな?
しいていうなら、動作が早い(かもしれない)とか・・・。
自分が使ってる言語で書き直すのもめんどくさいだろうしさ。

ていうか、その言語で使えるなら、どの言語でライブラリが書かれていようが気にする必要ないんじゃね?
ただ、同じ言語で書かれたライブラリがあったらそっち使ったほうが、良いかもしれない。

ぶっちゃけ、自分が使いやすいライブラリ使えばそれでいいんじゃね?あとは、ライセンスか?


870 名前:864 :04/01/17 12:40
>>868
ちょっと紛らわしい聞き方してしまったかもしれません。
リアルに言いますと今C#でデータベースアプリ作ってるのですが
なんだか速度が遅いのでC/C++で書いて呼び出そうかと
思ったのまでは良かったのですが具体的にどの部分を
C#からC/C++に書き直すかについて考えたところ
C/C++を採用する利点というものがそもそもわかっていないことに気づき
質問させていただいた次第です。
どういう部分をC/C++で書き直すと効率的に動作速度が早くなるのかなーと
悩んでいます。
なんでもかんでもC/C++で書いた方がいいのでしょうか?
作っているソフトは今のところ個人用なので私的には
C/C++で書いてもC#で書いても構わないので迷っています。

871 名前:デフォルトの名無しさん :04/01/17 12:46
>>870
データベースアプリというのは、サーバー側、それともクライアント側?

サーバー側だと細かいパフォーマンスチューニングを行うために、C/C++ で
書くのは必須だと思うが、それ以前に SQL Server なりナンなり買ってくる方が
安上がりだろう。

872 名前:デフォルトの名無しさん :04/01/17 12:47
問題を切り分けるときには、DLLになっていた方がいいだろうな。

たとえばバグを再現する簡単なテストプログラムを作って、
「これ実行してみろ。これはオマエんとこの問題だろ?さっさと直せや、ゴルァ!」
っていう具合に、DLLだと責任の所在を明確にし易い。
でもスタティックリンクだと、明確にしずらいね。

DLLかそうじゃないかは、言語とは直接の関係はないんじゃねーの?

873 名前:デフォルトの名無しさん :04/01/17 12:48
なんで遅いのかを分析しない限りC/C++で書き直したところで無駄。

874 名前:864 :04/01/17 12:50
>>869
レスありがとうございます。
時差で見落としてしまいました。
今しがた>>870で書いてしまいましたが
既に出来ているDLLを呼ぶ、というより
C#で重いからどの部分をC/C++で書き直すと
効率よく速度アップが望めるかなーと言う意味でした。

875 名前:デフォルトの名無しさん :04/01/17 13:02
>>874
俺ならGUI以外全部C++。


876 名前:デフォルトの名無しさん :04/01/17 13:32
> C#で重いからどの部分をC/C++で書き直すと
どの部分がネックになってるのか調べろよ。


877 名前:ヽ(´ー`)ノ :04/01/17 13:39
何を期待してるのか知らんが、順番がオカシイ。

1. ボトルネックになってるところを探す
2. アルゴリズムの改良等で対処
3. ダメぽ。
4. primitive な言語を使って実装しなおすことを考える
5. 選択肢として C/C++ が挙がる

「パフォーマンス悪いから C/C++ で書き直します。どこ書き直せばいいですか?」
って言われても、答えようがない。


878 名前:864 :04/01/17 14:13
今ログ読んでて自分の聞き方が悪いなーと考え直しました。
つまりお聞きしたいのはズバリ
C/C++が他の言語と比べて速度が早いと言えるのは
主にどういう処理を行った時か、ということです。
コンパイルしてしまえばなんでもかんでも
C/C++が優秀っていう理解でいいんでしょうか?
なぜかというと今作ってるプログラムのボトルネックの部分はそのうち見つけますが、
見つけたとしてそもそもC/C++の利点を知らねば
解決方法を限定できない、って思っているからです。

879 名前:デフォルトの名無しさん :04/01/17 14:21
ネイティブコード吐けるものならどんな言語でも大して変わらないと思うけど。
一番速度に影響するのはアルゴリズムだと思うぞ。


880 名前:デフォルトの名無しさん :04/01/17 14:22
数値演算ならライブラリやコンパイラの出来の話もあるがFORTRANのほうが早い。
ある種の文字列処理ならC++よりPerlが速い場合もある。
http://dada.perl.it/shootout/
なんて結果も一例としては存在する。

ただ、OSのAPIやライブラリ、圧倒的なユーザ数に起因する情報量等、
ネイティブアプリケーションを書くならC/C++が一番無難というだけの話。

881 名前:デフォルトの名無しさん :04/01/17 14:23
>>878
いや、だから話が逆だって。先にどこにボトルネックがあるか見付けてから質問に来い。

882 名前:デフォルトの名無しさん :04/01/17 14:27
C++はガベッジコレクター使わない分、メモリ操作などが早いかもしれない。
ただデフォルトのアロケータ使ったままだと、それほど早くならないかもしれない。
あとは、ビット演算とか工夫すれば早くなる部分もあるかもしれない。
とりあえず、実験してみるしかないわな。

883 名前:デフォルトの名無しさん :04/01/17 14:35
早い→速い

884 名前:デフォルトの名無しさん :04/01/17 17:45
>>880
fortranのほうが速いというわけではなく
fortranなら最適化の妨げになる仕様がCより少ないというだけ
結局はオプティマイザの出来次第

885 名前:デフォルトの名無しさん :04/01/17 17:54
素人の書くコードなら言語に何使っても同じ
メモリ操作で面倒なバグが出ない分、C#やJavaの方がマシじゃねえの?

設計やアルゴリズムの改善程度で済ますなら、わざわざCを使う必要なし。
今の言語でそのままやればいい。

効率を考えてきっちり書くならC/C++が一番いい。

886 名前:デフォルトの名無しさん :04/01/17 17:57
並列化コンパイラを作りやすいのは Fortran だけどな。一応。

887 名前:デフォルトの名無しさん :04/01/17 18:23
最近はFortran使ってコンパイラ作ってるのか。
構文解析とかFortranでは面倒そうだが、真のプログラマは
どんなプログラムでもFortranで作る、というしな。

888 名前:デフォルトの名無しさん :04/01/17 18:42
違う違う。
Fortran 用の並列化コンパイラが作りやすいって話。

889 名前:デフォルトの名無しさん :04/01/17 18:51
最近のディフォルトのアロケータはかなり速い。
これ以上速くするには用途限定や別の制約(解放が極端に遅いとか)しなければいけないというレベルの速さだよ。

890 名前:デフォルトの名無しさん :04/01/17 19:16
何言ってんのかわからんがアロケータくらい必要なら自分で書け

891 名前:デフォルトの名無しさん :04/01/17 19:28
>>880
全体的にC/C++の早さが際だってるな。
ただソースコードを組むのに要した時間まで入れると
かなり順位が変わりそう。

892 名前:デフォルトの名無しさん :04/01/17 19:33
>>891
俺も見てみたが、delphiがしばしばbccを追い越しているじゃ
ないか。bccは最適化で手抜きしてるのか?

893 名前:デフォルトの名無しさん :04/01/17 19:49
>>892
Borland の C++ コンパイラに関しては、良い意見を聞いた覚えがないが……。

894 名前:デフォルトの名無しさん :04/01/17 20:16
>>893
Turbo-Cの時代はそこそこ良かったのに。
今じゃコンパイル速度がばかっ速だけが取り柄だよ。とほほ・・・・

その肝心のコンパイル速度もDelphiと比べると可愛そうなほど
遅いし・・・・

895 名前:デフォルトの名無しさん :04/01/17 20:22
コンパイルが早いのは最適化をしてないからだ。


896 名前:デフォルトの名無しさん :04/01/17 20:51
>>895
それじゃDelphiのコードの実行速度が速い事の説明にならないよ。
それともObject Pascalは元々最適化がしやすい構造なのか?
C++に比べると随分文法が簡単なのは認めるけど。

897 名前:デフォルトの名無しさん :04/01/17 20:54
C++ のコンパイルは他の言語に比べて普通かなり遅い。

898 名前:デフォルトの名無しさん :04/01/17 20:55
>>896
delphiってオブジェクトコードも大きくなるし
出来上がったバイナリも大して速くないけど?


899 名前:デフォルトの名無しさん :04/01/17 20:59
>>897
やっぱりそうだよね。
>>898
コンソールアプリケーションに限って言えばそうでもないみたい。
>>880を見ての感想だから。一般的にはVCLが遅いし大きいから
WinアプリならMFCなどの簡単なフレームワークの方が速いよね。

900 名前:デフォルトの名無しさん :04/01/17 21:02
>>899
もちろん処理にも拠るけど、delphiの吐くコード自体が大して速くないの。
VBでもCでもC++でも、もちろんJavaでも似たような速度のコードを吐きます
特別に「速い」と形容できる処理系はほとんど存在しません

901 名前:デフォルトの名無しさん :04/01/17 21:05
>>900
まあマシンが同じならどんなコンパイラ言語を使おうが大同小異
だからね。

902 名前:デフォルトの名無しさん :04/01/17 21:19
>>901
アセンブラ言語つかえ

903 名前:デフォルトの名無しさん :04/01/17 21:36
>>901
科学計算など、かなり重い処理だとそうでもなかったり。

904 名前:デフォルトの名無しさん :04/01/17 22:26
delphiって、最適化はレジスタ割付に毛が生えた程度じゃなかったかな。
それでも言語仕様がきっちり決まってる分、c++よりは(単純な)最適化がしやすいとか。

とはいえ、bccよりdelphiが速くなるのは(VCL関係を除くと)
引数がレジスタ渡しだから、ってのが大きいかなと思ったり。

905 名前:デフォルトの名無しさん :04/01/18 00:46
> アセンブラ言語つかえ
おせっかいですが、言葉の使い方、間違ってますよ。

「アセンブリ言語をアセンブルするのがアセンブラだ!」
...と、昔どっかにあった。


906 名前:デフォルトの名無しさん :04/01/18 00:50
「コンパイリ言語をコンパイルするのがコンパイラだ!」



あれ?


907 名前:まるだいハンバーグ :04/01/18 01:38
はいり はいり ふろ はいりふろー
はいり はいり ふろ ほっほー

908 名前:デフォルトの名無しさん :04/01/18 01:41
はいれ はいれ ふろ はいれふろー
はいれ はいれ ふろ ほっほー

風呂はいりたいよ・・・_no

909 名前:デフォルトの名無しさん :04/01/18 01:54
ニーモニックから機械語に翻訳するのがアセンブラだ。

910 名前:デフォルトの名無しさん :04/01/18 02:20
>>878=864

話が関係ないほうに流れてるからちょっと戻すけど、
「作ったプログラムが遅いから、闇雲に「速い」といわれる方法を試す」という、
あなたがやろうとしてることは新人PG or 成長しないPGがよくやる意味なし行動の
代表格だ。それで実行速度が改善されればいいが、普通はほとんど効果は無い。

ほかのほとんどの人が言う通り、まずボトルネックがどこかを探すのが先決。
「プログラムの実行速度の80%はプログラムの20%が消費している」
という有名な言葉にもあるとおり、闇雲に変更したって、実行速度に大して影響を
与えていない80%をいじくることになる。結果、「だめでした」となる。

>>なぜかというと今作ってるプログラムのボトルネックの部分はそのうち見つけますが、

後輩がこんなこと言ったら、俺だったら小一時間説教だね。


911 名前:910 :04/01/18 02:21
続き。

ここから先は全然C++と関係ないスレ違いのレスだけど、
役に立てばということで書いておく。

書いてるレベルからして、DBアプリ開発っていっても
DBエンジンを自前で書いてるとかじゃなくて、
いわゆる業務系アプリケーションのの仕事だろ。

そうだったら、9割はSQLの書き方が問題。
遅い部分を絞って、まずSQLの調査。
帰ってこないSQLがあればDBの実行計画調査して、
インデックスの設計とかを見直すのが先決だろうな。

SQLでないとすれば、ループ。DBでリレーション貼らずに、
「自前のループの中でコードから名称を取得する」みたいなことをやると確実に遅くなる。
「コードから名前を取得する関数」とかを作っているとこういう処理をしがちになる。
その関数内でコードと名前の関係をキャッシュするとかすべし。
#ただしDB側とのリアルタイムな整合性をどう取るかはまた別課題。

ま、がんばれ&スレ違い申し訳ない>スレ住人。

912 名前:デフォルトの名無しさん :04/01/18 02:23
Windows環境でまともに使えるプロファイラが付いたコンパイラ
ってありますか?LSI-Cみたいな参照カウントだけではだめで、
ちゃんと時間まで表示してくれる奴。

913 名前:デフォルトの名無しさん :04/01/18 02:28
>>912
とりあえずVC

914 名前:デフォルトの名無しさん :04/01/18 02:46
>>913
おおそうだったのか。BCB派だったからなあ。

915 名前:デフォルトの名無しさん :04/01/18 05:05
>帰ってこないSQL
ここは凄いインターネットだな(W

業務系アプリケーションを見下した言い方がムカつくんだよヴォケが

916 名前:デフォルトの名無しさん :04/01/18 06:48
業務系がどう評価されているかもお前が脊髄レスしてるかどうかも関係ない。
とりあえずお前の発言はスレ違い。

917 名前:デフォルトの名無しさん :04/01/18 10:18
( ´∀`) <オマエモナー

918 名前:デフォルトの名無しさん :04/01/18 11:09
>>910=911 の書いてることは至極当然のことだと思うな。
漏れも後輩がおなじこと聞いてきたら小一時間...。

まぁ、データベースを扱うアプリのパフォーマンスが悪いときは、
そもそも表の設計がアフォだったりすることが多いので、
そんなときはいくらSQL文を最適化しても焼け石に水だったりする。


919 名前:デフォルトの名無しさん :04/01/18 13:09
C++でreallocのような実装をしたいんですが、newとかじゃあ無理ですよね?
reallocを使うか、リストでも作るくらいしか方法ないんでしょうか?


920 名前:デフォルトの名無しさん :04/01/18 13:15
ん?std::vectorでは不満かネ?
新領域をnew[]して、要素をコピーして、旧領域をdelete[]して、
新領域を返せばrealloc相当なんではないのかネ?

921 名前:919 :04/01/18 13:23
>>920
stdってMFC環境でも使えます?
MFC環境です。スレ違いかも知れませんが・・・

922 名前:デフォルトの名無しさん :04/01/18 13:26
>>921
stdってなんだよ。
STLのことか?

923 名前:デフォルトの名無しさん :04/01/18 13:27
頻繁にreallocするならstd::dequeを使うほうがいいかも。


924 名前:919 :04/01/18 13:28
>>922
はい

925 名前:デフォルトの名無しさん :04/01/18 13:28
MFCと併用できる。
MFCだけ使いたいんならCArrayかなんかを使え。


926 名前:919 :04/01/18 13:30
解決しそうですありがとうございます。

927 名前:デフォルトの名無しさん :04/01/18 13:48
>>923
どうしてかフォローきぼん

928 名前:デフォルトの名無しさん :04/01/18 13:51
>>927
ふたなりだから

929 名前:デフォルトの名無しさん :04/01/18 13:53
まだ〜(ry

930 名前:>>928は全てがネタなのか微妙だな :04/01/18 14:07
>>927
>>923じゃないけどvectorはcapacity超えたときに
全要素を再割り当てしないといけないから
dequeは内部的に複数の配列を論理的に連結した構造になってるから
全要素を再割り当てしないで済む。
C配列との互換性が不要でお尻が大胆に伸び縮みする場合はdeque推奨。

931 名前:デフォルトの名無しさん :04/01/18 14:34
途中への挿入が必要で、かつランダムアクセスしたいときにもdequeが有効ですか?

932 名前:デフォルトの名無しさん :04/01/18 14:40
頭が伸び縮みする場合もdeque。

933 名前:デフォルトの名無しさん :04/01/18 14:42
亀の頭が伸び縮みする場合はtimpo。

934 名前:デフォルトの名無しさん :04/01/18 15:43
やだ。dequeの速度<<<vectorの速度だもん。
まだlist使った方が速いやーい。

935 名前:デフォルトの名無しさん :04/01/18 15:43
ただlistはoperator[]が使えないが・・・・

936 名前:デフォルトの名無しさん :04/01/18 15:50
ランダムアクセスが不要なら、deque使う意味はあまり無いかな。

937 名前:デフォルトの名無しさん :04/01/18 15:54
>>930がネタなんだよな
vector≧dequeだろ。
要素数の半分未満の位置に挿入することがあるときはdequeで
それ以外の場合はvectorってのが選択の基準じゃなかったか?

938 名前:デフォルトの名無しさん :04/01/18 16:07
メモリの再割り当ての話をしていたところを
今は拡大されてるんだからかみ合わなくて当然だ。

939 名前:デフォルトの名無しさん :04/01/18 16:14
>>930 は deque を list と勘違いしているに1票。

940 名前:デフォルトの名無しさん :04/01/18 16:27
>>939は deque の(典型的な)実装について全く知らないに 1 票。

941 名前:デフォルトの名無しさん :04/01/18 17:21
std::listクラスにoperator[]をユーザ定義で追加したバカが
ここに約一名いるが・・・・std::advanceを使えば簡単。

942 名前:デフォルトの名無しさん :04/01/18 17:52
まあ、やれば出来るだろうな。
ランダムアクセスが可能なことと
[]でアクセスが可能なことは等価じゃないだろうし。

使う側は[]を見たらランダムアクセスを期待するだろうけど。

943 名前:デフォルトの名無しさん :04/01/18 18:39
>>942
データの個数が10000個程度で乱数で添え字を決めてアクセス
する分には、std::dequeとあまり変わらないよ。むしろstd::list
の方が速い。
それ以上長くなるとさすがにstd::listの[]は無理が出てくる。
それほどstd::dequeってのは遅い。

944 名前:デフォルトの名無しさん :04/01/18 18:44
>>943
それは無理があり過ぎないか?
dequeの場合、添字でのアクセスは
buffer[pregap + index]だけだろ?


945 名前:デフォルトの名無しさん :04/01/18 19:31
試してみた。

#include "stdafx.h"
#include <iostream>
#include <deque>
#include <list>
#include <iterator>
#include <windows.h>
#include <cstdlib>
#include <ctime>

enum {deque, list};

void func(int n, int mode)
{
std::srand(static_cast<unsigned>(std::time(NULL)));
if (mode == deque) {
std::deque<int> d(n);
for (int i = 0; i < n; i++)
volatile int v = d[std::rand() * n / RAND_MAX];
} else {
std::list<int> l(n);
for (int i = 0; i < n; i++) {
std::list<int>::iterator p(l.begin());
std::advance(p, std::rand() * n / RAND_MAX);
volatile int v = *p;
}
}
}

946 名前:デフォルトの名無しさん :04/01/18 19:31
int prof(void (*func)(int, int), int n, int mode)
{
__int64 start, end, freq;
HANDLE hprocess;
DWORD oldclass;

hprocess = GetCurrentProcess();
oldclass = GetPriorityClass(hprocess);

Sleep(10);
SetPriorityClass(hprocess, REALTIME_PRIORITY_CLASS);
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&start);

func(n, mode);

QueryPerformanceCounter((LARGE_INTEGER*)&end);
SetPriorityClass(hprocess, oldclass);

return (int)(end - start);
}

int main()
{
enum {deque, list};
int n[] = {100, 1000, 10000, 20000, 0};

for (int i = 0; n[i]; i++) {
std::cout << "deque " << n[i] << " elements result = " << prof(func, n[i], deque) << std::endl;
std::cout << "list " << n[i] << " elements result = " << prof(func, n[i], list) << std::endl;
}
}

947 名前:デフォルトの名無しさん :04/01/18 19:33
deque 100 elements result = 166
list 100 elements result = 111
deque 1000 elements result = 463
list 1000 elements result = 5192
deque 10000 elements result = 3367
list 10000 elements result = 488152
deque 20000 elements result = 6304
list 20000 elements result = 2041460

要素数100000にしたらlistが1分たっても終わらない(P4 2.8G)。
やはりstd::listにoperator[]は無理があり過ぎ。

948 名前:デフォルトの名無しさん :04/01/18 19:34
あ、コンパイラはVC7.1 + STLport4.6、Release Modeね。

949 名前:デフォルトの名無しさん :04/01/18 19:43
>>944-948
わざわざ試していただいてありがとうございました。
私の記憶違いだったようです。すみません。

こんなにlistが遅くなるとは。_| ̄|○

仕方ないですね。リストですから。

950 名前:デフォルトの名無しさん :04/01/18 19:54
ちなみにstd::vectorの結果も貼っておくよ。
STLPortはよくチューニングされていて、std::vectorとstd::dequeの
差は割と少ないよ。他のSTL処理系の方もよかったら教えてちょ。

vector 100 elements result = 48
deque 100 elements result = 179
list 100 elements result = 109
vector 1000 elements result = 139
deque 1000 elements result = 447
list 1000 elements result = 5234
vector 10000 elements result = 1452
deque 10000 elements result = 3106
list 10000 elements result = 294502
vector 20000 elements result = 2903
deque 20000 elements result = 5991
list 20000 elements result = 1967664

951 名前:デフォルトの名無しさん :04/01/18 21:03
あまり結果には関係ないと思うけど
doubleにキャストしないと添字が全部0になりそう。

952 名前:デフォルトの名無しさん :04/01/18 21:22
わかる方がいたら教えてください。
dllをリンクするときにlibファイルが要りますが、
なぜdllそのものを使わずlibファイルを使うのでしょうか?
dll中にもシンボルがあるのでリンクできると思うのですが...
dllになくてlibにある「何か」が存在するのでしょうか?

953 名前:デフォルトの名無しさん :04/01/18 21:41
DLLをリンクしたら、DLLとして分割している意味がなくなります。

954 名前:デフォルトの名無しさん :04/01/18 22:08
>>952
インポートライブラリ(.LIB)は必須ではない
定義ファイル(.DEF)を使ったり
GetProcAddressで同様の目的を果たすことができる

955 名前:952 :04/01/18 22:31
>>953
スタティックリンクするということではないのですが...
>>954
ありがとうございます。
今、DEFファイルとかググって調べてきました。
libファイルが必須でないことは理解できたのですが、
なぜリンカがdllファイルを作成するときにlibファイルを
副産物のように生成するのかがわからないのです...

956 名前:デフォルトの名無しさん :04/01/18 22:45
静的リンクと動的リンクを等価に扱うための仕組みだろ

957 名前:デフォルトの名無しさん :04/01/18 23:42
>>951
ん?今添え字を表示させてみたけど見事にバラバラだったぞ。
どこで全部0になると思われたのかな?もしかしてRAND_MAX
がstd::numeric_limits<int>::max()と同じ処理系もあるから?

その場合はもちろん修正しないといけませんが。Win32コンソール
ならば大丈夫みたい。

958 名前:デフォルトの名無しさん :04/01/18 23:56
>>955
「dll 明示的リンク 暗黙的リンク」でぐぐれ

959 名前:デフォルトの名無しさん :04/01/19 00:10
>>957
すみません。
std::rand() * n / RAND_MAX
これでいいんですよね。
ほとんどc++使ったことなくて知らないのですけど、c++だと0にならないんですか?

どうしてそうなるのか、もしよければ教えてください。

960 名前:デフォルトの名無しさん :04/01/19 00:15
>>955
__declspec(dllexport) _declspec(dllimport)使えばDEF
ファイルは不要だよん。
その代わりエクスポート序数はコンパイラ任せになる。

C++で作ったdllは名前マングリングのためにおかしな名前
に化けているので、dumpbinでエクスポート名を確認。
もしくは extern "C" を使用。ただし同一環境でexeとdllを
作成する場合は名前マングリングは気にしなくても良い。

明示的リンクは自分でLoadLibraryExとGetProcAddress
を使いまちゅ。この場合インポートライブラリ(.LIB)は不要
になりまちゅ。

961 名前:デフォルトの名無しさん :04/01/19 00:16
>>959
逆にどんな処理系だと0になりました?Cだとなるんですか?
もちろんCはstd::不要ですけど。

962 名前:デフォルトの名無しさん :04/01/19 00:18
なんかWin32 FAQになりつつあるんですけどこのスレ。。。

963 名前:デフォルトの名無しさん :04/01/19 00:26
>>962
いいんだよ、消えろ! 市ね!!

964 名前:デフォルトの名無しさん :04/01/19 00:28
言語じゃなくて処理系の問題でしょ。
一つは実際の評価順序、
もう一つは演算途中での精度じゃない?

965 名前:デフォルトの名無しさん :04/01/19 00:30
>>961
g++ 3.3.2 でこうなってました。
std::cout << std::rand () * n / RAND_MAX << std::endl;

std::cout << std::rand () * n / 2147483647 << std::endl
nを1000で10000回やって全部0でした。

966 名前:デフォルトの名無しさん :04/01/19 00:34
RAND_MAX == INT_MAX
の場合があるって事だね

967 名前:955 :04/01/19 00:34
>>956,958,960
みなさんありがとう...
もう一回勉強して出直してきますです(TT

968 名前:デフォルトの名無しさん :04/01/19 00:35
>>965
ああやっぱり。RAND_MAX == std::numeric_limits<int>::max()
の処理系だと0になります。だってintの結果をintで現せる最大
の数で割ってるんだもん。良くて1が出るだけ。

そういう処理系なら、

std::cout << (double)std::rand () * n / RAND_MAX << std::endl;

としてください。添え字の方は演算後 int にキャストしてください。
size_tでもいいです。

969 名前:デフォルトの名無しさん :04/01/19 00:37
>>967
めげなくてもいいよ。Win32 APIの簡単な入門書を買って読んで
ごらん。すぐ理解できるから。

970 名前:デフォルトの名無しさん :04/01/19 00:44
>>965>>966
ちなみにMinGW(gcc3.3.1)ではRAND_MAXは0x7FFFと
定義されていました。きっとLinux向けか何かのgccでしょう。

971 名前:デフォルトの名無しさん :04/01/19 00:48
すごい勘違いしてました。
c++だとRAND_MAXがdoubleになってるとか、
何か複雑なことになってるのかと思ってましたけど、
単にサイズの問題だったんですね。

972 名前:デフォルトの名無しさん :04/01/19 00:53
>>960
dllimportは実質何もしないんじゃないの?

973 名前:デフォルトの名無しさん :04/01/19 01:10
なんでお前らそんなアホなコードを前提に話を進めてるんだ?
フツーこーだろ? それとも漏れが馬鹿なのか?

std::cout << std::rand () %n << std::endl;

974 名前:デフォルトの名無しさん :04/01/19 01:21
>>973
その方法は n が大きい時に、
出現確率の不均一さが顕著になる。
前半が出やすく、後半が出にくい、と。

でも、もう1つの方法も、
RAND_MAX で割るようにすると
RAND_MAX が出たときだけ n になってしまうんだよね。
RNAD_MAX + 1.0 で割らなきゃ。

975 名前:デフォルトの名無しさん :04/01/19 01:23
藻前が馬鹿。

976 名前:デフォルトの名無しさん :04/01/19 01:39
>>973
線形合同法でぐぐれ

977 名前:デフォルトの名無しさん :04/01/19 01:42
>>974
そんなこと気にするぐらいなら始めから標準の乱数なんか使うなよ。
標準の乱数はクソだぞ。(無いよりはましだろう程度の最低の品質)
あと、>>975 は氏ね。

978 名前:デフォルトの名無しさん :04/01/19 01:44
>>976
you too.


979 名前:デフォルトの名無しさん :04/01/19 01:48
>>977
どの乱数でも同じこと。
不均一さが目立つほどループすれば
結局問題になる。
ただ、% の方がコストが低いので、
そこまで精度が必要で無いなら十分実用的。

980 名前:デフォルトの名無しさん :04/01/19 02:01
そろそろ新スレよろ。
こんな真夜中に立つなんて不気味。

981 名前:デフォルトの名無しさん :04/01/19 02:01
>>973
>>974 の方法を知ってて低コストな%使ってるならいいけど
知らなかったみたいだから馬鹿だろ。


982 名前:デフォルトの名無しさん :04/01/19 02:05
ムリだった。

983 名前:デフォルトの名無しさん :04/01/19 02:09
64-bit 整数をサポートしてるコンパイラなら、

(int)((uint64)std::rand() * n / ((uint64)RAND_MAX + 1));

(uint64 はコンパイラごとに分けて typedef すべし)
とすれば double にするよりコストを抑えられる。
サポートして無いコンパイラでも、
64-bit 整数を扱うコードを自前で組めば
それなりになんとかなる。

984 名前:デフォルトの名無しさん :04/01/19 02:26
>>983
;´Д`) RAND_MAX も 64 ビットになってたら何の意味もないんですけど。

>64-bit 整数を扱うコードを自前で組めば

;´Д`) さらっと言うけど、結構面倒な事だと思うんですけど。

985 名前:デフォルトの名無しさん :04/01/19 02:38
つーか、doubleのほうがコスト安いだろ。

986 名前:デフォルトの名無しさん :04/01/19 03:01
>>979
> ただ、% の方がコストが低いので、
浮動小数点演算では乗除算の演算コストはそんなに高くない
そして整数演算と浮動小数点演算のコストの差も最近では殆ど気にならない

987 名前:デフォルトの名無しさん :04/01/19 03:12
ていうか、boost::random使おうよ。C++スレだし。
ttp://www.kmonos.net/alang/boost/classes/random.html


988 名前:デフォルトの名無しさん :04/01/19 03:14
>>984
>;´Д`) RAND_MAX も 64 ビットになってたら何の意味もないんですけど。
uint64(64 ビット)じゃなくて、udint(int の倍長)にすれば問題なし。
rand の戻り値の型は int です。

>;´Д`) さらっと言うけど、結構面倒な事だと思うんですけど。
大丈夫。大抵のコンパイラは int より大きな(拡張)型を持ってるから。
しかも、コンパイラごとに処理を決めるので、RAND_MAX の値も仮定できる。
これは2の累乗 - 1 であることが多いので、
割り算はシフトで代用できることが多い。

>>985-986
>つーか、doubleのほうがコスト安いだろ。
>そして整数演算と浮動小数点演算のコストの差も最近では殆ど気にならない
0x01000000回の乱数の和を求めるコードで検証。
11回連続計測して、最初の1回を除いた残り10回の結果(ミリ秒)。
この環境では double の方が約2倍遅いという結果に。
PentiumIII 1.13GHz/WinXP Prof./VC++.net 2002/Release
udint: 486 double: 963
udint: 481 double: 976
udint: 482 double: 959
udint: 478 double: 1016
udint: 480 double: 962
udint: 476 double: 962
udint: 489 double: 959
udint: 481 double: 962
udint: 479 double: 960
udint: 480 double: 958

989 名前:デフォルトの名無しさん :04/01/19 03:43
>>988
PentiumVはdoubleが遅いね。
Pentium4 2.8G, WinXP, VC7.1(Release)
INT64 = 1496735, double = 1509503
INT64 = 1488272, double = 1503707
INT64 = 1492052, double = 1499723
INT64 = 1496729, double = 1493035
INT64 = 1490568, double = 1498648
INT64 = 1500993, double = 1498231
INT64 = 1492967, double = 1487411
INT64 = 1497845, double = 1494134
INT64 = 1494760, double = 1501952
INT64 = 1493469, double = 1509986
INT64 = 1500363, double = 1499311

990 名前:デフォルトの名無しさん :04/01/19 03:46
ちごた、>>989は無し。volatile付けるの忘れた。
volatile付けたらdoubleの方が速くなったぞ。

INT64 = 1755632, double = 1588463
INT64 = 1768286, double = 1587927
INT64 = 1761463, double = 1580657
INT64 = 1771689, double = 1587428
INT64 = 1767026, double = 1585672
INT64 = 1759140, double = 1580303
INT64 = 1765196, double = 1574253
INT64 = 1752424, double = 1587379
INT64 = 1756438, double = 1582123
INT64 = 1759046, double = 1594272
INT64 = 1762409, double = 1584770

991 名前:デフォルトの名無しさん :04/01/19 03:47
そういえば、RAND_MAXが2^n-1じゃなくて2^nになってるのも見たことがある。
それにそなえて((RAND_MAX + 1) & ~1)で割ればさらに良いかも。

もう一つ、rand()の型はint(符号付き)なので
x/(2^n)が(x>>n)に変換されない場合もある。
これに備えてunsignedでキャスト。


などというのは、
乱数の取得が速度上のボトルネックでない場合には
ソースを読みにくくするだけなのでおすすめしない。

992 名前:デフォルトの名無しさん :04/01/19 04:24
Pentium4 いいなぁ...。

993 名前:デフォルトの名無しさん :04/01/19 04:29
>>991
何で? >((RAND_MAX + 1) & ~1)
rand が RAND_MAX になるただその時だけ
n に等しい値が得られてしまうという問題が起こるというのに。
2^n - 1 かそうでないかとは関係ないぞい。
おそらくこれが原因であろうバグもたまに見るしね...。

double で [0, 1] の値が欲しいなら RAND_MAX で割るけども、
それを考慮しても上のコードはどっちつかずだ。

994 名前:デフォルトの名無しさん :04/01/19 04:32
>>992
打倒RISCを目標に作られたP4は、実数演算の速さだけが取り柄。
整数演算は、遅い。

995 名前:デフォルトの名無しさん :04/01/19 04:33
次スレキボンヌ
俺、どうやら立てれないみたい。

996 名前:デフォルトの名無しさん :04/01/19 04:37
>>993
話の流れの読めない奴

997 名前:デフォルトの名無しさん :04/01/19 04:38
何とか立てた。
C++相談室 part27
http://pc2.2ch.net/test/read.cgi/tech/1074454641/

998 名前:デフォルトの名無しさん :04/01/19 04:43
>>997


999 名前:デフォルトの名無しさん :04/01/19 04:44
じゃあ最後にこの話を。
昨日バスに乗ったんだが、満員で客同士がすごく密着してた。
俺も暑苦しくて早く降りたいと思ってたんだが、
気が付くと隣にすげー可愛い女子高生がいた。
たぶんセンター試験の帰りかな。
それで

1000 名前:デフォルトの名無しさん :04/01/19 04:46
>>979
rand() *n /RAND_MAX でも偏りを全体に拡散してるだけで
偏りそのものがなくなってるわけじゃないぞ。
あと、>>981 は、氏ね。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.