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
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.
Kodlama eski kodu yeniden düzenleme uy...
Yeniden düzenleme amaçlı sadece özelli...
Nasıl bir bölüm için UİTableView satır...
Böyle büyük mükafat 4 yeniden düzenlem...
Nasıl Veri türü güvenli olun ve yenide...