SORU
2 ŞUBAT 2014, Pazar


C 11 ile yeniden düzenleme

Yeni araç programcı c çok, kod basitleştirilmesi, ifade gücü, verimliliği amaçlayan tarafından sağlandı, eski kod ile yağsız ve ince ayarlar (bazı) anlamsız, bazı başarılı hedeflerine ulaşmak için yapmak. Bu tür uğraşları çok gevşek ve sadece sigara müdahaleci ve müstakil bir değişiklik yapmamaya gayret ederken, en iyi uygulamalar nelerdir?

Bana bariz Haç edelim :

  • Kullanınotoyineleyici temelli döngüler çalıştırmak için :

    for (std::vector<foo>::const_iterator it(lala.begin()), ite(lala.end()); it != ite;     
      it);
    // becomes
    for (auto it(lala.cbegin()), ite(lala.cend()); it != ite;   it);
    
  • KullanınkravatC-stil satır kod üretmek atamaları ( how to assign multiple values into a struct at once? )

    a = 1;
    b = 2; 
    c = 3;
    d = 4; 
    e = 5;
    // becomes
    std::tie(a, b, c, d, e) = std::make_tuple(1, 2, 3, 4, 5);
    
  • Sınıfı olmayan bir teoriye sadece "son" ve bu tür bir davranış elde kodu http://www.parashift.com/c -faq/final-classes.html sil . olarak ilan yapmak

  • Delete anahtar açıkça onlara özel (nesne, olmayan copyable vb nesneler yığını oluşturmak için örnek kod) ilan etmek yerine yapıcılar/yıkıcılar gizlemek için kullanın

  • İçine önemsiz funktorlar sadece tek bir STL algoritmaları yürütme facillitate için oluşturulan çevirinlambdafonksiyonları (kod yığılan azaltılması dışında inlined aramalar garantili olacak)

  • Sadece kullanarak bir nesnenin DEMİRYOLU sarma basitleştirmekakıllı işaretçi

  • Bind1st, bind2nd ve Kurtulbağlama

  • El değiştirmek tip özellikleri için yazılmış kod (İs_ptr_but_dont_call_for_const_ptrs&;>lt ve böyle :) ) standart kod ile tarafından sağlanmıştır< type_traits >

  • Başlıkları artırmak da dahil olmak üzere işlevsel, şimdi STL (BOOST_STATİC_ASSERT vs static_assert) implented için durdurmak

  • Sınıflar için hareket semantiği bu kirli/hızlı/kolay bir değişim olarak nitelemek olmaz rağmen) bulunur

  • Kullanınnullptrmümkünse BOŞ makro ve kod kurtulmak yerine 0 ile göstericiler konteyner dolu nesne türü için döküm

    std::vector<foo*> f(23);
    for (std::size_t i(0); i < 23;   i)
    { f[i] = static_cast<foo*>(0); }
    // becomes
    std::vector<foo*> f(23, nullptr);
    
  • Temiz vektör verileri sözdizimi erişiyor

    std::vector<int> vec;
    &vec[0];    // access data as a C-style array
    vec.data(); // new way of saying the above
    
  • At Replace() ilenoexcept(itiraz istisnası specifiation kaçınarak dışında bazı hız faydaları http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler @ 00.29.42 olsun)

    void some_func() noexcept; // more  optimization options
    void some_func() throw();  // fewer optimization options
    void some_func() ;         // fewer optimization options
    
  • Bir kap içinde bir tempory itmek istediğiniz kodu değiştirin ve iyileştirici kopya çekip, bir ellide umuyordu< . "" . emplace ^güçlü mükemmel bir argüman ileri ve doğrudan oluşturmak için kullanılabilir nerede işlevi, bir geçici olmayan bir kabın içine tüm nesne.

    vecOfPoints.push_back(Point(x,y,z)); // so '03
    vecOfPoints.emplace_back(x, y, z);   // no copy or move operations performed
    

GÜNCELLEME

The answer by Shafik Yaghmour haklı olarak seyirciler tarafından büyük kabul olması için ödül verildi.

The answer by R Sahu kabul ettim çünkü benim bir tane oldukombinasyonuyakalar spirit of refactoring öneriyor özellikleri : kod yapmak daha net ve daha temiz ve daha basit ve zarif.

CEVAP
3 ŞUBAT 2014, PAZARTESİ


1. Rand yerine

C 11 büyük kazanımlar bir bütün seçenekleri random header mevcut rand() kullanılması, değiştirilmesi gerekir. Birçok durumda rand() yerine yalındır olmalıdır.

T. Lavavej Stephanmuhtemelen bu yapılan sunumu rand() Considered Harmful ile güçlü noktası. Örnekler [0,10] üniforma tam sayı dağılımı rand() kullanarak göster:

#include <cstdlib>
#include <iostream>
#include <ctime>

int main() 
{
    srand(time(0)) ;

    for (int n = 0; n < 10;   n)
    {
            std::cout << (rand() / (RAND_MAX / (10   1)   1)) << ", " ;
    }
    std::cout << std::endl ;
}

std::uniform_int_distrubution kullanarak:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());
    std::uniform_int_distribution<> dist(0, 10);

    for (int n = 0; n < 10;   n) {
        std::cout << dist(e2) << ", " ;
    }
    std::cout << std::endl ;
}

Bununla birlikte çaba iyi olan std::shuffle 43 *hareketli olmalıdır Deprecate rand and Friends. Bu son zamanlarda bu KADAR soru Why are std::shuffle methods being deprecated in C 14? kaplanmıştı.

Dağılımları consistent across platforms garanti edilmez unutmayın.

2. Std::to_string kullanarak yerine std::ostringstream veya sprintf

C 11 eşdeğer std::sprintf gibi içerik üretecektir std::string rakamsal dönüştürmek için kullanılabilir std::to_string sağlar. Büyük ihtimalle bu std::ostringstream ya snprintf ya yerine kullanılacak. Bu bir kolaylık daha, muhtemelen performans pek fark yoktur ve eğer performans ana endişe ise muhtemelen çok daha hızlı var Fast integer to string conversion in C makalesinden alternatifleri görebiliriz:

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::ostringstream mystream;  
    mystream << 100 ;  
    std::string s = mystream.str();  

    std::cout << s << std::endl ;

    char buff[12] = {0};  
    sprintf(buff, "%d", 100);  
    std::string s2( buff ) ;
    std::cout << s2 << std::endl ;

    std::cout << std::to_string( 100 ) << std::endl ;
}

3. Yerine constexpr kullanarak meta-programlama şablonu

Eğer rakamları ile ilgili ise meta-programlama şablon üzerinde constexpr işlevleri kullanarak daha temiz bir kod üretebilir ve muhtemelen daha hızlı derler durumlar olabilir. Makale Want speed? Use constexpr meta-programming! asal sayı tespiti meta-programlama şablonu kullanarak bir örnek sağlar:

struct false_type 
{
  typedef false_type type;
  enum { value = 0 };
};

struct true_type 
{
  typedef true_type type;
  enum { value = 1 };
};

template<bool condition, class T, class U>
struct if_
{
  typedef U type;
};

template <class T, class U>
struct if_<true, T, U>
{
  typedef T type;
};

template<size_t N, size_t c> 
struct is_prime_impl
{ 
  typedef typename if_<(c*c > N),
                       true_type,
                       typename if_<(N % c == 0),
                                    false_type,
                                    is_prime_impl<N, c 1> >::type >::type type;
  enum { value = type::value };
};

template<size_t N> 
struct is_prime
{
  enum { value = is_prime_impl<N, 2>::type::value };
};

template <>
struct is_prime<0>
{
  enum { value = 0 };
};

template <>
struct is_prime<1>
{
  enum { value = 0 };
};

ve kullanarak constexpr fonksiyonları:

constexpr bool is_prime_recursive(size_t number, size_t c)
{
  return (c*c > number) ? true : 
           (number % c == 0) ? false : 
              is_prime_recursive(number, c 1);
}

constexpr bool is_prime_func(size_t number)
{
  return (number <= 1) ? false : is_prime_recursive(number, 2);
}

Constexpr sürümü çok daha kısa, anlaşılması kolay ve görünüşe göre çok daha iyi meta-programlama uygulama şablonuna göre gerçekleştirir.

4. Sınıf üyesi kullanarak varsayılan değerler sağlamak için başlatma

Son zamanlarda Has the new C 11 member initialization feature at declaration made initialization lists obsolete? sınıf kaplıydı Olarak Üye başlatma varsayılan değerler sağlamak için kullanılır ve bir sınıf birden fazla kurucular olduğu durumlarda kolaylaştırabilir.

Bjarne Stroustrup C 11 SSS iyi bir örnek teşkil ediyor, diyor ki:

Bu yazım biraz kurtarıyor, ama gerçek faydaları birden kurucular ile sınıfları. Genellikle, tüm kurucular üyesi için ortak bir başlatıcı kullanın:

ve sağlar, ortak bir başlatıcı olan üyeleri için bir örnek:

class A {
  public:
    A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {}
    A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {}
    A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {}
    int a, b;
  private:
    HashingFunction hash_algorithm;  // Cryptographic hash to be applied to all A instances
    std::string s;                   // String indicating state in object lifecycle
};

ve diyor ki:

Hash_algorithm ve tek bir varsayılan her gerçeğini kodu karışıklık içinde kaybolur ve kolay bakım sırasında bir sorun haline gelebilir. Bunun yerine, veri üyeleri başlatma faktörü yapabiliriz:

class A {
  public:
    A(): a(7), b(5) {}
    A(int a_val) : a(a_val), b(5) {}
    A(D d) : a(7), b(g(d)) {}
    int a, b;
  private:
    HashingFunction hash_algorithm{"MD5"};  // Cryptographic hash to be applied to all A instances
    std::string s{"Constructor run"};       // String indicating state in object lifecycle
};

Not, C 11 a sınıfı sınıfta üyesi başlatıcılar kullanarak bu kısıtlama C 14 kaldırılmış olmasına rağmen no longer an aggregate.

5. Elle sarılmış typedefs yerine cstdint sabit genişlik bir tamsayı türlerini kullanın

C 11 standart normatif bir referans olarak C99 kullandığından fixed width integer types, biz de. Örneğin:

int8_t
int16_t 
int32_t 
int64_t 
intptr_t

Onları çeşitli isteğe bağlı olsa da, tam genişliği için tamsayı türleri takip C99 bölüm 7.18.1.1 geçerlidir:

Bu tür isteğe bağlıdır. Eğer bir uygulama 8 genişlikleri ile tamsayı türleri sağlar ancak 16, 32, ya da 64 bit, bit doldurma yok, (imzalı tipleri için) bir iki tanımlamak zorundadır tamamlayıcı gösterimi var typedef isimleri ilgili.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ghosti66

    ghosti66

    27 AĞUSTOS 2006
  • How It Should Have Ended

    How It Shoul

    5 Mart 2007
  • sonia989

    sonia989

    26 EKİM 2006