2009-04-30 58 views
6

Ngay bây giờ tôi đang sử dụng std :: pair để biểu diễn một điểm 2d trong C++. Tuy nhiên, tôi cảm thấy khó chịu khi phải viếtTạo một lớp Point trong C++

typedef std::pair<double, double> Point; 

Point difference = Point(p2.first - p1.first, 
         p2.second - p1.second); 

thay vì có thể quá tải toán tử + và toán tử-.

Vì vậy, câu hỏi của tôi là, để làm cho lớp Point của tôi, nên tôi

  • công khai xuất phát từ std :: cặp và thêm chức năng thành viên của riêng tôi? Điều này là tốt đẹp bởi vì tất cả các mã của tôi có thể giữ nguyên. Tôi sẽ không làm bất cứ điều gì như std::pair<double, double>* p = new Point; vì vậy tôi không phải lo lắng về những thứ như destructors ảo.
  • Cuộn lớp Point của riêng tôi, điều này gây phiền toái vì tôi đang sao chép std :: chức năng của cặp, tuy nhiên tôi đang "làm theo cách thuần túy".
  • Tạo các chuyên môn mẫu của toán tử + và toán tử - cho cặp :: std, mà tôi thừa nhận rằng tôi không nhớ chúng có nằm trong tệp nguồn hay tiêu đề hay không.

Tôi đoán nó đang tranh luận, tôi thực sự thích làm # 1 nhưng tôi không biết nếu đó là một ý tưởng tồi vì tôi đã nghe nói rằng kế thừa từ STL là một không-không.

+3

FYI - lý do kế thừa từ STL là không có không là nó không có trình phá hủy ảo. Vì vậy, nếu bạn đã xóa lớp của riêng bạn thông qua một con trỏ tới kiểu cơ sở STL, thì hàm hủy của bạn sẽ không được gọi. – JohnMcG

+0

Tôi đã nói tôi sẽ không làm điều đó trong câu hỏi. – rlbond

+0

Không nghĩ rằng bạn sẽ; chỉ nghĩ rằng nó sẽ hữu ích để cung cấp lý do tại sao. – JohnMcG

Trả lời

14

Bạn có thể cuộn lớp Point của riêng bạn, nhưng sử dụng std :: pair nội bộ để lưu trữ dữ liệu. Điều này ngăn cản sự kế thừa từ vấn đề STL, nhưng vẫn sử dụng chức năng của std :: pair.

+1

+1. Nếu bạn tình cờ đọc Mã hoàn thành, nó cho thấy thực hành chính xác này: Nếu [điểm lớp] * là * một [std :: pair], sau đó kế thừa. Nếu không, [std :: pair] sẽ được lưu trữ như một thành viên riêng tư, và [Point] nên thay vào đó xác định giao diện riêng của nó. "point.first" không có ý nghĩa; point.x hiện. – ojrac

+0

Đó có lẽ là nơi tôi có ý tưởng. Cuốn sách đó đá! –

+0

Tôi hiểu lý do tại sao kế thừa từ 'stl :: pair' không tốt; nhưng tại sao lại sử dụng 'stl :: pair' ngay từ đầu? Những tính năng nào của 'stl :: pair' có liên quan đến' Point'? Có lẽ tôi đang thiếu một cái gì đó hiển nhiên, nhưng đặt hàng, 'swap',' get', các nhà xây dựng khác nhau dường như không liên quan gì đến 'Point'. – max

1

Một tùy chọn khác có thể là làm cho bạn sở hữu lớp Point và có lớp "std ::" riêng đại diện cho tọa độ điểm.

Rất nhiều lần mối quan hệ "HAS A" (sáng tác) thích hợp hơn mối quan hệ "IS A" (thừa kế).

1

Tôi nghĩ rằng "Các phương pháp hay nhất" sẽ nói để cuộn lớp Điểm của riêng bạn. Bằng cách này, bạn có thể làm cho nó 3D dễ dàng hơn nhiều trên đường.

+0

hoàn toàn không cần thiết cho 3d. Đó là trò chơi. Một trò chơi 2ngày. – rlbond

+0

2 kích thước là đủ cho mọi người !!! Xin lỗi vì điều đó –

1

Thừa kế riêng thừa kế thừa kế thực hiện, là bạn của bạn.

Điều này theo logic: một điểm KHÔNG phải là một cặp :: std, bạn không muốn có chuyển đổi công khai lên từ Point thành std :: pair, nhưng bạn muốn sử dụng std :: internals của cặp .

Khả năng khác là mối quan hệ hoặc thành phần có sẵn: mỗi điểm có một gói riêng tư :: cặp mà nó sử dụng trong nội bộ. Trong thực tế, không có nhiều sự khác biệt giữa thành phần và thừa kế riêng, ngoại trừ trong phần sau, bạn có thể buộc một up-cast thành std :: pair trong một hàm thành viên Point (điểm thành viên).

0

Cuộn lớp Điểm của riêng bạn. Điều này sẽ cho phép bạn làm bất kỳ số thứ với nó trong tương lai. Cụ thể, tôi đã giải quyết vấn đề này trước đây và những gì tôi thấy hữu ích là xác định cấu trúc điểm của riêng tôi và tạo một lớp Point thừa kế từ nó.

Tiết lộ đầy đủ: Tôi không thích STL rất nhiều.

2

Tốt hơn là cuộn của riêng bạn: lấy thư viện Vector/điểm miễn phí hiện có. Một đề xuất: đề xuất được đính kèm với Essential Math for Games Programmers. Bạn có thể sử dụng bất kỳ thư viện nào bạn tìm thấy làm điểm bắt đầu, sau đó tối ưu hóa/chuyên/tinh chỉnh từ đó.

2

Tôi muốn có lợi cho việc tạo lớp điểm của riêng bạn và sử dụng kế thừa hoặc thành phần riêng tư nếu bạn muốn sử dụng chức năng của std :: pair. Vấn đề với typedef (như tôi chắc chắn bạn biết) là bất kỳ hàm nào bạn viết có điểm cũng sẽ có thể sử dụng được bởi bất kỳ thứ gì được biểu diễn dưới dạng std :: pair < double, double >, có thể không hợp lệ.

Với điều này trong tâm trí, một lựa chọn khác tồn tại chỉ tạo ra một số chức năng xây dựng miễn phí như

Point addPoints(const Point& p1, const Point& p2); 
Point diffPoints(const Point& p1, const Point& p2); 

(tên chức năng có thể là tốt hơn).

0

Không kế thừa công khai từ std :: pair vì std :: pair có toán tử < nhưng điểm của bạn không nên có.

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