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/
0446デフォルトの名無しさん
2006/11/12(日) 16:29:37それって「私は例外投げませんよ」って指定じゃなかった?
0447デフォルトの名無しさん
2006/11/12(日) 16:38:41そんなことは分かったうえでの質問だろう。たぶん。
0448デフォルトの名無しさん
2006/11/12(日) 17:22:25お尋ねしたいのは、それを宣言に付けさえすれば良いのか、定義の方にも
付けねばならないのかということです。
0449デフォルトの名無しさん
2006/11/12(日) 17:27:37訊く前に実験実験。
struct hoge{
void payo()throw();
};
//void hoge::payo()throw(){}
void hoge::payo(){}
//error: declaration of `void hoge::payo()' throws different exceptions
0450デフォルトの名無しさん
2006/11/12(日) 17:46:56仕様そのものを知りたいなあと。
因みに、VC8だとそのコードが通ります。
0451デフォルトの名無しさん
2006/11/12(日) 18:28:51vcとg++とbcc。
時間があるなら標準規格読む。
0452デフォルトの名無しさん
2006/11/12(日) 20:35:39http://www.jisc.go.jp/
でX3014で検索。
PDFを開いてから例外指定で検索。
0453デフォルトの名無しさん
2006/11/12(日) 22:32:40class Coordinate{
public:
Coordinate(void): x(coo.X) , y(coo.Y) {}
short& x;
short& y;
COORD coo;
};
class Recta{
public:
Recta(void): t(rec.top) , b(rec.bottom), l(rec.left) , r(rec.right) {}
long& t;
long& b;
long& l;
long& r;
RECT rec;
};
Coordinate C( int x , int y ){
Coordinate c;
c.x = x;
c.y = y;
return c;
}
Recta R( Coordinate c1 , Coordinate c2 ){
Recta r;
r.l = c1.x;
r.t = c1.y;
r.r = c2.x;
r.b = c2.y;
return r;
}
0454続き
2006/11/12(日) 22:39:33void main(){
Recta r = R( C( 1, 1 ) , C( 10 , 10 ) );
}
環境:VisualStudio.net 2002
やろうとしてること・・・
1. Windows組み込みのCOORDやRECTを、COORDやRECTとして使えるように維持しつつ機能を拡張する
(サンプルなので余計なメンバ関数は省いてますが)
2. COORD.X とかを小文字のxでアクセスできるように参照変数を付ける
3. (mainでは)頂点を二つ指定して正方形を作る
上のソースを実行すると、四角形の頂点の値が滅茶苦茶な値になっています
(初期化されてない値っぽい?)
1ステップずつ実行すると、どうやらC関数で座標を作るところまではできていて
Cの戻り値でR関数を実行する時点でおかしくなっているようなのですが
どうしてそうなるのかが判りませんです・・・
どこか根本的に無理なことをしようとしてるのでしょうか
0455デフォルトの名無しさん
2006/11/12(日) 22:53:08デフォルトのコピーコンストラクタが参照の初期化に
コピー元への参照を使ってしまうから、コピー元が
破棄されることによって不正な参照が残ってしまう。
0456デフォルトの名無しさん
2006/11/12(日) 22:54:170457デフォルトの名無しさん
2006/11/13(月) 00:19:05コピーコンストラクタって今まであまり意識していなかったのですが
今回、参照の指す先がおかしいということでしたので
Coordinate( const Coordinate& C )
:x(this->coo.X)
,y(this->coo.Y)
{
this->coo = C.coo;
}
というコピーコンストラクタを明記してみたら、意図していた通りに動くようになりました
0458デフォルトの名無しさん
2006/11/13(月) 00:21:140459デフォルトの名無しさん
2006/11/13(月) 00:51:560460デフォルトの名無しさん
2006/11/13(月) 00:57:04それによると例外指定は関数型の一部にならないってあるから
throw()は宣言にだけ付けときゃ良いわけですね。
0461デフォルトの名無しさん
2006/11/13(月) 01:14:28でも、throw指定するのは(nothrow指定含めて)時代遅れだと
なんかで読んだ気がする。
0462デフォルトの名無しさん
2006/11/13(月) 01:57:25nothrowだけは例外的に使うべきだと思ってきたが。(除テンプレート内)
0463デフォルトの名無しさん
2006/11/13(月) 02:17:43nothrowは時代遅れ。
0464デフォルトの名無しさん
2006/11/13(月) 05:00:50多分GotW
Exceptinal C++ Styleでもかかれてる
>>463
文脈嫁
0465デフォルトの名無しさん
2006/11/13(月) 05:17:08>2. COORD.X とかを小文字のxでアクセスできるように参照変数を付ける
これをする理由がわからん。
参照を返すアクセサを用意するだけでいいような希ガス。
0466デフォルトの名無しさん
2006/11/14(火) 09:48:58COORD, RECTから
0467デフォルトの名無しさん
2006/11/14(火) 18:51:04try { hoge() }
catch(Hoge){throw;}
catch( ... ){ unexpected(); }
みたいなコードを自動生成するだけだら、使えネーって話だな。
0468デフォルトの名無しさん
2006/11/15(水) 02:36:58throw() は呼び出し側の最適化に役に立つ。
nothrow については、ググッたところ、
http://www.nothrow.com/
0469デフォルトの名無しさん
2006/11/15(水) 08:06:320470デフォルトの名無しさん
2006/11/15(水) 18:32:47俺は今まで、デストラクタには必ず付けていたが。
0471デフォルトの名無しさん
2006/11/15(水) 18:45:12つけなくていいんじゃない?
Boostも例外指定はしないで決定してるみたいだし
0472デフォルトの名無しさん
2006/11/15(水) 21:10:080473デフォルトの名無しさん
2006/11/16(木) 09:34:27「throw() を付けるかどうかは好みの問題だけど、
個人的には /* throw() */ とコメントで書いておくのが好き」
と言ってるな
0474デフォルトの名無しさん
2006/11/16(木) 10:57:47#define NOTHROW throw()
#endif
0475デフォルトの名無しさん
2006/11/16(木) 20:12:280476デフォルトの名無しさん
2006/11/16(木) 21:06:03書いてるね。なんとも含蓄があるよ。
教訓#1:例外仕様を決して書いてはならない。
教訓#2:空の例外仕様は除くが、私があなたなら、それさえも避けるだろう。
0477デフォルトの名無しさん
2006/11/16(木) 21:09:10ゴメン・・
含蓄kwsk
0478デフォルトの名無しさん
2006/11/17(金) 10:39:58char型、string型でもいいのですが、
文字列から特定の文字だけを全部削除できる関数はあるんでしょうか?
aaaabbbaaaabbbaaaaa
↓
aaaaaaaaaaaaa
という風にです。
0479デフォルトの名無しさん
2006/11/17(金) 10:51:20#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
int main()
{
std::string s = "aaaabbbaaaabbbaaaaa";
std::cout << s << std::endl;
s.erase(std::remove_if(s.begin(), s.end(), std::bind2nd(std::equal_to<char>(), 'b')), s.end());
std::cout << s << std::endl;
}
0480デフォルトの名無しさん
2006/11/17(金) 10:52:46複雑な削除条件も簡単に書ける。
boost::bindで何としても一行で済まそうという傾向もありますが
0481デフォルトの名無しさん
2006/11/17(金) 10:57:17remove() でいいだろ。
0482478
2006/11/17(金) 10:59:03解決しました
0483デフォルトの名無しさん
2006/11/17(金) 11:14:02#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void main()
{
string s = "aaaabbbaaaabbbaaaaa";
remove(s.begin(), s.end(), 'b');
cout << s << endl;
}
結果:aaaaaaaaaaaabaaa
remove()だけだと削除しきれない。
0484デフォルトの名無しさん
2006/11/17(金) 11:23:45うむ。 erase() も要るな。
0485デフォルトの名無しさん
2006/11/17(金) 11:25:400486デフォルトの名無しさん
2006/11/17(金) 13:10:350487デフォルトの名無しさん
2006/11/17(金) 13:19:240488デフォルトの名無しさん
2006/11/17(金) 13:22:000489デフォルトの名無しさん
2006/11/17(金) 13:24:530490デフォルトの名無しさん
2006/11/17(金) 13:57:170491デフォルトの名無しさん
2006/11/17(金) 14:59:22remove()でもいいですね。remove_if()をわざわざ使ったのは、例えば
'b'が2回現れた後は'c'も削除せよ、というような場合に便利ですね。
今回はremove()だけでいいみたいです。
0492デフォルトの名無しさん
2006/11/17(金) 15:20:42文字列を取り出していきたいんですけど、どうしたらいいでしょうか?
0493デフォルトの名無しさん
2006/11/17(金) 16:03:51無視する文字は改行文字だけ?ホワイトスペース文字全般?
0494デフォルトの名無しさん
2006/11/17(金) 16:14:11ホワイトスペースも無視する方法のふたつをお願いします。
0495デフォルトの名無しさん
2006/11/17(金) 17:14:22#include <iostream>
#include <fstream>
#include <string>
int getsome(std::ifstream& fs, std::string& s, int n);
int getwows(std::ifstream& fs, std::string& s, int n);
int main()
{
std::ifstream fs("ws.txt");
std::string s;
int n = getsome(fs, s, 10); // 改行文字のみを無視
std::cout << n << "文字: \'" << s << '\'' << std::endl;
fs.seekg(0, std::ios::beg);
s = "";
n = getwows(fs, s, 10); // ホワイトスペース文字を無視
std::cout << n << "文字: \'" << s << '\'' << std::endl;
}
int getsome(std::ifstream& fs, std::string& s, int n)
{
char c;
int i = 0;
while (i < n && fs.get(c))
if (c != '\n') {
s += c;
i++;
0496デフォルトの名無しさん
2006/11/17(金) 17:15:32return i;
}
int getwows(std::ifstream& fs, std::string& s, int n)
{
char c;
int i = 0;
while (i < n && fs >> std::ws >> c) {
s += c;
i++;
}
return i;
}
getsome()が改行文字のみを無視、getwows()はホワイトスペース文字を
全て無視します。
0497デフォルトの名無しさん
2006/11/17(金) 17:16:17---- ws.txt ----
1234
56
78
90
[EOF]
0498デフォルトの名無しさん
2006/11/17(金) 17:26:10>>497には所々文字列の前に' 'とかタブ文字を入れて見て下さい。
0499494
2006/11/17(金) 17:29:05問題を解決する事ができました!
ありがとうございます!
0500デフォルトの名無しさん
2006/11/17(金) 18:57:470501デフォルトの名無しさん
2006/11/17(金) 22:19:280502デフォルトの名無しさん
2006/11/18(土) 00:03:240503デフォルトの名無しさん
2006/11/18(土) 01:24:380504デフォルトの名無しさん
2006/11/18(土) 01:56:270505デフォルトの名無しさん
2006/11/18(土) 02:25:43{
public:
virtual int main( int argc, char **argv );
};
0506デフォルトの名無しさん
2006/11/18(土) 03:43:05ヘッダファイルa.hひとつで
class a{
void hoge(){
return 0;
}
};
という感じで定義も記述して、a.cppファイルを作らないのってよくないんでしょうか?
修正があったときhファイルとcppファイルをいじらなきゃならないのが嫌なので…。
今ぶちあたってる問題として、お互いのstaticなメンバ関数を
お互いが使うような二つのクラスがあるときは宣言と定義を分けないとどうしようもないようなのですが。
0507デフォルトの名無しさん
2006/11/18(土) 03:51:52ヘッダファイルには宣言だけ
cppに定義部を書く
0508デフォルトの名無しさん
2006/11/18(土) 04:45:10やはりコンパイル時間は遅くなりそうだが。
ちなみにテンプレートを使ってるとヘッダファイルしか使えないよな。
0509デフォルトの名無しさん
2006/11/18(土) 05:32:09という時代だからな
boostがちょろっと更新されるだけで
pimplパターンなんて水の泡だ
やるだけ無駄
0510デフォルトの名無しさん
2006/11/18(土) 09:33:34コンパイル時間より、コードの肥大化の方を心配した方がいい
0511デフォルトの名無しさん
2006/11/18(土) 11:53:22C++的にはexportつかえばヘッダに書かなくても大丈夫だよ!
0512デフォルトの名無しさん
2006/11/18(土) 11:56:59ちゃんと使えるコンパイラってどれがあるの?
0513デフォルトの名無しさん
2006/11/18(土) 12:56:240514デフォルトの名無しさん
2006/11/18(土) 14:04:47実際のところサポートしてるコンパイラって何てやつ?
0515デフォルトの名無しさん
2006/11/18(土) 14:15:350516デフォルトの名無しさん
2006/11/18(土) 14:32:16Borlandのってどう?
0517デフォルトの名無しさん
2006/11/18(土) 14:48:10exportがあっても何も解決しないっぽいよ。
0518デフォルトの名無しさん
2006/11/18(土) 15:42:490519デフォルトの名無しさん
2006/11/18(土) 15:45:08次期C++ではどうなの?
0520デフォルトの名無しさん
2006/11/18(土) 22:38:24寡聞にして知らん。
糞GCCもずっと長いことサポートしてなかったと思うが、4.0系移行はサポートしたのか?
0521デフォルトの名無しさん
2006/11/18(土) 23:20:570522デフォルトの名無しさん
2006/11/19(日) 01:13:56c#だと楽だよね
0523デフォルトの名無しさん
2006/11/19(日) 01:18:34UMLソフトでクラスしこしこ作ればそのへんは
骨だけは作ってくれるぞ
0524デフォルトの名無しさん
2006/11/19(日) 03:00:440525デフォルトの名無しさん
2006/11/19(日) 03:17:130526デフォルトの名無しさん
2006/11/19(日) 03:29:210527デフォルトの名無しさん
2006/11/19(日) 04:26:560528デフォルトの名無しさん
2006/11/19(日) 09:51:20...
};
こういうクラスがあって、実体化するときに以下の用に書きますがが、
MYCLASS<A> myclassA;
MYCLASS<B> myclassB;
こうかける方法を教えてほしいです。
MYCLASS myclassA;
MYCLASS myclassB;
このときTは、それぞれA, Bに死体です。
0529528
2006/11/19(日) 09:57:35template <typename T> class MYCLASS {
T* a;
MYCLASS(T* t) : a(t) {}
};
こういうクラスがあって、実体化するとき以下のように書きますが、
A a;
MYCLASS<A> my1(&a);
B b;
MYCLASS<B> my2(&b);
以下のように書きたいです。
A a;
MYCLASS my1(&a);
B b;
MYCLASS my2(&b);
このときTは、それぞれA, Bに死体です。
0530デフォルトの名無しさん
2006/11/19(日) 09:59:540531デフォルトの名無しさん
2006/11/19(日) 10:12:53boost::any a;
template<typename T>
MYCLASS(T* t) : a(t) {}
};
0532528
2006/11/19(日) 10:19:01ありがとう、boostインストールしてきます。
0533528
2006/11/19(日) 12:37:45デストラクタでTが使えないってエラーがでるんですが、
これは無理なんでしょうか?
class MYCLASS
{
boost::any a;
template<class T>
MYCLASS(T* t) : a(t) {}
template<class T>
~MYCLASS() {
cout << sizeof(T);
}
}
0534デフォルトの名無しさん
2006/11/19(日) 13:52:02無理。 T を決める方法が無い。
何がしたいんだ?
0535528
2006/11/19(日) 14:29:550536デフォルトの名無しさん
2006/11/19(日) 14:30:35何もしなくても呼ばれるだろ?
0537528
2006/11/19(日) 14:44:10T*なので
0538デフォルトの名無しさん
2006/11/19(日) 14:45:38template<class T>
MYCLASS(T* t) : a(*t) {}
0539528
2006/11/19(日) 15:02:46元々渡されたtのデストラクタを呼んで解放したいです。
529の例がスタック上のインスタンスになってるんですが、
実際はこういう風には使わないで、newしたものを渡します。
0540デフォルトの名無しさん
2006/11/19(日) 15:07:05{
boost::shared_ptr< void > p;
public:
template<class T>
MYCLASS(T* t) : p(t) {}
};
型が消えてるから MYCLASS 内で有用な仕事ができないとは思うけれど
0541デフォルトの名無しさん
2006/11/19(日) 15:08:41デストラクタじゃなくて呼ぶのdeleteじゃね?
とりあえずスマートポインタだと無駄に重装備っぽいので関数ポインタ使ってみた
class MYCLASS{
MYCLASS(const MYCLASS&);
MYCLASS&operator=(const MYCLASS&);
void*ptr;
void(*delfn)(void*);
public:
template<class T>MYCLASS(T* t) : ptr(t),delfn(deleter<T>){}
~MYCLASS(){delfn(ptr);}
};
0542541
2006/11/19(日) 15:10:46template<typename T>
static void deleter(void*p){delete (T*)p;}
0543528
2006/11/19(日) 15:19:31ありがとうございます。難しそうなのでじっくり調べてみます。
>デストラクタじゃなくて呼ぶのdeleteじゃね?
そうですdeleteです。わかりずらくてすいません。
0544デフォルトの名無しさん
2006/11/19(日) 15:33:43class aaa{
int v;
class bbb{
void func(int x){
v+=x; //コンパイルエラー
}
}b;
};
0545デフォルトの名無しさん
2006/11/19(日) 15:46:30aaa のインスタンスを渡せ。
■ このスレッドは過去ログ倉庫に格納されています