プレースメントnewについて

アバター
tk-xleader
記事: 158
登録日時: 14年前
連絡を取る:

プレースメントnewについて

投稿記事 by tk-xleader » 13年前

C言語掲示板のトピック「メンバ変数のconst」で、プレースメントnewの話が出ていたから、ちょっとそれについて調べてみました。

プレースメントnewは、端的に言うと、「既に確保してある領域に対してコンストラクタを呼んでオブジェクトを作るnew演算子」です。どういうことかというと、普通のnew演算子がメモリ領域の確保を行ってからそこにオブジェクトを生成するのに対して、プレースメントnewはメモリ確保はしないということですね。
参考ページ「programing place C++編(言語解説)第36章 placement new

ところで、ローカル変数だってメモリ領域なのですから、そこにプレースメントnewをすることも可能なはずですよね?
ところが、件のトピックでISLeさんが述べているように、何も考えずにそんなことをすると、オブジェクトに不整合が生じてしまいます。

そこで、実験してみました。テストコードは以下です。

CODE:

#include
#include

class CSample{
public:
	CSample() : num(0){
		std::cout
#include

class CSample{
public:
	CSample() : num(0){
		std::cout<<"constructor without any parameter"<<std::endl;
	}
	CSample(int num_) : num(num_){
		std::cout<<"contructor with one parameter"<<std::endl;
	}
	~CSample(){
		std::cout<<"destructor"<<std::endl;
	}
	int getNum()const{
		return num;
	}
private:
	int num;
};

int main(){
	CSample sample;
	std::cout << sample.getNum()<<std::endl;
	sample.~CSample // ←ここでデストラクタを明示的に呼び出す。
	new(&sample)CSample(100);
	std::cout << sample.getNum()<<std::endl;
}
すると、実行結果はこうなります。
codepadでの実行結果
constructor without any parameter
0
destructor
contructor with one parameter
100
destructor

というわけで、コンストラクタとデストラクタの対応は何とかなりました。とはいっても、普通はローカル変数をプレースメントnewで作り直す必要はないですよ。
最後に編集したユーザー tk-xleader on 2016年3月23日(水) 19:28 [ 編集 3 回目 ]

コメントはまだありません。