boost :: make_sharedを初めて使用して、共有ポインターが指すオブジェクトを作成しています。主な理由は、コードが遅すぎて、単一の割り当てがパフォーマンスの向上に本当に役立ったためです。
いくつかのメモリリークを「難しい手動の方法」で修正した後、アプリケーションの特定のポイントでまだ生きているオブジェクトを数えるためだけに、関連するすべてのクラスの新しい演算子をオーバーライドすることで、単純なメモリリーク検出器を実装することにしました。私はこれを数回実装しましたが、コードがオブジェクトを検出しなくなったことに驚きました。
make_sharedのブーストWebサイトのドキュメントから次の理由により、「通常の」演算子newではなく「placementnew」をオーバーライドするだけでよいと考えました。
"効果:タイプTのオブジェクトに適したメモリを割り当て、配置new式new(pv)T()またはnew(pv)T(std :: forward(args)...)を介してその中にオブジェクトを構築します。allocate_sharedのコピーを使用してメモリを割り当てます。例外がスローされた場合、効果はありません。」
ただし、新しい配置も呼び出されていません。動作を再現するための小さなテストプログラムを作成しました。
#include <iostream>
using namespace std;
#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"
class Test
{
public:
Test() { cout << "Test::Test()" << endl; }
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "Test new" << endl;
return malloc(size);
}
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw() {
cout << "Test non-throwing new" << endl;
return malloc(size);
}
void* operator new (std::size_t size, void* ptr) throw() {
cout << "Test non-throwing placement new" << endl;
return malloc(size);
}
};
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "Global new" << endl;
return malloc(size);
}
int main() {
cout << "..." << endl;
boost::shared_ptr<Test> t1(boost::make_shared<Test>());
cout << "..." << endl;
boost::shared_ptr<Test> t2(new Test());
cout << "..." << endl;
return 0;
}
これにより、次の出力がレンダリングされます。
...
Global new
Test::Test()
...
Test new
Test::Test()
Global new
...
出力の3行目に「新しい非スロー配置をテストする」と期待していました。行動はどうあるべきだと思いますか?make_sharedのドキュメントによると、配置を私のテストクラスの新しい演算子と呼ぶことに同意しますか?それとも私はそれを誤解しましたか?
もちろん、ブーストの実装をローカルにコピーして、配置の新しい演算子に呼び出しを追加することもできます。しかし、それは適切でしょうか、それとも新しい配置構文の意図されたセマンティクスに違反するのでしょうか?
あなたの時間とあなたの助けを前もって感謝します。