正規表現で、アスタリスクは0を含む任意数、クエスチョンは0か1という解説はよく見る。アスタリスクは最長一致の動作をするのに対して、前後にある別パターンで一致する場合はアスタリスクの部分はなるべく短くという意味合いの最短一致とさせるため、アスタリスクに続けてクエスチョンを付けるという用法もある。この用法についての解説はあまり見られず、実践の機会があって勉強になった。
C++ の class を引数として渡すときは、値とアドレス、どちらが良いかという疑問。それぞれトレードオフがあるが、継承した場合の問題を考えると、class はアドレス渡しのほうが良さそう。
C++ は以下のどちらの方法でも結果的にアドレス渡しになる。ただし、(2)は C++ のみの機能。
(1)仮引数は"*"を付けてポインタを指し、実引数は"&"を付けてアドレスを指す場合
(2)仮引数に"&"を付けて参照を指し、実引数は何も付けずに値を渡す場合
両者の違いはコピーコンストラクタがわかりやすい。アドレスのコピーなら(1)のコピーコンストラクタが、値のコピーなら(2)のコピーコンストラクタが呼ばれる。※コピーコンストラクタが未定義であれば値の複製が自動実行される。
const 付で渡した class は const メンバ関数しか呼び出すことができない。参照渡しは const で変更されないことを保証、ポインタ渡しは非 const で変更される可能性がある、とルールを決めたほうがいいかもしれない。
また、初期化と代入は別ものであるということにも注意をしたい。実体変数の場合は、代入ではコピーコンストラクタは作用しない。C++のクラスで記述と実行される処理は以下のようになる。変数宣言がコンストラクタ実行、代入がバイナリコピーというイメージが浮かび上がる。
class instance; → デフォルトコンストラクタ
class instance(other); → コピーコンストラクタ
※class instance = other; → コピーコンストラクタ
instance = other; → 代入演算子
なお、ポインタ変数の場合は、new で明示的にコンストラクタ実行またはコピーコンストラクタ実行を行い、delete で明示的にデストラクタ実行を行う。
関数の引数値や戻り値ではコピーコンストラクタが自動実行され、vector等のコンテナでも自動実行される。std::vector用にデフォルトコンストラクタとコピーコンストラクタ、配列用にデフォルトコンストラクタ、を定義しておく必要がある。コピーコンストラクタの定義では値の複製が自動実行されないように参照型変数を引数値とする。(値型変数では値の複製が自動実行されてしまう。)
引数が1つのコンストラクタは変換コンストラクタという機能に注意が必要で、explicitキーワードを付けで無効化すると良いが、コピーコンストラクタにはexplicitキーワードを付けてはいけない。
代入でも値の複製を自動実行させずにコピーコンストラクタを作用させるには、代入演算子のオーバーロードを定義する。代入演算子の定義では参照型変数を引数値と戻り値(戻り値は自己参照)とする。なお、コピーコンストラクタ、代入演算子のオーバーロード、いずれも、継承クラスでは基底クラスのものを明示的に呼び出す必要がある。
C++11 以降はコピーのほかにムーブというものも登場しておりコピーの例外安全にも関係しているようだ。
野良C++erの雑記帳:「 Copy して Swap 」 対 「 Copy して Move 代入」
ムーブ代入演算子をオーバロードした際に基底クラスのムーブ代入演算子を呼び出す書き方の例
class::operator=(std::move(other))
Effective C++ 総集編:コピーするときは、オブジェクトの全体をコピーしよう
<参考>
吉田誠一のホームページ:値渡しか、参照渡しか
プログラマーズ雑記帳:C++ のコピーコンストラクターと代入演算子
WisdomSoft(旧):C++入門 17. コピーコンストラクタ
satosystemsの日記:std::vector に入れる独自クラスにはデフォルトコンストラクタが必要
Programming Place Plus C++編【言語解説】:第19章 演算子オーバーロード
nyanp::blog:引数を参照とポインタのどちらで渡すか
ロベールのC++教室:第2部 - 第23章 同姓同名2
ロベールのC++教室:第2部 - 第23章 同姓同名3
C++ は以下のどちらの方法でも結果的にアドレス渡しになる。ただし、(2)は C++ のみの機能。
(1)仮引数は"*"を付けてポインタを指し、実引数は"&"を付けてアドレスを指す場合
(2)仮引数に"&"を付けて参照を指し、実引数は何も付けずに値を渡す場合
両者の違いはコピーコンストラクタがわかりやすい。アドレスのコピーなら(1)のコピーコンストラクタが、値のコピーなら(2)のコピーコンストラクタが呼ばれる。※コピーコンストラクタが未定義であれば値の複製が自動実行される。
const 付で渡した class は const メンバ関数しか呼び出すことができない。参照渡しは const で変更されないことを保証、ポインタ渡しは非 const で変更される可能性がある、とルールを決めたほうがいいかもしれない。
また、初期化と代入は別ものであるということにも注意をしたい。実体変数の場合は、代入ではコピーコンストラクタは作用しない。C++のクラスで記述と実行される処理は以下のようになる。変数宣言がコンストラクタ実行、代入がバイナリコピーというイメージが浮かび上がる。
class instance; → デフォルトコンストラクタ
class instance(other); → コピーコンストラクタ
※class instance = other; → コピーコンストラクタ
instance = other; → 代入演算子
なお、ポインタ変数の場合は、new で明示的にコンストラクタ実行またはコピーコンストラクタ実行を行い、delete で明示的にデストラクタ実行を行う。
関数の引数値や戻り値ではコピーコンストラクタが自動実行され、vector等のコンテナでも自動実行される。std::vector用にデフォルトコンストラクタとコピーコンストラクタ、配列用にデフォルトコンストラクタ、を定義しておく必要がある。コピーコンストラクタの定義では値の複製が自動実行されないように参照型変数を引数値とする。(値型変数では値の複製が自動実行されてしまう。)
引数が1つのコンストラクタは変換コンストラクタという機能に注意が必要で、explicitキーワードを付けで無効化すると良いが、コピーコンストラクタにはexplicitキーワードを付けてはいけない。
代入でも値の複製を自動実行させずにコピーコンストラクタを作用させるには、代入演算子のオーバーロードを定義する。代入演算子の定義では参照型変数を引数値と戻り値(戻り値は自己参照)とする。なお、コピーコンストラクタ、代入演算子のオーバーロード、いずれも、継承クラスでは基底クラスのものを明示的に呼び出す必要がある。
C++11 以降はコピーのほかにムーブというものも登場しておりコピーの例外安全にも関係しているようだ。
野良C++erの雑記帳:「 Copy して Swap 」 対 「 Copy して Move 代入」
ムーブ代入演算子をオーバロードした際に基底クラスのムーブ代入演算子を呼び出す書き方の例
class::operator=(std::move(other))
Effective C++ 総集編:コピーするときは、オブジェクトの全体をコピーしよう
<参考>
吉田誠一のホームページ:値渡しか、参照渡しか
プログラマーズ雑記帳:C++ のコピーコンストラクターと代入演算子
WisdomSoft(旧):C++入門 17. コピーコンストラクタ
satosystemsの日記:std::vector に入れる独自クラスにはデフォルトコンストラクタが必要
Programming Place Plus C++編【言語解説】:第19章 演算子オーバーロード
nyanp::blog:引数を参照とポインタのどちらで渡すか
ロベールのC++教室:第2部 - 第23章 同姓同名2
ロベールのC++教室:第2部 - 第23章 同姓同名3
コンピュータ上でいろいろ処理をするのに高校数学が役に立つのだが中には思い出せないのもあり、今回は点と直線の距離公式。
点と直線の距離公式はかなり情報が見つかるのだが、点から直線に向かって下した垂線の座標はまともなものはなかなか見つからない。一番頭にくるのはここから先を知りたかったら会員登録してねという流れのサイト。高校数学のような広くあまねく知っていていい情報を売り物にするんじゃねえ。
数学的にはベクトルで扱うのがラクなようだが、コンピュータ上で処理させるのにガチで座標で扱ってほしい。そんな中、有名私立中高のページで内容的にも発信元としても信頼のおける素晴らしい情報が見つかった。
海城中学高等学校:海城生に答えます~答えの一案~(PDF)
海城中学高等学校:海城生に聞きました~数学,ここがわからない~(PDF、26ページから)
(x→x0、PDF変換で出力が上手くいかなかっただけかもしれないし、容易に分かるものだから許せる)
点と直線の距離公式はかなり情報が見つかるのだが、点から直線に向かって下した垂線の座標はまともなものはなかなか見つからない。一番頭にくるのはここから先を知りたかったら会員登録してねという流れのサイト。高校数学のような広くあまねく知っていていい情報を売り物にするんじゃねえ。
数学的にはベクトルで扱うのがラクなようだが、コンピュータ上で処理させるのにガチで座標で扱ってほしい。そんな中、有名私立中高のページで内容的にも発信元としても信頼のおける素晴らしい情報が見つかった。
海城中学高等学校:海城生に答えます~答えの一案~(PDF)
海城中学高等学校:海城生に聞きました~数学,ここがわからない~(PDF、26ページから)
(x→x0、PDF変換で出力が上手くいかなかっただけかもしれないし、容易に分かるものだから許せる)
<C++やC#など、オブジェクト指向言語で、演算子、メソッド、どちらを使って比較するか>
演算子はオーバーロード、メソッドはオーバーライド、ということがポイント。
★演算子はオーバーロードなので、アップキャストすると基底クラスのものしか呼び出されない。
★メソッドはオーバーライドなので、アップキャストしてもスーパークラスのものが呼び出される。
.NET Tips (VB.NET,C#...):2つの値が等しいか調べる、等値演算子(==)とEqualsメソッドの違い
<ポリモーフィズム(特にC++)>
実現するならクラスはポインタ型で一択。
Theoride Technology:実践C++入門講座 第27回目 オジブェクト指向の3大特長の3つ目「動的ポリモーフィズム」-補足-
コピーコンストラクタは protected で定義し、仮想メンバ関数 clone() 等のみ使用可能とする。
オージス総研:オブジェクトの広場 C++ クラス設計に関するノート
格納には便利だが、継承クラスにはあるであろう独自のメソッドやフィールドへの対応は厄介がいろいろ。
negationの日記:C++でのポリモーフィズムと継承と、コード保守性
C++で実行コストを気にするなら、ダウンキャストが安全に行える確証を持てるようきちんと設計してstatic_cast、そうでなければdynamic_cast、といったところか。
Programming Place Plus:C++編【言語解説】 第31章 RTTI
<C++でポインタ型をalgorithmライブラリでソートや検索をするにはどうしたらよいか>
静的メソッドにおいて、参照型引数のままで値型をポインタ型に書き換える。
目指せプログラマー!:7章:STL
魂の記憶:【C++】独自に定義したクラス型ポインタを保有するlistのソート方法に関するメモ
なんとな~くしあわせ?の日記:vector<クラス>をソートしたいとき
minus9d's diary:C++で構造体をソートする4つの方法(おまけあり)
でも今日はSRMあるから:C++の関数オブジェクトが関数よりどれだけ速いか
オブジェクトの広場:C++ クラス設計に関するノート
演算子はオーバーロード、メソッドはオーバーライド、ということがポイント。
★演算子はオーバーロードなので、アップキャストすると基底クラスのものしか呼び出されない。
★メソッドはオーバーライドなので、アップキャストしてもスーパークラスのものが呼び出される。
.NET Tips (VB.NET,C#...):2つの値が等しいか調べる、等値演算子(==)とEqualsメソッドの違い
<ポリモーフィズム(特にC++)>
実現するならクラスはポインタ型で一択。
Theoride Technology:実践C++入門講座 第27回目 オジブェクト指向の3大特長の3つ目「動的ポリモーフィズム」-補足-
コピーコンストラクタは protected で定義し、仮想メンバ関数 clone() 等のみ使用可能とする。
オージス総研:オブジェクトの広場 C++ クラス設計に関するノート
格納には便利だが、継承クラスにはあるであろう独自のメソッドやフィールドへの対応は厄介がいろいろ。
negationの日記:C++でのポリモーフィズムと継承と、コード保守性
C++で実行コストを気にするなら、ダウンキャストが安全に行える確証を持てるようきちんと設計してstatic_cast、そうでなければdynamic_cast、といったところか。
Programming Place Plus:C++編【言語解説】 第31章 RTTI
<C++でポインタ型をalgorithmライブラリでソートや検索をするにはどうしたらよいか>
静的メソッドにおいて、参照型引数のままで値型をポインタ型に書き換える。
目指せプログラマー!:7章:STL
魂の記憶:【C++】独自に定義したクラス型ポインタを保有するlistのソート方法に関するメモ
なんとな~くしあわせ?の日記:vector<クラス>をソートしたいとき
minus9d's diary:C++で構造体をソートする4つの方法(おまけあり)
でも今日はSRMあるから:C++の関数オブジェクトが関数よりどれだけ速いか
オブジェクトの広場:C++ クラス設計に関するノート
Visual Studio で「in-class initializer のあるメンバーは const である必要があります」というエラーが出てしまい悩まされたが、クラスメンバのスタティック変数の初期化の書き方に問題があったようでした。
・staticメンバ変数はクラス宣言の外(ソースファイル)で初期化する。
・先頭に(const な場合はそれも含めて)型名を付ける。初期化子で記述も可能。
中の下の上の真ん中あたり:【C++】static constなメンバの初期化
Theoride Technology:実践C++入門講座 第28回目 staticメンバ、および、クラス外でメンバを定義する
秋山ブログ:C++で静的メンバ変数の配列を初期化する
・staticメンバ変数はクラス宣言の外(ソースファイル)で初期化する。
・先頭に(const な場合はそれも含めて)型名を付ける。初期化子で記述も可能。
中の下の上の真ん中あたり:【C++】static constなメンバの初期化
Theoride Technology:実践C++入門講座 第28回目 staticメンバ、および、クラス外でメンバを定義する
秋山ブログ:C++で静的メンバ変数の配列を初期化する