私はデバッガであなたと同じことを見ています。私は確かにわからないが、私はものがインラインになっていると思う。 basic_string
のデストラクタは非常に小さいです。小さな文字列の最適化のための単一のテスト、そしてアロケータのdeallocate
関数への呼び出し(allocate_traits
を介して)。 std::allocator
のallocate関数も非常に小さく、ちょうどoperator delete
のラッパーです。
あなた自身のアロケータを書くことでこれをテストすることができます。 (後で:下記を参照)
この質問を調べている間に私が生成したその他のもの;あなたが興味を持っているならば読んでください。
[注:あなたのコードにバグがあります - あなたが書いた2行目に:? - mystr1
宣言ですmystr1.begin(),mystr.end())
]:
それはタイプミスだと仮定すると、私はいくつかのわずかに異なるコードを試してみました
を
#include <string>
#include <new>
#include <iostream>
int news = 0;
int dels = 0;
void * operator new (size_t len) throw (std::bad_alloc)
{
void * mem = malloc(len);
if ((mem == 0) && (len != 0))
throw std::bad_alloc();
++news;
return mem;
}
void operator delete (void * ptr) throw()
{
++dels;
if (ptr != 0)
free(ptr);
}
int main(int argc, const char * argv[])
{
{
std::string mystr("testing very very very big string for string class");
std::string mystr2(mystr.begin(),mystr.end());
std::cout << "News = " << news << "; Dels = " << dels << std::endl;
}
std::cout << "News = " << news << "; Dels = " << dels << std::endl;
}
あなたはこのコードを実行した場合、それは(少なくとも私にとっては)出力します。
News = 2; Dels = 0
News = 2; Dels = 2
それはまさにそれが必要なものです。
コードをcompiler explorerに送信すると、私は期待通りにbasic_string::~basic_string()
への両方の呼び出しを表示します。 (まあ、私は3つのを参照してくださいが、そのうちの1つは例外処理ブロックにあり、これは_Unwind_resume
への呼び出しで終了します)。その後
- このコード:
#include <string>
#include <new>
#include <iostream>
int news = 0;
int dels = 0;
template <class T>
class MyAllocator
{
public:
typedef T value_type;
MyAllocator() noexcept {}
template <class U>
MyAllocator(MyAllocator<U>) noexcept {}
T* allocate(std::size_t n)
{
++news;
return static_cast<T*>(::operator new(n*sizeof(T)));
}
void deallocate(T* p, std::size_t)
{
++dels;
return ::operator delete(static_cast<void*>(p));
}
friend bool operator==(MyAllocator, MyAllocator) {return true;}
friend bool operator!=(MyAllocator, MyAllocator) {return false;}
};
int main(int argc, const char * argv[])
{
{
typedef std::basic_string<char, std::char_traits<char>, MyAllocator<char>> S;
S mystr("testing very very very big string for string class");
S mystr2(mystr.begin(),mystr.end());
std::cout << "Allocator News = " << news << "; Allocator Dels = " << dels << std::endl;
}
std::cout << "Allocator News = " << news << "; Allocator Dels = " << dels << std::endl;
}
プリント:
Allocator News = 2; Allocator Dels = 0
Allocator News = 2; Allocator Dels = 2
アロケータが呼び出さなっていることを確認。
最適化を有効にしましたか?デストラクタが呼ばれているのはなぜ理想的なのですか?デストラクタの観察可能な唯一の効果は削除呼び出しであるため、これはas-ifルールによって許可されます。 – user2079303
私は最適化を有効にしていません。basic_stringについては、アセンブリコードからoperator newを呼び出しますが、2番目の文字列作成の場合はallocatorを使用し、allocateメソッドでnew演算子を呼び出します。 basic_stringクラスのデストラクタを見ることもできますし、アロケータを使って文字列を作成した場合の破壊時に呼び出されるように書かれていると感じるコードを調べることもできます。 –