クラスコード自体の変更を最小限に抑えて、選択したいくつかのクラスのオブジェクトの削除を追跡したいと思います。
delete
演算子を(グローバルに)オーバーロードすることを検討しましたが、オーバーロードdelete
がすべてのコンパイルユニットに存在する必要があり、私の状況では面倒になる可能性があります。また、追跡対象オブジェクトの配列が作成された場合、delete[]
演算子をオーバーロードする必要がありますが、残念ながら、そのオーバーロードコード内で配列の長さ、および破棄されているオブジェクトの数を知る標準的な方法はありません。演算子をオーバーロードnew[]
して割り当てとその長さを追跡することもできますが、それはクリーンなソリューションのようには見えず、delete[]
演算子の同じ問題に悩まされています。つまり、すべてのコンパイルユニットでアクセスできる必要があります。
そこで、ターゲットクラスを少し変更することにしました。私の考えは、「ダミー」(場合によっては複数)の継承を使用して、ターゲットクラスの監視クラスのデストラクタを「注入」することです。もちろん、ターゲットクラスは別の子の子である可能性があるため、仮想継承の仕事のように見えます。これが私がこれまでに思いついたものです。
class track_death{
protected:
struct someusefulness{} info;
track_death(){}
explicit track_death(const track_death& o){
copy_info(o);
}
track_death& operator=(const track_death& o){
copy_info(o);
return *this;
}
void copy_info(const track_death& o){
//manage the copy of info, which is not trivial.
}
~track_death(){
//death has happened!
}
};
struct anyclass: virtual track_death{
//wathever 1...
};
struct anysubclass: public anyclass, virtual track_death{
//wathever 2...
anysubclass(){}
anysubclass(const anysubclass& copythis){
//initialization...
//the user MUST append this last
copy_info(copythis);
}
};
struct anysubsubclass: public anysubclass, virtual track_death{
//wathever 3...
anysubsubclass& operator=(const anysubsubclass& copythis){
//initialization...
//the user MUST append this last
copy_info(copythis);
return *this;
}
};
2つの質問があります。
これは仮想継承の良い使い方ですか?このパラシフトのアドバイスとは反対に、継承ツリーの最後のリーフに仮想キーワード(anysubsubclass
派生クラスがない定義を参照)を残すのは正しいですか?重要なのは、将来、下位の派生クラスをから追加するのか、たとえばベースと最後の派生クラスの間で削除するのかについては、できるだけ気にしないことです。anysubsubclass
anysubclass
2番。私のコードでわかるように、ターゲットクラスの1つにオーバーロードがあるか、コピーコンストラクターoperator=
がある場合、operator=
またはのコピーコンストラクターtrack_death
は呼び出されません。これは、track_death
コピーできないフィールドが含まれているため問題です。その些細なコピーコンストラクタで。私の解決策は、実装者に、コピーされるオブジェクトを使用してany*class
呼び出さなければならないことを伝えると、copy_info()
エラーが発生しやすくなります。より良い解決策はありますか?