class base {
int a;
protected:
template<class T>
class derived;
public:
base() {}
virtual ~base() {}
virtual void func() {}
static base* maker();
};
template <class T>
class base::derived
: public base
{
public:
derived() {}
virtual ~derived() {}
virtual void func() {
this->~derived(); //<--is this legal?
new (this) derived<int>(); //<--is this legal?
}
};
base* base::maker() {
return new derived<double>();
}
int main() {
base* p = base::maker(); //p is derivedA<double>
p->func(); //p is now derivedA<int>
delete p; //is the compiler allowed to call ~derived<double>()?
}
これは、短く、自己完結型で、正しい(コンパイル可能)、私のコードの例です(これは基本的any_iterator
に私自身の成長のために再発明されています)。
質問は次のようになります。共有ベース上に追加のメンバーがない場合に、同じベースから仮想的に派生した別のタイプで破棄this
および再構築するのは未定義の動作ですか?this
具体的には、コンパイラーは静的型を追跡する呼び出しを許可されていますか、それとも技術的に不適合ですか?
derivedA
[編集]スタック上に作成された場合、コンパイラが誤ったデストラクタを呼び出す可能性があることを指摘する人もいます。(1)コンパイラがそうすることを可能にする標準には何も見つかりません。(2)それは私の質問で意図したこととは別に、スタックに配置 derived
できないことを示すようにコードを変更しました。base
ただし、スタックに残すことはできます。