C++相談室 part54
■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v
2006/10/30(月) 22:34:08ただし質問の前にはFAQに一通り目を通してください。
IDE(VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
テンプレその他 >>2-15 付近参照
前スレ
C++相談室 part53
http://pc8.2ch.net/test/read.cgi/tech/1159340181/
0052デフォルトの名無しさん
2006/11/02(木) 00:28:04オブジェクトが普通に表示されたり、
deleteする前の値(位置情報 xやyなど)
をそのまま持っているかどうかで確認しています。
0053デフォルトの名無しさん
2006/11/02(木) 00:29:46> enemy = new Enemy1(arg_x, arg_y);
> EnemyArr.push_back(enemy);
原因の予感。push_back(const T&)じゃなかったか。
ゆえに、push_back(new Enemy1(arg_x, arg_y))で試してみて。
0054デフォルトの名無しさん
2006/11/02(木) 00:34:07それって、破棄したオブジェクトをそのまま使ってるんじゃないか?
erase()でvectorの方も縮めておかないとだめだろ。
0055デフォルトの名無しさん
2006/11/02(木) 00:34:33deleteしたからって中のデータは直ぐに破壊されん。
そんなん何の参考にならんし確認にもなってない。
0056デフォルトの名無しさん
2006/11/02(木) 00:36:15使いやすいぞ。erase()したら自動的にdeleteしてくれるしな。
0057デフォルトの名無しさん
2006/11/02(木) 00:42:11各個別は古典的にstateパターンで処理可能なルールとして実装できると思いますが
文脈を管理するためのクラスはどのように実現するのが一般的なのでしょうか?
ルールはR0 = Aから始まるとします。
A = B | C
B = a b c
C = a | b c
a = ...
b = ...
StateパターンでR0の状態を処理する。
0058デフォルトの名無しさん
2006/11/02(木) 00:42:59ポインタが指してる部分に情報が残ってるだけでは?
デストラクタにstd::cout << "Delete Enemy" << std::endl;って行を入れて動作を確認してみて。
0059デフォルトの名無しさん
2006/11/02(木) 00:44:190060デフォルトの名無しさん
2006/11/02(木) 00:45:17成る程、そういうことでしたか。
eraseする前に破棄されてるか確認したかったのですが、
それでは意味がないですね。
>>53
結局破棄されてないと勘違いしただけだったみたいですが、
その記述で一時的な変数が必要なくなって助かりました。
>>56
そういう便利なものもあるんですね。
ちょっと調べてみたいと思います。
>>58
成る程、デストラクタに入れておけば破棄された確認になりますね。
やってみます。
0061デフォルトの名無しさん
2006/11/02(木) 00:50:43とりあえず、文法を解析するときに
個別のルールはStateパターンで処理したいけど
文脈はどうやって処理すればいいのか思いつかないから助けて
ほしいだけかもしれない
0062デフォルトの名無しさん
2006/11/02(木) 00:53:03ないなら、0を代入しておく方法もある。vectorコンテナは要素数が
大きくなると、eraseにO(N)かかるので高くつく。そこでdeleteした要素
には0を入れておき、後で必要になったらまず0の入っている要素を
再利用するという方法もある。
もちろんプログラム側で要素に0が入っていたら処理をスキップする
必要があるが。
0063デフォルトの名無しさん
2006/11/02(木) 00:54:59まずデザパタに頼らず強引に文法解析の骨子を書いてみたら。
その後でStateパターンでまとめると綺麗にまとまるというだけの話。
0065デフォルトの名無しさん
2006/11/02(木) 01:03:50push_back(new ...) はあからさまに例外安全じゃないので考え直したほうがいい。
0066デフォルトの名無しさん
2006/11/02(木) 01:20:55破棄の確認が取れました。
ちゃんと破棄できていたようです。有難う御座います。
>>62
成る程、そういった利用方法もできるのですかぁ。
勉強になります。
>>64
持たせて破棄の確認をしました。
お騒がせしました。
>>65
それは
push_back(new ...)
にするより、元のコードのままの方がいいということですか?
0067デフォルトの名無しさん
2006/11/02(木) 01:27:11コンテナに対する操作とは分離しておいた方がいいだろう。
それと、コンテナの要素にアクセスする方法が単なるラウンドロビン的な
方法のみで、ランダムアクセスをしないのであればstd::listの採用を考え
るのもよい。こちらはeraseしても反復子が無効にならない上、常にコストは
O(1)だから。
0068デフォルトの名無しさん
2006/11/02(木) 01:27:12new に対応する operator new はクラスのメンバとして宣言されたものか、
グローバルなものかのどちらかになる。 (5.3.4 9)
0069デフォルトの名無しさん
2006/11/02(木) 01:28:15問題は push_back() が例外を投げた場合なわけだが。
0070デフォルトの名無しさん
2006/11/02(木) 01:29:52元のコードも多分例外安全じゃない(いや、まcatchで適切にリソースの解体しているなら別だけど)
auto_ptr<Enemy>enemy(new Enemy(..));
EnemyAry.push_back(enemy.get());
enemy.release();
だいたいこんな感じで書けば例外安全。
0071デフォルトの名無しさん
2006/11/02(木) 01:32:33ちょwwwwそれやり過ぎww
まあ業務用ソフトならそこまでするのかもしれんけど
0072デフォルトの名無しさん
2006/11/02(木) 01:40:29うーむ、まだまだ未熟で理解できない点がありますので、
これから習熟していく上で徐々に理解していきたいと思います。
有難う御座いました。
0073デフォルトの名無しさん
2006/11/02(木) 01:42:36これくらいがふつう
0074デフォルトの名無しさん
2006/11/02(木) 01:45:22いつの日か、こんなのがリークの原因になってしまったとしたら、見つける自信が無い。
最初に書くときに安全を確保してしまうのが吉。
0075デフォルトの名無しさん
2006/11/02(木) 01:47:45これって、もしEnemyAryがptr_vectorだったら例外安全難しくない?
1.
auto_ptr<Enemy>enemy(new Enemy(..));
EnemyAry.push_back(enemy.get());
enemy.release();
→enemy.release()が例外を投げるとptr_vectorとauto_ptrによる二重delete
2.
auto_ptr<Enemy>enemy(new Enemy(..));
EnemyAry.push_back(enemy.release());
→push_backが例外を投げるとリーク
0076デフォルトの名無しさん
2006/11/02(木) 01:51:02releaseは例外を投げなーい。
だから安心安心。
0077デフォルトの名無しさん
2006/11/02(木) 01:58:46prt_vector なら push_back(new ...) でいいだろ。 >>70 みたいな
コーディングを不要にするためのものなんだから。
0078デフォルトの名無しさん
2006/11/02(木) 02:03:000079デフォルトの名無しさん
2006/11/02(木) 02:08:320080デフォルトの名無しさん
2006/11/02(木) 02:08:38auto_ptr::release()は例外投げません……
0081デフォルトの名無しさん
2006/11/02(木) 02:10:45少なくともバッファが確保出来ないときは投げるんじゃない?
0082デフォルトの名無しさん
2006/11/02(木) 02:11:44配列の拡張時にメモリ確保失敗する可能性があるから投げると思うよ。
ちょっとソース見てくる。
008382
2006/11/02(木) 02:21:02>>77のいうようにptr_*系は直接push_back呼び出して問題ない。
というか内部でauto_ptrつかって実質的に>>70と同じ処理をやってる。
だから、むしろauto_ptr使うと例外時に2重開放になるから使っちゃ駄目。
例外発生時にはpush_backは何もしないと思ってたので、
勝手に引数の開放するのは予想外だったのでちょっと驚き。
これからはptr_*系をちょくちょく使っていくか......
0084デフォルトの名無しさん
2006/11/02(木) 02:23:110085デフォルトの名無しさん
2006/11/02(木) 02:29:03言えないな。
あれー?
http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html#modifiers
0086デフォルトの名無しさん
2006/11/02(木) 02:49:000087デフォルトの名無しさん
2006/11/02(木) 02:53:46new したオブジェクトの所有権が関数をまたいで頻繁に移動するならそうなるだろう。
0088デフォルトの名無しさん
2006/11/02(木) 03:22:22なるほど。忘れていました。そうですよね。所有権が移動するから使えるんですか。
ありがとうございます。
0089デフォルトの名無しさん
2006/11/02(木) 03:23:08使わんとは言わんが、結局目の届く範囲においとかないと怖くて仕方ないので
エラー処理とかでdeleteまとめんのが面倒くさいとかの時くらいしか出番ないですよ。
叩いて叩いて。
0090デフォルトの名無しさん
2006/11/02(木) 03:31:520091デフォルトの名無しさん
2006/11/02(木) 03:43:15あればあったで構わないけど積極的な使用を推奨する気にはなれん代物でFA。
0092デフォルトの名無しさん
2006/11/02(木) 03:46:02new があるところに auto_ptr あり。少なくとも new と同じぐらい使う。
boost 使ってるときは、ほとんどそっちになるけど。
0093デフォルトの名無しさん
2006/11/02(木) 03:46:45auto_ptr で増える不便って何?
0094デフォルトの名無しさん
2006/11/02(木) 04:00:22手動deleteで例外安全確保しようと思ったらauto_ptrの100倍は面倒だろ
0095デフォルトの名無しさん
2006/11/02(木) 04:08:200096デフォルトの名無しさん
2006/11/02(木) 06:42:13つか例外でたらabortせざるをえない。
0097デフォルトの名無しさん
2006/11/02(木) 09:30:17遅くなりました。
ネームスペースに入れるとクラスのメンバのような扱いになっているって事ですか??
もう少しヒントを・・・
0098デフォルトの名無しさん
2006/11/02(木) 10:44:22あー、よく聞くな。そのいいわけ。
0099デフォルトの名無しさん
2006/11/02(木) 10:45:53new を使ったときにメモリ確保に使われる operator new の決定方法は規格で
決められているわけだが、(以下 >>68 )
0100デフォルトの名無しさん
2006/11/02(木) 12:17:19始皇帝氏って奴?
0101デフォルトの名無しさん
2006/11/02(木) 15:17:56{
vector<T> array;
public:
vector<class T>::iterator getBeginIterator()
{
return array.begin();
}
};
こんなクラスを作ったのですが
main関数で
Test<unsigned char> test1;
vector<unsigned char>::iterator itr = test1.getBeginIterator();
とすると
main.cpp(37) : error C2440: '初期化中' : 'std::vector<_Ty>::iterator' から 'std::vector<_Ty>::iterator' に変換できません。
というエラーがでます。
どなたか原因がわかりませんか?
0102デフォルトの名無しさん
2006/11/02(木) 15:26:26typename std::vector<T>::iterator getBeginIterator()
0103デフォルトの名無しさん
2006/11/02(木) 15:27:00Tというclassとclass Tという先行宣言の差。
vector<class T>をvector<T>にすれば多分大丈夫
0104デフォルトの名無しさん
2006/11/02(木) 15:50:06push_back前の状態にロールバックするのが強い例外保証だからそれでいいんだよ。ていうか開放しないとリークしちゃうし。
newの戻り値をどっかに保存してたりするならそれはユーザー側の使い方が間違い。
abortするしかないとか言ってるやつは例外機構をメモリリーク防止くらいにしか思ってないんだろうなぁ。
0105デフォルトの名無しさん
2006/11/02(木) 16:05:08引数のオブジェクトの所有権を奪うという副作用を行っているんでしょ?
その副作用のロールバックが出来ていないと思うけど、俺の解釈の仕方が間違っている?
いや、ま、利便性考えればこの仕様が自然なんだけどね。
例外時にいちいち開放したくないし。
0106デフォルトの名無しさん
2006/11/02(木) 16:09:580107デフォルトの名無しさん
2006/11/02(木) 16:11:310108デフォルトの名無しさん
2006/11/02(木) 16:17:120109デフォルトの名無しさん
2006/11/02(木) 16:22:42仮想記憶無い環境だとnewできない時はもうどうしようもねぇんだよ。
0110デフォルトの名無しさん
2006/11/02(木) 16:28:14所有権の移動と配列の拡張という別個の事象を、
一つの関数で行うから、起きる問題だな。
stackのpop,topみたいに綺麗に二つに分けれると良いんだけど、
そもそも二つをくっつける為のptr_vectorというジレンマ
0111デフォルトの名無しさん
2006/11/02(木) 16:36:24vector<int> a(&(x[0]), &(a[2]) + 1);
a.sort(not2(less<int>() ) ); //
関数アダプタ not2() を入れた場合、エラーはでないのですが、実行した場合に強制終了となってしまいます。
なぜ、強制終了してしますんでしょうか?
ソフトはVC++EEです。
0112デフォルトの名無しさん
2006/11/02(木) 16:37:23&(x[0]), &(a[2])+1
0113デフォルトの名無しさん
2006/11/02(木) 17:00:17a(&(x[0]), &(x[2]) + 1);
です。
0114デフォルトの名無しさん
2006/11/02(木) 18:20:380115デフォルトの名無しさん
2006/11/02(木) 18:24:40少なくともうちのVC8には無い。
int x[3] = {3,5,1};
vector<int> a(&(x[0]),&(x[2])+1);
sort(a.begin(),a.end(),not2(less<int>()));//
ちなみにこれなら普通に実行できたが。
どこのvector使ってるんだろう?
0116デフォルトの名無しさん
2006/11/02(木) 18:43:31listです。
0117デフォルトの名無しさん
2006/11/02(木) 19:38:09もう信用できない。問題の発生するコードをコピペしろ。
0118デフォルトの名無しさん
2006/11/02(木) 19:50:31#include <list>
#include <functional>
#include <iostream>
using namespace std;
template<class InputIterator> void Display(InputIterator first, InputIterator last){
for(InputIterator i = first; i != last; i++)cout << *i << " ";
}
template<class T> struct MyGreater : public binary_function<const T, const T, bool> {
bool operator() (const T &t1, const T &t2) const { return t1 > t2;}
};
void main(){
int a[8] = {5,8,4,2,41,6,9,7};
int b[14] = {9,9,4,2,1,0,5,6,7,1,1,1,1,1};
list<int> lst1(&(a[0]), &(a[7]) + 1);
list<int> lst2(&(b[0]), &(b[13]) + 1);
list<int>::iterator w = lst1.begin();
advance(w, 3); lst1.splice(w, lst2);
Display(lst1.begin(), lst1.end());//3
lst1.sort(); Display(lst1.begin(), lst1.end());//4
lst1.sort(not2(greater<int>() ) );//-------ココです
Display(lst1.begin(), lst1.end());//5
}
0119デフォルトの名無しさん
2006/11/02(木) 20:08:02試したらデバッグモードのチェックで "invalid operator<" と言われたが、
「強制終了してします」ってのはこれのことか?
not(greater<int>()) つまり <= は比較関数に要求される
strict weak ordering の要件を満たさないってこと。
0120デフォルトの名無しさん
2006/11/02(木) 20:15:330121デフォルトの名無しさん
2006/11/02(木) 20:21:56>>120
わかりました!
ありがとうございました。
0122デフォルトの名無しさん
2006/11/03(金) 00:19:41また遅くなってしまい、スイセン
理解しました。まさしく文章通りでしたね。
確かにnew ヘッダも定義はstdの外でやっていました。
これで納得して進めることが出来ます。どうも有難う御座いました。
0123デフォルトの名無しさん
2006/11/03(金) 01:29:51Java風の命名を良く見かけるのですが、何か理由はあるのですか?
0124デフォルトの名無しさん
2006/11/03(金) 01:31:100125デフォルトの名無しさん
2006/11/03(金) 01:41:46バカは氏ね
0126デフォルトの名無しさん
2006/11/03(金) 02:12:57典型的なところで、XercesみたいにJava出身のライブラリは当然、Java風になるね。
0127デフォルトの名無しさん
2006/11/03(金) 03:43:18C++風の命名ってどういうものなんでしょう?
JavaからOOPL入ったので良くわかりません...
0128デフォルトの名無しさん
2006/11/03(金) 03:48:05class_name
func_name
Java
ClassName
funcName
確かにJavaスタイルをよく見かける。このスレ(板)でも。
0129デフォルトの名無しさん
2006/11/03(金) 04:20:340130デフォルトの名無しさん
2006/11/03(金) 04:48:46fuck_cpp
Java
fuckJava
コーディングスタイルは他でやれよ
0131デフォルトの名無しさん
2006/11/03(金) 05:14:520132デフォルトの名無しさん
2006/11/03(金) 05:21:23まあ、どうでもいいけどね
0133101
2006/11/03(金) 09:24:27>typename std::vector<T>::iterator getBeginIterator()
でいけました。
0134デフォルトの名無しさん
2006/11/03(金) 09:34:13仮の型指定がない次のような場合は通るのですが
template < typename _T > class A; // 前方宣言
typedef A< int > B;
template < typename _T > class A // 定義
{
};
main( void )
{
B b;
}
以下のケースのように定義側に仮の型指定がある場合の前方宣言の仕方がわかりません。
template < typename _T = int > class A; // 前方宣言 無理 ERROR
// template < typename _T > class A; // 前方宣言 無理 ERROR
// template < > class A; // 前方宣言 無理 ERROR
typedef A< > B;
template < typename _T = int > class A // 定義
{
};
main( void )
{
B b;
}
0135デフォルトの名無しさん
2006/11/03(金) 09:55:10> auto_ptr で増える不便って何?
頭悪い子が付いていけない。
0136デフォルトの名無しさん
2006/11/03(金) 10:37:34Moden C++とか読むと書いてあることは解るけどなんでそんなこと
思いつくのよこの変態とか思うわけで....
0137デフォルトの名無しさん
2006/11/03(金) 10:39:280138デフォルトの名無しさん
2006/11/03(金) 10:57:52いやそれだと狭い知識しかみにつかんからもし
機能を体系的に勉強できるような資料があればうれしいのよ
0139デフォルトの名無しさん
2006/11/03(金) 11:02:23lisp, Haskell, etc,,
0140デフォルトの名無しさん
2006/11/03(金) 11:07:13機能を学ぶ以前に、想像力(or創造力)を鍛えた方が医院で内科医?
0141デフォルトの名無しさん
2006/11/03(金) 11:16:17もう読んでいるのかもしれないけど、
>>4のC++ Templates
0142デフォルトの名無しさん
2006/11/03(金) 12:11:56template<int Depth, int A, typename B>
struct K17 {
static const int x =
K17<Depth+1, 0, K17<Depth,A,B> >::x
+ K17<Depth+1, 1, K17<Depth,A,B> >::x
+ K17<Depth+1, 2, K17<Depth,A,B> >::x
+ K17<Depth+1, 3, K17<Depth,A,B> >::x
+ K17<Depth+1, 4, K17<Depth,A,B> >::x;
};
template<int A, typename B>
struct K17<16,A,B> {
static const int x = 1;
};
static const int z = K17<0,0,int>::x;
0143デフォルトの名無しさん
2006/11/03(金) 12:16:47その実体化にまたK17<Depth,A,B>が必要になるから
struct A{ A a;};と同じことになるんじゃね?
0144デフォルトの名無しさん
2006/11/03(金) 12:16:58意味不明なエラーが出て困ってます。
0145デフォルトの名無しさん
2006/11/03(金) 12:22:06やっぱC++って腐りきってるよね、C#とかJAVAがいいんだろうな
0146デフォルトの名無しさん
2006/11/03(金) 12:26:355^16≒1526億回じゃなかろか?
0147デフォルトの名無しさん
2006/11/03(金) 12:31:40そうなると C++ 自体が使えないね。
0148デフォルトの名無しさん
2006/11/03(金) 13:44:380149デフォルトの名無しさん
2006/11/03(金) 15:36:240150デフォルトの名無しさん
2006/11/03(金) 15:47:270151デフォルトの名無しさん
2006/11/03(金) 17:06:07ふつうに再帰関数でもフリーズ。
関数の呼び出し回数が190734863281回にもなるから当たり前だけどな
■ このスレッドは過去ログ倉庫に格納されています