C#_自作例外の書き方

Exception クラス継承し、コンストラクタを作成。

コンストラクタには複数あり、出力されるメッセージが異なる。

1) 引数なし
2) 引数が文字列
3) 引数が文字列と、発生済みを例外オブジェクト

3) は、既に発生した例外を表示することができる。tyr cathc 文の入れ子で使用。

 

ex ) 自作例外名は OriginalException

コンストラクタ

    class OriginalException : Exception
    {
        public OriginalException ( ){ }
        public OriginalException ( string message ) : base ( message ) { }
        public OriginalException ( string message,
            Exception inner ) : base ( message ) { }
    }

 

OriginalException を使う

    class XXX
    {
        public YYYY( )
        {
            try
            {
                throw new OriginalException ( );
                throw new OriginalException ( "OMG" );
            }
            catch ( OriginalException )
            {
                Debug でコンソールに↓が表示される。
                例外がスローされました: 'TestHoge.OriginalException'
                    場所 ~~ 行目
            }
            catch ( OriginalException e )
            {
                Console.WriteLine ( e.ToString() );
               
                Debug でコンソールに↓が表示される。
                例外がスローされました: 'TestHoge.OriginalException'
                TestHoge.OriginalException: OMG
                   場所 ~~ 行目
            }
        }
    }

 

「 3) 引数が文字列と、発生済みを例外オブジェクト」の使い方。略ソース。

    try
    {
        try
        {
            //A 例外発生
        }
        catch( )
        {
            //B 例外発生
        }
    }
    catch( )
    {
        //A と B の例外を表示できる
    }

 

base の意味

継承元クラスコンストラクタを呼び出すことを意味している。
( 上記の場合 Exception クラス )

通常、クラスに継承関係がある場合、
継承元のコンストラクタが実行された後、継承先のコンストラクタが実行される。
この場合、コンストラクタの引数は継承先のコンストラクタに渡され、
継承元のコンストラクタには渡されない。

そこで、base を用いることで継承元のコンストラクタへ引数を渡すことができる。

 

 

OriginalException クラスに複数の例外作りたいと思ったが、
「 throw 文によって投げられる例外は、
System.Exception クラスの派生クラスのインスタンスなので、
それ以外のクラスのインスタンスを throw することはできない
とあったので、自作したい分クラスを作成する必要があるかと。

 

こちらから。
C# ユーザー定義の例外クラスを作る | プログラミングテクニック集キヤミー
http://lassy-tech.blogspot.jp/2008/01/cexception.html
https://qiita.com/github129/items/bc81d1dbb66f4afd589e
方法 : ユーザー定義の例外を作成する | Microsoft Docs
https://qiita.com/oika/items/1f8d8e423b2d0fad6da2

 

以上。

C#_List の深いコピー

ソースは色々略。

コンストラクタを使う。

    var fugaList = new List< int > ( hogeList ) ;

これにより、hogeList の中身を複製して fugaList に渡している。

 

 

以下は NG 。List や配列は参照型だから。

    var fugaList = new List<int>();
    fugaList = hogeList;

これだと参照型なので fugaList の要素を変更すると hogeList も変わってしまう。

 

 

こちらから。
https://webbibouroku.com/Blog/Article/list-copy

以上。

C++_コピーコンストラクタとは

operator= の意味が分からなかったので、コピーコンストラクタを
調べればわかるかと思ったが、結局不明。

コピーコンストラクタ

    C ( const C & );
    C &operator=( const C & );

オブジェクトのコピーがとられた時に実行する処理。
そのクラス型への参照を引数にとるコンストラクタ

 

コピー用の初期化を作成することにより、以下の時の問題を回避できる

    obj2 = obj1
メンバ変数がポインタであるメモリアドレスを指していた場合、
二つの異なるオブジェクトがまったく同じメモリアドレスを競合することになる。
これにより、
メモリアドレスが解放されなくなったり
デストラクタで 2 度同じ領域を開放するなどの不具合が発生する。

 

呼び出されるタイミング

コピーコンストラクタは、オブジェクトの初期化時 ( コピー 時 ) に呼び出されるもの。

宣言時 ( オブジェクトの初期化時 )
引数 ( オブジェクトを関数に値渡しする時 )
戻り値 ( 関数からオブジェクトを値渡しする時 )

 

ex ) 略ソース

    public:
    C ( ) { str = "Hello"; }
    C ( const C &obj ) { str = "Hey"; }

 

宣言時

    int main( )
    {
        C c2 = c1
        // この時、コピーコンストラクタが呼び出される
       
        std::cout << c1.str // Hello
        std::cout << c2.str // Hey
       
       
        // 下記場合コピーコンストラクタは呼び出されない。
        //   初期化ではなく代入なので
        //C c3;
        //c3 = c1
    }

 

引数

    int main( )
    {
        C c1
        auto get = getC ( c1 )
        return 0;
    }

 

戻り値

    C getC ( C obj )
    {
        return obj;
    }

 

 

コンストラクタが自動で作ってしまう関数を禁止する

コピーコンストラクタ・代入演算子は書かなくても自動で作成される。

自動作成を禁止する基本的な方法はコピーコンストラクタ、代入演算子
private 領域に書くこと。

 

C++ 11 では delete を使うと禁止される。
    C ( const C & ) = delete;
    C &operator=( const C & ) = delete;

 

 

こちらから。
http://yohshiy.blog.fc2.com/blog-entry-303.html
http://wisdom.sakura.ne.jp/programming/cpp/cpp17.html
http://wisdom.sakura.ne.jp/programming/cpp/cpp8.html
http://www7b.biglobe.ne.jp/~robe/cpphtml/html02/cpp02009.html

 

以上。コピーコンストラクタは一応わかった。operator= が結局わからない。

 

C++_operator= とは何か 01

調べても不明。コピーコンストラクタという単語の意味も調べる必要が ?
operator や T operator=(~ ) というコードが意味不明だった。

    C ( const C & );
    C &operator=( const C & );

代入演算子オーバーロード

operator= はメンバ関数の名前に過ぎない。
オブジェクトのコピーを行う際、そのクラス用に定義されている代入演算子
使用することになっている。

 

関数名としてoperator=」という特殊な名称を用いることで、
= 演算子の処理を定義できる。( operator = 、とスペースあってもOK )
代入演算子だけでなく、ほとんどの演算子で可能。( 演算子オーバーロード )

 

代入演算子は、次のように自分で定義することが可能。

    class MyClass
    {
        public:
            MyClass& operator=(const MyClass& rhs);
    };
   
    MyClass& MyClass::operator=(const MyClass& rhs)
    {
        // 代入操作時に行う処理を記述
        return *this;
    }

operator= は、*this を返すように実装。
単に「return this;」だとポインタになってしまうので、
「*this」のように間接参照をおこなう。

戻り値の型が参照になっているので、自身の参照 (*this) を返しておけば、
「a = b = c;」のような連続的な呼び出しが可能になる。( 意味不 )
これは「a.operator=(b.operator=(c));」と同じ。

 

自身と同じクラス型のオブジェクトの代入(コピー)を受け付けるには、
operator= の仮引数は「const 自身のクラス名&」、
戻り値の型は「自身のクラス名&」とする。

operator= の仮引数が、自身のクラスの参照型であることによって、
同じ型のオブジェクトが代入可能になる。

 

operator キーワード

クラスのインスタンスに適用された時の
operator-symbol の意味を指定する関数を宣言する。
これにより、演算子に複数の意味を与える

 

演算子オーバーロード

演算子を拡張する。
演算子オーバーロードは、独自のクラスに対する拡張。( ? )
クラスでメンバ関数として定義する。ここで用いるのが operator キーワード。

 

 

こちらから。
https://programming-place.net/ProgrammingPlacePlus/cpp/language/016.html#assign_op
http://wisdom.sakura.ne.jp/programming/cpp/cpp27.html
https://msdn.microsoft.com/ja-jp/library/5tk49fh2.aspx

 

以上。

 

--Memo--

//NativeClass
    NativeClass();
    NativeClass(const NativeClass &) = delete;
    NativeClass(& operator=(const NativeClass)) = delete;

青色がコンストラクタ、緑が型。
= delete により、勝手にコピーコンストラクタを作成するのを阻止する。

OpenCV_ROI とは

Region Of Interest : 関心領域。( 対象領域 )

ROI を設定すると、その部分領域を扱う際に本来なら考慮すべきことを
しないで処理できる。

 

ex ) ※ 変数名は適当に使いまわし。

    cv::Mat img ( Size(320,240), CV_8UC3 );
    cv::Mat roi ( img, Rect(10,10,100,100) );
    roi = Scalar(0,255,0);  // roi の部分を緑 で埋める。元画像変更される。


    cv::Mat img = cv::imread("./hoge");
    cv::Rect roi ( x, y, …) ;
    img ( roi );    // img に RIO を設定。


    //cv::Mat imgRoi = img(roi);
    //imgRoi は cv::Mat ヘッダ ( メモリの確保はされない )

 ・img ( roi ) は、cv::Mat roi ( img, rect ) と同じ
・cv::Mat roi ( img, rect ) → roi は切り取った画像。

 

 

こちらから。
https://ja.wikipedia.org/wiki/ROI
http://kazunori-ohmori.blog.so-net.ne.jp/2014-01-30
http://opencv.jp/opencv-2svn/cpp/basic_structures.html#mat
http://answers.opencv.org/question/10364/set-roi-in-cvmat/
http://opencv.jp/opencv-2.1/cpp/c++_cheatsheet.html

 

以上。

OpenCV_cv::Mat の行を指定して削除したい

経緯メモ)  要素を順次見ていき、条件が true の行だけを cv::Mat 型として欲しい。
resize だと欲しいデータにならない。

 

結論

mat.row( int ); で mat から int 行を取り出し、別 Mat へ挿入する。

    cv::Mat mv;
    mv.push_back ( mat.row( i ) );

mat が元 Mat。i は for 文などのループ変数。

 

 

軌跡

ソースは色々略。

部分行列として欲しい行を取り出し、マージすればいいのではないか。

    std::vector<cv::Mat> mv;
    mv.push_back( mat(cv::Range(i, i), cv::Range(0, 10));

mv の 各要素 Mat の rows も cols も 0 だった。
cv::Range(i, i) は NG らしい。

 

1 行取り出し、マージすればいいのではないか。

    mv.push_back( mat.row(i) );
    cv::Mat m_merged;
    cv::merge(mv, m_merged);

行列数がおかしい。
複数チャンネルを 1 Mat にする関数なので、欲しいデータになるはずがない。

 

 

こちらから。
http://opencv.jp/cookbook/opencv_mat.html#id27
http://pynote.hatenablog.com/entry/opencv_cvmat_submatrix
http://pinedge.oops.jp/tips/content.php?page=cv_mat

以上。

 

何をどうしたかったのかの経緯キャプチャ

f:id:koshinRan:20180712001015p:plain

OpenCV_Mat の行削除

OpenCV 逆引きリファレンス で 削除 と検索かけてもヒットしなくて焦った。
リサイズ でヒット。

    mat.resize(2);

行単位のみで変更。mat は cv::Mat 型。

 

3 * 3 を 2 * 3 にしたり、
    mat.resize(2);

 f:id:koshinRan:20180703223323p:plain  →  f:id:koshinRan:20180703223412p:plain

 

5 * 3 に削除・拡大できる。
     mat.resize(5, cv::Scalar(100)); //拡大される行に入る値。指定なしは 0 が入る。

 f:id:koshinRan:20180703224327p:plain ( 3*3 から 5*3にしたらこうなるだろうと想定 )

 

 

こちらから。
http://opencv.jp/cookbook/opencv_mat.html#id24
http://pen.agbi.tsukuba.ac.jp/~torarimon/?OpenCV ( アクセスできないが一応記載 )

 

以上。