2010-07-12 39 views
5

Tôi có hai lớp học, điểm và điểm ảnh:C++ thừa kế/mẫu câu hỏi

class point { 
    public: 
     point(int x, int y) : x(x), y(y) { }; 
    private: 
     int x, y; 
} 

template <class T> 
class pixel : public point { 
    public: 
     pixel(int x, int y, T val) : point(x, y), val(val) { }; 
    private: 
     T val; 
} 

Bây giờ đây là vấn đề của tôi. Tôi muốn tạo một lớp container (chúng ta hãy gọi nó là coll) có một vectơ riêng của điểm hoặc pixel. Nếu một thể hiện của coll chứa các pixel, tôi muốn nó có một phương thức toArray(), nó chuyển đổi véc-tơ của các điểm ảnh thành một mảng T đại diện cho nội dung của vectơ. Tôi sẽ làm điều này với thừa kế: ví dụ, tôi có thể tạo một coll lớp cơ sở chứa một vectơ các điểm và một lớp dẫn xuất chứa phương thức bổ sung, nhưng sau đó dường như tôi gặp phải vấn đề vì pixel là một mẫu lớp.

Có ai có đề xuất không? Tôi có thể làm điều này bằng cách nào đó bằng cách làm cho coll một mẫu lớp?

+0

Tôi nghĩ rằng 'coll' cũng phải là một lớp mẫu. Sau đó, bạn có thể chuyên biệt một phần 'coll' cho điểm và cho điểm ảnh. – Philipp

+0

Pixel có phải là tập hợp các tọa độ (tức là 'điểm kế thừa') hay nó có tọa độ (tức là chứa một thể hiện điểm)? – Patrick

+0

Nó kế thừa từ điểm. – amc

Trả lời

3

Câu hỏi: Ý của bạn là cho vectơ riêng tư chứa cả Điểm và Điểm ảnh cùng một lúc, hoặc chỉ một hay Điểm khác?

Câu hỏi: Nếu chỉ một hoặc khác, bạn có ý định trộn Pixels với các tham số mẫu khác nhau trong cùng một vector riêng không?

Giả sử rằng nó chỉ là Point hoặc Pixel trong vector riêng, và rằng Pixels trong vector tin tất cả đều có thông số cùng một mẫu, bạn có thể làm một cái gì đó như thế này:

template < class T > class CollectionBase 
{ 
    //common interface here 
    protected: 
    std::vector<T> coll_vec; 
}; 

class PointCollection : public CollectionBase<Point> 
{ 
    public: 
    ... 
}; 

template< class T> PixelCollection : public CollectionBase<Pixel<T> > 
{ 
    public: 
    Pixel<T>* toArray(); 

    ... 

}; 
+0

Trả lời: chỉ một hoặc khác. Trả lời: chỉ các pixel có cùng thông số mẫu. Giải pháp này có vẻ khá tốt, nhưng bộ sưu tập của tôi sẽ có nhiều chức năng giống nhau: điều này sẽ không yêu cầu nhiều trùng lặp mã giống nhau vì CollectionBase sẽ không có quyền truy cập vào vùng chứa không? – amc

+0

@amc đã cập nhật câu trả lời để ngăn trùng lặp mã. Nó làm cho PointCollection có một chút dư thừa, nhưng điều này sẽ ngăn chặn hầu hết các phôi từ PixelCollection đến PointCollection và ngược lại. Nếu bạn có ý định cho phép chúng được đúc giữa nhau thì bạn có thể thu gọn CollectionBase và PointCollection lại thành một lớp duy nhất. – diverscuba23

+0

TUYỆT VỜI, đây là chính xác những gì tôi muốn. Tôi đoán tôi đã không nhận ra rằng bạn có thể phân lớp một lớp mẫu. Cảm ơn! – amc

1

Nếu bạn muốn kiểm tra xem đối tượng point cũng là một loại pixel<T>, sau đó bạn có thể chỉ cần xem nếu dynamic_cast trả lại NULL. Để làm điều này, point sẽ cần phải được đa hình, do đó, thêm một destructor ảo cho nó.

Dưới đây là một ví dụ:

point x(0, 0); 
pixel<int> y(0, 0, 0); 
point *pX = &x; 
point *pY = &y; 
if(dynamic_cast<pixel<int> *> (pX) != NULL) { 
    std::cout << "x is a pixel<int>."; 
} 
if(dynamic_cast<pixel<int> *> (pY) != NULL) { 
    std::cout << "y is a pixel<int>."; 
} 

Đầu ra là như sau:

y là một int điểm ảnh <>.

Bạn có thể sử dụng mã này trong lớp coll để kiểm tra xem mỗi phần tử của vector<point *> là một điểm hay pixel. Nhưng để làm như vậy, bạn cần phải biết chuyên môn về pixel nào đang được lưu trữ (tức là nó là pixel<int> hoặc pixel<float>?)

Có thể đơn giản hơn để tạo mẫu coll một lớp học thay thế.

1

Nếu collection xử lý point s và pixel s chủ yếu giống nhau và chỉ chứa một hoặc cái kia, có ý nghĩa để biến nó trở thành một lớp mẫu.
Về to_array tuy nhiên, nó có thể là đơn giản để làm cho nó một chức năng miễn phí thay vì:

template<class T> struct collection { 
    std::vector<point<T> > data_; 
    // ... 
}; 

template<class T> 
void to_array(const collection<point<T> >& in, point<T>* out) { 
    // ... 
} 

Lưu ý rằng bạn sẽ phải cung cấp một giao diện nào cho đọc truy cập vào các dữ liệu tuy nhiên hoặc ít nhất là có chọn lọc cấp to_array() truy cập .