岐阜県美濃加茂市、可児市周辺で動物病院をお探しなら当院へ

美濃太田駅から徒歩圏内の動物病院です。

  • HOME
  • 院内・スタッフ紹介
  • 診療時間・アクセス
  • フォトギャラリー
家族みんないっしょに!げんきに!

院長のメモ帖

2016年6月18日 土曜日

C#プログラマへのC/C++の罠 その2継承修飾子?

最近はだいぶC++にも慣れ、変なエラーが出ることも少なくなりましたが、今日は久しぶりにやらかしました。
class Parent
{
 virtual void Method1();
}
class Child : Parent
{
 void Medhod1();
}
いわゆる、継承クラスを作ったわけですが、C++でもC#でもこの構文はだいたい同じですね。
C#では、常に修飾子overrideが子クラスのメソッドに必要ですが、C++の場合は抽象メソッドの実装時にだけ必要なのが違いますね。
まあ、そこも3分ぐらい手が止まりましたが、上記のC++コードにはもっと恐るべき罠が隠されていました。

C++プログラマーの方は、もう何が罠かお分かりかと思いますが、C#プログラマーにはその存在すら知られていない、継承修飾子というものが欠けているのです!
上記のChild定義ではこの継承修飾子を省略していますので、コンパイラはそれを補って
class Child : private Parent
{
 void Medhod1();
}
と解釈します。

するとどういうことが起こるかというと、親クラスの全メンバーのアクセス修飾子をprivateとして継承してしまいます。
となると、このChildクラスは親クラスからpublicメソッドを継承しても、外部からは呼び出せないprivateメソッドに変換してしまうので、外から見ると実質何も継承していないように見え、継承を前提としたコードはすべてエラー化してしまいます。

ですから、上記のコードは
class Child : public Parent
{
void Medhod1();
}
とpublic継承修飾子を書かなければならなかったのです。

いやー、継承修飾子にたどり着くまで、C++の継承解説ホームページを4つぐらい参照しましたよ。
このページにたどり着いて疑問が解消しました。継承修飾子について詳しく知りたい方は参照してください。
使わない機能なので解説してないんでしょうが、あるからには解説しておかないと、言語解説ページとしては失格ですね(<=他人に罪をなすりつけるな)。

以前、C++プログラマーの友人と話をしていて、彼はC->C++->C#の順に習得したので、C++からC#には非常にすんなり入れたといってました。
僕は、C->C#->C++の順なんですが、どうもこの道順には、いっぱいブービートラップが潜んでいるようです。

投稿者 こんどう動物病院