【電子工作番外編】Z-3.C++番外編 override指定子とは・・
こんばんわ。
SAIです。
最近質問されてSAIが全く知らなかったもの
override指定子
コード上に記載されていて、
どのような役割なのか質問されました。
class Test:public TestBase
{
public:
void hogehoge()override;
};
質問者:これはなぜ必要ですか?
・・・・
はっ?
なにこれ?
関数の後ろに・・・
const ではなく override?
2012年春までC++開発者だったSAIですが、
全く知りませんでした。
#割と巨大なシステムで、実質作業していたのは2011年春まで。
#以降は保守してたんで、経験はそこそこあるはずなのですが・・・
もっと偉い人に聞いてみたところ、
どうやら、子クラス側で、
オーバーライドした関数だよ!
という、明言をすることができる指定子だったらしいです。
どのように使うのか?
知らないので調べてみました。
※最初、overrideで検索しても全然Hitしなくて困ったのですが、
override指定子 で検索すると、Hitしました!
どうやら、
overrideを書いていると、継承した関数につければ、
継承に失敗したときにエラーをはいてくれるようです。
つまり、ベースクラスがこんなだった時に
class TestBase
{
public:
void hogehoge(); //virtualではない
virtual void hogehoge(int aParam); //引数がint1つ
};
派生クラスで以下のような関数を定義した際、
class Test:public TestBase
{
public:
//①親がvirtualではないので再定義になりoverride不成立
void hogehoge() override;
//②引数がdouble = オーバーロード扱いになるのでoverride不成立
void hogehoge(double aParam) override;
//③引数がint2つ = オーバーロード扱いになるのでoverride不成立
void hogehoge(int aParam, int aParam) override;
};
この状況下でビルドすると、
◆overrideを書いていない場合
コメントで記載した通り、オーバーライドできず、
すべて派生クラス固有の関数として定義されてしまいます。
ビルドすると、意図せず別関数になっちゃう可能性があるということですね。
※エラーは出ません!
◆overrideを書いた場合
overrideとして紐づける基底クラスの関数を探しに行く模様。
もし、基底クラスにvirtualの関数がない場合・・・
ビルドエラーになります。
こんなイメージですかね?
さて、ビルドするとどうでしょうか?
Arduinoで試してみました。↓
紐づける基底クラスのvirtual関数がないというエラーですね!
素敵!
これ、知ってたら絶対使ってたと思う!
以前、とある方が修正した後、特定の処理の時のみ画面遷移が崩れたことがありました。
この時、とある関数に引数を追加したかったらしく、、、
オーバーライドしている関数に引数を追加しちゃったんですよね。
その瞬間、別の関数になってしまいます。
もちろんビルドエラーなんて出ません。
別関数として宣言されて
特定の動作の時は親クラスの関数が呼び出されるようになっちゃったという落ちでした。
しかし、なんでこんな都合の良い指定子を知らなかったんだろう。。
おもむろにHEW起動・・・
はい、
ビルドエラーです。
もしかしてと思い、いろいろ調べてみたんですが、
↓ここのwikiにヒントがありました。
C++においてもC++11でoverride
修飾子が導入されたが、
override
修飾子の指定はオプションであり必須ではない。
なるほど。
SAIが見たことないわけです。
とっても勉強になりました!
他人のコードを見るのって、勉強になって楽しいね!
※今回は、Z-2のコードにoverride
を追記しただけなので、サンプルコードはなしです。
雑談
色々調べていると、
そして、同様に関数の後ろに記載する指定子として、
うーん・・
override に final
そういえばどこかで見たことがあるような気がしてきました。
何だっけ・・・・
ほかにSAIがオブジェクト指向で使ったことある言語といえば、
あっ! Javaだ!
Javaは、オーバーライドするためには
@override
がありました!
そういえば変数とかも変更されたくないときには
@final
ですね。
SAIが使っていたのは、
お遊びとテストアプリを作っていた
docomoのiアプリのDoja4.0とか
Javaで遊んだことがあるという理由だけで
急遽バグ解析+コードチェックやってくれと言われた
android1.6です。悪名高いIS01です。。
世間でボロカスに言われた、
その後、android2.0でアプリ作ってくれと言われて、
これ以上、組み込みJavaにかかわりたくないと思った記憶があります。
Javaなんてメモリ管理もできないの
ガベージコレクション任せ
組み込みには向いていないと思うのです。
懐かしいなぁ・・・