私は配置新しい呼び出しは、通常、デストラクタへの明示的な呼び出しと一致することを理解します。デストラクタ(コードを記述する必要がなく、デストラクタを持つメンバ変数)が必要ない場合、明示的なデストラクタ呼び出しを安全にスキップできますか?
はい。この回答を投稿する前にニューヨークに飛ぶ必要がない場合は、安全に旅行をスキップできますか? :)しかし、デストラクタが何もしないので本当に不要な場合は、それを呼び出す際にどんな害がありますか?
コンパイラがデストラクタがノーオペレーションでなければならないことがわかった場合、私はその呼び出しを排除することを期待しています。明示的なdtorを書いていないなら、あなたのクラスはまだdtorを持っていることを覚えておいてください。ここで興味深いのは、言語が些細なものかどうかです。
解決策:dtorがノーオペレーションであると思われる場合でも、それらの上に構築する前に、以前に構築されたオブジェクトを破壊してください。
C API用のC++バインディングを書きたいと思います。 C APIでは、多くのオブジェクトはポインタでしかアクセスできません。単一のポインタを含むラッパーオブジェクトを作成する代わりに(無駄で意味的に混乱します)。私はCオブジェクトのアドレスにオブジェクトを構築するために新しい配置を使用したいと思います。
これはレイアウト互換クラスとreinterpret_castの目的です。短い正気確認のために、静的なアサート(例えば、ブーストのマクロ、0x static_assertなど)とサイズやアラインメントをチェックしてください。しかし、最終的には実装がクラスをどのようにレイアウトするかを知る必要があります。ほとんどの場合、必要に応じてプラグマ(または他の実装固有のメカニズム)を使用してこれを制御します。
// in C header
typedef struct {
int n;
//...
} C_A;
C_A* C_get_a();
// your C++
struct A {
void blah(int n) {
_data.num += n;
}
// convenience functions
static A* from(C_A *p) {
return reinterpret_cast<A*>(p);
}
static A const* from(C_A const *p) {
return reinterpret_cast<A const*>(p);
}
private:
C_A _data; // the only data member
};
void example() {
A *p = A::from(C_get_a());
p->blah(42);
}
私はむしろ全体reinterpret_castsをstrewingよりも、カプセル化されたこのような変換を維持したい、より:
最も簡単な方法は、C++型内でCの構造体を含むことがあります(つまり、constとnon-constのcall-siteを比較する)、したがって便利な機能です。このタイプの使用がまだサポートされている必要があることに気づかずに、クラスを変更するのはもう少し難しいです。
正確なクラスによっては、データメンバーを公開することもできます。
あなたは実際にコードでデストラクタを実際に呼び出すことを意味しますか?あなたは(ほとんど)決してそれをするべきではありません。 – Falmarri
新しいプレースメントは、あなたがそうしているまれな時の1つです。 –
@ジョシュ:私は問題を理解しているとは思わない。なぜCオブジェクトをC++オブジェクトの唯一のデータメンバとしていないのでしょうか?次に、メンバー関数で、そのメンバーへのポインターを、委任先のC API関数に渡します。 –