2010-10-18 51 views
9

C++ STL dường như không sử dụng các lớp cơ bản hoàn toàn trừu tượng (hay còn gọi là giao diện) rất thường xuyên. Tôi biết rằng hầu hết mọi thứ có thể đạt được với các thuật toán STL hoặc lập trình meta mẫu thông minh. Tuy nhiên, đối với một số trường hợp sử dụng (ví dụ: trong API, nếu tôi không muốn cụ thể về loại vùng chứa tôi nhận được, chỉ về các phần tử chứa), giao diện của biểu mẫu sau sẽ được tốt đẹp:Tại sao không có giao diện "Iterable" trong STL?

template<typename T> struct forward_iterable { 
    struct iterator { 
     typedef T value_type; 
     typedef T& reference; 
     typedef T* pointer; 
     virtual reference operator*() const = 0; 
     virtual pointer operator->() const = 0; 
     virtual bool operator==(const iterator&) const = 0; 
     virtual bool operator!=(const iterator&) const = 0; 
     virtual operator const_iterator() const = 0; 
     virtual iterator& operator++() = 0; 
     virtual iterator operator++(int) = 0; 
    }; 
    struct const_iterator { ... }; // similar, but with const references 

    virtual iterator begin() = 0; 
    virtual const_iterator begin() const = 0; 
    virtual iterator end() = 0; 
    virtual const_iterator end() const = 0; 
}; 

Nếu container STL thực hiện lớp này như chức năng không ảo, điều này sẽ, theo ý kiến ​​của tôi, không ảnh hưởng đến hiệu suất (nếu tôi sử dụng các container trực tiếp và không qua giao diện này). Vậy tại sao có quá ít "giao diện" trong STL? Hay tôi chỉ nghĩ quá nhiều trong thuật ngữ "Java"?

+0

Hmm, tôi chỉ nghĩ về một biến chứng: do tính chất chung của các toán tử so sánh, kiểm tra kiểu động sẽ được yêu cầu để đảm bảo rằng các trình vòng lặp là "tương thích". Đó có phải là lý do nó không hoạt động? – summentier

Trả lời

6

STL (là một tập hợp con của thư viện chuẩn) không sử dụng OOP (như trong đa hình thời gian chạy) ở tất cả và theo thiết kế.

Với thiết kế của bạn, sẽ không có vấn đề gì khi trả về vòng lặp theo giá trị (hiệp phương sai không hoạt động đối với các loại giá trị)? Đó là, sẽ không tránh khỏi toàn bộ điều hoặc phải dựa vào các thành viên tĩnh (mà bạn có thể trở lại bằng cách tham khảo) hoặc trên iterators phân bổ heap? Cái thứ hai có vẻ khá vụng về trong một ngôn ngữ không được thu gom rác.

Những gì bạn đang mô tả (một iterator templated trên kiểu giá trị) có thể đạt được bằng cách sử dụng kỹ thuật gọi là kiểu tẩy xoá (và bạn có thể tìm any_iterator triển khai trên mạng) giống như tăng của functionany loại.

Ý tưởng cơ bản là:

//less templated interface 
template <class T> 
class any_iterator_base 
{ 
    virtual void increment() = 0; 
    /*...*/ 
}; 

//derived class templated on iterator type 
template <class Iter, class T> 
class any_iterator_impl: public any_iterator_base<T> 
{ 
    Iter it; 
    virtual void increment() { ++it; } 
    /*...*/ 
}; 

//and a class for the user which makes it all act like a regular value type 
template <class T> 
class any_iterator 
{ 
    shared_ptr<any_iterator_base<T> > it; 
public: 
    template <class Iter> 
    any_iterator(Iter iterator): it(new any_iterator_impl<Iter, T>(iterator)) {} 
    any_iterator& operator++() { it->increment(); return *this; } 
    //... 
}; 

int main() 
{ 
     std::vector<int> vec; 
     any_iterator<int> it = vec.begin(); 
     //... 
} 

Nó có thể phức tạp hơn thế (ví dụ như cần phải làm điều gì đó về mô tả và thực thi các loại iterator ?, như thế nào sẽ so sánh hai any_iterators làm việc (công văn đôi/RTTI)).

2

Lý do bạn không thấy nhiều lớp cơ sở trừu tượng "giao diện" trong STL là vì nó dựa quá nhiều vào các mẫu C++. Khi bạn sử dụng các mẫu C++, khá nhiều bất kỳ lớp nào, bất kể cha mẹ của nó có thể là gì, sẽ làm miễn là nó hỗ trợ tất cả các phương thức mà khuôn mẫu cố gắng sử dụng.

Có loại giao diện ngụ ý, nhưng thực sự viết nó ra là unicecary. Trong mã hóa của riêng tôi, tôi có xu hướng viết một cái gì đó, cũng giống như một sự thuận tiện cho người dùng, nhưng đó không phải là cách các nhà văn STL cuộn.

0

Cấu trúc STL không được xác định với thừa kế trong đầu. Nó không phải là dễ dàng để làm cho một trường hợp tốt cho subclassing bất kỳ bộ sưu tập stl. với ý nghĩ đó, stl không làm cho bạn 'trả' bất kỳ chi phí nào có thể đã được liên kết với thừa kế lớp bình thường. Nếu các phương thức ảo được sử dụng, thì chúng không thể được trình tối ưu hóa đưa vào.

Ngoài ra, STL muốn tương thích với những thứ không thể kế thừa từ lớp cơ sở trừu tượng cấp cao nhất, như mảng.

+0

Tôi nghĩ rằng các chuyên ngành ảo của các phương thức ảo thực sự có thể được gạch chân nếu phương thức lớp con được gọi trực tiếp (và không thông qua lớp cơ sở), vì vậy việc thêm giao diện sẽ chỉ thêm các hình phạt hiệu năng khi cần thiết. – summentier

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