placement newにおいて、コンストラクタとデストラクタを呼ぶ回数に疑問があります。
以下のコードで、base.~CBase()を明示的に呼ぶことで、コンストラクタとデストラクタを呼ぶ回数を合わせています。
base.~CBase()がない場合、コンストラクタは2回呼ばれますが、デストラクタは1回しか呼ばれません。
(そもそも、デストラクタで後処理を行う前に、その領域に対してplacement newを呼ぶことが好ましくない)
placement newで配置されたオブジェクトのデストラクタは、明示的に呼ばない限り、呼ばれません。
そのため、main関数を抜けて呼ばれるデストラクタは、placement newによって、すでに書き換えられたCBase base(3)が呼ぶデストラクタだと思います。
placement newで領域を書き換えているため、main関数を抜けて呼ばれるデストラクタが表示するメンバの値は、5です。
しかし、意図としては、new(&base) CBase(5)がデストラクタを呼ぶことを期待しているため、何か違和感を感じます。
参考サイト: ロベールのC++教室 - 第49章 破壊と創造 -
C++
1#include <iostream> 2#include <cstdio> 3 4class CBase { 5public: 6 CBase() = delete; 7 CBase(int data) : m_data(data) { 8 std::cout << "CBase::CBase(int data): " << m_data << std::endl; 9 } 10 virtual ~CBase() { 11 std::cout << "CBase::~CBase(): " << m_data << std::endl; 12 } 13 14 static void* operator new(std::size_t size, void* poolPointer) throw(){ 15 std::printf("CBase::operator placement new\n"); 16 return poolPointer; 17 } 18 static void operator delete(void* objectPointer, void* poolPointer) throw() { 19 std::printf("CBase::operator placement delete\n"); 20 } 21public: 22 int m_data; 23}; 24 25int main() { 26 CBase base(3); 27 base.~CBase(); 28 29 new(&base) CBase(5); 30}
また、以下のコードは、後処理を行うために、new(&base) CBase(5)の戻り値を使用して、明示的にデストラクタとplacement deleteを呼んでいます。
この場合、コンストラクタは2回呼ばれ、デストラクタは3回呼ばれます。
しかも、placement deleteが呼ばれた後に、デストラクタが呼ばれるため、違和感を感じます。
C++
1int main() { 2 CBase base(3); 3 base.~CBase(); 4 5 CBase* placementBase = new(&base) CBase(5); 6 placementBase->~CBase(); 7 CBase::operator delete(placementBase, &base); 8}
そもそも、ローカル変数のオブジェクトに対してplacement newを使用することが、非常に奇妙なことだと思いますが、それは前提としてください。
以上、宜しくお願い致します。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/02/21 09:39 編集