1 名前:デフォルトの名無しさん mailto:sage [2012/02/18(土) 06:07:36.70 ] C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレに お願いします。 前スレ C++相談室 part93 toro.2ch.net/test/read.cgi/tech/1324922431/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.77【環境依存OK】 toro.2ch.net/test/read.cgi/tech/1323692486/ ■長いソースを貼るときはここへ。■ codepad.org/ ideone.com/
577 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 23:39:54.67 ] >574は漏れもやったが30分で悔い改めた それはそうと、デカいオブジェクトの実体をSTLのコンテナに格納して 複数個所から参照しつつ必要に応じて追加するということをしたいんだけど コンテナにinsert()する前後で参照が有効であり続けるようなうまいやり方ってないですかね… コンテナの要素型を自作クラスでうまく作ればできなくは無いけど標準的なやり方は?
578 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 23:46:58.49 ] std::listを使う
579 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 00:18:51.98 ] using namespace std; がヘッダに書いてあるライブラリを使うことを強制されているんだ! windows.h が自動的にインクルードされていたり、まさに地獄だぜ。 >>577 listを使うか、間接参照するか
580 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 00:24:37.62 ] マクロ展開出力みたいに ADL展開出力オプション欲しいよな
581 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 02:41:59.29 ] >>577 なんでもかんでもshared_ptrでくるんじまいなよ! コンテナ用件は自動的に満たされるぜ!
582 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 05:47:00.52 ] using namespace std; をわざわざincludeするようのヘッダー作ってincludeしまくってるわ とりあえずusing std::stringとかにかえてみた
583 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 06:57:21.79 ] お前の using namespace std; のせいで ライブラリのヘッダでコンパイルエラーが出たわ
584 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 09:46:42.23 ] しかしこのcodepad、まさかの強制using namespace std;である codepad.org/wzgxNgw9 codepad.org/PSECxXqW
585 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 10:06:09.92 ] 全部std::付けたり関数毎に書くのは面倒なので自分の名前空間内でusing namespaceしてる ideone.com/uXfYk ideone.com/IiwPB
586 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 12:38:41.41 ] using namespaceはよほどのことがない限り使わないな。 namespace fs = boost::filesystem; とかはよくやるが。
587 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 13:24:50.23 ] そんなこともできるんだったな すっかり忘れてた
588 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 13:32:52.26 ] using namespaceを使っといて、完成版では置換すればよい。 手間の問題。
589 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 21:48:04.95 ] using namespace したものを置換するのは困難だぞ
590 名前:デフォルトの名無しさん [2012/04/17(火) 22:09:49.45 ] テストコードをそのまま本番に持って行ってるわけね
591 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 22:26:19.01 ] class Sample { const bool aaa(const a, const b) const const int bbb(const c) const const Sample(const d) const } 最近constに触れる機会があったのですが TYPEはintとかfloatとか 【const TYPE】 aaa(const x) const 質問なのですが、【const TYPE】の部分がconstだと 実際にはどういう利点があるのでしょうか 他の部分がconstになっていると 色々とパフォーマンスに影響がありそうだと直感的に理解できるのですが (変数には値とかコピーが入るわけですよね?) 戻り値の型にconstがあったからといって特に意味無いような気がしてしまいまして じゃあ、頭のconstにはどんな意味があるんじゃ!? ということで疑問が湧いてしまったのですが どなたか意味というか意義というか、教えてくださいまし
592 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 22:29:04.87 ] const TYPE&じゃなくてconst TYPEなの?
593 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 22:29:55.14 ] >>581 >なんでもかんでもshared_ptrでくるんじまいなよ! 何を言いたいのかわからんが、 確かに「型Tのset」のかわりに「型Tのshared_ptrのset」にでもして shared_ptr<T>のoperator<()とoperator==()を(適当なスコープで)定義するとしたら逝けそうですな ※ とにかくデカいオブジェクトなので同じものを複数持ちたくない。 当然insert時は重複チェックをやる。これをも極力高速、極力コンテナに任せにしたいからlistというのもちょっと、、、 >577における「コンテナの要素型を自作クラスでうまく作」るのより良さげな回答だけど しかしshared_ptrはSTL標準ではないのではないか
594 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 22:37:54.44 ] >>591 const病の伝染をやり過ごせる利点がある class Sample { int* p; // (適当な構築子) const int* GetPtrA() { return p; } const int* GetPtrB() const { return p; } }; であるとして、 const Sample foo(...); // constオブジェクトとして構成 int* p1 = foo.GetPtrA(); // コンパイル時エラー int* p2 = foo.GetPtrB(); // おk
595 名前:594 mailto:sage [2012/04/17(火) 22:41:43.73 ] ああスマン頭のconstか わからんメリットなど無いのではないか (でもテンプレート絡みでちょっとあるのかも?テンプレートについて人類は何一つ断言できない)
596 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 22:57:13.88 ] 戻り値はconstにする派ってのもいたと思う Effective C++に書いてあるけど、正直やりすぎだと思う
597 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 23:04:48.95 ] レスありがとう …やっぱり、頭が const TYPE の場合はあまり意味なさそうな感じですか? 恐らくコスト面でも無視できるような違いしかないってことですよね。 実際にもあまり使わないという認識でいいのかな そういえば、 const TYPE&の存在がありましたね…。 const TYPE& はパラメーター(参照)のstd::vectorのアイテム参照とかグローバル変数の配列の参照を返す時とかに有効な気がしますが intとかfloatみたいな値を返す時とかに積極的に使う理由ってありますか?
598 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 23:44:43.08 ] 戻り値 const Effective C++ でググれ >・ 戻り値にconstを使うと、問題のある関数の安全性や効率を改善できる > >例2) >const Rational operator* (const Ratioanl& lhs, const Rationa& rhs); > >(a * b) = c のようなコードは不正だが、const 指定すればコンパイル時エラーとなる。 >(a * b) = c; これを展開すると、const Rational (a * b) = Rational c となりエラー。 正直こんなのどうでもいいと思うが
599 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 00:02:43.13 ] 戻り値const派は右辺値参照の登場で窮地に立たされたな
600 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 00:18:49.01 ] 右辺値参照で何か不都合とかあったっけ?
601 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 00:21:29.89 ] 右辺値参照とconst絡みで問題なんてないと思うが 教義を貫けない的な話?
602 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 00:29:13.38 ] 折角右辺値参照を使ってるのに 無駄に複製が発生するようになるからじゃない
603 名前:デフォルトの名無しさん [2012/04/18(水) 00:40:30.17 ] 禿の自刃に殉じた使徒の数知れず (;ω;)
604 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:01:44.61 ] >>598 >・ 戻り値にconstを使うと、問題のある関数の安全性や効率を改善できる >・ 戻り値にconstを使うと、問題のある関数 >問題のある関数 メイヤーズ氏もついに演算子の多重定義をdisる境地に達したのか
605 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:23:01.73 ] 「定数式が必要です」と言われてしまいました……教えてください。 「sound_effect.h」に次のように書きました。簡略化しています。 #ifndef SOUND_EFFECT_H #define SOUND_EFFECT_H extern const int SOUND_EFFECT_MAX; class CSoundEffect{ public: CSoundEffect(); ~CSoundEffect(); void RaiseFlag(int Num); void LoadSet(int SoundSet_Num); void Play(); private: int File[SOUND_EFFECT_MAX]; int Flag[SOUND_EFFECT_MAX]; }; そして、「sound_effect.cpp」には次のように書きました。各関数の定義ははぶきます。 #include "sound_effect.h" const int SOUND_EFFECT_MAX = 45; CSoundEffect SE_Object; すると、SOUND_EFFECT_MAXが代入済みの整数定数とみなされていないのか、 「構造体または共用体中にサイズが 0 の配列があります」ということになってしまいます。 なお、extern const intではなく#defineを用いるようにすれば、エラーは出なくなります。 ですが、整数定数の定義には#defineではなくconstを使うようにしろと言われてきたので……
606 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:25:49.79 ] すみません、簡略化時に#endifを削ってしまいました。 「sound_effect.h」の末尾に#endifがあるものとしてお答えください。
607 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:28:02.72 ] enum { SOUND_EFFECT_MAX = 45 };でいいだろ
608 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:41:50.09 ] 俺ならメンバ変数にstatic const int SOUND_EFFECT_MAX = 45; ってやっちゃうな externだとリンクの時に初めて値が入るとかでコンパイル時にそういう風に使っちゃいけないんだろう
609 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 01:57:38.08 ] どうしてもexternでやりたいなら sound_effect.h extern const int SOUND_EFFECT_MAX= 45; sound_effect.cpp const int SOUND_EFFECT_MAX; だな
610 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 02:20:37.69 ] クラス定義はマクロじゃないからな。
611 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 04:44:22.33 ] const定数のリンケージがC++だと、Cと違ってそのモジュール内だけになるからだったか? そのルールって、C++は定数式で配列が初期化できるからあるってことかな?
612 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 05:03:50.99 ] 黙して共用ヘッダの無名空間に収めとけよ
613 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 07:34:46.83 ] 外部リンケージの const 定数は配列の要素数などには使えない仕様 内部リンケージ(const が付く場合はデフォルト)であっても、 実体定義より前には配列の要素数などには使えない 宣言だけでは無理で、コンパイラは 0 であると仮定してエラー復帰してコンパイルを続けるので 連鎖的に配列が 0 要素だとか変なエラーが出る class CSoundEffect{ public: static const int Max = 45; private: int File[Max]; int Flag[Max]; }; これでFA VC6のような化石コンパイラを使わない限りは大丈夫 VC6使うなら enum { MAX = 45 }; で
614 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 17:50:12.27 ] 皆さんありがとうございます。 おかげさまで解決いたしました。
615 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 18:50:22.14 ] こっちにしようかC++11スレにしようか迷ったけどこっちで。 template aliasで下のコードがエラーになる(clangで)のは何故ですか? barはfooの別名だと思うのですが。 -- template<typename T> struct foo{ /*empty */ }; template<typename T> using bar = foo<T>; template<template<typename> class T> struct zot { /* empty */ }; void qux( zot<foo> ){ /*empty */ } void quux( ){ qux( zot<bar>( )); // ココ }
616 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 19:52:51.68 ] >>586 俺も好き。Java使わさせられるとき 同等の機能が無いから不便で仕方ない。
617 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 19:54:39.53 ] >>615 未対応だからじゃね
618 名前:デフォルトの名無しさん [2012/04/18(水) 20:32:59.12 ] zot に bar を渡すときに foo のインスタンス化を要求するからだろ
619 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 21:33:36.47 ] fooのインスタンス化は出来るんじゃね? alias使わずqux(zot<foo>());だけならideoneでも通るし
620 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 23:47:55.07 ] C++規格素人だが>615はコンパイラの常識的挙動に照らしておかしくねえ? template<typename T> using bar = foo<T>; でbarを本当にfoo<T>の別名として使ってインスタンス化の片棒を担がせるには Tの型を明示的に与えるか、型推論できるような書き方であらねばコンパイラ困っちゃう 、希ガス
621 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 00:15:19.40 ] すわなち、(省略されている型パラメータUを補完したとして) template<typename T> struct foo{ /*empty */ }; のTはfooの自由変数だが、 template<template<typename U> class T> struct zot { /* empty */ }; において、 U,Tは束縛変数の1, 2であって、テンプレートzotの自由変数は 実は( template<typename U> class T )という全体である で、void qux( zot<foo> ){ /*empty */ } と書いたなら、この実体化では zotの自由変数( typename<typename U> class T)のTがfooでUがfooの自由変数T、と解釈できる (で、Uはzotの定義で使われないからUの定義が無くとも実体化できる。) 一方、qux( zot<bar>() )と書いたなら、barをfoo<T>の別名と解釈するときにTの定義が要るから、 上の話で言うUの定義が必要、という違いがある 、、多分、、
622 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 00:28:33.86 ] いま思いついたが>621説を検証するには、>615のコードの3行目を template<template<typename U> class T> struct zot { U x; }; に変更したときに4行目の void qux( zot<foo> ) { /*empty*/ } がエラーになるか確かめればある意味一応検証になる エラーにならなければ>621説は反証される
623 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 00:52:23.75 ] struct void std::wstring any(); return 3;
624 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 01:32:56.73 ] エイリアステンプレートはテンプレートとしては元のテンプレートと別物扱いってことなんだろ template<class X, class Y> class hoge {}; template<class X> using fuga = hoge<X, X>; みたいなときはhogeは引数2つのテンプレートでfugaは引数1つのテンプレートとしてふるまうから別物扱いするのが自然だし
625 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 18:36:57.09 ] WindowsXP以上,VC2003の環境です。 ある特定のウインドウの位置の変更や、サイズの変更があった場合に 通知を受け取るにはどうすればよいでしょうか? いまは、ループでずっとGetWindowRect()を呼んでいます。
626 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 18:41:08.73 ] イベントにWM_SIZEってなかったっけ?
627 名前:625 mailto:sage [2012/04/19(木) 18:51:46.80 ] >>626 監視対象が、自分の作ったウインドウ(アプリ)じゃないんですよね。 DLL作ってフックしないといけないんでしょうかね・・・。
628 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 19:23:52.04 ] ループ使わないなら基本的にはフックじゃね vista以降は上位権限のプロセスのメッセージは取れないらしいけど あと使ったことないけどCreateRemoteThreadっていうので何か出来るかもしれない
629 名前:625 mailto:sage [2012/04/19(木) 22:53:19.86 ] とりあえず、新しいプロジェクトでDLLを作って WM_SIZE,WM_MOVE,WM_MOVINGをフックできるようになりました。 それで、更新された新しいRECTをEXE側に渡したいのですが、 DLLからEXE側の関数を呼ぶにはどのようにすればよいでしょうか?
630 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 23:59:45.57 ] .exeの方にdllexportの関数って用意できないっけ? exeの方のウィンドウハンドルとってきてメッセージでもいいけど
631 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 00:23:32.12 ] セキュリティで弾かれるのはハンドルを取得する時だけで合ってた? 違うプロセスのウィンドウハンドルを指定してゴニョゴニョは問題ないっけ?
632 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 01:16:30.45 ] ヘンタイ仕様のAPIの話って、ここでして良いの?
633 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 01:22:36.10 ] Mayaのプラグイン作ってそんなかでFindWindowしてSendMessageしたりしてるけど特にはじかれはしてないなぁ、Windows7ね。 exeが多重起動してたらどれからとってくるかは知らね、目的は果たせたからあんま調べてない。
634 名前:631 mailto:sage [2012/04/20(金) 01:25:31.84 ] あ、ごめん ここC++スレだった。 でもWin32スレに書いてもまともな返答返ってこなさそうだし困ったもんだね。
635 名前:631じゃなくて633でした mailto:sage [2012/04/20(金) 01:26:30.15 ] たびたびごめんなさい。
636 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 02:11:53.23 ] Windowsは一度公開API群を再設計したほうがいい 仮想化でやってるのは内部的な整合性を保つ為だろうけど どうせなら今までの粗雑なAPIはレガシー化させて 整合性のあるAPIとして生まれ変わったほうがいい 現状の#defineだらけのヘッダーやら互換性の為に残されたAPIやらは 一度分離してくれたほうがみんな幸せになれる
637 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 02:12:40.39 ] >>636 Win64は随分まともになってるじゃないか
638 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 02:34:17.39 ] Win64? DWORD→DWORD_PTRのことかね
639 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 02:35:23.12 ] .netのクラスライブラリ群がネイティブになって winapiは、なくなるのじゃないの?
640 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 02:42:01.50 ] 現状では.NetのGUIはwinapiをラップしたものでしかないぞ…
641 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 03:04:20.32 ] メッセージとか継ぎはぎ感が否めないよな
642 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 03:53:34.34 ] C99対応を前提にして BOOLもbool型にしとくべきだろうね
643 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 07:01:04.44 ] >>636 WinAPI使わなきゃいいじゃん 使わない自由はある MSだって昔は.Net Frameworkで切り捨てるつもりだったんだし
644 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 08:40:17.72 ] だから WinRT を設計したじゃないか
645 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 10:42:47.33 ] WPFでGUI APIを一新したかったんだろうけど、普及しなかったな。
646 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 11:38:25.04 ] 粗雑で素朴なCのAPIでもABI的な意味で需要はあるし手間の点はQtとかのラッパで十分とも言えるし
647 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 12:15:25.67 ] Windows8でAPIが近代っぽいのに変わるんじゃなかった? Win32APIとかのレガシーなのをやっととっかえる気になったと聞いたが
648 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 16:01:31.74 ] .netとかwinrtなんてvmじゃ、いつまでたってもwinapiは撲滅させられない
649 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 16:21:37.49 ] 俺もWinRTには期待してた ふたを開ければ機能限定版のWin32APIラッパだった Windowsにフタをしてやりたくなった
650 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 16:59:12.08 ] クラスについて質問です クラス内にメンバ変数しかなかったら newする度に変数の分だけメモリを消費するだろうと推測できるのですが 例えば、メンバ変数は2〜3個でも、メンバ関数が100個くらいある場合には newする度にメモリの消費量が半端ない感じになってしまったりしますか? クラスのメモリを確保した時の挙動がちょっと気になってしまいまして 詳しい方いらっしゃったら教えてくださいまし
651 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 17:12:53.29 ] >>650 こうかな?? ttp://ideone.com/8d2zK クラスのメンバ関数は普通の関数にthisを食わせる暗黙のパラメータがあるもんだと思ってもらえればイイと思うお。 だから、関数のインスタンスは、一個でいいし、最適化すればクラスに内包してる必要はないと思う。 ちなみに、テンプレート関数にするとちょっと事情が変わってくる。
652 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:02:11.61 ] template<typename T> class boo { friend class T; }; こんな具合にテンプレート引数をフレンドクラスにしたいのですが方法教えて下さい。
653 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:39:22.82 ] クラスのメンバでistream&をもってるんだけど、デフォルトは何で初期化すればいいの? class A { istream& is; A(): is(???) {} A(istream& is): is(is) {} };
654 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:41:08.84 ] 悪い事は言わないから参照ではなくてポインタを使いなさい。
655 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:41:11.70 ] 初期化できないのでA()は定義しちゃダメ
656 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:42:03.98 ] >>653 参照だと色々不便な気がするけど大丈夫なの? んで、デフォルトコンストラクタをProtectedにするとか・・・。
657 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:46:06.02 ] すまん、もちろんpublic:を忘れている。 ストリームの終端をA()で表現して、 iter!=A() 的な判定をするんだが、654の根拠は何? iostreamってあぶなっかしい?
658 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:50:04.32 ] >>657 いや、参照は初期化時以外に実態を束縛できないのでNULL参照になりやすいからアブネーという話だと思うよ。
659 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:53:19.88 ] istream&じゃなくてistream_iteratorとか持ったら?
660 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:54:35.39 ] コンストラクタを別の場所から呼び出すのにthisを使う、次のようなコード(拾ってきたもの) って規格的にはアリでしょうか? struct sample_class { int value; sample_class(int i): value(i) {} sample_class() { *this = sample_class(10); } };
661 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:57:04.04 ] ありだけどそれぐらいならsample_class() : value(10) { }ってしたほうがいいだろ
662 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 21:59:04.72 ] >>658 ふむふむ、あんまそういうのに遭遇したことがないからよくわからんが、 シングルスレッドでワンショットで終わっちゃう(走り続けない)ようなソフトでもヤバイのかね? >>659 そういう人もったことないけど、やってみるわ。アイディアありがとう。
663 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:02:31.54 ] >>662 実態が生きてるうちは大丈夫かな。デストラクタ走ったら死亡コース。
664 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:07:11.12 ] >>663 なるほど。自分が書くような小さいプログラムだと、 mainの最後だけでデストラクタ呼ばれるパターンが多いから、 いつも気にしてないんだよね。 でもこれからは気をつけてみるわ。ありがとう。
665 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:21:45.54 ] >>652 11ならこれで通る。(gccだと4.7以降) template<typename T> class boo { friend T; }; 98だと直接は無理でメンバ関数をfriendにするしかないかな codepad.org/Ako1qKqh
666 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:37:27.70 ] さっきのistream_iteratorを使えばいいという話ですが、これが通らない・・・ メッセージが邪悪すぎるから、誰か助けてくれ〜 #include <iostream> #include <utility> #include <iterator> using namespace std; istream& operator>>(istream& is, pair<int,int>& p) { is >> p.first >> p.second; return is; } int main() { istream_iterator<pair<int,int> > is(cin); }
667 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:16:13.35 ] グローバルフックするDLLからEXEに通知を受け取るために、 boost::functionをDLL側に渡して、DLLから呼び出したんですが デスクトップ、スタートボタン、タスクバーが消えましたww どうしたらよいでしょうか? (コンソールアプリや他ライブラリでDLLを使いまわしたいので、 ウインドウメッセージでは受け取りたくないんです) いまこんな感じです↓ >// EXE側 >boost::function<bool(STRUCT&)> func = &CallbackFunction; >StartHook(func); >//DLL側 >boost::function<bool(STRUCT&)> callbackFunc; >EXPORT BOOL StartHook(boost::function<bool(STRUCT&)> &func) >{ > callbackFunc=func; > : > callbackFunc(struct); >}
668 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:23:33.48 ] >>667 そんなことできるわけねーだろアホか
669 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:42:36.38 ] >>666 あんまりいいサンプルじゃないけどこういうのも有るよ的な。 ttp://ideone.com/qaals 正直、std::cinは使ったこと無いからメチャクチャ大変だった。そして、勉強になった。
670 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:47:36.28 ] >>669 う〜ん、求めているものではないなぁ。 とりあえず、コンパイルエラーの意味がわからんかったんだが、 それに関して何かコメントない?
671 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:51:02.72 ] >>670 テンプレートを使った実装を使うときにエラー起こすと意味不明な文字の羅列が出て上級者でもイラッと来るらしい。 で、コンセプトっていう機能が入る予定だったけど、ウヤムヤになって空中分解した。 コンセプトがあればエラーメッセージはもっとシンプルになる予定だったそうな。
672 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:58:11.19 ] 別に空中分解したわけじゃないよ コンセプトマップをユーザーが定義すべきか自動で定義されるべきかが決まらなかったのでC++11に入らなかっただけ
673 名前:650 mailto:sage [2012/04/20(金) 23:59:43.85 ] >>651 さん virtutal属性とかテンプレート関数の有無が鍵になる感じなのですね! 便利なクラスにする為に大量にメンバ関数を作る分には問題ない事が分かったので 安心してクラスを作り込みたいと思います。 ちょっと返信遅れちゃいましてごめんなさい。 どうもありがとうございました!
674 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 00:00:12.19 ] すまん。ちょっと誇張した。
675 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 00:01:13.04 ] >>674 -> >>672
676 名前:デフォルトの名無しさん [2012/04/21(土) 00:03:44.63 ] >>672
677 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 00:03:57.15 ] >>671 メタプログラミングとかでエラー出ても、メッセージの雰囲気でけっこうわかるんだが、 stringとiostream関連はいまだに読めないw
678 名前:デフォルトの名無しさん [2012/04/21(土) 00:09:21.77 ] >>666 は神待ちです。
679 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 00:12:42.02 ] パンピーで悪かったわね。
680 名前:677 mailto:sage [2012/04/21(土) 01:11:26.04 ] すいません、色々調べましたがギブアップです。 EXEからDLLにコールバック関数を登録して、DLL側から構造体を受け取るにはどうすればよいでしょうか? EXE(またはコンパイラ)が変わってもDLLを修正せずにできる方法でお願いします。
681 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 01:38:32.64 ] shared_ptr使えばいけるじゃないの?
682 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 01:48:01.02 ] exeが適当なウィンドウを作って dllがFindWindowでexeが作ったウィンドウを見つけて そのウィンドウハンドルにWM_COPYDATAで構造体を送り付けたらいい
683 名前:677 mailto:sage [2012/04/21(土) 01:54:10.77 ] コンソールアプリや関数だけのライブラリからも呼びたいので、 メッセージは使いたくないんです>< 関数ポインタはDLLとEXEでアドレス空間が違うんですかね>< >// EXE側 > >bool CALLBACK func(STRUCT struct){ > return true; >} > >int main(){ > StartHook((LPVOID)&func); > : >// DLL側 >EXPORT BOOL StartHook(LPVOID func) { > STRUCT data; > data.dat = 0; > > bool (*callback)(STRUCT); > callback = (bool (*) (STRUCT))func; > callback(data); // ←この次の行の関数呼び出しでランタイムエラー >
684 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 01:57:11.92 ] 共有メモリとか名前付きパイプとか
685 名前:677 mailto:sage [2012/04/21(土) 03:43:58.56 ] 共有メモリだと、フラグとか値が変わるのを無限ループで監視しないといけないですよね? それは無駄に重くなるのでやりたくないんですよね。。。 名前付きパイプ調べてみましたが、イベントってのが使えそうな気も・・・。 それと、DLLからEXEの関数呼び出しはなんとなくできました。 EXE側の関数をdllexportして、DLL側からEXE側にGetProcAddress()して関数アドレスを取得して 呼び出せました。これなら新しいEXEを作るときもDLLを変えずに済むかなと思ったのですが、 フックプロシージャからEXE側の関数を呼び出すと、なんかダイアログ出てきてシステムに無理やりDLLをとめられました・・・。 自分のミスなのか、フックプロシージャ内はなにか特別なのか??
686 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 03:48:34.25 ] 当たり前だろ フックされたプロセスとフックを仕掛けたプロセスは違うんだから 呼び出せるわけがない
687 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 03:59:22.71 ] どうでもいいけどC++関係ねぇ
688 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 04:01:23.44 ] そろそろ toro.2ch.net/test/read.cgi/tech/1333095907/ こっちに移るべきだな
689 名前:677 mailto:sage [2012/04/21(土) 04:04:56.72 ] >>686 そうなんですか・・・。 EXEと静的リンクしたDLLは同じプロセス空間、 DLLのフックプロシージャの中は別のプロセス空間ということでしょうか?
690 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 07:05:04.65 ] >>662 コンストラクターの引数は参照で、 内部ではポインターで保持したら?
691 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 09:49:36.25 ] c++ではmallocとfree関数はつかわないんでしょうか? newとdelete演算子ですか?
692 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 09:51:40.35 ] deleteも使わない
693 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 09:53:15.77 ] えっそうなのw 横から便乗で質問だけど、コンストラクタ・デストラクタ呼び出したい時はnew deleteなのはわかったけど その必要がない場合でもnew deleteすべき?
694 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 09:53:56.00 ] そんな質問する様なら、1つ良い事を教えてあげる。 混ぜるな危険!
695 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 10:17:08.33 ] newは遅いという説が・・・・
696 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 10:22:17.05 ] >>695 右辺値参照で改善に期待。
697 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 10:24:19.29 ] >>695 placement newでおk
698 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 10:53:22.07 ] newの中身は普通はただのmallocだよ 他にはコンストラクタも動かすけど、それはplacement newでも同じ
699 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 11:41:10.25 ] >>697 placement newを教えるからにはstd::aligned_storageもだな…。
700 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 11:42:27.96 ] そしてoperator new の闇に嵌まって逝く訳ですね
701 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 13:38:50.23 ] >>666 istream_iteratorの中からは自分でグローバルに定義したoperator >>が見えない(stdのoperator >>に隠蔽される)からエラーになる。 ・解決法の一つ。stdじゃない場所に自分で定義したクラスを介する。 class mypair { pair<int, int> p; public: mypair() : p() {} mypair(pair<int, int> const & p1) : p(p1) {} operator pair<int, int>() const { return p; } istream & readvalue(istream & is) { return is >> p.first >> p.second; } }; istream & operator >>(istream & is, mypair & pr) { return pr.readvalue(is); } int main() { istream_iterator< mypair > is(cin); pair<int, int> p = *is; }
702 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 18:01:10.22 ] >>691 malloc()は使用する必要性がほぼ0になるが 個人的にはrealloc()はしばしばまれに使うべ std::vector()が使えるならそれに越したことは無いが
703 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 18:15:42.26 ] >>702 > しばしばまれ どっちなんだよ…
704 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 18:19:38.93 ] reallocはPOD型(C++11では概念変わったけど)にしか使えないのがねえ まあ、環境依存でいいなら多少危険でも使えるケースはもうちょい多いと思うが
705 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 20:25:59.49 ] >>701 諦めてたのですが、有り難い限りです!
706 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 23:52:24.21 ] デフォルトのnewだとサイズsで取った領域をサイズs+1にしたいとき無条件にnewし直ししかないじゃん? realloc()はヒープ管理のリンクリストに直に触るから、サイズsの既存分を動かさずに済むことがある std::vector<T>が中で何やってるかは知らんが、案外realloc()を呼んでいるのではないか
707 名前:デフォルトの名無しさん [2012/04/21(土) 23:55:39.79 ] >>706 reserveで出来なかったっけ?
708 名前:デフォルトの名無しさん [2012/04/22(日) 00:01:56.82 ] newのデフォルトの実装は、環境やコンパイラに依存だろ。 reallocとかと混ぜる根性がよくあるな、おまえら。
709 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 00:02:23.30 ] >>706 実装によるけど一般的には、vector<T>は要求よりも多めに確保して現在の利用状況をリポートする。 領域確保時は、何だったかな、現在の1.5倍だったかの領域をnewしてコピーするんだったかな。 まー、実装依存だわね。
710 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 00:09:22.80 ] >>706 reallocなんで呼ぶわけないだろw 事前確保の容量超えたら新しくnewしてコピー/ムーブだよ >>709 GCCとMSVCがそれぞれ1.5倍と2倍(どっちがどっちか忘れた)だったはず
711 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:08:33.21 ] 勝手にコピーや元の領域の開放を行わないreallocがあれば vectorもどきを作るのに使えるのにね・・・ 伸ばせるなら伸ばす、伸ばせなければ失敗、 あるいは、新たな領域を確保して、それを返すだけ、という
712 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:14:34.54 ] >>711 誰がコンストラクタ走らせるの? そういう用途はプレイスメントnewという機構があるよ。
713 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:15:34.87 ] >>712 vectorがどういう風に実装されてるか知ってる?
714 名前:デフォルトの名無しさん [2012/04/22(日) 01:19:53.01 ] 実装を知らないと使えない、とか、 オブジェクト指向と言うかC++の思想に反するよな。
715 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:23:08.37 ] >>714 何を言ってるのか意味が分からない
716 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:23:30.27 ] >>713 詳しくは知らない。 でも、アロケータにメモリ確保を任せて帰ってきたメモリをプレイスメントnewしてるのかねぇ。 オブジェクトをプッシュバックしたら、コピコンかムーブで移譲だよね。 その段階で破棄されるオブジェクトのデストラクタ走るし。 俺はユーザープログラマだからそんな詳しく知らなくても使える。と、言い訳。
717 名前:716 mailto:sage [2012/04/22(日) 01:25:35.85 ] アロケータの実装がreallocであることもある可能性は捨て切れない。
718 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:29:43.11 ] reallocは絶対に使えないのよね 領域が移動する場合に、reallocが勝手に内容をmemcpyするから ちゃんとしたコピーなりムーブなりが行われない 逆に言えば、この領域移動さえなければ使えると言う事
719 名前:716 mailto:sage [2012/04/22(日) 01:32:35.49 ] ほぇ〜。そうなんだ。 アロケータのことはよく知らんのよ。実装する機会もないし。
720 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:36:35.68 ] newした内容をmemcpyでコピーできないのと同じ事さ アロケータの知識は正直あまり関係ない
721 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:37:04.38 ] ※ただしPOD型は除く
722 名前:716 mailto:sage [2012/04/22(日) 01:47:33.69 ] >>720-721 なるほど。勉強になるよ〜。
723 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:03:06.82 ] >>722 PODだろうとmalloc、realloc、freeは使うなよ おいおいnewで確保したか、mallocで確保したか 管理しきれなくなってバグの原因になりかねんから PODとCの関数で思い出したが、POD型にmemsetでゼロ 初期化するヤツなんなんだろうな。 Type value = {0}; こういう形で十分だろうに。
724 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:04:10.52 ] Type value = {}; こうだろ
725 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:11:14.53 ] >>718 >>720 それって、要素型Tにコピーコンストラクタが定義されていれば どうとでもなるんじゃねwwwwwwwwwww 代入と異なりコンストラクタは構築先が何であるかを問わないから (そうでない作りにすると普通の構築時に必ずバグって発覚する、) 生のメモリ領域を与えてから構築することができる 、、ハス
726 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:21:38.13 ] >>723 それ警告出すコンパイラあるから俺は使わない
727 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:23:10.78 ] >>725 reallocが内部でmemcpyするって言ってんじゃん コピーコンストラクタもoperator==もガン無視でbitwiseコピーされる
728 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:24:33.50 ] >>726 Cの仕様で定義されてるんじゃなかったっけ? 俺はそういうふうに習ったけど。 某らんどとかは、変数の初期化処理に警告だしたりするからな。あれは不味いだろうと思う。
729 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 03:00:04.36 ] 定義はされてるよ でも、初期化忘れか、意図的な0クリアかを コンパイラが機械的に判断するのは難しかろう
730 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 03:01:59.22 ] >>726 じゃあどうやって初期化してるの?
731 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 03:19:43.82 ] >>727 だからプレースメントnewでrealloc()した後にコピーコンストラクタで構築すればいいでしょキイッ www.geocities.jp/ky_webid/cpp/language/036.html というわけで、realloc()とプレースメントnewの組み合わせで 領域が増えたときのコピーの回数をしばしばたまに減らせることがある C++ばパフォーマンス命の言語
732 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 03:33:04.27 ] それともいっこ、単純にあらかじめ大きめの容量を確保しておくという戦略は 使わないかもしれないオブジェクトについてデフォルトコンストラクタを呼んでしまう欠陥がある コンストラクタというのは初期化しか仕事しないから高速を要する処理中に極力呼びたくないわけよ この意味でも常にぎりぎりの領域サイズでrealloc()しつつプレースメントnewというのは 高速処理中にちまちまstd::vec<T>のインスタンスを生成するのに比べたらかなり手堅い (本当に手堅いのは高速を要する処理開始前に必要なサイズを全部確保しておくことだが)
733 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 03:49:59.13 ] 命令型言語のPGで新規の領域を不定値のままにして気持ち悪くない奴はカス なぜなら、命令型言語を選択したPGはその時点でチューリングマシン教の教徒であり、 チューリングマシンは状態の書き換えによって計算を進めるモデルだからだ そのためのType a = { }だったり(new Typeではく) new Type() 構文だろうノシ
734 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 04:03:38.84 ] >プレースメントnewでrealloc()した後にコピーコンストラクタで構築 とか意味が分からないけどとりあえず >使わないかもしれないオブジェクトについてデフォルトコンストラクタを呼んでしまう std::vectorもそんな挙動はしないよ?
735 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 04:39:50.99 ] >>734 >std::vectorもそんな挙動はしないよ? ちょっwwwwごめwwwwwwwwっうぇwwwwVS2010のstd::vector<T>で今調べたらそうだったわwwwwwww (確保した要素数しかデフォルトコンストラクタが呼ばれた) >意味が分からない サソプル イズ ベスト: struct TypeB { int x; TypeB() : x(-1) { } TypeB(const TypeB& other) { x = other.x + 100; } }; // コピーされたら100足される void test2() { const int n = 100; TypeB* sizableArray = (TypeB*)realloc(0, sizeof(TypeB) * n); for (int i = 0; i < n; ++i) { TypeB a; a.x = i; new(sizableArray + i) TypeB(a); // It's new! } for (int i = 0; i < n; ++i) cout << "sizableArray[" << i << "]=" << sizableArray[i].x << endl; } 実行結果は、sizeableArray[0] = 100\c\rsizableArray[1]= 101\c\r...
736 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 08:46:29.23 ] 語るね〜 終わったら呼んで。
737 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 13:56:10.85 ] >>731 bitwiseコピーした後にどうコピコンすんだよ 既にアドレス変わってる上に、初期化元は自分自身だろ
738 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:11:44.62 ] >>737 >new(sizableArray + i) TypeB(a); // It's new!
739 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:25:17.62 ] >>738 a って何だ?
740 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:27:32.56 ] >>739 アドレスsizableArray + i以外の場所にあるTypeB型のオブジェクト
741 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:29:39.39 ] 元データを論理的に保存しないといけないのに なんで別のものでコピコンすんの?
742 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:34:26.68 ] >>741 コピコンで元データが論理的に保存されないとする根拠は? >735のサンプルにおけるTypeBのコピコンにおいて、仮に100を足すのをやめたら >738で(スタック上の)aと論理的に同じオブジェクトがアドレスsizableArray + iにできるわけだけど?
743 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:35:49.79 ] >>742 そもそも、realloc したら元データが元の場所から無くなるんだよ
744 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:41:54.04 ] というか、>>735 読んでなかったが、今話してる事じゃねえよこれ vectorの伸張の話してんだぞ?
745 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:46:30.01 ] >>743 ああスマン、それはそうね p1がTypeBのコピー元配列srcArrayを指しているとして、 TypeB* p2 = realloc(p1, sizeof(TypeB) * n) の実行後、p2 != p1でありなおかつsrcArrayの要素がsrcArray内の他要素のアドレスに依存するならそうね しかし>702以降の流れはstd::vector<T>との比較という文脈なのを思い出してホスイ、 Tにそのような型が許されるだろうか?
746 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 14:56:54.97 ] >>711 からの流れだと思ってたのだがまあいいや
747 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 18:51:11.01 ] >>731 意味が解らん。reallocで1度コピーreplacement newでもう一度初期化。 処理が遅くなるだけだろ何のメリットが有るんだ?
748 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 18:53:19.14 ] >>733 命令型ってbashとかzshだろ メモリ確保は自動で行われるから 確保も開放も意識する必要は無い
749 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 18:54:29.33 ] あれだけruby厨だったuy( >>735 )がC++に手を出すようになったか
750 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:00:12.55 ] >>735 その内容ならmallocでいいだろ
751 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:04:47.26 ] >>730 memset か std::fill に決まってるジャン(std::fill_n は警告出る事あるのでやはり使わない) = { 0 } は可読性に劣るとも思うしね 初期化忘れか意図的な 0 クリアかが コメント残さないと確実に伝えられないから 最初の 0 がある意味マジックナンバーじみているのも気持ち悪い
752 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:30:08.71 ] 普通構造体に = { 0 }してたら初期化だと思うがな。 あと組み込み向けのしょぼいコンパイラーだとこっちの方が早いことがある 逆にmemsetの方が早いってのは聞いたことないけどね
753 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:43:36.33 ] >>751 それ初期化じゃないじゃん。 それに ={}; で初期化し忘れと読み取るアホはおらんよ。
754 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:04:39.00 ] = { }; は C で使えないよね
755 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:09:06.33 ] 使えないけど、それがどうかしたの?
756 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:13:57.52 ] 知らない人が結構いそうだから使いたくないわ
757 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:24:10.37 ] >>747 >reallocで1度コピー 領域拡大時であってもrealloc()だとコピーが起きないことがある 縮小時はもちろんほぼ常に起きないことが期待できる >replacement newでもう一度初期化。 誰も2回も初期化しないわけだが つかデフォルトのnewは使えば必ずメモリ確保してから初期化するのに対し、 プレースメントnewはそれ自体はメモリ確保しないから、 メモリがすでに確保されている場合はより早いの ワカル?
758 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:38:05.66 ] >>757 理解出来てないなら黙ってろ
759 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:38:21.85 ] >>748 ソウジャナイ 破壊的代入が本質的(それ無しには何事も進まない)のが命令型言語、 非破壊的代入で全て済ますのが関数型言語 前者はチューリングマシン、後者はλ式をそれぞれ数学的基礎とする 一方で書けるアルゴリズムは他方でも書けるという意味で両者の計算能力は等価 ただし得手不得手はもちろん違う
760 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:41:11.32 ] >>758 どこらへんがおかしいのかkwsk つかrealloc()が勝手にコピーするとオブジェクト必ず壊れるとか思ってる? std::vector<T>の要素型として使える型Tについてはそれは心配せんでええ
761 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:50:37.51 ] >領域拡大時であってもrealloc()だとコピーが起きないことがある >縮小時はもちろんほぼ常に起きないことが期待できる どういう理屈なんだ?
762 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:51:25.25 ] >>759 お前が言ってるのは手続き型だろ
763 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:54:06.90 ] >>759 関数型は、演算式と制御文を全て関数で記述する事を目的とした言語 破壊的代入が無いというだけだと宣言型とダブるので、 破壊的代入が無い = 関数型というのはおかしい
764 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:03:04.70 ] >>761 K&Rの終わりぐらいに書いてあるmalloc()の実装例でも読めばおk サイズs1、s2の領域がこの順で隣接しており、s2が開放されたなら サイズs1をサイズs1+s2までコピー無しで拡大することができる (※簡単のため管理用のヘッダサイズは無視) >>762 関数型言語であってもリストで手続き(順序的な処理)を表わせるから 手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念 Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、 手続き型というのはそれの対義語
765 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:12:41.32 ] >>763 宣言型というのは、ようわからんが非手続き型っていうのとほぼ同義ジャネ? 破壊的代入無しでチューリングマシンの計算能力と等価な言語、 といえば多分λ式ベースの言語(つまり関数型言語)しかないんじゃないかなあ、、 なお、関数型は、(関数で)新しい関数を作り出すことしかしない故に関数型
766 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:12:47.96 ] >>764 mallocじゃなくreallocの内部の話なんだけど 実際コピーしない処理系が存在するのか? gccのreallocはソース公開されてるがコピーしてる 実際どの処理系がしてるんだ? 普通に考えてもmalloc内部の実装に依存するreallocなんてクソだろ
767 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:15:18.80 ] >>764 >関数型言語であってもリストで手続き(順序的な処理)を表わせるから >手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念 >Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、 >手続き型というのはそれの対義語 お前だけの常識で語られてもなぁ
768 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:32:45.54 ] >>766 realloc()をmalloc()と別階層とすべきですかそうですか、、 コピーを生じない処理系の具体例については、 少なくとも下記コードをVS2010で走らせるとp1 == p2なんだけど? void* p1 = malloc(1000); void* p3 = malloc(1000); free(p3); void* p2 = realloc(p1, 2000); cout << "p1=" << p1 << ", p2=" << p2 << endl; glibcのソースをよく読みなおすことをお勧めする >>767 漏れだけの常識がどうかはようわからんが、そうなの? >764で妥当だと思うがなあ〜
769 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:35:05.31 ] で、いつまでちんたらちんたら続くんだ?
770 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:36:14.02 ] >>760 おいおい、オブジェクト領域でreallocなんか使ったら壊れるだろうがw ポインタ関係が全部おかしくなるわ。
771 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:38:31.10 ] >>768 サイズ変更が「可能な場合」はコピーされない。不可能な場合はコピーされる。 コピーされる場合はありえるんだが、たまたま特定環境化で動作するから使っていいとかアホの極み。ドシロウト。 仕事でそれ使ってたらリアルで背任でクビになるようにもっていく。
772 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:39:33.64 ] >>768 そのコードじゃそりゃそうだろ。 つかそのコードはreallocの問題じゃねぇ。言い方悪かも試練が偶然だ。 解放された領域をもう一度使用してるのは意図して書けばできる事だが、 reallocが同じ領域であることを知っててコピー処理を省略してるかどうかは別問題。
773 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:40:57.09 ] >>770 >ポインタ関係が全部おかしくなるわ。 ポインタを含まないか、ポインタを含んでも指す先が移動対象でないなら そういうオブジェクトは勝手にコピーされても無問題でしょ? で、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、それは成立している、というしくみ
774 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:45:00.34 ] >>771 >>772 まあ冷静に コピーされる場合がありえるし、コピーされる/されないを realloc()の呼び出し側で制御できないのは承知していますから ただ、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、 プレースメントnewをうまく使って安全にrealloc()で領域管理できるという話
775 名前:デフォルトの名無しさん [2012/04/22(日) 21:54:51.43 ] マジレスしないでニヨニヨ笑ってる人が絶対いる悪寒 あまりにも不自然すぎる
776 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:56:42.25 ] >>774 二重コピーされる分realloc使うのが無駄なのは事実だろ まだmalloc, free, mallocしてreplacemente new呼んだ方がマシだ
777 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:06:36.44 ] >>776 ちょっと前のレスから気になってたが、replacement newってなんぞね? また、realloc()の呼び出し1回で同一オブジェクトのコピーが2回起きるみたいな書き方も気になるが、 それっていつどういうシチュで?? もし>738のようなコピーコンストラクタ呼び出しの回数のことを言ってるのなら、 それはrealloc()一回につき同一オブジェクト当たり1回以下にできる (realloc()がコピーするかしないかや呼び出し下で制御できないが、 領域の移動があったかどうかは呼び出し元で判定でき、移動しなかったオブジェクトについて呼ぶ必要はないため。)
778 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:08:51.64 ] その程度の処理が問題になるなら動的確保自体使わなきゃいいだろ。 まずはEffectiveC++でも嫁やザコ
779 名前:777 mailto:sage [2012/04/22(日) 22:10:35.64 ] スマン訂正 std::vector<T>の要素型として使えるような型Tのオブジェクトなら、 勝手にコピーされても何もする必要がないから、領域の移動は関係なかったな、、
780 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:14:06.10 ] >>777 reallocで1回、new( buffer ) Type();で1回、合わせて2回だろ。
781 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:23:58.97 ] >>773 自分自身をさすポインタをもつ場合、コピーコンストラクタ/operator=を正しく書けばvectorに入れられるが、メモリコピーでは正しく処理できない。
782 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:34:14.86 ] >>780 普通そうはならないべ サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。) 運が悪ければ、領域の移動を要し、サイズs1の部分のみコピーされる(コピー1回)。 ここには今の想定だと構築済みオブジェクトが入っているが、コピー安全なオブジェクトなのでそれ以外なにもしなくていい。つまり、コピーはオブジェクト毎に高々1回。 で、new(p) Type(); が必要なのは、新規に確保されたサイズs2の領域だけ。よって、2回コピーされるオブジェクトは生じない。 なお、細かいことを言えば、new(p) Type()はアドレスpについてType型のデフォルトコンストラクタを呼び出すだけなのでコピーではない。 また、Typeのデフォルトコンストラクタが全フィールドを確実に初期化する保証があるなら new(p) Type(); と書くより new(p) Type; の方がよろしい。(0 fillが省略されるから早くなる。いつの規格からかは知らん。) >>781 ああすまん、それはそうね。
783 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:41:23.02 ] >>782 >サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。) この前提が間違ってるって何度も指摘されてるだろ
784 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:45:14.75 ] >>782 手間が増えるだけでreallocするメリットねぇじゃねぇか
785 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:45:21.40 ] >>783 >何度も指摘 kwsk すくなくとも、(たまたまかどうかはともかくとして)realloc()前後で領域が移動しなかった実例が>768にあるわけだが これって呼び出し前後でアドレスが変わらない部分についてもrealloc()は律儀にコピーしてるってことなの?? >738おすすめのヒープメモリ管理方式を聞いてみたい気がするカモメ、
786 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:49:16.76 ] >>785 ことなの?じゃなくコールスタック追いかけるか 逆アセしてみろよ。memcpy呼ばれてるだろ
787 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 23:06:31.08 ] >>786 VS2010のデバッグモードでmemcpy()にブレークポイントしかけて見て見たが、 >768のコードにおける4行目 void* p2 = realloc(p1, 2000); の呼び出し中のmemcpy(src, dst, count)の呼び出し回数は3回、ただしcountはどれも2だったべ これはリンクリストか何かのコピーじゃねーの? (>783の指摘どおりだとしたら1000バイト級のmemcpy()が起きないとおかしいが) で、仮に万が一>783の指摘が正しかったとして、2回コピーされる件はどうなったのよさ? 主張を取り下げて>782で納得?
788 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 23:09:34.08 ] 不毛だ
789 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 23:27:27.52 ] >>787 2回コピーは俺だが。新しい領域のみコンストラクターの結果を コピーするんならたしかにコピーは1回だな。そこは納得するよ。
790 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 23:45:41.19 ] >>787 codepad.org/tlYgmcrc そもそも、同じアドレスだからと言って一旦解放された領域に 同じ値が入ってるとも限らんからな このコードVSにコピペして実行してみ
791 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 01:13:06.56 ] >>790 ちょっwwwwwwおまwwwwwwwwww 例示のコードはrealloc()とは話が違うわけだが そりゃーfree()で本当に解放してしまった領域には誰に何書かれるかわからんでしょうよ (別スレッドあり、デバッグビルドのfree()だと丁重に0xccccccccで埋めてくれたりすることあり。 セキュリティー目的で埋めるライブラリもあるかも試練、) なんつーか>768のコードの意図が伝わってないようだけど、 K&R式なmalloc()およびrealloc()な実装の下で>768をシングルスレッド状況で走らせると >782で言うコピー0回な挙動になるんすよ >768は、その挙動を演出するために、使用中の領域(p1)とは関係ない領域(p3)を一旦malloc()後にfree()してるだけ p1が指す領域は一貫してfree()されない。
792 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 01:26:27.20 ] >>779 vector の要素型に realloc() で発生しうる memcpy() への耐性なんて要求されてないんだが
793 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 01:43:35.76 ] >>791 realloc内部でfreeされるがな
794 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 02:08:56.95 ] だから、C++ならnewだけを使えよ。 わざわざ危険を犯そうとする冒険者になることは、ない。
795 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 02:19:24.31 ] newの使い方よりも newそのものの速度が問題になる状況って どんな状況だ?
796 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 03:05:19.97 ] もうほっとけよ
797 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 03:19:14.56 ] class MyClass{ public: bool hoge(); } MyClass instance; があるとして、 「instance.hoge()」 が与えられたときに、 「MyClass::hoge(),&instance」 を返すようなマクロは作れませんでしょうか?
798 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 04:24:58.06 ] メンバ関数ポインタ
799 名前:797 mailto:sage [2012/04/23(月) 04:25:55.73 ] なんとか、 「instance.hoge()」 という記述から、メンバ関数ポインタとthisポインタを取得したいんですよね。。。
800 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 06:50:18.40 ] 「&MyClass::hoge,&instance」が欲しい理由じゃないのか?
801 名前:797 mailto:sage [2012/04/23(月) 12:43:53.90 ] これが欲しい理由は、一度&MyClass::hogeと&instanceを保存しておいて、 あとでそのメンバ関数を呼び出したいんです。 使う箇所が多いので、テンプレートとかでなんとかできないかと思いました。
802 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 12:53:08.14 ] std::bindとstd::functionでおk