2012-08-19 16 views

Trả lời

3

Điều này là do đặc điểm ký tự là cách tạo ra các biến thể của các lớp tiêu chuẩn (như chuỗi) và toán tử kiểu nguyên thủy có thể không thực sự là thứ bạn muốn. Ví dụ:

Ví dụ: xem xét một lớp lưu trữ chuỗi không phân biệt chữ hoa chữ thường; bạn có thể triển khai assign() theo cách lưu trữ cùng một thứ cho cả chữ cái viết hoa và phiên bản chữ thường. (Đối với vấn đề đó, các hoạt động đặc điểm nhân vật khác như bình đẳng cũng sẽ bị ghi đè.)

+1

Thú vị ... nhưng đó không phải là điều 'so sánh' là gì? – Mehrdad

+1

Tôi cho rằng việc ghi đè 'compare()' sẽ là cách tốt hơn để xử lý trường hợp không nhạy cảm; có lẽ có những ví dụ tốt hơn. Điểm duy nhất của tôi là một phân lớp của các đặc điểm ký tự có thể làm bất cứ điều gì nó muốn, và chắc chắn rằng một lớp có thể muốn làm "nhiều hơn" đơn giản là sao chép giá trị chính xác của ký tự (như một toán tử). –

7

Bạn thực sự sử dụng chức năng này mỗi lần sử dụng std :: string :). std :: string thực sự là typedef cho std :: basic_string, được định nghĩa là:

template< 
    class CharT, 
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT> 
> class basic_string; 

(xem this). Đặc biệt chú ý đến thông số mẫu Traits. Nếu bạn quá nghiêng, tham số mẫu Traits cho phép bạn tùy chỉnh các thuộc tính nhất định của hành vi của lớp chuỗi. Một trong những thuộc tính này là những gì sẽ xảy ra khi bạn thực hiện một nhiệm vụ.

Đây là ví dụ về cách sử dụng này. Nó sẽ buộc các bài tập phải là chữ thường.

#include <string> 
#include <iostream> 
#include <cctype> 

struct ci_char_traits : public std::char_traits<char> { 
    static void assign(char& r, const char& a) 
    { 
     r = std::tolower(a); 
    } 

    static char* assign(char* p, std::size_t count, char a) 
    { 
     for (std::size_t i = 0; i < count; ++i) 
     { 
      p[i] = std::tolower(a); 
     } 
    } 
}; 

typedef std::basic_string<char, ci_char_traits> ci_string; 

std::ostream& operator<<(std::ostream& os, const ci_string& str) { 
    return os.write(str.data(), str.size()); 
} 

int main() 
{ 
    ci_string s1 = "Hello"; 

    // This will become a lower-case 'o' 
    s1.push_back('O'); 

    // Will replace 'He' with lower-case 'a' 
    s1.replace(s1.begin(), s1.begin()+2, 1, 'A'); 

    std::cout << s1 << std::endl; 
} 
+1

Nó sẽ là một câu trả lời tốt hơn nhiều nếu bạn có thể giải thích lý do tại sao điều đó hữu ích hơn là chỉ tìm cách sử dụng nó. :) – Mehrdad

+0

Vâng, giả sử rằng chúng ta muốn có một kiểu chuỗi 'lc_string' để duy trì bất biến mà tất cả các ký tự là chữ thường. Điều đầu tiên bạn sẽ làm, có lẽ là ghi đè 'char_traits :: copy' (và' char_trains :: move', tại sao không) để khi bạn khởi tạo chuỗi ('lc_string str =" HELLO "'), nó sẽ chuyển đổi nó để giảm trường hợp. Tuy nhiên, không có cách nào để bảo vệ sự bất biến 'chữ thường' vượt ra ngoài trừ khi bạn cũng ghi đè 'char_traits :: assign', vì người dùng của chuỗi luôn có thể sử dụng' replace' hoặc 'push_back()'. – nevsan

Các vấn đề liên quan