Tôi hy vọng bạn nhận ra rằng tất cả những điều này được định nghĩa triển khai sâu sắc, cả cho Java và C ++. Điều đó đang được nói, mô hình đối tượng của Java đòi hỏi khá nhiều không gian.
Các đối tượng C ++ không (nói chung) không cần bất kỳ lưu trữ nào ngoại trừ những gì các thành viên cần. Lưu ý rằng (không giống như Java, trong đó mọi thứ do người dùng định nghĩa là loại tham chiếu), mã máy khách có thể sử dụng một đối tượng làm kiểu giá trị hoặc làm kiểu tham chiếu, tức là một đối tượng có thể lưu trữ con trỏ / tham chiếu đến đối tượng khác hoặc lưu trữ đối tượng trực tiếp không có sự quyết định Một con trỏ bổ sung cho mỗi đối tượng là cần thiết nếu có bất kỳ virtual
phương thức nào , nhưng khá nhiều lớp hữu ích được thiết kế để hòa hợp mà không cần đa hình và không cần điều này. Không có siêu dữ liệu GC và không có khóa trên mỗi đối tượng. Do đó, class IntWrapper { int x; public: IntWrapper(int); ... };
các đối tượng không cần nhiều không gian hơn int
s đơn giản và có thể được đặt trực tiếp (tức là không có hướng dẫn) trong các bộ sưu tập và các đối tượng khác.
Mảng rất đơn giản vì không có tiền chế tạo, tương đương với Mảng Java trong C ++. Bạn chỉ có thể phân bổ một loạt các đối tượng với new[]
(hoàn toàn không có chi phí / siêu dữ liệu) nhưng không có trường độ dài - việc triển khai có thể lưu trữ một đối tượng nhưng bạn không thể truy cập nó. std::vector
là một mảng động và do đó có thêm chi phí và giao diện lớn hơn. std::array
và mảng kiểu C (int arr[N];
), cần một hằng số thời gian biên dịch. Về lý thuyết, nó chỉ nên là bộ lưu trữ của đối tượng cộng với một số nguyên duy nhất cho chiều dài - nhưng vì bạn có thể thay đổi kích thước động và giao diện đầy đủ tính năng với rất ít không gian, nên bạn chỉ cần thực hiện điều đó trong thực tế. Lưu ý rằng tất cả những thứ này, cũng như tất cả các bộ sưu tập khác, mặc định lưu trữ các đối tượng theo giá trị, do đó giúp bạn tiết kiệm được không gian và không gian cho các tài liệu tham khảo và cải thiện hành vi bộ đệm. Bạn phải lưu trữ rõ ràng con trỏ (những người thông minh, xin vui lòng) để có được sự quyết định.
Các so sánh trên không hoàn toàn công bằng, vì một số khoản tiết kiệm này được cung cấp bởi không bao gồm các tính năng Java bao gồm và tương đương C ++ của chúng thường ít được tối ưu hóa hơn so với tương đương Java (*). Cách phổ biến để thực hiện virtual
trong C ++ áp đặt chính xác nhiều chi phí như cách phổ biến để thực hiện virtual
trong Java. Để có được một khóa, bạn cần một đối tượng mutex có đầy đủ tính năng, rất có thể lớn hơn một vài bit. Để có được số tham chiếu ( không phảitương đương với GC và không nên được sử dụng như vậy, nhưng đôi khi hữu ích), bạn cần một con trỏ thông minh có thêm trường đếm tham chiếu. Trừ khi đối tượng được xây dựng cẩn thận, số tham chiếu, đối tượng con trỏ thông minh và đối tượng được tham chiếu nằm ở các vị trí hoàn toàn riêng biệt và ngay cả khi bạn xây dựng đúng, con trỏ dùng chung có thể (phải?) Vẫn là hai con trỏ thay vì một. Một lần nữa, phong cách C ++ tốt không sử dụng các tính năng này đủ để nó trở thành vấn đề - trong thực tế, các đối tượng của thư viện C ++ được viết tốt sử dụng ít hơn. Điều đó không nhất thiết có nghĩa là sử dụng ít bộ nhớ hơn, nhưng điều đó có nghĩa là C ++ có một khởi đầu tốt trong vấn đề này.
(*) Chẳng hạn, bạn có thể nhận các cuộc gọi ảo, mã băm nhận dạng và khóa chỉ bằng một từ cho một số đối tượng (và hai từ cho nhiều đối tượng khác) bằng cách hợp nhất thông tin loại với các cờ khác nhau và xóa bit khóa cho các đối tượng không cần khóa. Xem Triển khai mô hình đối tượng Java (PDF) không gian và thời gian hiệu quả của David F. Bacon, Stephen J. Fink và David Grove để được giải thích chi tiết về điều này và các tối ưu hóa khác.
int
? Nếu vậy, bạn nên so sánh điều đó vớiint
Java, chứ không phảiInteger
- miễn là số nguyên C ++ của bạn là 32 bit.