2011-10-17 5 views
18

Đây là một tốt đẹp cũ mảng C:mảng liên tục

int a[10]; 

Và đây là một mảng C cũ tốt đó là const:

const int b[10]; 

Trong C++, hình như vẫn có hai cách để xác định std::array s là const:

std::array<const int, 10> c; 
const std::array<int, 10> d; 

Hai định nghĩa này là hai valent? Nếu vậy, thành ngữ là gì? Nếu không, sự khác biệt là gì?

Trả lời

9

Vâng, bản gốc const int b[10]; chỉ hữu ích khi bạn có thể khởi tạo mảng, do đó cả hai ví dụ std::array không hoạt động trong thực tế.

1:

std::array<const int, 10> c; 

Đây là gần gũi nhất với const int c[10];. Vấn đề là sẽ không có constructor mặc định cho nó, và bởi vì các phần tử không thể thay đổi được, nên nó không có giá trị để sử dụng nó. Bạn phải cung cấp một số khởi tạo cho nó trong hàm tạo. Như là, nó sẽ cung cấp cho một lỗi biên dịch bởi vì các nhà xây dựng mặc định đã không khởi tạo các yếu tố.

Mã này có nghĩa là c có thể thay đổi, nhưng bản thân các phần tử thì không. Tuy nhiên, trên thực tế, không có đột biến nào trên c không ảnh hưởng đến các yếu tố.

2:

const std::array<int, 10> d; 

Điều này có nghĩa d là không thể thay đổi, nhưng các yếu tố của thể thay đổi loại int. Bởi vì const sẽ truyền cho các thành viên, điều đó có nghĩa là các yếu tố vẫn không thể thay đổi được bởi người gọi. Tương tự như ví dụ trên, bạn cần phải khởi tạo d vì đó là const.

Trong thực tế, cả hai sẽ hoạt động tương tự liên quan đến tính đột biến, bởi vì các hoạt động có thể thay đổi trên array luôn chạm vào các phần tử.

5

Định nghĩa trên phân bổ một mảng các số nguyên không đổi trên ngăn xếp, trong khi giá trị thứ hai phân bổ một mảng không đổi của các số nguyên biến. Trong trường hợp đầu tiên, bạn phải xác định nội dung của mảng khi bạn khai báo nó, vì nội dung của nó là hằng số và nó không thể được sửa đổi sau này. Tôi đoán, tuyên bố thứ hai đầu tiên cũng sẽ tạo ra một cái gì đó giống như

const std::array<const int,10> c; 

từ một mảng tĩnh luôn được cấp phát trên stack và con trỏ đến phần tử đầu tiên của nó có thể không muộn được sửa đổi.

+1

+1 mặc dù mảng tĩnh không bao giờ được phân bổ trên ngăn xếp. Một mảng size_fixed có thể được cấp phát trên stack (tự động lưu trữ declspec) hoặc trong một phân đoạn dữ liệu toàn cục (static storage declspec). Thông tin bên lề: trong 'typedef int ints_t [10]; ints_t * ints = new ints_t(); 'là' ints' một mảng kích thước cố định hoặc một mảng động? – sehe

+3

Cả hai mảng yêu cầu khởi tạo khi được khai báo. IMHO, không có sự khác biệt giữa hai - chúng chính xác giống nhau từ một quan điểm thuật toán và sử dụng (thực tế, các trình lặp là như nhau; 'const int *'). Thành thật mà nói cách tốt nhất để khai báo là như bạn nói trong câu trả lời, 'const std :: mảng c;' Điều này làm cho nó rất cụ thể, một mảng const của const ints. – Nim

5

Họ không phải là tương đương - c.referenceint& trong khi d.referenceconst int& (không phải là bạn có thể sử dụng cú pháp đó để truy cập typedefs, nhưng bạn có thể nắm bắt được loại bởi trích lập luận mẫu và biết sự khác biệt).

Nhưng tôi chắc chắn rằng tenfour có quan sát chính, "không có đột biến nào trên c không ảnh hưởng đến các yếu tố".Vì vậy, như xa như bất cứ điều gì bạn thực sự làm cho các mảng là có liên quan họ đang giống nhau, họ chỉ có siêu dữ liệu khác nhau vì các loại khác nhau của họ.

Trường hợp chính tôi có thể nghĩ nó sẽ tạo sự khác biệt ở đâu nếu bạn sử dụng chính loại đó trong giao diện (trái ngược với tham số vòng lặp hoặc tham số mẫu phạm vi). Tôi muốn nói rằng khi dùng nó như một con trỏ hoặc tham số tham chiếu, bạn nên tự động nhập loại array vì nó không tốn chi phí cho bạn và cho phép người gọi sử dụng chức năng của bạn tùy theo lựa chọn của họ. Bạn có thể const-đủ điều kiện loại phần tử, nhưng bất kỳ loại nào bạn sử dụng không tương thích với loại khác, vì vậy về cơ bản, mọi người phải đồng ý sử dụng hoặc nếu không sẽ cần một số yêu cầu sao chép. Điều đó đòi hỏi sự phối hợp hoạt động theo phong cách, tôi nghĩ, vì tôi nghi ngờ rằng bạn sẽ khiến mọi người trên thế giới đồng ý điều tốt nhất. const int có thể có trường hợp tốt hơn, theo nguyên tắc bạn nên const mọi thứ bạn có thể, nhưng tôi mong đợi int là những gì mọi người sẽ sử dụng, những người chưa từng nghĩ về nó, vì chúng được sử dụng cho tất cả các thùng chứa C++ 03 đó không thể có loại giá trị const.