2015-09-20 21 views
7

Bối cảnh của tôi là C++ và trong C++ chúng ta có thể dễ dàng tạo mảng đối tượng bằng cú pháp đơn giản. className obj[n]; và cũng là nhà xây dựng sẽ gọi n thời gian.Mảng đối tượng trong Java vs C++

Nhưng khi tôi cố gắng tạo mảng đối tượng trong java className[] obj=new className[n]; không có lệnh gọi hàm tạo nào. Sau khi tìm kiếm tôi tìm thấy câu trả lời của câu hỏi này trên stackoverflow rằng nó chỉ tạo ra một tài liệu tham khảo n có thể trỏ đến n đối tượng và tôi cần tạo lại đối tượng cho từng tham chiếu như thế nào. obj[0]=new className();

Bây giờ tôi chỉ muốn hỏi tại sao java làm điều này? là có bất kỳ lý do ngay cả C + + cho phép nhưng java không cho phép tạo ra các mảng của các đối tượng trong cùng một cách? Tôi đã tìm kiếm điều này nhưng vẫn không nhận được câu trả lời chính xác.

Trả lời

9

Trong C++ bạn có thể linh hoạt chọn bộ nhớ mà bạn tạo đối tượng. Bạn có thể tạo các đối tượng trong vùng tự động (trên ngăn xếp), trong vùng tĩnh hoặc trong vùng động. Trong trường hợp cuối cùng bạn nhận được một con trỏ đối tượng và chịu trách nhiệm giải phóng nó sau khi bạn đã hoàn tất.

Ngược lại, tất cả Java có tùy chọn vùng động, bởi vì tất cả các đối tượng là đối tượng tham chiếu. Trong C++ sẽ tương đương với việc sử dụng các đối tượng chỉ thông qua con trỏ và luôn tạo chúng với new. Khi bạn làm điều này trong C++, bạn cũng phải điền vào mảng của bạn của con trỏ với new đối tượng -ed:

myclass *array[10]; 
for (int i = 0 ; i != 10 ; i++) { 
    array[i] = new myclass(); 
} 
... 
for (int i = 0 ; i != 10 ; i++) { 
    delete array[i]; 
} 

Cho phép tạo ra các mảng đối tượng trong C++ là một sự lựa chọn quyết định bởi nhu cầu để cho các lập trình viên phân bổ mảng của các đối tượng trong khu vực tự động. Nó đến với một sự cân bằng, bởi vì các đối tượng mà từ đó bạn tạo ra các mảng phải có một hàm tạo mặc định. Đây không phải là lý tưởng, bởi vì các yêu cầu của constructor mặc định âm thanh tùy ý.

Java, mặt khác, không có yêu cầu bộ nhớ tự động, vì vậy chúng đã đi cho một giải pháp đơn giản yêu cầu bạn khởi tạo các đối tượng riêng lẻ.

2

Những gì được phép hoặc không làm là tùy thuộc vào nhà thiết kế ngôn ngữ.

Nếu bạn muốn khởi tạo tất cả các yếu tố của một Array với một tham chiếu đến cùng một đối tượng trong Java bạn có thể sử dụng:

className[] obj = new clasName[2]; 
Arrays.fill(obj, new className()); 

hoặc để tạo các đối tượng khác nhau và vượt qua đối số khác nhau cho mỗi constructor

className[] obj = new className[] {new className(), new className()};

+0

thì tại sao chúng tôi chọn ngôn ngữ khác nhau có lý do rằng mỗi ngôn ngữ có sự khác biệt về hiệu suất, bảo mật vv và ngôn ngữ của mỗi nhà thiết kế chọn cú pháp/logic cho một lý do Xin lỗi vì tiếng anh nghèo -_- –

+1

Lưu ý rằng giải pháp 'Arrays.fill' sẽ tạo một đối tượng và gán nó cho mọi phần tử mảng. Kết quả như vậy hiếm khi được mong đợi.Thông thường, bạn cần các đối tượng riêng biệt cho mọi phần tử mảng –

+0

cảm ơn @TagirValeev đã sửa đổi một swer. –

3

Không thường xuyên cần bạn tạo các đối tượng cùng loại với mảng với hàm tạo mặc định. Đôi khi bạn muốn gọi hàm tạo tùy chỉnh. Đôi khi bạn muốn khởi tạo các lớp con và lưu trữ chúng trong mảng.

Lưu ý rằng mảng Java className[] obj tương đương với mảng C++ className* obj[n], không chỉ className obj[n], bởi vì nó là một mảng tham chiếu đến các đối tượng, không phải mảng các đối tượng. Với Java-8, bạn không thể tạo một mảng các đối tượng (chúng được thảo luận như một phần của project Valhalla, nhưng sẽ không xuất hiện ngay cả trong Java-9). Khi bản thân các đối tượng được lưu trữ trong mảng trong C++, bạn phải khởi tạo mảng. Bạn không thể giữ "nulls" hoặc một cái gì đó như thế này ở đó, bởi vì null không phải là một đối tượng, nó là tham chiếu (hoặc con trỏ). Khi bạn tạo mảng className* obj[n] trong C++ (tương tự với mảng Java className[] obj), nó cũng chưa được khởi tạo.

Cuối cùng lưu ý rằng trong Java-8 bạn có thể khá dễ dàng tạo ra tất cả các đối tượng instantiating chúng với constructor mặc định như thế này:

className[] array = Stream.generate(className::new).limit(n).toArray(className[]::new); 
+0

@Tiger nếu chúng ta cần một thời gian không-argu-constructor và đôi khi argu-constructor thì tại sao chúng ta tạo tài liệu tham khảo? chúng ta có thể tạo đối tượng khi chúng ta cần constructor khác nhau.'className obj = new className (5); 'hoặc đôi khi' className obj2 = new className ("A"); 'Như tôi mong đợi Nó có thể chỉ dành cho khả năng đọc mã và ít mã hóa hơn. Có lý do nào khác không? (Xin lỗi vì tiếng Anh kém) –

+0

@Tagir Không phải lỗi của bạn tất nhiên, nhưng tôi sẽ không đi xa như gọi giải pháp Java-8 "dễ" –

+0

@LetDoit, xin lỗi tôi không hiểu câu hỏi của bạn. Hãy thử rephrase nó. Nếu khu vực nhận xét không đủ, hãy cân nhắc đăng câu hỏi mới thêm tất cả các ví dụ cần thiết. –

1

Trong Java, bất cứ khi nào bạn khai báo một biến, có thể là một thành viên của một đối tượng hoặc biến cục bộ, đó là loại nguyên thủy (byte, char, ...) hoặc kiểu tham chiếu (con trỏ đến đối tượng của một số loại).
Vì vậy, không có mảng đối tượng, chỉ mảng tham chiếu.

Trong C++ bạn có quyền tự do và trách nhiệm để lựa chọn bao nhiêu indirections bạn làm gì, làm thế nào để phân bổ, miễn phí, xây dựng và tiêu diệt các đối tượng, thêm nhiều phức tạp:

  • dereference-điều hành (*pointer)
  • dereference-and-use-viên (pointer->member)
  • address-of-nhà điều hành (&object)
  • một cách để lấy được một con trỏ-to-type từ các loại khác (type* var).
  • theo vị trí mới (`mới (con trỏ) gõ (arg1, arg2);.?
  • rõ ràng xóa-điều hành (delete pointer)
  • nhiều hơn nữa
Các vấn đề liên quan