単なる例外処理よりもこっちのほうが良さそう
http://monpe.cliff.jp/computer/cpp/330_cpp_ed_doc.html
#include <iostream> using namespace std; template <class A, class T> inline void Assert(A assert_arg, T except) { if (!assert_arg) throw except; } void main() { int i_a; int i_b; int i_except; cout << "オペランド1:"; cin >> i_a; cout << "オペランド2:"; cin >> i_b; try { Assert(i_b!=0, i_except=10); cout << "結果:" << i_a/i_b << endl; } catch(int i_catch){ cout << "0で割り算を実行しました" << endl; } }
http://www.hiroshima-cu.ac.jp/japanese/IPC/hunet99/sun/WorkShop/ja/html_docs/c-plusplus/c++_ug/exception.doc.html
http://www.geocities.jp/ky_webid/cpp/language/025.html
http://www.bugbearr.jp/?C%2B%2B%2F%E4%BE%8B%E5%A4%96
http://www.02.246.ne.jp/~torutk/cxx/exception/programming.html
// Class DivideByZeroException definition. #include <stdexcept> // stdexcept header file contains runtime_error using std::runtime_error; // standard C++ library class runtime_error // DivideByZeroException objects should be thrown by functions // upon detecting division-by-zero exceptions class DivideByZeroException : public runtime_error { public: // constructor specifies default error message DivideByZeroException(); }; // end class DivideByZeroException //Fig. 16.1 Class DivideByZeroException definition. DivideByZeroException::DivideByZeroException() : runtime_error( "attempted to divide by zero" ){ }
// Fig. 16.2: Fig16_02.cpp // A simple exception-handling example that checks for // divide-by-zero exceptions. #include <iostream> using std::cin; using std::cout; using std::endl; #include "DivideByZeroException.h" // DivideByZeroException class // perform division and throw DivideByZeroException object if // divide-by-zero exception occurs double quotient( int numerator, int denominator ) { // throw DivideByZeroException if trying to divide by zero if ( denominator == 0 ) throw DivideByZeroException(); // terminate function // return division result return static_cast< double >( numerator ) / denominator; } // end function quotient int main() { int number1; // user-specified numerator int number2; // user-specified denominator double result; // result of division cout << "Enter two integers (end-of-file to end): "; // enable user to enter two integers to divide while ( cin >> number1 >> number2 ) { // try block contains code that might throw exception // and code that should not execute if an exception occurs try { result = quotient( number1, number2 ); cout << "The quotient is: " << result << endl; } // end try // exception handler handles a divide-by-zero exception catch ( DivideByZeroException ÷ByZeroException ) { cout << "Exception occurred: " << divideByZeroException.what() << endl; } // end catch cout << "\nEnter two integers (end-of-file to end): "; } // end while cout << endl; return 0; // terminate normally } // end main /* Output Enter two integers (end-of-file to end): 100 7 The quotient is: 14.2857 Enter two integers (end-of-file to end): 100 0 Exception occurred: attempted to divide by zero Enter two integers (end-of-file to end) Copyright 1992-2006 by Deitel & Associates, Inc. All rights reserved. */
#include <iostream> #include <boost/thread.hpp> #include <boost/bind.hpp> using namespace std; using namespace boost; // 引数なし関数をマルチスレッドで実行 const int kCount = 100000000; const int kInterval = 1000000; void PrintHello() { for(int i = 0; i != kCount; ++i) if (!(i % kInterval)) cout << "Hello "; } void PrintWorld() { for(int i = 0; i != kCount; ++i) if (!(i % kInterval)) cout << "World! "; } int main() { thread thr_hello(&PrintHello); // PrintHello関数を実行するスレッドの生成、実行 thread thr_world(&PrintWorld); thr_hello.join(); // thr_helloが走らせているスレッドの終了を待つ thr_world.join(); return 0; }
#include <iostream> #include <boost/thread.hpp> #include <boost/bind.hpp> using namespace std; using namespace boost; // メンバ関数をマルチスレッドで実行 class PrintMessage { public: PrintMessage(const char* msg) :kMessage_(msg), kCount_(100000000), kInterval_(1000000) {} void run(); private: const int kCount_; const int kInterval_; const char *kMessage_; }; void PrintMessage::run() { for(int i = 0; i != kCount_; ++i){ if (!(i % kInterval_)){ cout << kMessage_; } } } int main(){ PrintMessage hello("Hello "); PrintMessage world("World! "); thread thr_hello(bind(&PrintMessage::run, &hello)); thread thr_world(bind(&PrintMessage::run, &world)); thr_hello.join(); thr_world.join(); return 0; }
unix環境ならgettimeofday
windows環境ならWIN32APIの関数を調べる
参照ウェブサイト:http://kzk9.net/column/time.html
継承される基本クラスのデストラクタにはvirtualをつける。
C++のクラスは継承されることを前提として作る。
しかしSTLのクラス(vector,deque,string,map 等)は継承されないことを前提として作られている。
したがって、STLのクラスを継承するのはあまりよろしくない。
継承するのでは無く、クラスのメンバ変数としておくのが望ましい。
(オブジェクト指向におけるIs-aとHas-aの関係・・だそうだ)
vectorの方がアクセス時間が少々早いようだが、
vectorはpush_front(),pop_front()を持っていないので
dequeを使った。
変数:val, 行数:row, 列数:col
・宣言
0×0の行列 val deque< deque<double> > val; (row,col)行列 val deque< deque<double> > val(row, deque<double>(col));
・要素の追加
deque<double> val1; //末尾行に追加 val.push_back(val1); //先頭行に追加 val.push_front(val1);
double val2; //列に追加 val[row].push_back(val2); val[row].push_front(val2);
・要素の削除
//末尾行を削除 val.pop_back(); //先頭行を削除 val.push_front();
//列を削除 val[row].pop_back(); val[row].pop_front();
・宣言後のサイズ変更
deque< deque<double> > val; val.resize(row); for(unsigned int i=0; i < val.size(); i++){ val[i].resize(col); }
数値をそのままの形で文字列に変換するときに便利です。
参照ウェブサイト
http://ppwww.phys.sci.kobe-u.ac.jp/~akusumoto/program/detail.php?d=c/10-other/sstream_trap
C++のstring型は便利だ(当たり前か?)
面白いことに気づいたので、覚え書きでも少々書いてみます。
string型からcharポインタ型への変換 [#eb02a673]
string str = "str"; char* ch; ch = str.c_str();
charポインタ型からstring型への変換 [#ac7bab70]
char* ch; string str = ch;
charポインタ型文字列とstring型文字列の結合 [#u7b497d9]
char* ch = "char"; string str = (string)ch + "str";char配列型文字列ってstring型でキャストできるんですねえ・・
でも無理矢理な方法のような気がするのでだれか正当な方法を見つけてください。
List,Vector,DequeなどのCollectionインターフェイスにジェネリクスが導入された。
簡単に言うと、C++のtemplateと良く似た機能がJavaに追加された。
ラッパークラスInteger,Double, ・・ から基本型 int, double,・・ との間の変換が自動的におこなわれるようになった。
Staticクラスをインポートできるようになった。
Mathクラスをインポートすれば、 Math.PI, Math.sin()などのMath.を省略できる
新機能ではないが、getenv()が非推奨メソッドじゃなくなっている
Common/corba/Makefile.common
を書き換える。
警告がでる原因は、
JDK5付属のjavaidlコンパイラidljにより生成されるソースコードが
JDK5の新機能に対応していないこと。
対応させるために、Makefile内部でgrepをかけました。
下に添付しておきますが、非保証です。
ModelLoader/server/ObjectStruct.java
を書き直す。
やっちゃいけないことをしているのかもしれない。
でも一応添付
警告はでていないけど表記統一の関係上VrmlSceneEx?.javaも添付
勿論非保証
client/gui/com/generalrobotix/ui/util/AlertBox.java
を書き直す。
これもまた変なことが起こりそうで怖い
でも一応添付
勿論非保証
Javaのアップデートをすると突然動かなくなる。
JMFをインストールするとjmstudioというmovを再生したり、
movをaviに変換できたりする便利なソフトウェアがついてくる。
Vine3.2なら、JMFをインストールしたディレクトリ/binの下で
./jmstudio
と打てばjmstudioが起動したのだが
Ubuntu 7.04 Feistyの場合、JMFをインストールしたディレクトリで
java -Dawt.toolkit=sun.awt.motif.MToolkit JMStudio
FedoraCore6ではもっとめんどくさい
1, libXp.so.6というライブラリをyumでインストール
# yum install libXp.so.6
2, $(JMFHOME)/bin 以下で
$(JAVA_HOME)/bin/java -Dawt.toolkit=sun.awt.motif.MToolkit JMStudio
FedoraCore6の場合は動かすまでに相当苦労した。
気づいたきっかけは
・java.lang.UnsatisfiedLinkError? という Exceptionが発生し
Can't load IA 32-bit .so on a IA 32-bit platformというエラー文が出力された
ことを手がかりにGoogle先生とお話することにより、
jdk5 version10以降はエラー文がおかしい
という謎の記述を見つけたこと
・私のFedoraCore?にjdk5のversion6が入っていたこと
そしてエラー文を一所懸命に読んで、
・libXp.so.6が足りないということがわかったこと
・FedoraのレポジトリにlibXp.so.6が存在していたということ
です
/home/.bashrc
に追記する。
例えばこんな感じ
export JAVA_HOME=/usr/java/jdk1.5.0_11 export PATH=$PATH:$JAVA_HOME/bin
grep -lr 検索文字列 検索対象ファイルのディレクトリ | grep -v '検索から除外するパス' | xargs sed -i 's/検索文字列/置換後の文字列/g'
実行ファイルの最後に "$*" と書いてあげれば良い。
例えば、こんな感じ
$ ./client $NS_OPT $*
出力前に、ターミナルで
$ script
とタイプしておき、その後
$ (出力コマンド)
として出力する。
出力が止まったら、ターミナルで
$ exit
と打つ。 そうするとtypescriptというファイルが出来る。 これにはscriptを実行した後のターミナルの入出力が全て記録される。
_out型にマッピングされるので、
毎度おなじみの_var型を使って領域を確保する。
あとはほとんど下に書いてあるのと同じなので、
めんどくさいから書かない。
注意としては、下と同様にポインタ演算で要素にアクセスするということ。
最近CORBAのキモさに対して快感を覚えてきた。
機関銃をぶっぱなす女子高生の如く・・・
Sequence型の配列を戻すような場合、
_slice*型を取り扱わなければならない。
こんなときも万能スマートポインタ(見たいなもの)_var型 変数が活躍する。
ただし、[]演算子がオーバーロードされてない(そのくらいしとけ、omniのアホ)
のでポインタ演算のお勉強が必要
CorbaServerClient::DblSequence3_slice* CorbaServerClient::CorbaServer_impl:: returnDblSeq2(const CorbaServerClient::DblSequence& seq){ CorbaServerClient::DblSequence3_slice* seq3_ptr; CorbaServerClient::DblSequence3_var seq3_var; seq3_var = DblSequence3_alloc(); for(int i=0; i<3; i++){ (*(seq3_var + i)).length(seq.length()); for(int j=0; j<seq.length(); j++){ (*(seq3_var + i))[j] = seq[j]; } } seq3_ptr = seq3_var._retn(); return seq3_ptr; }
idlで関数の戻り値の前にonewayキーワードを付ければ良い。
ただし、戻り値はvoid型で引数はinパラメータのみ
という制限がつく
oneway void server_method(in short param);
Sequence型はキモい。 お約束どおりに書いてあげないと領域確保に失敗して、
セグメンテーションエラーやメモリリークが発生する
DynamicsSimulator_impl.cppのおかげでなんとかお約束がわかった。
CORBAの資料ってスクネエなあ。
なんとかならんものかなあ。
struct Gait{ double x; double y; double z; double sstime; double dstime; }; typedef sequence<Gait> GaitSequence; void getGait2(out GaitSequence gait_seq);
void SwissRanger_impl::getGait2(OpenHRP::GaitSequence_out gait_seq_out){ GaitSequence_var gait_var = new GaitSequence; gait_var->length(gaitv.size()); if(gaitv.size() > 0){ for(int i=0; i<(int)gaitv.size(); i++){ gait_var[i].x = gaitv[i].x; gait_var[i].y = gaitv[i].y; gait_var[i].z = gaitv[i].z; gait_var[i].sstime = gaitv[i].sstime; gait_var[i].dstime = gaitv[i].dstime; } } gait_seq_out = gait_var._retn(); }
SwissRanger_var sr; void SwissRangerClient::getGait2(std::vector<OpenHRP::Gait>& gait_v){ OpenHRP::GaitSequence_var gait_var; sr->getGait2(gait_var); gait_v.resize((int)gait_var->length()); for(int i=0; i<(int)gait_v.size(); i++){ gait_v[i].x = gait_var[i].x; gait_v[i].y = gait_var[i].y; gait_v[i].z = gait_var[i].z; gait_v[i].sstime = gait_var[i].sstime; gait_v[i].dstime = gait_var[i].dstime; } }