コンストラクターまたはDesturctorで仮想機能を呼び出すのを防ぐ方法は?
質問
一部のC ++資料は、CTORまたはDTOR内の仮想関数を呼び出すことができないことを言及しています、
(
申し訳ありませんが、変更する方が良いと思います
一部のC ++資料は、CTORまたはDTOR内の仮想関数を呼び出さないことをお勧めします。
)
しかし、私たちはそれらを偶然に呼ぶかもしれません。それを防ぐ方法はありますか?
例えば:
# include < iostream >
using namespace std;
class CAT
{
public:
CAT(){ f();}
virtual void f(){cout<<"void CAT:f()"<<std::endl;}
};
class SMALLCAT :public CAT
{
public:
SMALLCAT():CAT()
{
}
void f(){cout<<"void SMALLCAT:f()"<<std::endl;}
};
int main()
{
SMALLCAT sc;
}
出力:
void CAT::f() //not we expected!!!
ありがとう
正しい解決策はありません
他のヒント
これらの「C ++材料」をゴミ箱に投げる必要があります。
あなたは確かに できる コンストラクターまたはデストラクタから仮想関数を呼び出します。そして、彼らは仕事をします。仮想ディスパッチメカニズムがに従って機能することを明確に述べている言語仕様に注意する必要があります 現在 オブジェクトの動的タイプは、そのものではありません 最後の 意図された動的タイプ。これらのタイプは、建設/破壊下のオブジェクトでは同じではありません。これは、コンストラクター/デストラクタから仮想関数を呼び出すときに初心者を混乱させることがよくあります。それにもかかわらず、ConstructorとDestructorから仮想関数を呼び出すことは、言語の有用な機能と、そのような場合にそれらがどのように機能するかを知っている限り、言語の有用な機能です。なぜあなたはそれを「防止」したいのですか?
ゼロで何かを分割できるため、ディビジョンオペレーターは危険であると言って、プログラムでの使用を「防ぐ」方法を尋ねることができるようなものです。
デストラクタ内の仮想関数を呼び出すことができます。特定の場合にのみ、機能しなくなり、プログラムをクラッシュさせる可能性があります。それらを呼び出すことを避ける方法は、それらを呼ばないことです。あなたのコードを見て、このような潜在的な問題を警告するためのいくつかの静的分析ツール以外に、私が知っているより空想的なことは何もありません。
確かに、CTOR/DTOR内の仮想関数を呼び出すことができます。問題は、Vtableが各コンストラクター(およびDestructor)に設定されているため、仮想関数呼び出しが現在設定されているクラスの実装を呼び出すことです。それがあなたが望むものなら、かっこいい。ただし、Vtable Lookupを保存して、スコープされた関数呼び出しを実行することもできます。