Geri Döndürme Bir String sınıfı MyString
(evet, ödev olarak) yazıyorum ve bir unique_ptr<char[]>
(ve Vector
değil) döndüren bir toCString
yöntemi sunmak zorundayım. Ne yazık ki, işaretçiyi arayan kişiye döndürürken başarısız olurum: Sonuç her zaman yanlış içerikle doldurulur - yığınta işaretçiyi ve/veya karakter dizisini oluşturduğum anlaşılıyor. Hata ayıklama yaparken, her zaman beklenen davranışı alırım. Sorunlar sadece arayanlar sitesinde gerçekleşir. Benim hatam nerede?Eşsiz bir ptr
cevap
ama bu sorunu çözmez. İstemci tarafında sorun oluşuyor çünkü c-dizgisini null olarak sonlandırmıyorsunuz.
Ne tür m_string olduğunu bilmiyorum, bu yüzden bir an için bir std :: string olduğunu varsayalım. Sen gerçek yöntemleri kendini çevirebilir: Christophe'un öneri gereğince
std::unique_ptr<char[]> MyString::toCString() const
{
// get length (in chars) of string
auto nof_chars = m_string.size();
// allocate that many chars +1 for the null terminator.
auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};
// efficiently copy the data - compiler will replace memcpy
// with an ultra-fast sequence of instructions in release build
memcpy(cString.get(), m_string.data(), nof_chars * sizeof(char));
// don't forget to null terminate!!
cString[nof_chars] = '\0';
// now allow RVO to return our unique_ptr
return cString;
}
, burada yine, std :: copy_n açısından yazılı bir yöntem. Std :: copy [_xxx] işlev grubunun hepsinin son yazılanı geçtiği bir yineleyici döndürdüğünü unutmayın. Boş sonlandırıcının yerini yeniden derlemek için kullanabiliriz. Standart kütüphane harika değil mi?
std::unique_ptr<char[]> MyString::toCString() const
{
// get length (in chars) of string
auto nof_chars = m_string.size();
// allocate that many chars +1 for the null terminator.
auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};
// efficiently copy the data - and don't forget to null terminate
*std::copy_n(m_string.data(), nof_chars, cString.get()) = '\0';
// now allow RVO to return our unique_ptr
return cString;
}
Görünüşte, nesne 'm_string', 'm_start' ve' m_len'’in bir alt dizesini temsil eder. Ancak alan yaratma ve NUL terminatörü ekleme konusunda kesinlikle haklısınız. –
[eski 'memcpy()' işlevinin 'std :: copy()' veya 'std :: copy_n()'] ile değiştirilmesi anlamlı olmaz mıydı (http://stackoverflow.com/questions/4707012/kullanması daha iyi-stdmemcpy-veya-stdcopy-in-terms-to-performance)? – Christophe
@Christophe, daha akılcı olacaktı. –
Yaptığınız gibi bir unique_ptr'ye başvuru oluşturmayın. Hareket yapıcı herşeyi ilgilenir: Bunun yerine, doğrudan unique_ptr dönmek Ben kabul edilen bir yanıt zaten orada bkz
return unique_ptr<char[], default_delete<char[]>>(characters);
Ayrıca C++ derleyicinin C++ 11'i desteklediğinden ve etkinleştirdiğinden emin olun. –
@NathanielJohnson elbette! Öte yandan, eğer 'unique_ptr' kullanır ve kullanımdan kaldırılmış 'auto_ptr' kullanırsa ve dahası onunla bazı kodları derlerse, C++ 11'in verildiğini varsayabilirim ;-) – Christophe
ne demek istediniz? Dönüş Değeri Optimizasyonu her şeyle ilgilenecektir ". Değerin verimli bir şekilde geri dönmesi, bir hareket ettiriciye bile gerek duymaz. –
ve şimdi
unique_ptr<char[]> cString = unique_ptr<char[]>{new char[m_len]};
İlk gelişme kullanıyor: auto kullanmak
auto cString = unique_ptr<char[]>{new char[m_len]};
İkinci gelişme: Etiketinizde, C + 11 ama eğer C + 14'ü kullanıyorsunuz, daha sonra 'u şu şekilde kullanın:
auto cString = std::make_unique<char[]>(m_len);
Ayrıca Scott Meyers'in dediği gibi C + 11'i kullanıyorsanız, make_unique
işlevini kendiniz yazmanız yeterli. Bu zor değil ve çok kullanışlı.
template<class T, class... Types>
inline auto make_unique(Types&&... Args) -> typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
{
return (std::unique_ptr<T>(new T(std::forward<Types>(Args)...)));
}
template<class T>
inline auto make_unique(size_t Size) -> typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, std::unique_ptr<T>>::type
{
return (std::unique_ptr<T>(new typename std::remove_extent<T>::type[Size]()));
}
- 1. "(void)! Ptr" nedir?
- 2. Android eşsiz anahtar
- 3. Normal İfade eşsiz sonuç
- 4. mongodb: o eşsiz öğeleri
- 5. Update_or_create alışkanlık saygı eşsiz anahtar
- 6. Asp.net Kimlik 2.0 - Eşsiz Email
- 7. laravel nasıl eşsiz sütununu kaldırabilirsiniz
- 8. bash: Eşsiz tutarak, dosya adları kesecek
- 9. AngularJS Eşsiz Kimlik olmadan Serileştirilmiş Form Girdileri
- 10. Eşsiz Fatura numaraları Django Modelleri için Görünümler
- 11. Yakut Sorgusu'ndan eşsiz ülke Takip edilenler
- 12. Eşsiz tüm URL'leri Express ile nasıl yönlendiririm?
- 13. Kriterler API ve eşsiz sonuçlar tüm satırlarla
- 14. nasıl Ek açıklamalar, eşsiz zorunlu bağımsız değişkenle bir kurucuya sahip
- 15. dplyr ile grubu ile eşsiz gözlemlerinin bir düzenin oluşturma ve
- 16. Modül HANDLE func ptr Win32 dosyasından nasıl edinilir?
- 17. gdb print ptr ile karıştırılır ve baskı "% s"
- 18. Çözülemeyen adı hatası std kullanırken :: Ben <code>ptr::set_memory</code><a href="http://smallcultfollowing.com/rust-int-variations/imem-umem/std/ptr/fn.set_memory.html" rel="nofollow">the std module</a> itibaren kullanıyorum ptr :: set_memory
- 19. Angularjs - Eşsiz girişler nasıl kontrol edilir ve eğer geçersiz
- 20. Eşsiz değerler ile Guava ile harita inversiyonu nasıl yapılır?
- 21. Eşsiz "association_type" ve "association_id" olmayan raylarda polimorfik tablo nasıl indekslenir?
- 22. DBIx :: Sınıf :: ResultSet Güncelleme veya birden fazla eşsiz kısıtlamaları
- 23. Güney: Eşsiz ve null olmayan bir sütun için bir geçişi çalıştırma
- 24. nasıl Android için ormlite kullanıyorum ve bir çok kolonlu eşsiz-kısıtlamayı almaya çalışıyorum
- 25. pylibmc: 'Assertion' ptr-> query_id == query_id +1 "işlev için başarısız" memcached_get_by_key "'
- 26. Bu parametre yanlış. MS.Internal.XcpImports.MethodEx de (ıntptr ptr, dize adı, CValue [] CVData) WP7 üzerinde
- 27. mümkün mü (renk uyumlu BW eşsiz,) ben şimdiki eğilimi gibi 2 grup eşleşen istatistikler skor olacaktır
- 28. Symfony/TWIG: Eşsiz kimliğe sahip form için özel tema ayarlanamıyor (createNamedBuilder)
- 29. Neden dolu bir alana bir başvuru döndüremiyorum?
- 30. Türetilmiş bir sınıf nasıl yapılır?
Neden akıllı işaretçi geri dönüyor? _C_ dize, "char" (ve bir diziye değil) için yalnızca bir işaretçidir – ForceBru
'unique_ptr (karakterler)' Bu bir anlam ifade etmez ve derlemez. Gerçek kodunuzu gösterin. –
Akıllı göstergeyi yığında referans olarak ayırıyorsunuz, ardından işlevden çıkıyorsunuz. Bu davranış doğru görünse bile tahmin edilemez davranışlar üretecektir. http://stackoverflow.com/questions/10643563/how-to-return-smart-pointers-shared-ptr-by-reference-or-by-value –