SORU
16 Mart 2011, ÇARŞAMBA


STL Karakter Özellikleri anlamı nedir?

BİLGİSAYARINIZDA STL benim referans kopyalama, Karakter Özellikleri hakkında bir sayfa olduğunu fark ettim ama bu nasıl kullanıldığını göremiyorum? Dize değiştirin.h fonksiyonları? std::string örneğin std::string length() yöntem Karakter Özellikleri kullanımı length() yöntem yapmaz tarafından kullanılacak gibi görünmüyor. Neden Karakter Özellikleri var ve şimdiye kadar uygulamada kullanılır?

CEVAP
16 Mart 2011, ÇARŞAMBA


Karakter özellikleri stream/string sınıfları mantığı ayırmak için izin çünkü akışları ve dizeleri kütüphanelerin son derece önemli bir bileşenidirne karakterler saklanıyormantığındanmanipülasyonlar bu karakterler üzerinde yapılması gerekenler.

Başlamak için, varsayılan karakter özellikleri sınıf char_traits<T> yoğun C standardı kullanılır. Örneğin, sınıf std::string adı yok. Aksine, bu gibi görünüyor 14* *sınıf bir şablon var:

template <typename charT, typename traits = char_traits<charT> >
    class basic_string;

Sonra da, std::string olarak tanımlanır

typedef basic_string<char> string;

Benzer şekilde, standart akış olarak tanımlanır

template <typename charT, typename traits = char_traits<charT> >
    class basic_istream;

typedef basic_istream<char> istream;

Neden bu sınıflar olarak yapılandırılmış? Neden bir şablon bağımsız değişken olarak garip özellikleri bir sınıf kullanarak olmalıyız?

Bunun sebebi, bazı durumlarda biraz daha farklı bazı özellikleri ile std::string, gibi ama bir dize sahip olmak isteyebiliriz. Bu klasik bir örnek ise, göz ardı eden bir şekilde dizeleri depolamak istiyorsanız. Örneğin, bir string CaseInsensitiveString aramam böyle yapmak isteyebilirim

CaseInsensitiveString c1 = "HI!", c2 = "hi!";
if (c1 == c2) {  // Always true
    cout << "Strings are equal." << endl;
}

Bu, iki dize küçük / büyük harf duyarlılığına göre farklı eşit karşılaştırıldığı bir dize olabilir.

Şimdi, standart kütüphane yazarlar özellikleri kullanmadan dizeleri tasarlanmış varsayalım. Bu standart kütüphanede olurdu anlamına gelir benim durumda tamamen işe yaramaz olduğunu son derece güçlü dize bir sınıf. Karşılaştırmalar her zaman onlarla çalışmak istedim nasıl karşı işe yarayacağını beri bu string sınıfı için fazla kod yeniden kullanım, yapamadım. Ama özelliklerini kullanarak, aslında mümkün std::string büyük küçük harf duyarsız dize almaya iten kodu yeniden.

Eğer yukarı çekin bir kopyası C ISO standart ve bak tanımının nasıl dize karşılaştırma operatörleri, göreceksin ki hepsi tanımlı açısından compare işlevi. Bu işlevi devre arayarak tanımlanır

traits::compare(this->data(), str.data(), rlen)

str dize olduğu için karıştırıyorsunuz ve rlen iki dize uzunlukları daha küçük. Bu compare tanımı doğrudan compare işlevi özellikleri şablon parametre olarak belirtilen türü tarafından ihraç kullandığı anlamına gelir çünkü aslında oldukça ilginç. Sonuç olarak, eğer tanımladığımız bir yeni sınıf özellikleri, tanımlamak compare böylece karşılaştırır karakterleri büyük-duyarsızca, biz inşa bir dize sınıf davrandığı gibi std::string, ama gönlünü şeyler vaka-duyarsızca!

İşte size bir örnek. std::char_traits<char> yazmıyoruz tüm işlevler için varsayılan davranış almamız miras:

class CaseInsensitiveTraits: public std::char_traits<char> {
public:
    static bool lt (char one, char two) {
        return std::tolower(one) < std::tolower(two);
    }

    static bool eq (char one, char two) {
        return std::tolower(one) == std::tolower(two);
    }

    static int compare (const char* one, const char* two, size_t length) {
        for (size_t i = 0; i < length;   i) {
            if (lt(one[i], two[i])) return -1;
            if (lt(two[i], one[i])) return  1;
        }
        return 0;
    }
};

(Dikkat edin de eq ve eşitlik için karakter ve daha az-daha sırasıyla karşılaştırın ve daha sonra bu işlevi açısından compare tanımlanan lt burada) tanımlanan ettim.

Bu özellikleri dersimiz var şimdi, Basit olarak CaseInsensitiveString tanımlayabiliriz

typedef std::basic_string<char, CaseInsensitiveTraits> CaseInsensitiveString;

Ve voila! Şimdi her şey vaka-duyarsızca davranan bir dize var!

Tabii ki, özellikleri kullanmak için bunun yanında başka sebepler de var. Eğer bir sabit boyutlu bazı temel karakter türü kullanan bir dize tanımlamak istiyorsanız, örneğin, daha sonra bu tür char_traits uzman ve bu tür dizeleri yapabilirsiniz. Örneğin, Windows API, ya dar ya da geniş bir karakter ön sırasında ayarlanmış bağlı olan 39* *bir tür var. Sonra dizeleri TCHARs dışarı yazarak yapabilirsiniz

typedef basic_string<TCHAR> tstring;

Ve şimdi TCHARs Bir karakter dizisi var.

Bütün bu örneklerde, biz sadece bu tür bir dize almak için bazı Şablon Türü için bir parametre olarak bazı özellikleri sınıf (ya da zaten var olan bir kullanılır) tanımlanan dikkat edin. Bütün mesele bu o basic_string yazar sadece ihtiyaçlarını belirtmek için nasıl kullanılacağı özellikleri ve sihirli bir şekilde yapabilirsiniz onları kullanmak bizim özellikleri yerine varsayılan almak dizeleri biraz nüans ya cilvesi öyle bir varsayılan dize yazın.

Bu yardımcı olur umarım!

EDİT: @Phooji belirttiği gibi, özelliklerin bu kavramı sadece STL tarafından kullanılmaz, ne de C özgüdür . Olarak tamamen utanmaz kendini promosyon, kısa bir süre önce yazdığım an implementation of a ternary search tree (bir tür taban ağacı described here) kullanan özellikler için mağaza dizeleri her tür ve ne olursa olsun kullanarak karşılaştırma türü müşteri istiyor onlara saklayın. Eğer bu uygulamada kullanılan örnek görmek isterseniz ilginç bir okuma olabilir.

EDİT: std::string traits::length, kullanmayan iddia yanıt olarak birkaç yerde yaptığı ortaya çıktı. char* C-tarzı bir ipten std::string oluşturmak zaman, en önemlisi, dize uzunluğu dize traits::length çağırarak elde edilir. Öyle görünüyor ki traits::length kullanılan çoğunlukla uğraşmak C-tarzı dizilerin karakterleri olan "en az ortak payda" dizelerinde C , süre std::string kullanılan iş dizelerle keyfi içeriğini.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ralph Phillips

    Ralph Philli

    5 Aralık 2006
  • SerienTrailerMP

    SerienTraile

    7 HAZİRAN 2012
  • Tome Rodrigo

    Tome Rodrigo

    9 Temmuz 2006