なぜランタイムポリモーフィズムはコンパイル時に解決できないのか?
疑問点
考えてみてください。
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() { cout<<" In Base \n"; }
};
class Derived: public Base
{
public:
void show() { cout<<"In Derived \n"; }
};
int main(void)
{
Base *bp = new Derived;
bp->show(); // RUN-TIME POLYMORPHISM
return 0;
}
なぜこのコードはランタイムポリモーフィズムを引き起こし、なぜコンパイル時に解決できないのでしょうか?
どのように解決するのですか?
なぜなら、一般的な場合、それは 不可能 であり、実行時にどのような型になるかを決定することはできません。 あなたの例はコンパイル時に解決できますが (@Quentin による回答を参照)、そうでないケースも構築できます、たとえば。
Base *bp;
if (rand() % 10 < 5)
bp = new Derived;
else
bp = new Base;
bp->show(); // only known at run time
EDIT: @nwpのおかげで、もっといいケースがあります。 以下のようなものです。
Base *bp;
char c;
std::cin >> c;
if (c == 'd')
bp = new Derived;
else
bp = new Base;
bp->show(); // only known at run time
また チューリングの証明 によって、以下のことが示される。 一般的な場合 C++ コンパイラが実行時にベースクラスのポインタが何を指しているかを知ることは、数学的に不可能です。
C++コンパイラのような関数があると仮定します。
bool bp_points_to_base(const string& program_file);
これは、入力として
program_file
の名前を入力します。
任意の
C++のソースコードのテキストファイルで、ポインタ
bp
(を呼び出す(OPのように)。
virtual
メンバー関数
show()
. そして、以下のように決定することができます。
を一般的なケースで
(シーケンスポイント
A
が存在する場合
virtual
メンバー関数
show()
が最初に呼び出されるのは
bp
): ポインタ
bp
のインスタンスを指しているかどうか。
Base
を指すかどうか。
C++プログラム "q.cpp"の次の断片を考えてみましょう。
Base *bp;
if (bp_points_to_base("q.cpp")) // invokes bp_points_to_base on itself
bp = new Derived;
else
bp = new Base;
bp->show(); // sequence point A
では、もし
bp_points_to_base
は、"q.cpp"で、そのことを判断します。
bp
のインスタンスを指しています。
Base
で
A
で、"q.cpp" のポイント。
bp
にある他の何かに
A
. そして、"q.cpp"でそう判断された場合。
bp
のインスタンスを指していない。
Base
で
A
であれば、"q.cpp" のポイントは
bp
のインスタンスに
Base
で
A
. これは矛盾しています。 つまり、最初の仮定は間違っているのです。 そこで
bp_points_to_base
は書けません。
一般的な場合
.
関連
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
-
[解決済み】派生クラスでオーバーライドされた関数が、ベースクラスの他のオーバーロードを隠してしまうのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン