1 :
ゆとり :
2010/12/09(木) 19:31:20
2 :
ゆとり :2010/12/09(木) 19:32:59
3 :
ゆとり :2010/12/09(木) 19:34:23
4 :
ゆとり :2010/12/09(木) 19:35:36
5 :
ゆとり :2010/12/09(木) 19:37:03
6 :
ゆとり :2010/12/09(木) 19:39:58
おっつ
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
javaではpublic class{}と出来ますが、C++はクラスの修飾子が無いんですか?
ありません
名前空間が後付けだから必要なかったのかなー。
enum A { a, b, c } に d を動的に増やすことはできますか?
enumってコンパイル時定数だよね。
gccで開発しているのですが、 コマンドライン引数をmain関数以外で取得する方法はありますか? BCBのParamCount()のようなものを探しています。
15 :
質問 :2010/12/10(金) 00:40:53
VC++2005でコンパイルするとVC++2005再頒布可能パッケージがどうして必要になるのでしょうか?
そういう仕様だから
A n = (A)3;
>>15 ランタイムライブラリを動的リンクしてるから
静的リンクすれば必要ない
19 :
質問 :2010/12/10(金) 01:02:00
>>16 無駄なレスで貴重なスレを消耗しないでください。
そういやいつの間にか
>>8 は1レスにまとめられるようになってたんだな
てか
>>8 って毎度貼られるけど何なの?
part80くらいからしか見てないからわからん。
>>22 かなり前に面白い流れだからって新スレを立てた人が次スレにも貼ったのが
始まりだったと記憶している
過去ログを漁ってみた。 「STLつかうと〜」の初出が part16 (2003/02/21) で、 part17 にデジャブネタとして コピペされたときにテンプレ指定され、隣接していた「C1010: プリコンパイル済みヘッダーの〜」の くだりまでまとめて part18 で貼られ、その後長らくテンプレとして毎度貼られていた。
初代C++相談室のスレ建てが 2001/01/22 だった。 もうすぐ10周年になるようだ。
wmain てマイクロソフトの拡張なんですか?
はい
整数型なんですけど、-1,0,1のようにある特定の範囲以外を代入しようとするとエラーを吐くような型(クラス)を作りたいのです どうすればよいでしょう?
クラスに Set用の関数とget用の関数つくるしかないんじゃね?
class Int { public: int operator =( int val ){ return this->val = val; } private: int val; }; これでなんとかしろ
operator int(){return val;}も必要じゃね?
コンストラクタ/デストラクタで特に何もしないときに、 わざわざコンストラクタ/デストラクタを宣言しますか?
>>34 The value of the result of both operators is implementation-defined, and its type (an
unsigned integer type) is size_t, defined in <stddef.h> (and other headers).
要するに処理系定義の符号なし整数型
inlineを付けると関数呼び出しのオーバーヘッドが減るらしいですね でも、インラインと非インラインの関数の違いがイメージ出来ません 説明お願いします
int i = 0; ++i; これと void increment(int& i) { ++i; } int i = 0; increment(i); これ どっちも同じことしてるけど後者の方が遅いっていうのは分かるよな? それでinlineを付けるとコンパイル時に前者に置換されるわけだ
39 :
37 :2010/12/11(土) 22:13:18
>>38 > どっちも同じことしてるけど後者の方が遅いっていうのは分かるよな?
わかんねーだろjk
37 も何納得してんだ。
アセンブリレベルのコードで比較しないと意味無い。
>>40 がアセンブリレベルのコード比較でinlineがどんなものか教えてくれるらしいぞ
普通にわかったけど
関数呼び出しがなくなる分 スタック積む?処理がなくなるから オーバーヘッドがなくなるってことなんじゃないの? C++ はじめてまだ15分ほどなんでよくわからないですけど。 Cは未経験です。 童貞って意味じゃないです。 いや、まぁ童貞なんですけどね。
>>29 目指しているものと一致してるかはわからんが
演算子をオーバーロードして範囲チェックを行うやり方があるね
範囲そのものはポリシーで挿げ替えるという実装
オライリーの本だかに載ってたと思う
>>39 おいおい安易に納得するな
inlineはregister指定と同じで、コンパイラはこれを無視する事が出来る
本当にインラインになっているかどうかは
>>40 の言う通りで逆アセンブル
画面を出して見てみないと分からないぞ
だれもそういうことを聞いているんじゃないんだよね。
>>38 これ見て後者が遅いと思い込むなんてのは、 for の中で変数宣言したら
遅くなるから外で(なんならグローバルで)とか言うのと同じような勘違いだ。
C++ 上の字面とパフォーマンスを直結させるべきじゃない。
>>47 必ずinline展開されると思い込んでいる馬鹿もどうかと思うけどね
誰がそんなこと言ってるんだ?
現代のコンパイラは最適化の上ではinlineキーワードの有無をほぼ確実に無視する。 inlineはリンカに関数定義の重複を無視するように指示するものだと考えた方が 実用上は便利だ。
inline展開の早くなる仕組みを聞いてるのに実際展開されるかどうかは別の問題なんだよね
>>48 質問の意図を履き違えて関係ないことをべらべら喋り出すアホの典型
class Super { string &m_str; public: Super(string &s) : m_str(s) {}; } class Sub : public Super { public: Super(): Super("string") {}; } スーパークラスの&m_strを使う事は危険ですか?
>>54 そもそもprotectedでないと派生からはm_strは使えない
それとなぜに参照?""で渡すと
一時オブジェクトが破棄されて存在しないものの参照が出来上がるんじゃないか?
56 :
54 :2010/12/12(日) 14:11:20
class SubにSuper()ある
58 :
54 :2010/12/12(日) 14:32:54
std::string &s = std::string("hellow"); って怒られるんだね 知らなかった
コンパイルしてから聞けよ
const string&s なら一時変数も束縛できる、って知ってたよな
これどこ間違ってるん?表示が滅茶苦茶なんだが class Super { protected: const std::string& m_str; void write() const { std::cout << m_str << std::endl; } public: Super(const std::string& s) : m_str(s) {}; }; class Sub : public Super { public: Sub() : Super(std::string("string")) {}; void write() const { Super::write(); } }; int main() { Sub* s = new Sub; s->write(); delete s; }
63 :
デフォルトの名無しさん :2010/12/12(日) 15:26:42
>>46 そういえばコンパイラが無視していいものの中には volatile もあるな
>>51 単一定義規則は inline がついていても見逃してもらえないぞ
>>62 class Superのm_strが束縛する責任があるのはコンストラクタのsのみ
コンストラクタのsを束縛する必要があるのはSubのコンストラクタの一時変数のstringのみ
したがってm_strはSubのstringを束縛する責任がない
つまり、Superのコンストラクタの実行が完了した時点でSubのstringの一時変数は解体
されてしまうので、m_strの参照は実体が無くなる
これを防ぐには
class Super {
protected:
const std::string m_str; // 参照にしない
void write() const {
std::cout << m_str << std::endl;
}
public:
Super(const std::string& s) : m_str(s) {}
};
のようにコピーを保持しなければならない
>>64 なるほど、const参照のconst参照という風に2段以上に重ねると
問題が生じるようですね
これは盲点でした
これから気を付けます
ありがとうございました
何を面白いことを言っているのだ。 Super s ( std::string("string") ); の時点でアウトなんだよ。 SuperとかSubとか書いてたり、仮想関数を知らなかったりするあたりJava使いだと思うんだが、 Javaの発想は全部捨てないとCやC++はぜんぜん挙動が違うぞ?
>>63 volatile は無視しちゃいかんだろう。
inline で単一定義規則の制限が少し楽になるのは確かだろう。
>>66 なんでアウトなんだよ
ただの一時オブジェクトじゃないか
それに今回は仮想関数は必要ないだろう
>>70 一時オブジェクトを指して初期化された参照は、 Supuer の初期化が完了した時点ではすでに
無効になっている。
>>66 にある初期化の後、 s を使ったあらゆる操作が未定義動作になりうる。
>>71 だからお前の言ってる事は
>>64 で全部書いてあるだろう
なぜ同じ事を二度も言うんだ?
>>65 が「なるほど」とか言いながらさっぱり理解してないからだろう。
>>74 65 が理解している問題発生の条件は「const参照のconst参照という風に2段以上に重ねると」
となっているが、実際には2段重ねなくたって同じ問題は発生する。
struct S { std::string const& s } s = { std::string("string") };
>>75 だったら最初からそのようにシンプルに書けばいいだろう
ネチネチと厭らしいんだよてめえの書き方は
>>75 だいたいコンパイルが通らないコードを書いてどうするつもりなんだよ?
>>77 そうだな。すまんかった。
#include <string>
struct S { std::string const& s; } s = { std::string("string") };
>>79 「コンストラクタがありません」と言われますけど?
>>81 BCC(ECC)6.3.1だ
エラーメッセージは「リファレンス メンバ 'S::s' があるクラスにコンストラクタがない」だ
当然だと思うが?
gccの拡張だろう
>>62 は継承とか使っているが、根本的に
一時オブジェクトと参照がどういうもかと言う基礎的ことを知らないってのが原因じゃね
恐らく、
>>62 はポインタ使ったのでも一時オブジェクトを気合を入れて指すコード書くんだろうな
>>83 だからお前のは単なる憶測に過ぎないから
なんでそう自分の価値観を人に押しつける?
うぬぼれが強すぎるんと違うか?
>>82 codepad は -std=c++98 -pedantic-errors だから gcc 拡張の線は薄いな。
http://codepad.org/about 暗黙宣言のデフォルトコンストラクタが使われれば暗黙定義で S::s が初期化されて
いないことが問題になるだろうが、この例では { ... } による初期化が行われているので
問題にならないほうが正しいと思う。
>>85 §12.6
4 If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case
where there is no mem-initializer-list because the constructor has no ctor-initializer), then
? If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base
class, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a nonstatic
data member of a const-qualified type, the entity class shall have a user-declared default constructor.
? Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a
(possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
a const-qualified type, the program is ill-formed.
お前さんの言っている事はデタラメである事がはっきりしている
>>86 念のためにこれも付け加えておくか
After the call to a constructor for class X has completed, if a member of X is neither specified in the
constructor’s mem-initializers, nor default-initialized, nor value-initialized, nor given a value during execution
of the body of the constructor, the member has indeterminate value.
はっきりと「メンバの値は不定」と書いてあるだろう
つまりgcc拡張である事が明らかだ
>>86 いや、だからさ、それは暗黙定義のデフォルトコンストラクタで問題になるわけで、
>>79 では暗黙定義のデフォルトコンストラクタは使われていないから問題ないだろ。
>>88 お前英語が読めないんだろう
the program is ill-formed.
の意味が分かるか?
リファレンスをメンバに持っていてそれがコンストラクタで初期化されない時は
そのプログラムは不適格とすると書いてあるだろう
つまりコンパイルが通らないので正しいわけだ
>>87 それも関係ない。参照型メンバは初期化リストで初期化されなければコンパイルエラーに
なるから、当該のコンストラクタが実行されることもないし、もちろん完了することも無い。
>>89 コンストラクタ定義の中で
>>86 の条件に合えば ill-formed なんだよ。
>>79 では問題のコンストラクタ定義が無い。
何度言わせるんだ?お前は日本語が読めないのか?
>>91 もう好きなようにしろ
規格を呈示しても難癖付ける奴にはもう言う事はないよ
自分独自の世界でプログラムでもしてろ
>>92 規格を提示って言っても、関係ないところ提示されて話になるわけないだろ。
最後に一つ 「英語が読めない奴はJIS規格でも読んでろ」
英語の規格がちゃんと読めてもダメな人ってのはいるもんだな。
>>81 をVC2005でやったがコンパイル通った
よく分らんが、
struct S { std::string const& s; } s = { std::string("string") };は
"{" std::string("string") "}";
{}あるからSはクラスじゃなくC的な構造体ととらえられてるんじゃない?
C++のstructはpublic class扱いのみで、データをまとめるC的structとしては扱えないの?
クラス扱いでs = { std::string("string") }; はありえる?
97 :
66 :2010/12/12(日) 21:44:53
こんばんわ。java厨のガラスのハートに傷をつけてしまいましたか?w
>なるほど、const参照のconst参照という風に2段以上に重ねる
これに対して「何を面白いことを」ですよ^^
>>64 のいってることはあってますよ^^
>>96 > {}あるからSはクラスじゃなくC的な構造体ととらえられてるんじゃない?
逆。 aggregate として扱われているから { ... } による初期化ができる。
> C++のstructはpublic class扱いのみで、データをまとめるC的structとしては扱えないの?
問題なく扱える。
> クラス扱いでs = { std::string("string") }; はありえる?
あり得る。
エラーが発生しているのは BCC(ECC) のバグ。
参照メンバを持つクラスの集成体で初期化とかやったことないな
100 :
デフォルトの名無しさん :2010/12/12(日) 22:32:19
参照メンバというのが実用上あまり使わない →過剰なポインタ嫌悪の権化 Cスタイルの初期化でコンストラクタとかもう聞いただけで汚らわしい
集約の規則に参照型のデータメンバがあっちゃだめって規定はないから問題なし。 むしろ、ユーザー定義のコンストラクタがあるほうがだめ。
>>101 それはstructの時だけだよね
classでできる?
>>102 class { public: .. } とすれば同じこと。
集約の規定に「privateまたはprotectedの非静的データメンバを含まないこと」ってある。 classかstructであるかは問題ではない…が、結局いっしょ。
106 :
96 :2010/12/13(月) 00:34:59
まぁ、BCCは準拠度低過ぎで随所でダメだしされてるわね。 テンプレート使うと大爆発するし。
規格を晒してキリッと断言してる人、道化師でワロタ
switchのなかにswitchってぱっと見でごちゃっとしてて見にくいけど、 普通にやってることなんだよね?
普通にってほどじゃないけど、まぁある。 関数化すれば?
bccとか使ってる人いまだにいるんだ
112 :
デフォルトの名無しさん :2010/12/13(月) 13:30:03
自らの意思で選んでいる人もいるし 組織の力学で決まってしまっている人もいる
113 :
デフォルトの名無しさん :2010/12/13(月) 15:00:18
constでないstd::vectorインスタンスを途中からconst扱いに変えることはできますか? 初期値を代入した後は変更できないようにしたいんですが。 std::vector<int> foo; for(int i=0; i<n; i++){ foo.push_back( hoge(i) ); } const std::vector<int> bar = bar; //←コンパイルエラー(当然か) 一旦 std::vector<int> temp; あたりに初期値を作って const std::vector<int> bar = temp; とかやるしかないでしょうか?
変えたいと思ったあたりを関数化できないか検討してみる。 だめなら、その方法しかないかなと。const参照にすればいいよ。
>>113 vectorをメンバに持ち、const参照を返すメンバ関数とコンストラクタのみをpublicに持つクラスでも作れば。
初めからconst付きにして、初期値を入れるときだけconst_castする
117 :
113 :2010/12/13(月) 18:10:50
>>114-116 アドバイスありがとうございます。
const_castが最小限の変更ですっきり書けそうですね。
多用して慣れきっちゃうのも怖いですけど。
それぞれ試してみます。参考になりました。
揚げ足取りだけど、constで「定義」されたものをconst_castして状態を変更 したら規格的には未定義動作になるお。 std::vector について言えば多分平気だと思うけど
C++0xではconst な vectorメンバを定義する新しいコンストラクタの記述法が導入されるとかされないとかビッグなうわさがあったと思うんだけど・・・どうだっけ?
const std::vector<int>bar = std::move(foo); でいいじゃん
>>119 今でも普通にできるんだから、何か勘違いしてるんだろう。
static const mapとかは初期化がめんどいけど、それが解消されるという話があったかもしれない
巨大なルックアップテーブルを static const map で書ければいいなあ。実行時にせこせこ代入していく生活はやめたい。
0xなら楽勝
テンプレートでmapって作れんのかな 作れそうだけどすごいめんどくさそうだな
mapってテンプレートじゃね?
巨大なテーブルをstd::mapで作りたくはないな。std::lessでキーの比較してるだけでしょ。 やっぱ連想配列はハッシュしてからless比較だべ。
unordered_mapでやれ
typedef Map< 1, 5, 4, 6, ... > map; cout << get<map, 4>::value; // 6 こんな感じならできそうだけど、整数だけ扱えてもあんま嬉しくないよなぁ
0xのstd::arra::operator[]ってvectorと同じく範囲チェック無いのな。 今時、範囲チェックぐらい全部入れろよと思う。ar.at(16) = 100なんて書いてられん。 せめて天ぷら引数で範囲チェックありなしのポリシーを指定するとか考えなかったのか。
それぐらい自前でやるかat使え低能
at()は典型的な例外の誤用だろう。配列の添字のチェックなんてことはassert()でやるのが筋だ。
operator[]の範囲チェック無いのは0xじゃなくても結構あるな。くそったれが。
なんでそんなにコストを増やしたがってるのか分からん。配列にアクセスするたびに範囲チェックされるとか考えたくもない
Releaseビルドではオフになればいいだけだろが
範囲間違えてアクセスするような人はC++向いてないのでRubyでもつかっててください
で、でたー!バグは出さなければいい理論!
範囲チェックでパイプラインが詰まったとして、それが一体何ナノ秒のロスなんだよ。 コストが本当に問題なら先頭要素のアドレス取ってポインタで操作するのが当たり前だろ? 危険な動作をデフォルトにするんなんて、今時の言語からしたら仕様のセンスが疑われる。
>>139 お前はC/C++向けじゃないんでLL言語かJavaかC#でも使っててください
へぇ、特にオーバーロードされていない添え字演算子よりもポインタ操作の方が速いんだ
つーか範囲外アクセスを検知できてうれしいことなんて無いだろ
検知できればオーバーランした時点で落とすことができるから、別に悪いことでもないと思うよ。
ただ、コストが無駄だと思う。
Releaseビルドでオフになっていいと思ってる人にはそれでいいと思う。
ただ、
>>130 はReleaseビルドでも残ってほしいんだろ。at使うんだから。
>>143 配列操作でバグによるメモリ破壊が起こらないことが保証されてるってのは
とても大きいと思うが。Releaseビルドにこそ必要な機能だと思う。
vectorみたいにある程度速度を求めるところに使うのは範囲チェックも意外とバカにならないよ VC使うと分かるけど。あれなんで標準オンなんだよ
事前に一回範囲調べればいいのに アクセスするたびに範囲チェックするなんて無駄なコスト払えないよ それにエラー処理コード書くぐらいならその手間で範囲オーバーしないためのコードを書くよ
>>141 言いたい事はそれだけか低脳
仕事でも使ってますが何か?
>>146 ReleaseではオフになるけどDebug版で製品だしてるの?
実行時の強力なチェック機構がほしいなら何もC++にこだわらなくてもいいじゃないか。 SEは言語の選択もまた重要な仕事の一つじゃろ^^ いまどき単一言語で何もかも開発するなんてバカげちょる
C/C++に文句言うのは筋違い。他のLLに行くのが正しい。
>>151 仕事なくなったからってこんなとこで遊ぶなよ
>>151 お前は文句の矛先を間違えている
間違っているのはC++ではなくお前の頭
そうしているうちにC++のメリットの少なさとデメリットの多さから、 C++の仕事がどんどん無くなっていくのであった。 C++屋も「嫌なら他の言語やれ」と固執しているのでめでたしめでたし
守銭奴言語やLLならちゃんと例外投げてくれるぞw よかったねw
>>149 たしかリリースでも有効な罠があったはず
デバッグでも重いのは勘弁して欲しいところなんだが
>>157 範囲チェックで重くなるってどんな処理系でやってるの?
>>155 良かったなあC++脳じゃなくて
せいぜい単価の安いJava土方でもやっててね
>>155 職を失うのは単に本人の責任だろ^^
知識ポートフォリオは技術者なら当然なわけで。
>>158 処理系ってVCとかのことを言うんじゃないの?
それともWindowsって答えればいいの?
>>161 windowsプログラムで範囲チェックしたら重くなるようなプログラム書いてるってこと?
>>142 当たり前じゃね?
配列インデックスがポインタ演算に置き換わる最適化なんて限度があるんだし、
かけ算と足し算を毎回実行してたらまずいだろ。
>>162 そうだよ。つかVCのvectorをWindows以外で使う人はほとんどいないと思うんだが…
166 :
デフォルトの名無しさん :2010/12/15(水) 00:39:47
>>139 語るに落ちてるぜ
おまえ自身が何ナノ秒かわからなくて言ってるんだろ?
for(i=0;i!=v.size();++i) { if(v.size()<=i) return FAILED; ・・・ } 範囲チェック派ってこれに違和感感じない人ってことだよね?ちょっと頭やばくない?
無意味な例を持ち出してきたお前の頭のやばさを疑うよ
>>166 まわりのコードやループ回数にもよるだろうし定量的には言いにくいね。
分岐予測して仮実行してたのが当たった時の遅れだからたいしたことはないだろうけど、
5ナノ秒はかからんだろたぶん。まあ実測あるのみだね。
>>167 ループの中でi以外のインデックスを使わないんだったらイテレータで
安全に書けるでしょ。i+4とかi-1とかの要素にアクセスするんなら
チェックがあってもおかしくないんじゃない?
171 :
デフォルトの名無しさん :2010/12/15(水) 00:57:52
>>169 5ナノ秒を「保証」できるか?
さもなくば、おまえの論も「危険」なのか?
>>170 おかしい
それは開発段階で排除できるミスだからリリースまでチェックを残す必要性が無い
>>168 よくわかってるじゃないか。operator[]が範囲チェックするのは無意味なんだよ。
>>167 はoperator[]が範囲チェックするってのはこれと同じことですよといっている
>>170 vectorはランダムアクセスイテレータだからoperator[]に範囲チェックが欲しい人は
イテレータにも範囲チェック欲しいだろ
>>173 その例じゃ無意味さを表現出来てないから頭やばいと言ってるんだけど
boost::arrayに範囲チェックあるのはなんでなの?
C++の仕事減っているんだが、お前らのところどう? やっぱり、日本は低脳が超増えているから、ゆとり言語じゃなければ駄目な国に になってきてるんだよな
おお、盛り上がってるな。 非常に残念だが明日早いから寝るわ。
範囲チェックしたけりゃすりゃいいがな ライブラリに範囲チェック組み込まれたら範囲チェックしたくないときは使えないという選択しかできない
180 :
130 :2010/12/15(水) 01:13:10
なんかスレがすすんでるなオイ。お前らこんな議論するより
>天ぷら引数で範囲チェックありなしのポリシーを指定するとか考えなかったのか。
にしとけばどっち派でも好きな方選べて文句無いんじゃねーの?
範囲チェック有り無しのif文なんて最適化で消えてオーバーヘッド無いだろ。
>>179 いやだからテンプレ引数で選択できるようにしたらと最初から言ってるのだが。
「せめて」とか書くから争いの元に…
それこそ無意味だろ []とatできりかえれるんだから
183 :
130 :2010/12/15(水) 01:22:39
範囲チェックのオンオフでコードを壮大に修正したくはないのだが。 まあいいや。もう寝る。
正直このへんくると微妙な議論だが テンプレ引数で選択できるようにしたら範囲チェックするvectorと範囲チェックしないvectorは別の型になるが大丈夫か?
ポリシーにしたほうが壮大な修正はいるわあほかwww
規格では「未定義の動作」で FA だろ。 未定義の動作の一部として処理系が独自の条件で throw out_of_range をあてがえばいいだけのこと。
範囲チェックを全部に入れて欲しいのか、それとも範囲チェックの有無を 簡単に切り替えたいのかイマイチ主張がわからんな 既存のソースを修正せずに範囲チェックを追加したいってことか?
>>186 チェックしてくれるのはありがたいけど、その通知方法はabort()にして欲しいな。
リリース版であっても、いやリリース版だからこそ、
バグを検知したら即座に異常終了してデバッグ情報を残すのが誠実なプログラムだと思う。
そういうコンテナを自前で作ればいいじゃん
>>188 客先にJITデバッガでも入れてるのか?いきなりabortされたらデバッグ情報も残せないだろ。
サーバアプリならcatchハンドラで各変数の状況をログに残して
プロセス終了した方がいいと思うし、
GUIアプリならプログラムがabortするより丁寧なお詫び文を表示して
プログラム終了した方がユーザーの怒りが少ないだろう。
コアダンプとかワトソン先生のような仕組みが存在する前提での話。 無ければ自分でなんとかしないとならないけど、いずれにせよ例外でロールバックされちゃかなわん。
メモリダンプ読むなんて暇だな。その労力、別に使った方がいいと思うよ
ダンプも読めない女子供はすっこんでろ。
194 :
デフォルトの名無しさん :2010/12/16(木) 20:59:01
ダンプ読みは1年目の研修でみっちり叩き込まれた アセンブラに自信があったのに甘さを思い知らされた
Javaにした方がいいぞ。メモリダンプなんていらん。 本当にC++屋はくだらないことに努力して仕事を失っていくのが好きだな
ここ数十年C++で仕事してるが、メモリーダンプなんか見た事無いぞ。 よっぽど効率悪い開発してるな、又は組込か?
Windowsアプリじゃありえないよな。組み込みだろ
Linux環境だな
コア読む暇があったらログの強化とコードレビューに時間使った方がいいぞ。 あとはプログラムの再起動を仕込んでおけばOK
コードレビューw
>>195 > Javaにした方がいいぞ。
> した方がいいぞ。
「した方がいいぞ」
お前働いてないことがよく分かる一言だな。
C++なんて糞は捨ててC#に城
C#とか糞のかたまりでしかない
#ifndef DEBUGWRAP_DEBUG #define DEBUGWRAP_DEBUG //Debug.hpp namespace DebugWrap { void OutputDebugStrA(const char* pString); void OutputDebugStrW(const wchar_t* pString); } #endif //Debug.cpp #include "DebugWrap/Debug.hpp" #include <windows.h> namespace DebugWrap { void OutputDebugStrA(const char* pString) { OutputDebugStringA(pString); } void OutputDebugStrW(const wchar_t* pString) { OutputDebugStringW(pString); } } というのをVCで /Za(言語拡張を無効にする)オプションで コンパイルしたところ、予期せぬ EOF が検出されました。エラーが出ます どこがおかしいですか?この有効状態ではコンパイルが通ります
VB --> C# と進む人が居ても、 C++ --> C# と進む人は少ないんじゃないだろうか。 C#使うならVBでいいや。
それはねーよ
>>205 プリコンパイル済みヘッダは無効になっています
日本には低脳土方しかプログラムしないのに、なんで高脳用のC++使うの 低脳用言語C#、VB使いなさいよ
底辺派遣プログラマがいくら「俺はC#で行く」っていったところで プロジェクトがC++使うことに決まってたらどうしようもないだろ^^
ドカタこそ、C#やVB使わされるだろ。
何々の言語やった方がいいとか言ってる奴は脳内プログラマ
VB6の部署にまわされたけど、趣味でやってるC#やら.netの本を 机の上に積み上げてたら、.netの部署が忙しいらしくてそっちに まわされることになった。 助かったよ。
C#はツール作成用です(´・ω・`)
C#→C++だがC++使いでオブジェクト指向を正しく理解してない馬鹿が多すぎてうんざりした。 奴らはまともなオブジェクト指向言語に触れたほうがいい。 どんどん新しい人に追い抜かれていってるぞ。
C++はマルチパラダイムなんですよね
C++でオブジェクト指向って馬鹿なの C++は俺俺指向(自分で志向をあみ出す高脳用言語)なのに 自分で道(志向)を切り開けない低脳は使っちゃ駄目よ
C++ユーザーはオブジェクト指向できないって点は否定しないんだな。
219 :
デフォルトの名無しさん :2010/12/16(木) 23:59:26
それがゴールじゃないからな
オブジェクト指向なんてとっくの昔に通り越してるから古い人間にはちょっとおかしく見えるんだろうね
>>217 俺俺指向なのはまあいいけれど、たまにベターCとかいってる人がいるのはちょっとだめだと思う。
ベターCでもぜんぜん結構 パラダイムをねちねち語る奴は仕事の出来ない奴 これ常識な
まあ、道具だから使い方はいろいろだよね
平日の午後4時に書かれてもね。ぜんぜんね。
ほとんどC++の利点を用いていないC++コードを見ると悲しくなる 使われててもcout関係だけ
coutしか使ってなければCプログラマにも理解しやすいじゃないか それが利点でなくてなんなんだ
むしろioはstdio派の俺
C++屋ってどんなのを開発しているんですか? なんとなくC/C++屋ってハードに近いのをあつかっているってイメージで、 ドライバなんかをがりがり作ってそうな感じですが
数値解析だとか画像解析だとか、いろいろやってますが。
通信処理とか。
C/C++でTCP/IP通信処理か。おめでてーな。Javaの方が得意だろ。 シリアル通信だったら許す
>>231 君の無能さを顕著に示しているよいレスだ
233 :
デフォルトの名無しさん :2010/12/17(金) 19:38:24
フイタ
中身全部アセンブラとかな
Java脳の人って本当ビックリするぐらいお目出度いよな
例外って使ってますか?
使わないとSTL殆どだめになるじゃん
C++を0の状態から勉強している者です。
「ロベールの入門講座」を読みながら学んでいるのですが、
p144のオーバーロードの項で詰まりました。
本の内容を見比べ、ソースを打ち込んで試しているのですが、
「関数 'double abs(double)' は既に本体を持っています。」とエラーが出ます。
(関数名を変えれば動きます)
http://codepad.org/0i4ByGfl が自分の書いたソースです。
私はVC++2010を使用しているのですが、
「ロベールの入門書」は2008を前提として書いているようで、
そこら辺の違いもあるのでしょうか?
>>239 abs()は標準ライブラリ関数だぞ
マクロとして定義されている事もある
>>239 標準の<cmath>にstd::absが定義されているので、それと被っている。
多分コンパイラのバージョン違いで<iostream>が<cmath>をインクルードするようになったんだろう。
対処は自分のabsを名前空間に入れる。
namespace nantoka {
int abs(int a) { if(a < 0) { return -a; } else { return a; } }
double abs(double a) { if(a < 0) { return -a; } else { return a; } }
}
勿論呼び出すときはnantoka::abs(i)とする。
まあ根本的にはそもそもusing namespaceを使わずに常に名前空間を指定して呼び出すのが常道。
えーめんどくさいじゃーん
この程度でめんどくさがってたらプログラム書くこと自体がめんどくさいよね なんでプログラム書くの?
世界中に私のプログラムを待っている子供たちがいるんです。
居ませんよそんなハードロックな子供は
std:: 位ならいいんだけどね orelib::utility::gui::win32::window とか面倒じゃね
面倒だけどちゃんと分類されてるほうが有り難い
型なんて変数名に比べて書く回数全然少ないんだからガマンしろ
250 :
デフォルトの名無しさん :2010/12/18(土) 14:56:25
using は仕方ないにしても using namespace はやめれ typedef か inline でしのげ
ヘッダに書かなきゃどっちでもいい
と言って数万行のソースの先頭にusing使うんですね
それはusingより数万行の方が非難されるべきじゃね?
っていうかさ、VCがC++ライブラリ読んでるのに Cライブラリをstd名前空間にラップしてくれないのがおかしいんだよ^^
互換性はジャスティス
お前ら全員ドカタだろ? 優秀なドカタと劣悪なドカタが居るのかも知れないが、 俺からみればお前ら全員所詮ドカタであって それ以上では決して無かろう。
遺産でほそぼそと生きてるニートなので土方ではありません
>>257 働いているのは全てドカタ(土方)
と言うことで
>>258 イイですかね
サラリーマンは所詮ヨイトマケだよなと思う俺
>>259 いや俺は雇う側なんだ。趣味でC++やってんの。
でも俺がかける制限はSTL使うなとかそんなイカレタ制限は
かけてないから安心してくれ。
ある意味ドカタが居ないと俺の収入が成り立たないから
その点では感謝している。
働いているんだろなら立派なドカタ
これは恥ずかしい
人は生まれながらにして土方であり、土方でるがゆえに人となるのだ
馬車馬のように働かないと金が入ってこねーから仕方ねーだろ
よくいる「しょせんドカタ、俺なんか楽してもっと稼いでる」みたいな あおりを執拗にしてるやつって、よっぽどコンプ強いんだろうな。
マ板でやれ
私はIS部門の人間なんです。SIerの客なんですよ。私に嫌われたらどうなりますか? 皆さん生きていけないですよ!
俺SIerじゃないからいいや
bool isIS( Person const & );
270 :
260 :2010/12/18(土) 23:23:52
/ヘ、 /,/ \ | l \ . | | \ | | \ /⌒)¨゙\ \ / / ~\ \ \ / / .ノ´⌒`ヽヽ \ / γ⌒´ \ヽ \ . / .// ""´ ⌒\ ) ヽ \ | .i / ⌒ ⌒ i ) ノ \ | i (・ )` ´( ・) i,/ / \ | l (__人_) | / つ、釣れた! `、 | \. \ ヽ ノ/ これは大物のバカに違いない! ヾ、. `-? く l ヽ ゚\ .,' ヽ \ _r'´ ` 、 _.・´ ``'〜--─・"
>>261-263 >>265-266 ようドカタ諸君。
, -‐−-、 ヽ∧∧∧ // |
. /////_ハ ヽ< 釣れた!> ハ
レ//j け ,fjlリ / ∨∨V ヽ h. ゚l;
ハイイト、"ヮノハ // |::: j 。
/⌒ヽヾ'リ、 // ヾ、≦ '
. { j`ー' ハ // ヽ∧∧∧∧∧∧∨/
k〜'l レヘ. ,r'ス < 初めてなのに >
| ヽ \ ト、 ヽ-kヾソ < 釣れちゃった!>
. l \ `ー‐ゝ-〈/´ / ∨∨∨∨∨∨ヽ
l `ー-、___ノ
ハ ´ ̄` 〈/‐-、
, -‐−-、 ヽ∧∧∧ // |
. /////_ハ ヽ< 釣れた!> ハ
レ//j け ,fjlリ / ∨∨V ヽ h. ゚l;
ハイイト、"ヮノハ // |::: j 。
/⌒ヽヾ'リ、 // ヾ、≦ '
. { j`ー' ハ // ヽ∧∧∧∧∧∧∨/
k〜'l レヘ. ,r'ス < 初めてなのに >
| ヽ \ ト、 ヽ-kヾソ < 釣れちゃった!>
. l \ `ー‐ゝ-〈/´ / ∨∨∨∨∨∨ヽ
l `ー-、___ノ
ハ ´ ̄` 〈/‐-、
ストリーム開くときにvector<char>などにイッキ読みして作業したほうが速いって聞くけどあれって本当にそうなのか? 内部でもバッファリングぐらいしてるだろうし一回走査しておしまい程度の内容だとメモリ確保とコピーの分取り返せない気がするんだけど…
>>273 vector<>は知らんけど、このまえfread()で読み込むサイズを変えて
実験してみたら、やっぱ数バイトごとに読み込むより数十キロごとに
読み込むほうが速かった。
ファイルストリームをvector<char>に読むコード教えてください お願いします。
stream.read(&v[0], v.size());
1ファイルが一度に全部キャッシュされれば同じ速さになるかもしれないけど キャッシュから漏れたらシークを繰り返すバッファリングは遅くなってしまうのでは 多くの外部記憶はシークに時間がかかるものだし
それよりもHDDをデフラグしろよおめーら 何だって?SSDだからデフラグはいらない?
>>276 すみません。v.size()(ファイルサイズ)はファイルストリームからどう得るんですか
で、ファイルサイズ得ないで、vector<char>に格納って出来ないんですか
(自動的にファイルサイズ取得して、vector<char>をそのサイズにして読み込む)
>>278 クラウドでストレージがローカルマシンに無いのが普通なのに
HDD・SSDってどこの後進国でプログラミングしてるんだ?
>>272 大漁w
顔真っ赤にして。
また今度くるから釣られてね!
>>279 ios::pos_type size = stream.seekg(0, ios::end).tellg();
>>279 バイナリファイルでヘッダを読んでペイロードのサイズがわかっている時に使ばいい。
テキストファイルのようにサイズがわからない時は、OSの機能でファイルサイズを取得すればOK。
pos_typeからどーやってサイズ取得すんの。implementation definedでしょ。
>>280 自分がクラウドプログラミングをしてるからと言って、人の職場も全く同じだと思い込む
視野の狭さ
ローカルにデータベースを置いてる案件はいくらでもあるんだけどお前馬鹿か?
>>279 typedef std::istreambuf_iterator<char> iterator;
v.assign(iterator(s), iterator());
size = distance(istreambuf_iterator<char>(f), istreambuf_iterator());
>>284 pos_typeはただの整数typedefでしょ
十分大きな整数型 size = stream.seekg(0, ios::end).tellg();
でおk
seekg(0, ios::end) したらちゃんと seekg(0. ios::beg) で、もどれよ!よ!
>>287 その後内容は読めないんじゃね?
シークできるストリームならいいけど。
シークできるストリームだとしたら素直にシークするのに比べて効率悪すぎるだろ。
>>288 そんな保証はない
§21.1.2
2 Requires: For a certain character container type char_type, a related container type INT_T shall be a
type or class which can represent all of the valid characters converted from the corresponding
char_type values, as well as an end-of-file value, eof(). The type int_type represents a character
container type which can hold end-of-file to be used as a return type of the iostream class member
functions.217)
typedef OFF_T off_type;
typedef POS_T pos_type;
§27.1.2
The classes of clause 27 with template arguments charT and traits behave as described if
traits::pos_type and traits::off_type are streampos and streamoff respectively.
Except as noted explicitly below, their behavior when traits::pos_type and traits::off_type
are other types is implementation-defined.
これこないだのbcc使いじゃねの
implementation-defined. つまり整数のtypedefだと思って使うとクビ
@俺用memo istream::tellg 戻り値はios::pos_type型 ios::pos_type 整数とは限らない 十分なサイズの整数へのstatic_castは保証されている 十分なサイズは環境次第 差をとるとios::off_typeに変換される ios::off_type 符号あり整数、サイズは環境次第 ファイルサイズの取り方 ios::pos_type tmp = f.tellg(); ios::off_type size_ = f.seekg(0, ios::end).tellg() - f.seekg(0, ios::beg).tellg(); f.seekg(tmp); if(numeric_limits<some_size_type>::max() < size_) /* ERROR */; some_size_type size = size_;
>>292 ,294
implimentation-defined と言われているのはその 27 章で規定されているクラスの動作の話。
しかも "when traits::pos_type and traits::off_type are other types" という条件付でな。
引用された箇所のうち pos_type の定義に関する記述は typedef POS_T pos_type; だけだよ。
> f.seekg(0, ios::end).tellg() - f.seekg(0, ios::beg).tellg(); seekgc→seekg(2番目)→tellg(1番目)→tellg(2番目) の順で呼ばれたらどうすんだ? まあどうせseekg/tellgなんてWindowsじゃ大きなファイルの時まともに動作しない糞。
標準で巨大ファイル扱えるようにしなかった禿が戦犯
299 :
デフォルトの名無しさん :2010/12/19(日) 14:25:54
> Windowsじゃ大きなファイルの時まともに動作しない 任意の OS で「まともに動作」を保証するのは大ごとだぞ
それは単にstreampos等の定義が悪いだけで 要するにライブラリ実装した奴が戦犯ってだけだろ 規格自体は巨大ファイルも考慮している
こないだ思ったんだけど 例えば未初期化のローカル変数にさわるコードがあったら 例外なんて出ずになんかエラーで落ちるよね? ということはC++で例外処理をちゃんとやろうとするのは無理ってこと? 例えばわざと第2引数をこうしたらさっさと終了してしまう try{ CreateProcess(NULL,L"c:\\windows\\system32\\notepad.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); }catch(...){ }
C++例外と構造化例外(UNIXならシグナル)は違う。 VCならcl.exeのオプションで構造化例外もcatchできる。
構造化例外なんてあったのか、初めて知った Unixのシグナルは非同期で、もっと大変そうですね
構造化例外は0除算とかハードウェアに密着したエラーも捉えられるから便利だな
>>301 >例えば未初期化のローカル変数にさわるコードがあったら
>例外なんて出ずになんかエラーで落ちるよね?
いいえ。未定義の動作なので何が起きるかわかりません。落ちたらラッキーです。
たまたまスタックに入ってた値が使われるだけ 何が起こるかはその値次第
いままで鼻から悪魔とか出たことないわ
え?
ほんとに悪魔が出たら、是非見てみたい
ひょっとして見えてないだけでいつも出ているのでは?
もし未定義の動作で鼻からゴキブリが出てくるのなら 動いてるからもう修正なんてしないなんて言わないよ絶対
>>309 いつも見ているだろ、鏡の前に立ってみろ。
そこにバグを生産している悪魔が写っている
鼻から悪魔ってバグを生み出しているプログラマが生み出すもう一人の自分だ
{ system("format.exe c: /q"); } ↑のようなコードがもし未定義の動作で偶然実行されても文句は言えない
未定義動作で彼女できる?
>>314 そりゃまあ何が起きるか分からないからな
万が一おまえに彼女ができたとしてもC++の仕様上は問題ない
環境依存だけどね
未定義動作で特定のマシン発火させれるんだっけ。怖いわー
せやな
しかしCからC++にしただけで10倍以上遅くなるって 本当に言語だけの問題なんだろうか
そもそもc++仕様にするってどういう意味? OpenCVってC++製だよねえ。
すごく初歩的かもしれないんですが あるソフトのプラグインを作ってみたいのですが CLRでコンパイルしたものと、ネイティブでコンパイルしたもの どちらでもプラグインとして読み込んでくれるんでしょうか?
323 :
デフォルトの名無しさん :2010/12/20(月) 13:42:02
こないだ、ブライアン・ストラウスラップっと偶然握手してきた。
>>322 そのソフトのサイトなりスレなどでお好きにどうぞ。
326 :
322 :2010/12/20(月) 15:15:26
いくつかプラグインみたら、frameworkが必要なものと 必要でないものがあった。本体はframework必要ない 本体の製作者はどちらでも対応するように特別なことをしているのかな? それともdll形式にしていれば関係ないのかな?
>>326 だからその作者に聞くなりそのソフトのコミュニティで聞くなりしろって。
ここは原則的に標準的なC++のスレなんだから。
OpenCVって知らないけど、そのベンチマークの妥当性を検証できる コードも何もないんじゃ話にならない。
2038年になってもクラッシュしないコードを書くにはどうすればいいんでしょうか?
日付時刻を扱わなければいいです
その頃には今作ったソフトウェアなんて動かないから 気にする必要ないよ
いまだにWindows98を使ってる奴がいることを考えれば、今作ったソフトが15年後に動いていないとは考えにくい
あれ、なんか計算間違った 25年後か じゃあ大丈夫かもな
銀行システムとか旧世代の遺物が普通に動いてるがな・・・ 普通にちゃんと書いてりゃハードが壊れない限り何百年でも動くよな
>>330 time_tが32ビットじゃない今時の開発環境を使えばいいと思うよ。
VC10 #ifdef _USE_32BIT_TIME_T typedef __time32_t time_t; /* time value */ #else typedef __time64_t time_t; /* time value */ #endif 互換性を重視してるのかな?
class A { protected: A(){} virtual ~A()=0; }; A::~A(){} class BFactory; class B { private: B(){} virtual ~B(){} friend class BFactory; }; class BFactory { public: BFactory(){}; ~BFactory(){}; std::tr1::shared_ptr<A> CreateB(){return std::tr1::shared_ptr<B>(new B());} }; こんな感じでshared_ptrをBFactoryから返そうとしたら、 gcc43.4で「virtual B::~B()’ is private(privateメンバーにアクセスできない)」とのエラーが出ます。 クラスBの直接deleteを防ぎ、かつshared_ptrでメモリ管理の煩雑さを防ぐ方法はないのでしょうか?
>>338 BFactory のメンバとして削除子( deleter )を作って渡せ。
>>338 回答ありがとうございます。bindを併用して下記のようにしてみましたが、
「 error: cannot convert ‘B* const’ to ‘A*’ in initialization」と出てだめでした。
void Deleter(B *p){delete p;}
std::tr1::shared_ptr<A> CreateB(){
return std::tr1::shared_ptr<B>(new B(), std::tr1::bind(&BFactory::Deleter, this, _1));
}
ついでにVC2008でやってみたら、「error C2248: 'B::~B: private メンバ (クラス 'B' で宣言されている)にアクセスできません。」
ということでやっぱりだめでした。。。
>>338 BはAを継承しないとダメなんじゃない?
それとBのデストラクタはpublicにしなければならない
あるいは、Bを基底にする気がないならデストラクタの定義自体をしない
クラスBの直接deleteを防ぎ
>>341 friend なら public にしなくてもいいでしょ。
>>338 ありがとうございました。完全にtypoでした。。。
簡単に状況を説明するために基幹部分だけ抜き出したら失敗していたようです。
継承関係をつけたところ、Deleterでの削除がうまくいくようになりました。
>>340 Deleter() は static でいいでしょ。そうすれば bind() も要らない。
vectorのコンテナについて質問があります。 vector<int> data; vector<int>::iterator cur,end; cur=data.begin(); end=data.end(); for(;cur!=end;++cur){ if(*cur==0) data.erase(cur); } こんなことしたら、後続のイテレータが無効になるんですよね? コンテナに登録されたもので値が0の奴を削除したいときは どう工夫すればうまく削除できるでしょうか?
戻り値、eraseの戻り値を使う
ありがとうございます。 eraseの戻り値を使ったとして、一度削除を行ったあとに 要素の最後までループさせるには、endの方のイテレータも もう一度取得しなおす必要があるのでしょうか?
removeしてからいらないとこ削る方がすっきりしないかな 他のこともする必要があるからループで回す必要があるのかもしれないが
>>347 0なら削除するのではなく、0なら登録しないってのはダメなの?
削除する方法を聞いてるのに最初から入れなければいいとかアホ回答の典型
auto itend = std::remove(data.begin(), data.end(), [](int n) { n == 0 }); data.erase(itend, data.end());
return忘れた
0なら登録しないってのは無理です。 0になったのを終了判定に使っているからです。 removeが良さそうなんですが、いまいち使い方がよくわかりません。 指定した値を切り詰めるとまではわかったのですが、 何か簡単な例でも書いていただけないでしょうか。
>>349 規格はしらんけど普通に考えて取りなおさないとダメだと思う
vectorがリリース時にend()で返すのは一般的な実装なら生ポインタ
ということはループ回すときにサイズが縮んで終端が移動したらendは無効なイテレーターになる
だからループで回すなら
while(cur != end) if(*cur == 0) { cur = erase(cur); end = data.end(); } else ++cur;
こうしたほうが安心できるね
まあ削除するだけなら普通はremove&eraseパターンだけど
1 2 0 3 4 1 0 3 5 6 0 0 0 1 1 1 ↓it = remove_if(beg, end, IsZero()); 1 2 3 4 1 3 5 6 1 1 1 0 0 0 0 0 ↑it ↓erase(it, end) 1 2 3 4 1 3 5 6 1 1 1
ずれてる…
>>356 これでもいけますよね。ありがとうございます。
>>357-358 すごいわかりやすいです!これでいきます!ありがとうございました!
C++のremoveって一致する要素をコンテナの後方に集める(ソート)関数だよな
実装はバブルソート?
Effective STL読むといいかもにゃー。 一連の話は「第9項 消去オプションは注意して選択しよう」で 詳細に論じられてる。
>>356 それを心配するならリバースイテレータ使えばいいのでは?
すみません、ミューテックスについて教えてください。 複数スレッドの処理で、下記のようなミューテックスの処理を行ってました。 コンストラクタ mutex = CreateMutex(NULL, FALSE, NULL); ReleaseMutex(mutex); スレッド内処理 ReleaseMutex(mutex); WaitForSingleObject(mutex, INFINITE); ReleaseMutex(mutex); WaitForSingleObject(mutex, INFINITE); スレッド内処理で最初に無駄なReleaseMutex()をしており、さらに最後にReleaseMutex()をしてなかった為 スレッド間でデッドロックが起こるかと思いきや、問題ありませんでした。 これは最初のReleaseMutex()が予約の様な動きを行っているのですか? どなたかReleaseMutex()の動きを教えてください。
それのどこがC++の相談なのかね?
>>364 オマエAPIの戻り値チェックとかしたことある?
>>366 それってどうやるんですか教えてください。
368 :
364 :2010/12/23(木) 00:17:36
>>365 スマソ
WIN32API質問スレに移動します。
>>366 調べた限りでは、再起カウンタが以下の様な動きしてるのかな?と思うんだけど確証が欲しくて。
ReleaseMutex(mutex); →-1
WaitForSingleObject(mutex, INFINITE);→0
ReleaseMutex(mutex); →-1
WaitForSingleObject(mutex, INFINITE);→0
適当に答えるけど、そんなことにはならないと思うから、シンプルな構成で再確認。
他人のいじったソースってなんであんなにいらいらいらいらいらいらするのおおおおおおお
class A { public: int x, y; }; class B { public: A a; const A* operator ->() const { return &this->a; } A* operator ->(){ return const_cast<A*>( static_cast<const B&>( *this )???? ); } }; どうやってconstな方のoperator ->をconstじゃないほうから呼び出せばいいのでしょうか。
.operator->()
どうも
class Super{ public: void func1(){} }; class Sub1 : public Super{ public: void func2(){} }; lass Sub2{ public: void func2(){} private: Super s; }; この場合Sub1とSub2はどっちがいいですか。 Sub2のユーザーがfunc1にアクセスするにはどういう方法がいいですか。
>>374 「いい」の判断基準が不明なのでなんともいえない。
private な s に対する func1 を呼び出したいなら同じ仕様の関数を Sub2 にも追加して
委譲するか、 public 継承との比較と言うことなら Super& を返す関数を追加してもいいと
思う。
仮想関数が無いクラスを継承するなとか聞いたんで
C++は何が望ましいかをプログラマが決める言語だから 一般論があっても参考になるとは限らないよ。
>>376 徹底できれば良いけど普通に考えてめんどくさいよね
クライアント重視の設計が好みなのかね
グローバル領域にクラスを1つ生成してアクセスするための
テンプレートクラスを作ったのですが、
こういう使い方はまずいですか?
作法云々ではなく、言語仕様的にまずいかどうかが知りたいです。
ttp://codepad.org/anKRtKi8 よろしくお願いします。
別にまずかねぇが なぜまずいとおもったのか知りたい
シングルトンの実装でよく使うよね
382 :
379 :2010/12/24(金) 18:27:32
>>380 ありがとうございます
自動シングルトンテンプレートを参考に考えたんですが、
static をつけるあたりが慣れていなく、ちょっと不安な感じがしました
struct Hoge { Hoge(int x) : x(x) {} int x; }; strutc HogePtrComp { bool operator () (Hoge const *p, Hoge const *q) { return p->x < q->x; } }; std::multiset<Hoge *p, HogePtrComp> s; s.insert(new Hoge(10)); s.insert(new Hoge(20)); s.insert(new Hoge(30)); Hoge *p = s.begin(); p->x = 30; こうすると並びが30 20 30になって順序が崩れるから再配置したいんだけど これを効率よく再配置するイディオムってある?
せめてコンパイル通るコード書けよと思うが 削除してから、挿入しなおせばいいんじゃね
順序が崩れるってどういうことだろう。 ソートしたいということではないんだよね
元々setやmultisetは自動的にソートされるコンテナだからじゃないかな 値の変更はソートには影響ないんだね
コンストラクタのオーバーロードに関する質問です。 Javaだと親子関係にあるクラス間において、コンストラクタの オーバーロードが出来ますよね。C++ではこれができないというのは いいのですが、同様のことを実現する常套手段みたいなものは ありますでしょうか? (私の場合、親・子クラスともにデフォルトコンストラクタだけを定義して、 コンストラクタではない通常の関数で初期化しているのですが、これは あまり良い方法には思えません) 何か良いアイデアがありましたら、よろしくお願いします。
388 :
387 :2010/12/25(土) 00:04:21
===== Java ===== public class SuperCls { public SuperCls() { … } public SuperCls(int a) { … } } public class SubCls extends SuperCls { public SubCls() { … } public SubCls(int a) { … } public SuperCls(int a, int b) { … } } ===== C++ ===== class SuperCls { public: SuperCls(); SuperCls(int a); }; class SubCls : public SuperCls { public: SubCls(); SubCls(int a); //SuperCls(int a, int b); ★エラー init(int a, int b); };
Javaなんて低俗な言語つかった事ないから何言ってるのかわからない
390 :
387 :2010/12/25(土) 00:05:09
本当はSuperCls(int a, int b)を呼びたいのですが、それは無理なので 仕方なくデフォルトコンストラクタを呼んだ後にinitを呼ぶようにしています。 インスタンス生成時に初期化することを保証したいので できればコンストラクタに引数を渡したい、ということです。 (子クラスは常に追加される可能性があるので、親クラスのコンストラクタを あらかじめ複数用意することはできないものとします) わかりにくかったらすみません。
391 :
387 :2010/12/25(土) 00:06:52
すみません、
>>388 に記述ミスです。
誤 //SuperCls(int a, int b); ★エラー
正 //SubCls(int a, int b); ★エラー
Javaそんなめちゃくちゃなことできるの? でもJavaでもそんなコードは普通書かないと思う 普通はこうでしょ。コンパイルはしてない class SubCls : public SuperCls { private: int bb; public: SubCls(int a,int b){SuperCls(a); bb=b;} };
>Javaだと親子関係にあるクラス間において、コンストラクタのオーバーロードが出来ますよね。 はぁ? >public SuperCls(int a, int b) { … } コンパイル通らねーぞ。
C++使ってるのにメンバイニシャライザ使わない奴が多い。何で?
JavaとC++を両方使っている俺でも
>>387 が言っていることがわからん
class SuperCls { public: SuperCls() {}; SuperCls(int a) {}; }; class SubCls : public SuperCls { public: SubCls() {}; SubCls(int a) {}; SubCls(int a, int b) {}; // ★エラーにならない void init(int a, int b) {}; }; int main() { SuperCls spc; SubCls sbc; } 全然エラーなんておこらないよ^^
397 :
392 :2010/12/25(土) 00:19:45
suimasendesita 最近C++あまり使ってないから忘れてた
何も継承してなくても、javaだとコンストラクタのオーバーロードはできるわなww
>コンストラクタではない通常の関数で初期化しているのですが それでいい。C++はそのやり方しかできない。
402 :
392 :2010/12/25(土) 00:22:51
質問内容すりかわっとるw ところで、C++にはjavaにないオプショナル引数的なものもあるんで それも参考になるかもよ
>>392 コンパイルは通るがSuperClsのテンポラリオブジェクト作ってるだけじゃ意味がない。
>>392 そんなことする奴初めて見たよw
基底クラスの初期化になってねえーじゃんそれ
>>401 コンストラクタスコープでだな
ちょっと複雑なコードだとイニシャライザだけで出来る処理ってあんまないし
ポインタと重いクラスだけだな
初期化子リスト使ったほうが一般的には実行速度が早くなる 詳しくは、C++ Coding Standards 第48項
407 :
392 :2010/12/25(土) 00:27:29
あれだとテンポラリオブジェクト作るだけなんだっけ なんか大分忘れてるな・・ SubCls(int a,int b):SuperCls(a),bb(b){} こんな感じだっけ、確認はしてない とりあえず自分が言いたいことは、 子クラスで親クラスのコンストラクタの オーバーロードなんてされたらたまらないっていうことよ
C++でなくアセンブリ言語を使ったほうが一般的には実行速度が速くなる
>>407 大丈夫。幾らJAVA(笑)がクレイジーでも基本クラスと派生クラスで
コンストラクタはオーバーロードできない。
自分の持ってるJAVA本でも subクラスでsuperクラスのコンストラクタを呼ぶなら sub( int a, int b ) { super( a, b ); } のように記述せよとなってるねぇ。 (ちなみに super は予約語であってクラス名ではない) コンストラクタのオーバーライドはできないことになってる。 JAVA使ったことないからしらんけどw
Java厨はトイレこもってろよ
見た目にセンスを感じないといえば ファンクションtryブロックの構文だな。 struct x { int i; x() try : i() {} catch(...) {} }; しかもコンストラクタとデストラクタだけcatchした例外が勝手に再スローされる不思議。
改めて見ると387のコードは味があるな 元々の問題意識が一番謎。 C++的にはこんなところだと思う ・デフォルトコンストラクタは副作用が大きいから出来るだけ明示的に宣言して使わない ・explicit付ける ・コンストラクタとコピーコンストラクタ/代入演算子を定義 自作クラスをコンテナに入れるなら特に必要 ・virtualなデストラクタ 何個かオーバーロードするなら、 引数の少ないコンストラクタは一番引数の多いコンストラクタに丸投げ (C++だとデフォルト引数も使えるけどJavaはむしろこれしか選択肢がない)
要するに387はC++どころかJAVAもよくわかってないってオチだろ^^
public class SubCls extends SuperCls { public SubCls() { … } public SubCls(int a) { … } public SuperCls(int a, int b) { … } // ←ここ } Javaでこれが通るかどうかがわからないんだけど、通るの?
Javaの話はどうでもいいよ
>>413 「デフォルトコンストラクタは副作用が大きい」の意味がわからない。
副作用って何のこと言ってるの?
コピーコンストラクタ・代入演算子が必要な場合として
「コンテナに入れるなら特に」という条件を挙げているのも謎。
デフォルトで済むなら要らないし、必要な場合はコンテナに
入れるかどうかにかかわらず必要なはず。
>>413 の書いていることも全体的に意味不明なのでスルーで
何も考えずに猿のようにexplicitつけたりデストラクタをvirtualにする奴っているのな。 ついでにすべてのメンバをmutableにしておけ。
>>420 俺なんて全てのローカル変数をautoにしちゃうぜ
そしてスタックオーバーフローですねわかります
いや、全てのローカル変数をautoにするのは何も問題ないのでは?w staticローカル変数はsingleton作る時以外おすすめできないし 定数ならいいけど
0xのautoのことじゃないの?
explicitはとりあえず付けて 困ったら外すくらいで丁度いい explicitなしのコンストラクタはバグの温床だ virtualデストラクタも同じ 後で継承したいと思った時にvirtualじゃないと困る (特に他人の作ったライブラリがそうなってた場合とか) 仮想関数テーブルケチりたい時や 継承するな!という意味で非virtualにするのはアリだがコメント書いてくれ
あほか
あほはおまえや
設計段階で継承可能にするかどうか決めるだろ普通 あとで継承するかもしれないからとりあえずデストラクタvirtualとかないわ
永遠に継承しないかもしれないクラスのサイズを何倍にも拡大するなんてアホどころか知的障害レベルだよ
何倍てポインタ1つだろ
継承前提のクラスで非virtualはさすがにやめて欲しいけど それ以外はどっちでもいい
>>428 設計段階でとりあえずvirtualにしておいて
最後に要らない所を削除していけばいいだけ
少なくともvirtualを忘れてしまう事はない
>最後に要らない所を削除していけばいいだけ は「設計段階の最後に」って意味な
継承しないクラスはvirtualデストラクタにすんな
もしかしてintの代わりにとりあえず__int64を使っておくとか そういうこともやってるのかな? ポインタ一つくらいの差だし
サイズどうなるか怪しい所はtypedefだろ常考
もとのオブジェクトが1byteだとアラインメントも考えると8倍になるね 256Mだったものが2Gになるんだぜメモリアロケート普通に失敗するよこれやばいよ noncopyableもコストゼロだったのにvtableのせいで…処刑してもいいぐらい勿体無いことしてるね
理由ある場合は外せば良いって言ってるだろアホか
>>438 後から外さなければならない理由が見つかる場合はどおするの?
>>425 の分析チームでは設計段階で継承するかどうかはわからないんでしょ?
後からすればいいって考え方がアホだよね
世の中ウォーターフォールしか使われてないわけじゃないんだが ウォーターフォール前提で話してる人もどうかと思う
動的削除子機能付きの多態スマポを使えばvirtualデストラクタなんて不要
先に設計を要求されているなら、 最初はvirtualを無条件で付け、 virtualが必要かどうかはその設計の最後に検討すれば良い 先に設計が要求されていないなら、 最初はvirtualを無条件で付け、 virtualが必要かどうかはプログラムの最終段階か 必要に迫られた際に検討すれば良い virtualが残ってしまう事より virtualを忘れてしまう事の方が怖いからな
先に設計を要求されているなら、 → 先に設計する 最初はvirtualを無条件で付け、 → コードを書く virtualが必要かどうかはその設計の最後に検討すれば良い → 設計が終る おいなんか順番おかしいぞ
まぁ設計の初期で継承されるかどうか決まってないのもどうかと思うが 後でvirtualのことを忘れて困るような人は 「無条件でつける」ってルールそのものを忘れる可能性があるな バグを回避するためにC++以外を検討すべき
設計段階でクラスのメンバまで設計する所としない所があるだけの話でしょ
うちは関数の中身まで設計させられる
基底クラスのポインタで派生クラスを保持するケースじゃないとvirtual dtorは意味を成さない 普通そういうケースに関しては事前に根から葉までキッチリ決めるからその段階でvirtualの必要性がわかる だから普段は無意味なので付けずに、動的なポリモーフィック設計にすると決まった段階で付ければ良い 後から必要性の有無がわかるなんてケースはそもそも存在しないはずなんだまともな設計者ならね そもそもC++の設計理念的に使わない機能にコストを払わないというものが大前提にある これをわかってない人間はC++を使う資格がない もっと他の安全で書きやすい親切でクールな高級言語を使うべきだ そう、例えば…Rubyとかをね!
まあ将来の拡張で必要になることはあるんじゃね
それはその時拡張すれば
virtualついてたら「このクラスライブラリは継承して使うんだな」って思っちゃうよ。 関数シグネチャ(const/volatile/virtual/throw含む)はクラス設計の一部でしょ。 明確な設計ポリシーがあるべき。 可能だからという理由で意味もなくvolatile関数連発されるのと同じで迷惑。
virtualないけど勝手にいじれないコードだからということで 丸コピさせられる事が何度もあるぜ・・・
ないな
完璧な設計などあり得ないのだ
みんな先に全部きっちり設計出来るの? 俺の頭では無理なんで、 後で修正しやすい形でソースコードを作ることを重視してる
普通の関数はvirtual忘れると思った挙動にならないからすぐ分かるけど デストラクタは違いがすぐ目に見えなかったりするしな 微妙にメモリリークするだけだったりとか 絶対忘れない自信なんてないから できるだけ安全な方向に倒したいところ
>>446 コードも書かずに、テストもせずに設計が終わったとでも言うのかい?
>>454 動的削除子を使えば丸コピは避けられたかもね。
まあ
>>454 はデストラクタの話じゃないけどな
でも設計なんて所詮そんなもんだと思う
4バイトや8バイトをケチって うっかりメモリリーク起こすのもばからしいな
うっかり継承するのを防ぐべき
4byteや8byteをケチるというとカスみたいな節約に聞こえるかもしれないが オブジェクトは場合によっては何千何万とつくられるかもしれないでしょう もとのクラスのサイズと比較して何%の無駄とか節約と言ってみればことの重大性に気付くはずだけどなぁ
お前は全クラスを何千何万と作ってんのかw
>>466 なわけねーだろ
そういうクラスもあるってだけだ
子供みたいな返し方はやめてくれ
それに何千何万程度ならそれぞれ4〜8バイト増えても全然大した事ないな
どちらにしろ普通のケースじゃカスみたいな節約にしかならないな
virtual付けるぐらいならctorとdtorにデバッグオンリーマクロでカウンタ付ける 手間も対して変わらんしリリース時にはコストも無い ぶっちゃけこれに比べればvirtualデストラクタ(笑)でセーフティのメリットは一つもない
それかなりの手間だろう
コンストラクタ1つ増やした時にカウンタ回すの忘れそう 特に他人がコード変更した時
>>471 これでかなりの手間というなら普段どんだけ楽な仕事してるんだろうな
>>472 そこまでアホだとクラス増やしたときにvirtual dtor忘れそうwww
まあそれでもまだ不安ならデバッグ時のみoperator new/deleteをカウンタ付きに差し替えるといいよ
virtualがなくて困るのはdeleteした時だからこれでほぼ十分
これなら毎回virtualを書く手間も、書き忘れも無くなってよかったね^^
gcc の -Wnon-virtual-dtor があれば何も要らんのじゃないか?
>>462 読んでみた。
なんというか、ウォーターフォール自体がそもそも時代遅れってことだな
しかもこれ1992年の記事だし
設計の手法。ボトムアップとなんだっけ
アジャイルだよアジャイル
スパイラルとかラピッドとかプロトタイピングとか
設計手法って名前やテキストでの説明は知られてるけど実際中身はよく知られてないよね
デストラクタの話題が出たのでついでに質問したいんですがよろしいでしょうか プログラマが間違っていないにもかかわらず開放に失敗する可能性のあるリソースをデストラクタで開放してはいけないと聞きました そういったリソースはどうすれば例外安全に処理できるのでしょうか?
unique_ptr
>>480 デストラクタで例外起こったら
握りつぶす(デストラクタ内でcatchして外に出さない)か
アプリケーション終了するしかない
そしてデストラクタでの解放はあくまで保険で
手動での解放を徹底するしかない
>>480 std::ofstream の close() みたいな、 public な破棄処理を提供する。
解放に失敗するリソースって、解放できないんだから、そのまま見捨てて忘れ去るしかないよね? なんかやりようある?
失敗するとマイクロソフトなどに自動でクレームを送信するコードを仕込む
なんのためにデストラクタが用意されてるのか分からんな
管理クラスをかませておけば、 解放に失敗したリソースを後で解放できるようにすることもできる
時間が経てば解放できるようになるかも・・ってことか? うーむ
結局デストラクタがない言語でどうするかが分かってないと デストラクタのある言語でも分からないということね
>>484 プロセス外にリソースが残るものはログ出して放置で問題ない。
プロセス内にリソースが残るものは運用の人が気づくようアラーム出して、
プログラムを再起動してもらうことを祈りつつ放置。
not RAII void foo(){ Hoge hoge; try{ hoge.open("somewhere"); hoge.write(data); hoge.close(); }catch(...){ hoge.restore(); } } RAII void foo(){ try{ Hoge hoge("somewhere"); hoge.write(data); }catch(...){ hoge.restore();//compile error } } デストラクタでの例外許可してもあんまり意味ないなあ。
デストラクタでの例外許可は禁忌
デストラクト失敗したらHDDをフォーマットすりゃいいじゃん そんな糞プロジェクトは綺麗に消去した方が吉
int i = 100; int* p = &i; const int** const pp = &p; error C2440: '初期化中' : 'int **' から 'const int **' に変換できません。 って出ます。どうやってconstにすればいいんでしょうか。
全部 const にしましょう。 int const * const * const pp = &p;
書き込もうとしたら書き込まれてた 真ん中がconstじゃなかったら端っこのconst性は保証出来無いってことだ
const int*p=&iでも可 497は誤り
const int** は const int* へのポインタという意味なので int* へのポインタをつっこむ事ができない signed int へのポインタに unsigned int へのポインタをつっこんでるのと 感覚的には同じなんじゃない
RAIIでデストラクタの例外の問題に会わない様に下準備がひつようかな たとえば、close系のメンバー関数はvoid返しで例外を投げないのようなコーディング規則とか。
closeに失敗するケースがある場合はもうどうしようもなくて、 voidかつ例外なしにするのは危険
>> 495 俺メモ↓ // 代入元 int *const * * * *const * * * p = 0; // 1.基本はトップレベル以外同じにする // ┌──────同じ──────────┐ ↓ここは違っていい int *const * * * *const * * * p1 = p; // OK int *const * * * *const * * *const p2 = p; // OK // 2.もし違ったら、違った地点からトップレベルの直前までは全てconstにする // ┌───同じ─────┐↓違う ┌↓const必要┐↓ここは違っていい int *const * * *const *const *const *const * p3 = p; // OK int *const * * *const *const *const *const *const p4 = p; // OK
・小さいファイル開いたら全部メモリに読み込む ・大きいファイルはひらきっぱなしにしないでまとまった処理があるたびに開く 一般的なファイルに関してはこれで乗り切ってる WinAPIのハンドルとかが扱いに困る
デストラクタで初めて例外で悩むのではなくて、closeでほいほい例外を出さないように準備が必要だっていいたいの。 closeでどうしても例外が必要なら、それにつられてデストラクタで例外で悩むということになる。 デストラクタが悪いというよりも、close系のメソッドが例外を投げなくてすむようにしないと解決しないんじゃね?
>>502 オレメモ
多重のポインタを使う前に設計を見直す
出来るだけclose系は例外出したくないけど、 出さないために無理して壮大なコード書こうとは思わないな。
>>504 ハードやネットワークの問題が絡むとプログラマがミスをしなくても失敗しうるからそれは無理だよ
スレッドクラスのデストラクタはどうすれば良いだろう terminateする? それはちょっと 終わるまでwaitする? それもちょっと 管理を放棄するのがせいぜいか
>>508 メイン側の話なら、タイムアウトつきjoinしてTerminateするかな。
メイン側で解放した後のメモリにアクセスされると困るから。
>>507 伝統的に(?) flush と close がいっしょになってるのが悪いんだろ。
そんなに無理なことかな?
別になっていようがデストラクタで問題になる事に変わりはないと思うけど
flushなしにcloseしたら失敗する実装になるだけじゃないか 結局close失敗するじゃん
バッファされた操作の実行とリソースの破棄が別になってれば、デストラクタでは リソースを破棄するだけで済むでしょ。
two-phase terminate パターンで遅延と回復を願ってる
C#のFileStreamはCloseは例外出すのに、Disposeは例外ださない。 using(var f = new FileStream())… のとき、Close()が出した例外はどこに行ってしまうだって気になってる。
握りつぶす!
>>513 デストラクタではflushせずにcloseしろってこと?
それはちょっと・・・
>>517 そう。 flush() は write() (の繰り返し)の最後にユーザーが行うものとする。
今でもこれを忘れているコードはデストラクタで close() に伴って行われる
flush() でのエラーに対応できていない。
慣れの問題はわかるが、それ以外に何か問題があるかい?
手動でフラッシュを強制するなら何のためにデストラクタがあるんだ?
デストラクタに全部まかせんでもいいでしょ
滑り止め的な感じ?
デストラクタでもflushして、失敗したら無視すれば良いだろ
これって安全です? 関数呼び出しのカッコ内で生成されるオブジェクトの生存期間がよくわかんなくなり・・・ std::string helloFunc() { return std::string("hello1"); } struct HelloStruct { std::string text; HelloStruct() { text = "hello2"; } operator const char*() { return text.c_str(); } }; printf("test1:%s\n", helloFunc().c_str()); printf("test2:%s\n", (const char*)HelloStruct()); VC++でデバッガで追うとstd::stringのデストラクタは安全なタイミングで呼ばれてるんですが 他のコンパイラに持っていっても問題ないのかなと
>>524 一時オブジェクトの寿命は文(正確には完全式)の終わりまであるから、大丈夫。
それとは別に、その変換演算子 operator const char* () は一般的な変換演算子の
話として危険だと思う。
>>524 カッコ内で生成されるオブジェクトってのがどれをさしてるのかわからんけど
"hello1"のことならばは生成されてすぐhellofuncの中でデストラクタが呼ばれる。
ただ、コピーコンストラクタで内容がコピーされて
それが戻るので大丈夫なはず
よかった、ありがと!戻ってきたオブジェクトは文の終わりまでOKなのね
>>524 キャスト演算子はどっかで見たなあと書いたけど確かに・・・
たいして便利でもないしc_str()関数とか作った方が間違いにくいですね
実際に最初printfにキャスト無しで渡してハングさせたし
>>524 まあ、無駄に遅いプログラムが出来るだけ。
個人ツールなら何でもいい、仕事でやったらどうだろうね〜〜
>>526 そういうのは普通戻り値最適化されて、
return std::string("hello1"); の時点で
戻り値用のテンポラリオブジェクトがコンストラクトされるようなコードが生成される
530 :
526 :2010/12/26(日) 20:36:30
>>529 C++ 0b>=ではそれが仕様的に許されることになったとか
そんな話をどっかで見たような
531 :
526 :2010/12/26(日) 20:37:29
ん、過去形はおかしいな
>>530 C++98 から許されてはいるから、そんな話はないと思うよ。
パフォーマンスを調べるときにとりあえずforで大量に呼んで計測してるんだけど このforのオーバーヘッドなしの測定方法ってある?
マクロかTMPにする
535 :
デフォルトの名無しさん :2010/12/26(日) 20:56:32
for のオーバーヘッドがどのくらいかわかれば差し引くだけ 中学レベルの数学でどうにでもなる
>>533 for の中だけ計測すればいいじゃない
>>533 ・無視する
・ループをunrollingするソースコンバータを作って評価
forのみで処理させて、それを引けば forの影響はある程度なくせるけど でも結局ループでパフォーマンス調べるのでは キャッシュの影響が入っちゃうから 本当のパフォーマンスなんてのは分からないものだ
>>533 一般的な実験では
何も内容(効果)が無いであろうものも同時に調べておき、最後にそれらを比較する
Hoge *p = new Hoge(new Fuga); これって例外でたらリークする?
する
人に聞かなくてもデストラクタにトレース出力入れればわかるだろ
>>540 Hogeコンストラクタの実装次第、としか言いようが無い
とりあえず
class Hoge {
public:
Hoge(Fuga* fuga) : m_fuga(fuga), ... { ... }
private:
std::auto_ptr<Fuga> m_fuga;
...
};
となってるならリークしない
>>543 new Fuga の評価後に Hoge のための operator new で bad_alloc 出たら
Hoge のコンストラクタ定義に関係なく漏れるでしょ。
>>544 operator newの実装次第としか言いようがない。
ユーザー定義のoperator newがあってガベージコレクションが
実装されているかもしれない。
newで生成したオブジェクトを受け取る設計は糞だと思うが、 auto_ptr<Fuga> unko(new Fuga); Hoge *p = new Hoge(unko); unko.release(); でいいんじゃない?
>>544 ああ、そうか
それ忘れてた
まあoperator newまで考えると分からんが、危険だな
>>546 Hoge のコンストラクタで所有権が移動するなら中で release() するだろ。
移動しないなら release() しちゃダメだし。
もとが Hoge *p = new Hoge(new Fuga); なんだから、 Hogeの引数はauto_ptrじゃなくてFuga*型だし、 Hogeがメモリ解放する設計になってるんでは?
>>549 なら new Hoge(unko.get()) だな。ただの書き間違いか。
おそらく.get()の間違いとして、auto_ptrで囲めば例外安全になるの?
Hogeの引数をauto_ptrにしろって話じゃないの?
Hogeの引数がスマポでimplicitコンストラクタ持ってるなら
>>540 でも例外安全か
auto_ptr<Hoge> hoge(auto_ptr<Fuga>(new Fuga));
これでいいのかな
>>553 >>544 を100ぺん読み直せ
> auto_ptr<Hoge> hoge(auto_ptr<Fuga>(new Fuga)); ? auto_ptr<Hoge> hoge(new Hoge(auto_ptr<Fuga>(new Fuga)));
ボスはサンタもやってるのか
>>554 引数のテンポラリオブジェクトの作成とnewって
どっちが先だっけ?
C++って糞だな。 おJAVA様(笑)なら new Hoge(new Fuga()) でオーケーだぜ
>>558 結局そこに行き着くんだよなぁ
C++もそろそろ根っこから新しくしないと時代に取り残されるよ
C++にガベージコレクションを付けろと?
Hogeがテンプレートならいいけど、そもそもauto_ptrを受け取る設計はいかんでしょ。 operator newとoperator deleteでC++ライブラリの不整合が あったらどうすんの
>>562 どうにもならんと思うが、 auto_ptr を受け取らなければなんとかなるのか?
>>561 newとコンストラクタ引数の評価順はundefinedかunspecifiedってことか
それだと無理だな
動的削除子を載せた shared_ptr のコピーにすればライブラリの不整合とやらがあっても大丈夫だね。 だからと言って auto_ptr 渡しに原因があるかのように言うのは筋違いだろう。 生ポインタだって unique_ptr だって、動的削除子無しで所有権の移動をする限り同じこと。 そもそもライブラリの不整合なんて心配しないといけないのもおかしいだろうと思う。
auto_ptrは解放を自動化するための技でしかなくて、 ライブラリ境界をまたいでnew/deleteしないような設計にするのは基本だろ。 deleteする側が性的リンクしてnewする側が動的リンクとか不整合は簡単に起こる。
operator newを定義して、その中ですまぽ<T> hogeに入れて、*hogeを返すって実装はどう
struct Test { Test* mawari[9]; }; ってなってるやつを 0 1 2 3 4 5 6 7 8 って考えて Test t; t.mawari[0][0]で添え字4にアクセス t.mawari[-1][-1]で添え字0にアクセス t.mawari[-1][0]で添え字3にアクセス みたいなことをオペレータでやりたいんですけどどうすればできますか?
proxyを使います
Test *p = reinterpret_cast<Test (*)[3]>(mawari + 4); p[0][0]; みたいな感じ? 確認はしてない。
572 :
571 :2010/12/27(月) 01:27:29
xとyが逆だったすまん。 int ar[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; struct proxy_y { int *p, x; proxy_y(int *p, int x) : p(p), x(x) {} int &operator[](int y) { return p[4 + (3*y) + x]; } }; struct proxy { int *p; proxy(int *p) : p(p) {} proxy_y operator[](int x) { return proxy_y(p, x); } }; proxy p(ar);
struct Test { struct { struct { Test& operator[](int i); } operator[](int i); } mawari; Test& operator=(Test*); }; とりあえずプロトタイプ宣言的なものは上の形でできました(VC++で赤い波線が消えました)
>>569 めんどくさいから mawari(int, int) って関数にしたほうがいいよ。
コスト面でもoperator()だよね普通
>>574 思ったよりめんどうだったので関数でやってみます
577 :
デフォルトの名無しさん :2010/12/27(月) 13:55:06
なんでだよ。 int &marari(int x, int y) { return p[4 + (y * 3) + x]; } が一番シンプルだよ
無理にoperatorを使う必要はない Test* Test::mawari(int x, int y) { return t.mawari[(y + 1) * 3 + (x + 1)]; } で十分 演算子オーバーロードにこだわるのは初心者にありがちな悪癖
ああ t. いらねえや
581 :
576 :2010/12/28(火) 01:21:10
>>577 は自分ではありません
あと、関数でやろうとしましたが=のオペレータがどうしたらいいかわからなくなったのでやめました
いろいろな意見を出していただきありがとうございました
struct Test {
Test* mawari[9];
void move(int index){
*this = this->mawari[index];
}
}
のようにして
Test t;
t = t->mawari[2];
を
t->move(2);
のようにしようとすると*this = this->mawari[index];の=に赤波が付きます
このようなことはできるのでしょうか
>>581 赤波って、コンパイルエラーだろ。エラーメッセージを見ろ。
(その例だとどうせ「型が合いません」とか言われてるはず)
すいません これらのオペランドと一致する演算子"="はありません とでます *thisに代入できないということなのでしょうか
>>583 = の左辺が Test 型、右辺が Test* 型になってる
やっとわかりました thisってconstだから代入できないんですね ということは自分自身を変更することはできないということでしょうか?
>>585 メンバ関数 move() の中で this は const だが *this はそうではない。
>>585 = の左辺が Test 型、右辺が Test* 型になってる
*this = *this->mawari[index]; だとエラーはありませんでしたが t = t->mawari[2]; と等価の働きはしませんでした t = t->mawari[2];と同じ動きにはできないでしょうか
>>588 t の型が Test なのか Test* なのか、はっきりしないな。
「等価の働きはしませんでした」と言われてもどうなったのかがわからない。
コンパイルできるソース貼れ。
Windows(VC++)のマルチスレッドで、スレッドBからスレッドAの中で割り込みを発生させることはできますか? UNIXのシグナルのような感じで、スレッドAが動作中にスレッドBからスレッドAの中で割り込みを発生させて、別の処理をさせたいのですが
>>590 >スレッドBからスレッドAの中で割り込みを発生させて
オマエはUNIXシグナルの基礎を理解していなさそうだから、
あきらめた方がいいよ。
592 :
591 :2010/12/28(火) 07:28:28
VC++はスレッドBでraiseすると、シグナルハンドラは確かスレッドBで実行される。 Ctrl+CとかのSIGINTだと別スレッド。 シグナルハンドらはvolatile変数のフラグ立てるぐらいしか処理しちゃしけない。 これでUNIXシグナル相当のことはできるはず。
>>591 わかりずらかったでしょうか?
UNIXのシグナルはプロセスになっちゃいますが、シグナルみたいなことをスレッドでやりたいのですが
基礎を理解していないんじゃなくて、説明が下手だったのか。
>>594 で、メッセージを投げるんじゃダメな理由が何かあるのか?
どっちみち、ここよりも汎用C/C++スレかWinAPIスレで聞いた方がよさそうだが。
STLコンテナって一般のコンテナと何が違うんですか? ググルとアルゴリズムがどうのこうのと言ってるんですがよくわかりません
一般のコンテナより少ない体積で沢山入る マジ便利
一般のコンテナとは何ぞや
今までは標準のコンテナがなかったのさ。 だからソフトハウスが独自に用意するか、さもなくばコンテナなしに済ませてたってこと。
>>596 C++標準のコンテナ。それ以上の意味はない。
VC++でメルセンヌツイスタ(SFMT)を使いたいのですが、どのようにすれば組み込めますか? プロジェクトと同じフォルダにSFMT.hとSFMT.cを移してソースコードに#include"SFMT.h"だけではだめなのでしょうか
アプリの使い方はそのアプリのスレに行ってくれ。 せめて何がどうダメだったのか位書いてあれば兎も角、ここはエスパースレじゃない。
エスパドリューがエスパーの履く靴だと思っていたあの頃…
>>602 わかりました。
-----------------------
#include"SFMT.h"
int main(){
init_gen_rand(0);
return 0;
}
------------------------
上記を入力してデバッグすると
1>------ ビルド開始: プロジェクト: tst, 構成: Debug Win32 ------
1> tst.cpp
1>tst.obj : error LNK2001: 外部シンボル ""void __cdecl init_gen_rand(unsigned int)" (?init_gen_rand@@YAXI@Z)" は未解決です。
1>c:\(中略)\visual studio 2010\Projects\tst\Debug\tst.exe : fatal error LNK1120: 外部参照 1 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
というエラーが出ます。何か分かりましたらよろしくお願いします
>>604 extern "C" void __cdecl init_gen_rand(unsigned int);
.cもプロジェクトに追加しなさい
607 :
デフォルトの名無しさん :2010/12/28(火) 19:32:02
MinGW gcc4.4.1 でコマンドラインアプリケーションを作っているのですが 標準C++に違反しないまま、他人が配布しているDLL内にある関数を使用することはできますか? ググってみたところ、どれもwindows.hをincludeして LoadLibrary,GetProcAddress,FreeLibrary を使用しているようですが。
>>607 LoadLibraryみたいなAPIを使うことを標準C++に違反するとは言わない。
そんな事言ったらそのDLLを使うこと自体が違反だと思うが?
…ちょっとエスパーすると、
そのDLLもDLLと言うモノ自体もC++の規格にはないので
あなたの求めるような方法が存在するわけがない。
DLLなんてものがC++にあると思っているバカがいるのはここですかw
インポートライブラリつかえ
>>607 DLL内で例外処理さえ使わないようにしておけば安全
例外処理はコンパイラに依存するので、同じコンパイラで組んだDLLでないと
例外処理を行わせると未定義の振る舞いになる
DLLは結局Cで書くんだよね俺らって
>>605-606 ありがとうございます。が、今度は別のエラーが出てしまいました.。まだ何か足りないようです
状況:プロジェクトのソースファイルにSFMT.cを追加
ソース"tst.cpp"
------------------------
#include"SFMT.h"
extern "C"{
void __cdecl init_gen_rand(unsigned int);
}
int main(){
init_gen_rand(0);
return 0;
}
------------------------
1>------ ビルド開始: プロジェクト: tst, 構成: Debug Win32 ------
1> SFMT.c
1> tst.cpp
1>c:\(中略)\visual studio 2010\projects\tst\tst.cpp(2): error C2732: リンケージ指定は、別の 'init_gen_rand' に対する指定と矛盾しています。
1> c:(中略)\visual studio 2010\projects\tst\tst.cpp(2) : 'init_gen_rand' の宣言を確認してください。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
init_gen_randの下に下線が出ており、マウスポインタを置くと
「リンケージ指定は前の"init_gen_rand"(宣言された行 79 ファイル名STMT.h)と互換性がありません」
と表示されます。なお、SFMT.hの79行目は以下の通りです。
--------------------
void init_gen_rand(uint32_t seed);
--------------------
何か助言がいただけましたら幸いです
>>613 extern "C"{
void __cdecl init_gen_rand(unsigned int);
}
なんで中括弧つけた?
>>614 あ、さーせん。それはネットで調べてていろいろ試してたのがそのままだからです。
-----------------
extern "C" void __cdecl init_gen_rand(unsigned int);
-----------------
に表記を直してもエラーは同じものが出ています
extern "C"{ #include"SFMT.h" } int main(){ init_gen_rand(0); return 0; }
>>616 おお!通りました!
ありがとうございます!!
SFMTである必要がなくて、単にメヌセンヌツイスタ使いたいだけなら、 Boost、TR1 (VC++ 2008)、0x (VC++ 2010)のRandomライブラリを使うのも手。
そんなことは知っているが誰も聞いてない。
MFCのCArrayのGetDataのようなことをSTLのvectorでやりたいんだけど、できますか? CArray<char, char> hoge; char *parray = hoge.GetData(); みたいにデータの先頭のアドレスを取得したいのです (もちろんこれがSTLではあまり綺麗なやり方でないことは承知しています) std::vector<char> hoge; char *parray = hoge.begin(); だと「error C2440: '型キャスト' : 'std::_Vector_iterator<_Ty,_Alloc>' から 'char *' に変換できません」のエラーになります(VC++2005)
&hoge[0]
>>621 !hoge.empty() を確認してから使おうね。
C++0xならdata()があるんだけど 何でC++03で導入されなかったんだろうなあ
禿が間抜けだったから
そんなアホなことせずイテレータ使えってことだろ
C++03ってのは、vectorのメモリ上の連続性を保証する仕様を導入した規格なんだよ なら先頭アドレス取得するメソッドも追加しろって話
&* vec.begin()
629 :
デフォルトの名無しさん :2010/12/31(金) 09:05:49
コンパイルエラーが出すぎて困ってるんだけど、 ファイルにダンプする方法、 g++のオプションで減らす方法、 エラーをひとつひとつステップ出力する方法 のどれかを教えてもらえますか?
> IDE (VC++など)などの使い方の質問はその開発環境のスレに > お願いします。
631 :
デフォルトの名無しさん :2010/12/31(金) 10:27:50
以下のコードでBUGというメッセージが出る可能性はあるでしょうか? このコードが複数のスレッドから同時実行されているのですが、、、 #include <iostream> #include <string> #include <set> int main() { typedef std::set<std::string> TagSet; typedef std::pair<TagSet::iterator, bool> TagEntry; TagSet checkList; std::string tag("abcde"); if (checkList.find (tag) == checkList.end ()) { TagEntry tent = checkList.insert (tag); if (! tent.second) { std::cout << "BUG\n"; } } return 0; }
余裕でありそうだけど どうして無いと思う?
>>631 そのコードそのままのmain関数を複数スレッドから呼んでも
競合が起きる可能性はないよ。
もしcheckListが非ローカルなら当然アウトだけど。
自分自身のコピーを作る関数で以下のようなコードがありました。 ClassA& ClassA::Dup() { return *this; } このコードは以下のように書いては駄目なのでしょうか? 違いがわかりません。 ClassA ClassA::Dup() { return *this; } よろしくお願いします。
>>634 上のコードはコピーなんて作ってなくてただの参照を返してるだけ
単純にC++の参照の機能を勉強すれば違いがわかるんじゃないだろうか
むしろ上の書き方がだめ。Dupという名前にふさわしくない動作をする。
つまりDuppunですね
>>635 参照については、書籍やホームページで勉強したのですが、
return *this;とする場合に、参照で渡すのとそのまま渡すので
どう違いがあるのかよくわかりません。
参照で渡したほうがメモリを食わないのかなとは思いますが…
>>636 二つのコードで振る舞いに違いが出るのは
どういう場合でしょうか?
代入演算子のオーバーロードのサンプルコードでは、
戻り値が参照でreturn this*;と
なっているコードを見たりするのですが、
そういう書き方はよくないということでしょうか?
640 :
634 :2011/01/01(土) 11:49:31
>>639 理解できました。
ありがとうございました。
てす
Unit1.cpp const char * const szStr1 = "aaaaaaaaaaaa"; --------- Uit2.cpp extern const char * const szStr1; ----------- const char * const を const char * にするとOKなんですが const char * const のままだとリンカエラー(参照の未解決)になるんだけど、理由が分かりません。 なぜリンクできないのか教えてください。 お願いします。
float型で割り算をするとき、 0割エラーが発生しないもっとも0に近い値はいくつですか?
>>644 0でも発生しないと思うよ
結果が非数とか無限大とかになるだけで
ありがとうございます。 ということは、0かもしれない値で割り算するときは、 除算後にその値をisfiniteマクロあたりで調べる、というのがベターでしょうか?
>>646 どう考えても除算前に0かどうかを比較するのがベストだろ
648 :
644 :2011/01/01(土) 18:26:21
ではひきつづき644の質問をお願いします
floatの最大値を超えると無限大になるので、floatの最大値をちょうど超えないような結果になる除数を知りたいということだな 被除数が 1 ならおよそ 3.0e-39 くらい 被除数が 2 ならおよそ 5.9e-39 くらい 被除数が 0.5 ならおよそ 1.5e-39 くらい 被除数が x ならおよそ (x / FLT_MAX + ulp) くらい で割るといいと思うよ
650 :
644 :2011/01/01(土) 19:10:08
0.0 / 0.0 にカレーをつけると美味しいらしい。
VC++6を使用して、エクセル操作って出来るのか? 操作する環境はInterop.ExcelとかのOffice関係のライブラリが一切インストールされてないんだが 無理じゃね? dllをexeと同じ階層に持ってきちゃえばいける気がするのだが 金が掛かっている以上、MSのdllを無許可で使用するのは得策じゃないし・・・
質問です。配列を初期化するようにクラスを初期化したくてstd::arrayをぱくったんですけど、どうしても変数をパブリックにしないと実現できなそうです。 そこで、プロテクトを考えたんですけど、ここまでやる必要はありますか?#undefするまではありだと思うんですけど、最後の@に置換してるのがキモイです。 #define Value_ ValueIsProtected_ template<class T> class MultiValue{ enum {Size_ = 3}; public: T Value_[Size_];//Dont Touch The Direct Value. void Initialize(){ Value_[0] = T(); Value_[1] = T(); Value_[2] = T(); } void Initialize(const T& A,const T& B,const T& C){ Value_[0] = A; Value_[1] = B; Value_[2] = C; } T& A(){ return Value_[0]; } T& B(){ return Value_[1]; } T& C(){ return Value_[2]; } }; #undef Value_ #define ValueIsProtected_ @
イミフ
えーっと、 MultiValue<T> V={A,B,C}; 的な初期化がしたいのですよ。 で、std::arrayをみて、コンストラクタを書かずに、対象の変数をパブリックにすれば、 言語の標準機能で初期化できることがわかりました。 しかし、クラスの隠蔽の観点からそういうパブリックな変数は意にそぐわないと思います。 そこで、パブリックにする代わりに、プリプロセッサで予測が難しい文字列に置換することにしました。 で、defineしたものを使い終わったらけして、隠蔽を図るまではアリだと思うのですが、 その後の使用においてもパブリックなフィールドに手をつけられないようにするべきでしょうか。それが@に置換なんですけど。 そもそも、どの程度のプロテクトをかければ正常な運用の上で不具合が起こらないでしょうか?? vc10なんですけど、イニシャライザーリストさんがまだ来ないので困っています。
そんなところで頑張っても無意味なのでpublicにするか普通にコンストラクタを使ってください 変なマクロで識別子を汚されると皆が迷惑するんです
>>657 無駄な努力ですか〜。まーそうかもですね。
体裁整えたかったんだけど、イニシャライザーリストさんをまちますよ。
解答ありがとう。
むしろMultiValueなのに型の指定が1つというのが気になる
タプル的な意味ではなくて、メンバ変数的な意味で、マルチバリュー。 適当な名前が思い浮かばなかったんだ。Orz
覚えたては、覚えたテクニックを駆使したくなるもんだよ。
>>643 const なオブジェクトのリンケージはデフォルトで内部リンケージ。
これは C と C++ で違うところ。
外部リンケージにしたいときには extern の指定が要る。
ヘッダで宣言せずに extern で取ってくる、なんて行儀の悪いことを
しようとするからそんなことになる。
>>656 documentに「publicにしてあるけどさわったらちゃんと動きません!」って強くその旨記載してあれば
正常な運用の上で不具合は起こらない。
俺だったら
Do_Not_Touch_This_Member_xxxxないしdo_not_touch_this_member_xxxx
ってやる。
そもそもそうならないようにするけど。
teamの仲間が良識があればさすがに触らないでしょ。
664 :
663 :2011/01/03(月) 19:53:15
× 俺だったら × Do_Not_Touch_This_Member_xxxxないしdo_not_touch_this_member_xxxx × ってやる。 ○ 俺だったら ○ Do_Not_Touch_This_Member_xxxxないしdo_not_touch_this_member_xxxx ○ っていうメンバ名にするよ。
考え方としては有りだと思うがtouchはない
おさわり禁止だよな
actually_private_member_xxx とか
ご意見ありがとう!
>>663-664 最初それ系を考えたんですけど、保守性の観点からクラスの記述はシンプルにしたかったので、defineにしたんですよ。
それでもコード補間で候補に出るから参ったって感じでしたけど、まー良識を信用したほうがいいところに落とせそうです。
>>665-666 もう触れるのもやめてくれ的な強い意味でタッチを選んだんですけどナシですか。英語は難しいです。
あ、ごめん
>>669 だが
よく読んだら「あのコードには(違法に盗まれたものなので)関わらないでくれ」って意味だったみたい
コード修正するな、だとdonot modify this codeの方が明確なのかな
スレチだから命名スレ行けカスども
>>672 !!!!!!!!自治厨乙!!!!!!!!!!!!
どうでもいいさ
>>671 > コード修正するな、だとdonot modify this codeの方が明確なのかな
でも質問者は「コード修正するな」じゃなくて
「このメンバ(変数)は(C++的に気持ち悪いけどpublicにしたんで)関わらないでくれ」
って意味だからtouchでいいんじゃないのかね。
>>652 Interop.Excelって.NETのタイプライブラリインポートだよな(以下その前提で話をする)。
そうならそもそもVC6ではそんな機能動かないぞ。
なので、選択肢は2つ。
VC6でやりたい→Interop系使わない。Excel操作なら#import使え。
Interop系使いたい→VC6を使わない。
ちなみに、Interop.Excelを自分のアプリと一緒に配るべきでないのは正解。
なぜならMS Officeの一部としてインストールされているから。
http://msdn.microsoft.com/ja-jp/library/aa159923.aspx ただし、アプリを作る側でも、自分のInterop.ExcelではなくこのExcelのPIAを参照させる必要がある。
細かい話はVC++なりなんなりのスレへ行け。
>>675 延々と続けられるのもあれなので答えを書くと
dont access this member directly
678 :
デフォルトの名無しさん :2011/01/04(火) 22:19:27
もっとシンプルに dont access here
leave_me_alone
north_korea
gtfo
685 :
デフォルトの名無しさん :2011/01/05(水) 03:11:42
>>682 c++スレでc++の命名について議論しちゃダメなんですか?
>>682 面白いね。理屈理解するのにちょっと悩んだぜ。
template<class T> struct identity { typedef T type; }; struct A : identity<int> { type value; //これはOK? }; typedef base::type type;とtypedefし直してるのをよく見ますが、typedefって継承されますか? VC++、gccでコンパイル通るようですがC++としてはどうなんでしょうか。
>>687 継承されるメンバに種類の区別は無いよ。 (ISO C++ 2003 10 [class.derived] p1)
>>688 読みづらくなりそうですが、typedefし直さなくても問題ないんですね。
ありがとう。
class Hoge { }; class Fuga { private: Hoge *pHoge; public: void change1(Hoge **p) { Hoge *tmp=pHoge; pHoge=*p; *p=tmp; } Hage *change2(Hoge *p) { Hoge *tmp=pHoge; pHoge=p; return tmp; } }; main() { Hoge *hoge; change1(&hoge); hoge=change2(hoge); } --- コンストラクタ、デストラクタは省略。 change1とchange2の実装だったらどっちが良い?
あっmainは以下で。 main() { Hoge *hoge; Fuga f; f.change1(&hoge); hoge=f.change2(hoge); }
>>690 実装じゃなくてインターフェースの比較の話だよね?
値の交換しか提供しない、似たような std::set_new_handler() の
インターフェースが問題とされたりしている。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3189.htm どちらというより、まず値の取得と設定は分けておいたほうがいいと思う。
Fuga const からは読み出せないとかいうのも問題になりそう。
そうは言っても値の交換を複数スレッドからアトミックにしたい場合は似たような
インターフェースが必要になるかもしれないとは思う。その場合は "swap" という
名前付けができる change1() のインターフェースのほうがいくらかわかりやすい
かもしれない。
本筋とは関係ないけど、暗黙の int は標準から外れるんでやめといたほうがいいよ。
>>692 > 値の取得と設定は分けておいたほうがいい
これはどういう意味?
> 暗黙の int は
mainの戻り値のこと?ここは説明用に書いただけで省略しちゃいました。
>>693 あたいのしゅとくをするかんすうとせっていをおこなうかんすうをふたつ
よういすればいいんだとおもうよ。
695 :
デフォルトの名無しさん :2011/01/06(木) 18:18:17
C++の文法の質問です。 二択条件式 | 論理和式 | 論理和式 ? 式 : 代入式 となっていますが、2番目が C言語では 論理和式 ? 式 : 二択条件式 となっています。違いの意味は何でしょうか? また ++x の評価が C++ では左辺値、Cでは右辺値となっている と思うのですが?違っているのは何か意味があるのでしょうか?
x ? y : z = 1; がC++では x ? y : (z = 1); と解釈されるがCでは (x ? y : z) = 1; と解釈される (そしてエラーになる) という意味では ++x は左辺値の方が参照が取れて便利だから?
++は変数にしか使えない演算子なんだから、 右辺値になっているCの設計がおかしいだけ。
698 :
デフォルトの名無しさん :2011/01/06(木) 21:04:53
>>696 C++では x ? y : (z = 1); と解釈される
ありがとうございます。
C++ が x ? y : (z = 1); とする方を仕様とした理由が知りたいです。
(++x は左辺値の方が参照が取れて便利だから? )と同様な
x ? y = 1 : z = 1; こうやりたかったんじゃないの? こういうのはif-elseでやってくれとは思うが
>>698 エラーだったのを動くよう直すのに何か特別な理由がいるのか?
x ? y : z = 1;なんか書かねーだろ
下記のコードが VC9 と VC10 で C2664 になりますが、GCC4 では問題ありません。 const なメンバ関数の型を正しく推測できていないようです。 何か規格外の事をしているのか、それとも単なる VC のバグなのでしょうか? struct Foo{ void test1(){ cout << "test1" << endl; } void test2() const{ cout << "test2" << endl; } }; template<typename F> void test( Foo* foo, F Foo::*func ){ ( foo->*func )(); } Foo foo; test( &foo, &Foo::test1 ); test( &foo, &Foo::test2 ); // C2664
#pragmaの指定を使って、そのソースをコンパイルしたときに 別のobjを一緒にリンクして実行ファイルを作ってくれるように指定することはできないでしょうか? (コンパイラはclを使っています。) #pragma comment(lib, "sub.obj") ←こんな風に書きたいのですができませんでした
704 :
デフォルトの名無しさん :2011/01/07(金) 04:00:43
>>700 エラーだったのを動くよう直すのに何か特別な理由がいるのか?
Cではエラーではない。Cとの互換性をできるだけ維持しようとしていた
はずのC++が何故、些細と思われる仕様の変更を行ったのか?または言語
仕様上こうしなければならない理由があるなら、それを知りたいだけです。
知りたいだけです(キリッ
#pragma 指定をどう解釈するかはコンパイラに依存する
>>703 その別のobjとやらをライブラリ化すればいいんじゃないのか?
>>702 template<typename F>
void test( Foo* foo, F func ){
( foo->*func )();
}
でいいんじゃないかな
STL, Qtの両コンテナで動くテンプレート関数を作ろうとしています。 コンテナの定義が STL template<class T, class Alloc=allocator<T>> class vector; Qt template<class T> class QVector と、コンテナのテンプレート引き数の数が異なるのが問題で template<template<class A, class B=allocator<A> >class C, class T> T func(C<T>& a) みたいな関数はSTLコンテナから呼び出せますがQtコンテナからは無理です。 template<template<class A>class C, class T> T func(C<T>& a) ではQtコンテナはOKでSTLコンテナはNGです。 なんか、上手く両方から使えるテンプレート関数を作ることはできないものでしょうか。 STLのデフォルト引数周りをゴニョゴニョすれば行けそうな気がするのですが・・・
template <class T> typename T::value_type func(T & a); じゃだめなの?
>>702 > template<typename F>
> void test( Foo* foo, F Foo::*func ){
これだと func は F 型の非静的データメンバ( Foo のメンバ変数)へのポインタに
なりそうなんだけど、これでメンバ関数へのポインタもマッチしちゃう gcc がなんか
おかしいんじゃないかな?
713 :
709 :2011/01/07(金) 12:34:50
>>710 あざーす
そんな型が定義されているとは知りませんでした。
Qtの方にもSTL互換用に定義されてました。
テンプレートに定義されて無いといけない関数が 定義してなかったらエラーじゃなくて デフォルトのことをするなんてことできませんよね?
できます
template <typename T> class C{ C(){ T.a(); } }; ではこのa()が定義されてなかったときの例について教えてください。
>>702 test( &foo, &Foo::test2 );
この場合、constでないオブジェクトfooがconstなメンバ関数test2を呼び出しているけど、いいんだろうか?
継承使えばいいんじゃね?
>>717 それのどこが問題なんだ?
const なオブジェクトが非const なメンバを呼び出せるのが不味いってんなら分かるが
>>717 書き換え可能なオブジェクトに対して書き換えしない関数を呼んでも何も困らない。
>>716 has_member が要るケースか。それは標準では無理だな。
722 :
717 :2011/01/07(金) 13:39:26
ごめん。超勘違いしてた
>>723 型名を持ってるかどうかの判別じゃダメでしょ?
725 :
デフォルトの名無しさん :2011/01/07(金) 14:37:39
>>711 ごめんなさい。言い方(書き方)をまちがえていました。
Cではエラーとなる仕様なのに、C++ではエラーとならない仕様となっているのは何故?
といううことです。
C++では第二演算対象、第三演算対象が左辺値であって同じ型である場合は
「二択条件式の結果をその型の左辺値とする。」とする仕様と関係があるのか?
>>699 のとおり if-else で十分なのではないかと思うに、何故?
しつこくてごめんなさい。
>>725 どちらも不要な制限事項を取り払ったもの。
Cではエラーになっていたものなので、互換性の問題も無い。
>>725 むしろ、エラーのままにしておいたほうがいいと思う理由は何?と聞きたいぐらいだ。
>>725 構造体名の前の struct が不要になったことについても君は理由を問うのかね?
730 :
デフォルトの名無しさん :2011/01/07(金) 19:26:37
mainから呼ばれた関数の中でnewし、 main関数内でdeleteすることは推奨されるのでしょうか。 例えばこんな感じです。 ポインタを参照渡しするのもなんか気持ち悪いので もっと良い書き方があれば併せて教えて頂けるとうれしいです。 int ReadVariableData(char* &a) { int size = GetSize(); a = new char[size]; ReadData(a,size); return size; } void main(void) { char* a; int size = ReadVariableData(a); //処理 delete[] a; }
731 :
デフォルトの名無しさん :2011/01/07(金) 19:27:05
>>728 構造体名の前の struct が不要になったことについても君は理由を問うのかね?
C++ で struct を前置してもエラーにならないのはCとの互換性のためでは?
二択条件式の例では、
>>726 のとおり、Cではエラーになっていたものなので、
互換性の問題も無い。 (CでコンパイルできたソースをC++でほぼコンパイルできる)
「どちらも不要な制限事項を取り払ったもの。」なのか、C++の言語仕様で必然的に
そうしているのか?(私自身はなにによって必然となるのか理解していませんが)
ということを知りたい。またまたしつこくてごめんなさい。
>>730 別に問題は無いけど直接newを使うとdeleteし忘れの可能性があるし、関数のシグネチャからは内部でnewしてることがわからないので
いちいち関数の中身を見ないとdeleteが必要かどうかわからないなど保守の手間がかかるので避けたほうがいい。
この場合はstd::vector<char>を使うのがいい。スコープを超えて使いたいならスマートポインタの類を使う。
int ReadVariableData(std::vector<char>& a)
{
int size = GetSize();
a.resize(size);
ReadData(&a[0],size);
return size;
}
void main(void)
{
std::vector<char> a;
int size = ReadVariableData(a);
//処理
//delete不要
}
それに直接new,deleteをつかえば途中で例外が飛んだ場合にメモリリークしてしまう。
734 :
デフォルトの名無しさん :2011/01/07(金) 20:27:33
C++でネットワークプログラミングしてみたいんですが、よい入門によい 書籍・サイトとかありますか? チャットツールとかが作れるようになりたいです。
>>731 たぶん"その理由はこうです"的なものは見つけるのが難しいんじゃないかなぁ
だいたいの予想としては
c ? x = 42 : y = 42 ← xはいいけどyはダメ
みたいなイミフなルールを是正するためだと思う
736 :
デフォルトの名無しさん :2011/01/07(金) 21:27:32
>>735 ありがとうございます。
いろいろ調べていたら、JIS X3014 附属書Cの 5.16,5.17,および5.18 に
改変内容 条件式、代入式 又はコンマ式の結果は左辺値となりうる。
改変理由 C++は、オブジェクト指向言語の一つであり、左辺値を比較的
重要視している。例えば、関数は左辺値を返してもよい。
とありました。
ネットワークならjavaあたりから入ったほうがいいんじゃないか?
ruby最強
>>734 1. まずsocketのマニュアルを開きます
2. 次に簡単なechoサーバーを作ってみましょう
3. あとは応用で何でもできます
完
ダブルポインタで渡ってきたクラスのメンバを呼び出す時に *を使わないですむ演算子はないのでしょうか? Hoge(CTest **p) { ……… (**p).guhe(); //方法1 (*p)->guhe(); //方法2 p-->guhe(); //こんな感じで*を使わず呼び出したい
hoge moge(huga** in){ huga* P = *in; P->proc(); } ってかんじじゃね?
CTest*& pってやればいいんじゃね
>>741-742 ありがとうございます。
ポインタへの参照ですっきり書くことができました。
744 :
デフォルトの名無しさん :2011/01/08(土) 00:14:13
>>739 なんかよくわかりませんがとりあえず手順通りにググッたり書籍を探してみたり
してがんばります。
745 :
730 :2011/01/08(土) 00:30:22
>>732 >>733 アドバイスありがとうございます。
説明不足というか後出しで大変恐縮なのですが
目標はBMPファイルをロードする関数を作るので、
fin.read()で一気にピクセルデータをロードしたいと思っています。
fin.read() の第一引数に &a[0] を入れても(std::vectorの内部構造的に)大丈夫なんでしょうか?
746 :
730 :2011/01/08(土) 00:41:58
すみません、「vector メモリ 連続」でググって自己解決しました。
std::vectorはメモリ連続性が保証されてるので、
>>732 の方法でOKなんですね。
>>732 の方法で行きたいと思います。
ありがとうございました。
イテレータのようなものを作っててわからなくなりました template < class T > class renketu { struct list { list *prev; list *next; T n; } list *begin; public: class iterator { public: iterator& operator++(); ・・・・ private: list *listPtr; } renketu(){ begin = new list; } iterator beginIterator(){ return ???; } } のような感じにするとiteratorでprivateにしてるlistPtrに対してアクセスすることができずlist *beginを持つiteratorを返すことができません だからと言ってiteratorのpublicに書き換えるための関数を用意するのもスマートではありません どうにかして例外的にprivateにアクセスさせるなどの方法はないでしょうか
748 :
730 :2011/01/08(土) 22:12:32
>>730 の続きの質問をさせてください。
>>732 の方法を用いて、bmpのピクセルデータを
std::vector<char> a に格納することには成功しました。
このデータをメディアンフィルタ関数に渡したいのですが、
a_2d[i][j] というアクセスを可能にできますか?
今まではダブルポインタとnewを使って
char** a_2d = new char*[height];
for(int i=0; i<height; i++)
a_2d[i] = a+(i*width);
としておいて、メディアンフィルタ関数には a_2d を渡していました。
メディアンフィルタ関数にvector<char> a と一緒にwidthも渡せば
a[i*width+j] という形でアクセスは可能なのですが、
今までwidthは渡さずに済んでいたので、できればそうしたいです。
既に存在するvectorに二次元アクセスする綺麗な書き方を教えて頂けませんか。。
vector< vector<char> > a; a.resize(height); for(int i=0; i<height; i++) a[i].resize(width); a[i][j]=0;
a.size()と、a[0].size()で配列サイズを取得できる。
749の代わりに。 vector<string> a; でも良い。 2次元のchar配列確保できる。
[1] 授業単元:画像処理
[2] 問題文(含コード&リンク):
http://codepad.org/7N0GSgtiを完成させよ また上記のプログラムを構造体で表現しなさい
[3] 環境
[3.1] OS: Windows7
[3.2] コンパイラ名とバージョン: Microsoft Visual C++ 2008
[3.3] 言語: C++
[4] 期限:2010年 1月12日
[5] その他の制限:ありません
出力しても写真が表示されません。よろしくおねがいします。
宿題スレにいけ
>>747 コンストラクタに引数で渡せば private な変数に触る必要もない。
>>751 そこは vector<char> だろ。 string にしてなんかいいことあるの?
むしろはじめから vector<unsigned char> じゃないのが気になる。
>>755 それはiteratorのコンストラクタでbiginでlistPtrを初期化するってことですか?
毎回beginを使うわけではないのでそれだと無駄が出てしまいますし
std::vectorのbegin()ようにbeginIterator()で渡して初期化したいんですけど
どうにかなりませんか?
>>757 何が無駄になると言ってるのかわからん。
> beginIterator()で渡して初期化したいんですけど
だからそうすればいいと言ってるだろう。
>>760 iterator に list* を受け取るコンストラクタ iterator(list*) を追加して beginIterator() で
iterator(begin) と渡せば renketu から iterator の private な変数 listPtr に触る必要も無い。
>>761 それをするとmainなどの外部から
renketu::iterator ite( ??? );
のような宣言をしたときにも???に勝手に値を渡せますよね?
内部実装をできるだけ隠してこのクラスの使用者はそのようなことができないようにしたいのです
何かいい方法はありませんでしょうか
renketu<T>::iterator::iterator(int) なんて馬鹿な物を作らなければ外からはrenketu<T>::listに触れられないから問題ない
単純に >747 の質問に答えるなら「friend 使え」で終わりじゃないの?
APIのラッパークラス作りたいんですけど、どうしたらいいですか
>>766 ありがとうございます。そちらで質問してみます
C++書こうとしてもなんかbetter Cっぽくなっちゃうんだけど STLとかクラスとかガンガン使うのがC++っぽいプログラミング?
動けば何でもいいが、 C++っぽいプログラミング と言えば、最低クラスは普通に全体的に使わないとな。
テンプレートでキモいコード書き始めるとC++だなぁって感じる
vectorとアルゴリズムを使っているとC++っぽい気はする。
その状態でガンガンとか考えない方が安全な気がする。 「C+α+継承無しクラス」な状態で2,3年趣味ってた身としては。 今はSTLの簡単なところは使うけど自作クラスを継承とかやった事ないな。
extern void Hoge(); と void Hoge(); では何が違いますか? 静的リンクライブラリ関係で意味の違い等あれば教えてください
C++では違いは無い
>>775 void Hoge(); の場合、
static void Hoge(); が void Hoge(); より前にあれば、void Hoge(); は static になる
static void Hoge(); が void Hoge(); より前になければ、void Hoge(); は extern になる
extern void Hoge(); の場合、常に extern になる
>>777 externが常に外部リンケージ?
ソース出せや
780 :
デフォルトの名無しさん :2011/01/10(月) 22:48:43
>>775 779
static void f();
void g(){
extern void f(); // 内部結合
.....
}
779 のとおりだと思うけど、自分で例だして示したら
ねー、作る物によって言語って使い分けるもんなのかな?
使い分けると楽なのなら使い分ければいい
C++で何でもかんでも書いてたら嫌になるだろ?
15個くらい使えたらいいと思うよ
>>780 誰が教えてくれなんて頼んだ?
お前は諮問されてるんだろうが
人様に物を教える立場か
思い上がるのも大概にしろ
C++ && (Python || Ruby || Perl) && (brainf*ck || whitespace || unlambda) ぐらいが使えれば十分生きていけるんじゃないのかな
>>785 はどうしてそんなに必死なの?ねぇねぇどうして?
788 :
デフォルトの名無しさん :2011/01/11(火) 18:59:24
他人にケチはつけるけど、自分ではできないから
789 :
デフォルトの名無しさん :2011/01/11(火) 20:26:33
>>785 でも人様にソース出させて教えたかったんだろう
なにを教えたかったか見たかった
790 :
779 :2011/01/11(火) 23:03:13
>>779 は俺だが
>>785 とは別人だ。
ISO14882の3.5Program and linkageを読めばすぐにわかる
嘘をつかれたのでイラっとした。
さらっと嘘を回答する奴の精神構造が知りたい。
不遜メソッドでググれ
>>790 extern で宣言されながら外部リンケージを持たない例を教えてください。
793 :
779 :2011/01/12(水) 06:39:38
794 :
デフォルトの名無しさん :2011/01/12(水) 09:50:35
難しい、わからん 以下の例で // e01.cpp #include<stdio.h> void f(){printf("extern void f()\n");} int i = 0x0e; // e00.cpp #include<stdio.h> static void f(); static int i = 0; void g(){ extern void f(); int i; { extern void f(); extern int i; f(); printf("i: %d\n", i); } } static void f(){printf("static void f()\n");} int main(){ g();return 0;} 出力(改行無視) g++(gcc 4.5.0 20091105) : extern void f() i: 14 VC(cl 15.00.30729.01) : static void f() i: 0 大抵は、 gcc の方が正解だと思うが static void f(), i: 14 が正しいのでは
>void g(){ > extern void f(); > int i; ここで、e00.cppのfとiが隠蔽されるんじゃないか?
>>795 i は隠蔽されて後続の extern int i で外部リンケージになるが、
f() は static void f() の宣言になって、後続の extern void f() も同じくそれを受け取り、
結局内部リンケージになるらしい。
ってことで static void f(), i: 14 が正解だな。
797 :
デフォルトの名無しさん :2011/01/12(水) 16:51:29
>>795 ありがとうございます。
void g()直下の extern void f(), と int i をコメントアウト
すれば、gcc, VC ともに static void f(), i: 0 を出力しました。
gcc はそのように隠蔽されたと解釈しているのだと思われます。
しかし、 ISO 14882 ではコメントアウトしない状態で、
static void f(); // @
static int i = 0; // 1
void g(){
extern void f(); // A internal linkage
int i; // 2. i has no linkage
{
extern void f(); // B internal linkage
extern int i; // 3. external linkage
}
}
となっています。
私の拙い英語力での仕様書の解釈は、
3. の i は、2. の結合を持たない i で 1. の内部結合を持った
i が隠蔽され、結果 外部結合を持った i を参照することになる。
B の f() はAの f() が@のf() の内部結合を受け継ぎ、その
内部結合を受け継いでBの f() も内部結合を持つことになる。
で、static void f(), i: 14 が正解だと考えスレしました。
よろしく、お願いします
798 :
デフォルトの名無しさん :2011/01/12(水) 16:53:41
>>796 797 です。すいません。簡潔にすでに答えられていたことをきずいていませんでした。
ひさびさにこのスレで勉強になった
不遜メソッド強力だな
勉強っていうか、糞言語C++の無駄に複雑な仕様を垣間見ただけだな。
コンパイラの実装以外で役に立つことはまずないだろうなぁ
じゃあ、役に立つ言語って何だよ
日本語とか日々の生活に役立つと思うよ
805 :
デフォルトの名無しさん :2011/01/14(金) 00:36:40
確かにC++は仕様書を日本語でも理解しにくいくらい複雑 でも糞という言葉はでてこないから、我慢しなければと思っている
糞と言い放つことがカタルシスそのものなんだろうから、 そっとしておく
vector<string>を直接ファイルに書き出して、読み込むこと出来ますか。 たとえば合計サイズが10Mだとしたら一回のロードで格納すむといいんですが。
boost::serializationでも使ったらどうかね それを使わずにやるのは、そういう質問してる段階だと厳しいかも
>>807 ifstreamからstd::getlineで一行づつ取得しつつ、ofstreamに1行づつ書き出してもらう。
for文まわすだけのようなきがする。
でも、一発で1個のブロックとして読み出すのは構造上難しい。
サンクスでした。
int main() { std::vector<std::string> vs, vs2; vs.push_back("abcde"); vs.push_back("fghij"); vs.push_back("klmno"); std::ofstream ofs("test.txt"); std::copy(vs.begin(), vs.end(), std::ostream_iterator<std::string>(ofs, "\n")); ofs.close(); std::ifstream ifs("test.txt"); std::copy(std::istream_iterator<std::string, char>(ifs), std::istream_iterator<std::string, char>(), std::back_inserter(vs2)); std::copy(vs2.begin(), vs2.end(), std::ostream_iterator<std::string>(std::cout, "\n")); } これでもあまり美しくないなあ pstreambuf_iterator<char>とc_str()を使えばコンパイラ側から見て一回の入出力に見えるんだけど 文字単位なので効率悪いし
文字列に改行が含まれる場合と、std::stringはnull終端とは限らない点を考慮しないとだなぁ
そうならやはりboost::serializationが手っ取り早いですね
>>811 みたいにboost::serializationで書いたコードを頂戴
boost::serializationはビルドが必要なので面倒だよ でも入れる価値があるかもね
マルチスレッド化でfactoryクラスを利用したくてsingletonパターンを適用したのだけど 今度はfactoryが生成するインスタンスを抽象化する必要が出てきてfactoryを抽象化しようとしたら singletonパターンの継承ではまってしまいました。 C++で上手く切り抜ける方法はないでしょうか? singletonをやめて普通にstaticな大域変数として生成したほうがマシでしょうか?
>>815 ビルド必要なんですか><
なんかコードだけで実現できる良い方法ない?
ない
>>816 なんかこう無理にパターンに当てはめようとしないで、
本当にそれが必要かどうか再検討してみては?
それでも必要なら、
もうちょっと具体的なことを書けばなにか良いきっかけが生まれるかもしれん
>>819 作業クラスとその結果を表示するクラスがあって1対1で関連付けられています
この関連性を壊さないために、この2つのクラスを必ずFactory内部で関連付けてからインスタンスを得るようにしたいです
で、作業クラスと表示クラスの抽象化に伴ってFactoryも抽象化する必要が出てきた次第です。
822 :
デフォルトの名無しさん :2011/01/18(火) 23:37:40
>>821 あまり理解しておらず、申し訳ないが、文字通り
Abstract Factory パターンというのがあるみたいだけど
(説明はできない)
>>816 「factoryを抽象化しようとしたらsingletonパターンの継承ではまって」の意味がわからない。
抽象化とシングルトン化はまったく関係なくできるだろう。
困っている点についてはよくわからないが、とりあえずシングルトンパターンは捨てていい。
これは間違いない。
>>823 肝心なところが抜けてました
Factoryが複数あると不味い状況になるので必ずインスタンスが1個であるようにsingletonを適用し
そのあと抽象化の問題が発生しました
無理に設計時に何とかするより、使用時に注意する方向の方が楽そうですね・・・
>>824 だから、「抽象化の問題」ってなんだよ?
とりあえず
>>822 方式でConcreteFactoryをシングルトンにすればいいんじゃないの
SingletonにしたいのはFactoryだけって認識であってるのだろうか
継承の話は、基底クラス経由でシングルトンが破綻するので
一般にシングルトンは継承出来無かったように思うけどそれのことと予想
シングルトンにこだわらないでスレッドセーフを目指すって方向もあると思う
>>824 class Object;
class Factory { public: virtual ~Factory() {} virtual Object create() = 0; };
Factory& MyGlobalFactory();
class ConcreteFactory : public Factory { ... };
Factory& MyGlobalFactory() { static ConcreteFactory singleton; return singleton; }
これで何か問題でもあるか?
class ConcreteFactory : public Factory, Singleton<ConcreteFactory>
関数ポインタ なのか 普通のポインタなのか 判定するif文ってどう書けばいいのでしょうか? boost.mpl使わないとダメでしょうか?
>>829 SFINAE がやりたいなら TypeTraits の is_function 使え。Boost または TR1 にある。
あるいは void* が実際に指す型で動的にディスパッチしたいなら Type Erasure でやれ。
class A{}; class B : public A{}; B b; A* a = &b; BをAにキャストするのを禁止する方法ってありますか?
832 :
デフォルトの名無しさん :2011/01/20(木) 21:56:44
private継承でも通せるのひどいな
>>832 何言ってる? private 継承では派生クラスのポインタから基底クラスのポインタへは変換できない。
>>831 C++03 の機能では無理。
C++0x では operator static_cast のオーバーロードが可能なので、実装されていれば可能なはず。
operator&をオーバーライドしてA*に変換できない別の型を返す!
できるかボケ^^
>>834 本質的な解決にならないうえ boost::addressof で破られる。
バッファにファイルを読み込んで構造体の形に変換するにはどのキャストを使えばいいですか? struct A { int a; int b; }; char buf[ 1000 ]; A* a = reinterpret_cast<A*>( buf ); A* a = static_cast<A*>( static_cast<void*>( buf ) );
基本的にC++ではそれ自体禁止だけど、この場合は下のやり方。 ところで union U { A* a; char buf[ 1000 ]; }; はやっていいんだっけ?^^;
やってもいいけど
>>838 の意図するだろう挙動にはならない
配列はポインタじゃないから やるならこう union U { A a; char buf[1000]; };
>>838 どうでもいいけど型名Aのメンバー変数がaなのにA*型の変数名にa使われるとイラっとする
ハンガリアン信者?
せっかくどうでもいいって言ってるんだから、変なのに触って無駄にスレを消費しないようにしよう。
インスタンス名がデータメンバ名とかぶるのがいやなんでない? a.aとかになるから。
説明用の仮コードなんだからどうでもいいじゃんと言いたいが 名前被ると説明し辛い事もあるから場合によっては避けた方がいいはいいな
説明用に適当に書いたコードに細かい文句言うなよ。
>>842 &aと&bufが同じアドレスになることは言語仕様で保障されてないでしょ。
>>838 bufのメモリアライメントが保障されていないからキャストは不可。
bufが動的に確保した領域ならどっちでも構わないが、普通はreinterpret_cast。
だがその前に構造体のメモリイメージを保存することはやめた方がいい。
>849
>
>>842 > &aと&bufが同じアドレスになることは言語仕様で保障されてないでしょ。
いや、保証されてるだろ、と思って探してみた。以下、14882:2003 が参照仕様。
> 9.5 Union /2
> (略) Each data member is allocated as if it were the sole member of a struct. (略)
> 9.2 Class members /17
> A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial
> member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There
> might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to
> achieve appropriate alignment. ]
単一メンバの構造体の場合と同じように配置される、か。 なら全て同じアドレスになるね。
シングルコアで複数個の無限ループさせたいのですが、 可能ですか?どうすればできますか?教えてください。
スレッド使えば?というかC++関係なくね
その複数個の無限ループと言うのは。 本当に完全に並列なら −> 無理 OSが管理するスレッド単位の並列なら −> 可能
>>852 メニーコアで複数個の無限ループさせるのと同じ要領でいいよ。
今こうしている間にも起動しているほとんどのアプリケーションが無限ループを行っているよ。
C++0xのthreadさえ実装されれば・・・
int now_thread = 0; while(1) { if(now_thread == 0){ func_0(); } else if(now_thread == 1){ func_1(); } else if(now_thread == 2){ func_2(); } now_thread++; if(now_thread == THREAD_MAX){ now_thread = 0; } }
>>857 なんで
while(1) { func_0(); func_1(); func_2(); }
じゃないの?
nowじゃなくてcurrentだろ 略すならcur
curはcursorのcur
new/cur/tmp ですねわかります
Maildir
master_thread/maid_thread
master/slaveって言うけどこれいいんだろうか 放送には載せられないよね
>>858 >>857 は説明が足りないだけで、別スレッドがnow_threadの値を変更することを考慮してるからだよ。
んなバカな
using std::swap; swap(a,b); と using namespace std; swap(a,b); は同じですか?
>>867 template <class T>
void swap( T& a, T& b ) { std::cout << "unnamed::swap" << std::endl; }
void hoge( int a, int b )
{
using std::swap;
swap(a,b); // std::swap が優先
}
void hogehoge( int a, int b )
{
using namespace std;
swap(a,b); // エラー オーバーロード関数の呼び出しを解決できない
}
using宣言とusingディレクティブの違い
eclipseってすげえな ボタン一つで文字列を全部外部ファイルに外出しにできたりする JavaDocで関数仕様の資料作成も一瞬だしVisualStudioって馬鹿じゃねーのってレベル
そうなの? eclipseの推奨環境ってどのくらいかな。 Q6600+4GBでさくさく動くなら移行しようかしら…。
前者はアドオン作らないとだめかなーって思わんでもない。 後者は、なんでC++スレでJavaDoc?って気がしなくも。 VisualStudioの機能の数パーセントぐらいしか使ったことがなさそうなのはわかった。
VS道を究めるには俺のIDEはあまりにもexpress editionだった まあjavadocはdoxygenで困らんよね
>>871 今のJavaクライアントはJITコンパイラが優秀になってるのでAthlon64 4000+程度でもサクサクだ
すみません。 超初心者で間違ってる箇所が分からないので指摘お願いします。 #include<stdio.h> int main(void) { int i=1; int j=0; printf("テストの点数を入力してください。(0で終了)\n"); while(i= 0){ scanf("%d",&i); j = j+i; } printf("合計は%dです。\n",j); return 0; }
>>875 > while(i= 0){
while(i != 0){
エラーがあったら標準エラー出力に出力しればいいですか?
エラーと分かれば何でもいい
>>878 何で標準エラー出力に出力するかわかる?
>>881 お前、エラーと分からないような文をエラーで吐くのか!
無能のレッテルを貼られるぞw
標準エラー出力は確かバッファリングしないんだったよね 他の要因でプログラムが落ちる前に出来るだけはき出しておきましょうって事だろ
884 :
デフォルトの名無しさん :2011/01/28(金) 21:23:05
ぶっちゃけ *stderr が記憶保護されていないから 言い出すときりがないんだけどね
記憶保護ってなんぞ
c/c++に入出力を任せるという発想がそもそも間違い。
VCコンパイラで使える、高精度なタイマーというと何があるんでしょうか?
それはC++の質問なのかね?
VCだとclockが1ms単位くらいの精度だったような気がする。
>>889 apiでもっと細かいのがあるけど、ググるのがめんどうだ。
>>887 QueryPerformanceFrequency
QueryPerformanceCounter
メディアプレイヤーを起動しつつそれらのAPIを使うのが胡散臭い方法 どうしてもしたければタイマー精度を変更する
894 :
デフォルトの名無しさん :2011/01/30(日) 10:18:39
もっと頑張れよw 最近落ち目だぜww
My Love, My Love.
boost::timer
C++って関数内に局所的な関数ってかけませんでしたっけ? むかしどこかで書いたようなきがしたのですが・・・。
>>897 struct{
void operator()()
{
}
}Func;
auto func = [](int& n) { n++; } int i; func(i);
C++0x int Func(){ auto Fn = [](int Args)->int{ return 0; }; return Fn(0); } って感じか。
901 :
900 :2011/02/01(火) 17:21:13
かぶた。
>>898 >>899 >>900 どもです、0x系ではないコンパイラだとやっぱりstructの中にかくことになりますか・・・。
ありがとうございました。
>>900 int Func(){
return [](int Args)->int{
return 0;
}(0);
}
これでおk
905 :
デフォルトの名無しさん :2011/02/02(水) 12:32:41
zip書庫を解凍なしに参照するライブラリなどありますか? たとえば、1ギガのファイルがあったとき、それをメモリかファイルに展開せずに 部分読み出来るものです。
前にもこんな質問あったな 仕様読んで自前でやれって言われてたよ
Windows7 だと普通に出来てた
908 :
905 :2011/02/02(水) 14:25:05
OSの機能使わず、どのOSでも同じアクセスしたいのですが。 ヘッダにzip、zip64、LZMAなどあって、その方言ような誤差の吸収や複数圧縮形式あり 自作するのは辛いですが。ないですか。
とりあえず905=908には無理なことだけは俺にもわかった
>>905 メモリに展開せずに、どうやって部分読みできると思うんだ?
まさかとは思うが、レジスタに展開しろとでも言うのか?
912 :
905 :2011/02/03(木) 07:41:49
全てをメモリに格納せず、一部分ずつをメモリに格納するという意味でした。
できるよ 圧縮前の内容は読めないけどな
914 :
905 :2011/02/03(木) 10:54:30
シーケンシャルリードでいいのですが・・・
>>908 zip書庫のヘッダ形式のLZMAってなんじゃいな
C++0xって向こう10年以内には正式の規格にはなら無いんだろ
918 :
デフォルトの名無しさん :2011/02/03(木) 20:06:47
早くて 99 年後だな
テンプレートパターンでテンプレート関数をインライン化する 方法をいくつか紹介してください。
struct boo { boo() : a(){} int a[100]; }; これで配列aが0で初期化されるのは正しい動作なんでしょうか?
値を書かなければ0とみなされます
>>920 デフォルト初期化が行われて 0 になるので正解。
独自フォーマットのアーカイバ(非圧縮)を開発することについて質問です。環境はWinXP+VC++2010です。 以下の質問では、より良い標準的な方法があったらそれも教えてください(例えばmemcpy関数じゃなくてこっちのほうが標準的でいいよ的な) 沢山質問してしまいますがよろしくお願いします。 0, (そもそもこういう処理のためのライブラリがあったりしませんか?スレチ気味ですが) 1, ヘッダ部を処理するために例えば struct Header{ unsigned char sign[8]; //8bytes unsigned char datasize[8]; //8bytes }; Header hdr = {0}; のような構造体を定義します。 まず、特定のバイト数を確保する際のやりかた(ここでは8バイト)はこれでいいのでしょうか? 2, 1,で定義した構造体のメンバにあるバイト列を代入する場合どうすればよいのでしょうか? 例えば代入元がUINT128(適当ですからなかったらすいません)の場合は、 UINT8 i = 234; memcpy(hdr.datasize,&i,sizeof(UINT128)); でいいんでしょうか? memcpyでサイズが違うものに使ったことがなく不安です。例えば、 コピー元(UINT128=16バイト): 0xFF 00 00 00 00 (略) 00 AA BB CC の時memcpyで8バイトコピーしたら、コピー先は0x00 00 00 00 00 AA BB CCってことでいいんですか? つまりmemcpyの起点はいったいどうなってるんですか? 3, boost::FileSystem::file_sizeがuintmax_tの返り値をくれるんですが、これはどうやって1の構造体に代入すれば? sizeofで実行時にサイズを計算して、8バイトと比べて小さい方をmemcpy? 4, wchar_t* なんかもそのままmemcpyで大丈夫ですか? 5, できあがったhdrをメンバ変数を一つづつファイル出力するとして 選択1: C++のfstream; 選択2: Cのread&write; 選択3: win32api(低水準) 巨大なバイナリ列を扱う時の、定番の入出力法はなんなんでしょう?ちまたのアーカイバはどうしてるんですか? なお、fstreamに渡すときは(char*)にキャストしてバイト数指定でいいですよね? 強制的にリトルエンディアンですか?
>>923 0 については知らない。
1 について、構造体のメンバ間や終端には実装依存のパディングが入ることがある。
ただし実際には理由無くパディングを入れることはまず無いので、 sizeof や
offsetof と assert あるいは BOOST_STATIC_ASSERT を組み合わせてレイアウトを
確認しながら使うことはできる。
2, 3 4 について、整数型の表現形式は実装依存。ただし unsigned char については
そのビット数ぶん隙間無く詰まっていることが保証されている。移植性を最大にするなら
すべて unsigned char のレベルで処理することになる。つまり大きな整数型のまま
memcpy() するのではなく、想定しているバイト並びを明示的に組み立てるのがいい。
移植性は必要なくて速度が必要だと言うなら、そのことをコメントで記載したうえで
特定の実装に依存してしまうのもいい。
5 について、要求に応じて決めればいい。エンディアンとか気にするなら↑に戻る。
925 :
923 :2011/02/06(日) 02:37:13
>>924 ありがとうございます。
1, では変数を個別に書き出すことにします。
2,3,4,5について、気持ちが悪いので実装に依存しない方法で書くことにします。
>想定しているバイト並びを明示的に組み立てるのがいい。
どういうコードになりますか?
memcpy(&unsignedchar, &largeinteger, sizeof(unsigned char));
このときlargeintegerのどの部分から取り出されるんですか?
これが実装依存だとどうしようもない気がするんですが。
>>925 > memcpy(&unsignedchar, &largeinteger, sizeof(unsigned char));
unsignedchar が 8 ビット、 largeinteger が 32 ビットだとして、
リトルエンディアンで保存したいなら
unsignedchar = largeinteger & 0xff;
ビッグエンディアンで保存したいなら
unsignedchar = (largeinteger & 0xff000000) >> 24;
という感じになるかな。
uint64_t largeinteger; uint8_t byte_array[8]; // リトルエンディアンで格納される for(int i = 0 ; i < 8 ; i ++) { byte_array[i] = (uint8_t)((largeinteger >> i*8) & 0xFF); }
928 :
デフォルトの名無しさん :2011/02/06(日) 10:52:22
visual C++でのIEを操作したいです。 MSTHMLのライブラリを使っているのですが、問題がおきました。 質問はここでいいでしょうか?
930 :
デフォルトの名無しさん :2011/02/06(日) 11:17:03
↑有難うございます。こっちで聞いてみます。
int* x = new int(10); delete x; はメモリ確保→開放をポインタでやってるわけだよね int x = 10; delete &x; とは書けないの?
deleteは動的に確保されたメモリを開放する命令だから int x = 10;みたいに静的に確保されたメモリには使えない。 っていうか、使う意味がない。 int x = 10;はスコープから抜ければ勝手に破棄されるから。
いや、違うな。int x = 10;は自動であって静的じゃないね。
>>932 > 開放をポインタでやってるわけだよね
どこからそんな変な知識を得たんだろう...。
前者はヒープ、後者はスタック
規格で自動変数がスタックに確保されると決まってるわけじゃないだろ。 そうじゃない実装はほとんどないだろうけど。
入門書はヒープとかスタックとかについて解説すべき 大抵2冊目の本にしかその辺のことがかかれてない
939 :
932 :2011/02/06(日) 18:52:22
初心者質問スレがあったみたいだわ とりあえずヒープとスタックでググります
940 :
925 :2011/02/06(日) 21:31:29
>>926-927 ありがとうございます。
>>927 で実装してみたところ、上手くいってる……と思ったら、
いくつかある変数のうち1つだけが値がおかしいのでよく調べたら、
wikipediaによればC++ではシフト元を超えてシフトする場合の動作は未定義とのことで。
iの値は、元が64ビットの保証がない時はsizeof使うってことでいいんでしょうか?
>>940 cstdint や stdint.h が使えれば簡単に保証できるんだけどね。
無いなら numeric_limits 使って確認、かなぁ。
PSPの環境で sizeof( int64_t )が4という値を返してきたんですがどうしてですか?8byteじゃないんですか。
>>942 単にバグってるか、 CHAR_BIT が 16 だとか。
CHAR_BIT関係なくね?
>>944 CHAR_BIT が 16 なら sizeof(int64_t) は 4 で正解でしょ。 16*4 == 64
>>944 sizeof は char いくつ分かを返すんだよ。
stdint.h見ると typedef long int64_t; typedef unsigned long long uint64_t; となっています。バグですか?
948 :
925 :2011/02/06(日) 22:23:57
>>941 これならいけそうです。ありがとうございました。
>>947 uint64_t と int64_t で long long と long が違うのか。バグっぽいな。
BOOST_STATIC_ASSERT((sizeof(int64_t) * CHAR_BIT) == 64); あるいは assert(...) してみて、
失敗したら確実にバグ。
CHAR_BITってはじめてきいたわ、これなにもの??
charは1byteであることは規格で定められているが、1byteが何bitであるかは定めていない。 CHAR_BITはchar型のbit数を定義してあり、ひいては、1byteが何bitであるかをあらわしている。
>>951 ありがとう、わかりやすい解説でたすかりました。
class test { public: test(char* a) : pchar = a {}; char& operator[](size_t i) { return pChar[i]; } } test temp = test("aaa"); temp[0] = 'b'; 上記コードの最後で書き込みアクセス違反となってしまいます。 []のオーバーロード方法が間違っているのでしょうか? よろしくお願いします。
public: test(char* a) : pchar = a {}; ↓ public: char* pChar; test(char* a) : pChar(a) {}; でした
char* p = "aaa"と char p[] = "aaa"の違い分かってないでしょ コンストラクタでメモリ確保してそこに渡された文字列をコピーしないとだめ
>>955 仰せのとおり同じものと認識していましたorz
ありがとうございました
char* p = "aaa"と char p[] = "aaa"の違い分かってないでしょ はい。中身は同じですよね。で、どう違うんですか?
958 :
デフォルトの名無しさん :2011/02/07(月) 20:26:48
sizeof が同じになるねw
char* p = "aaa"; は、staticに4byteを確保しておいて(最後の1byteは'\0')、そのポインタだけを得る。 静的領域へのポインタだから、今のメモリ管理システムだと書き換えできない。 …でも昔はできた気がする。 char p[] = "aaa"; は、ヒープに必要なサイズのメモ地(この場合は4byte)確保して、そこに"aaa"をコピーする。 ヒープだから書き換えできる。
char* p = "aaa"; p[1] = 'b';
>959 >静的領域へのポインタだから、今のメモリ管理システムだと書き換えできない。 多分メモリ保護のこと言ってるんだろうけど環境によっては ROM 上になるべ。 いずれにしろ未定義動作だ。 >は、ヒープに必要なサイズのメモ地(この場合は4byte)確保して、そこに"aaa"をコピーする。 >ヒープだから書き換えできる。 スタックか静的領域か、いずれにしろヒープには取らないだろう、普通。
かなり上げ足取りだが、 クラスのメンバなら普通にヒープになる場合もあるがなー
おまえらはヒープって言っているけど、実はヒープの説明できないだろ
スコープつきの変数はスタックに取られる。 ヒープはメモリのプールでプログラマの権限で管理する。 スタック自体はヒープに取られることもありうる。
そんなルール、規格に書いてあったっけ?
スタックはCPUレベルならespとかで操作 関数型言語ならCPUスタックは使わずにヒープで実装されてるイメージがある しかしヒープ自体についてはあまりよくわかってないので教えて
ヒープとはいったいナンなのだ!!!
closure を stack allocation するのは基本的な最適化の一つじゃなかったっけ。 だから関数型言語の実装者もスタックが使えるなら使いたいと思ってる筈。 ただ、継続とか、プログラムの実行制御を言語の機能として持っていると、 それがなかなか難しいみたいな感じなのかな。
>>963 自分で brk して取ってくるのがヒープ
プロセスの起動時に勝手に brk して貰えるのがスタックとかテキストエリアとか
>>971 古いUnix系のシステムコールだよ。今でも使えるOSはそれほど多くない。
今でも現役だと思いますが?
わかった、仮想メモリの.bssの上あたりにbrkとかsbrkで保存される コンパイルオプションで与えるスタックサイズが 自動でbrkされるサイズなのか?
コンパイル時にスタックサイズを決めるって何か新鮮だな ulimit とかが無いシステムなのか
976 :
デフォルトの名無しさん :2011/02/08(火) 01:03:23
スタックサイズが見積もられていないプログラムも悪い意味で「新鮮」だが
コンパイル時に指定しなくて良いという話と、見積もらないで良いという話を ごちゃ混ぜにしちゃったのかな? 普段からスタックを食いつぶす様なコードを書いていたら俺も不安になるかもなあ。 不思議な世界もあるもんだ。
クラスがメンバ変数にPODな構造体を持っていて、
コンストラクタの初期化子にその構造体を明示的に記述した場合、
構造体の中身が全て0で初期化される。
初期化子に書かなかった場合、0で初期化されない。
という認識で間違いないでしょうか。
http://codepad.org/1lm8NweW 試したらちゃんと0になってくれて、合ってると思うのですが、
ネット上にあるコード見てると、ZeroMemoryとかmemsetを使ってる人が多くて、不安になったので…
テンプレートクラスを引数にとる関数を作りたいのですが、 テンプレートクラスのテンプレート引数に関係ない部分を処理するので、 いちいちこの関数に対してテンプレート引数を要求したくありません 何か良い実装法はないですか?
>>978 その認識で合ってる。不安なら規格を確認しれ。
C++の標準ライブラリ≒STL だろうと思うけど、 逆にSTLでない標準ライブラリって何があるん でしょうか。
std::coutとか。 stdでテンプレート以外の奴が大体そうじゃね
standard template laiburarii = STLだから、tennpure-to使ってないものならSTLには含まれない。
あ標準入出力やファイル入出力や文字列クラスがそれに該当するか。 stringは確かbasic_string<char>とかで、結局はいずれも、内部では STLを使って型を特定したバージョンにすぎないのかも知れんな。
どうせならsutanda-doくらい書けよpgr
うめ
boostのmulti_arrayとかコンストラクタでメンバ変数をまるごと指定できないクラスで、その内容をconstにしたい場合、 初期化のときだけforループでまわしてconst_castして初期化、という方法くらいしか思い浮かばないのですが、 何かconst_castみたいな気持ち悪いもの使わない方法はありませんか?
valarrayとかbitsetもSTLの中には入ってないはず。 STLと呼ばれるためには単にテンプレートを採用しているだけでなく algorithmと協調動作するために一定の要件がある。
>>989 特定の要件を満たしたときにSTLの一部と呼ばれるようになる、なんてことはないお
>>988 それって別にboost::multi_arrayだけでなくて通常のクラス配列にも成り立つ事だよね
リファレンス変数とかconst変数の初期化を行いたい時はどっちにしろクラスの数分
コンストラクタを呼び出さなくてはいけないのでは?
デフォルト値ならともかく
単純な配列にしてもこんな方法しか思いつかない #include <iostream> class Test { const int i; public: Test() : i(0) {} Test(int j) : i(j) {} void Set_i(int j) { const_cast<int&>(i) = j; } void Print_i() const { std::cout << i << ' '; } }; int main() { Test* t = new Test[10]; for (int i = 0; i < 10; i++) { t[i].Set_i(i); t[i].Print_i(); } std::cout << std::endl; delete t; }
>>988 非constなコンテナにforループで代入して、それを使ってconstなコンテナを初期化して
コンパイラの最適化を祈る
未来にはnested_collectionコンセプトみたいなのができるてるといいな
でもpublicなconst変数があるとユーザがそれを利用して悪さというか 間違った操作をする可能性はないか? まあCもC++も「プログラマはコンピュータに何をさせようとするか全て知っている」 という前提だけどな
次スレ建つまで埋めんなよ
>>993 collectionで一気にコンストラクタを呼び出す機能とかは確かに欲しいな
>>993 非constなコンテナにforループで代入して返却するstaticメソッドなら作ったりしたなぁ
.
∧,,,∧ ( ・∀・) 1000ならジュースでも飲むか ( ) し─J
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。