2011-09-25 33 views
7
import std.stdio; 

class IntegerContainer 
{ 
    public int Integer = 1; 
} 

void DoubleInteger(IntegerContainer Container) 
{ 
    Container.Integer *= 2; 
} 

void main() 
{ 
    IntegerContainer Container = new IntegerContainer; // Internal integer defaults to one. 
    DoubleInteger(Container); // Internal integer changes to two inside the function. 
    writefln(Container.Integer); // Prints "2." 
} 

Trong D, tham chiếu và giá trị là đặc điểm của loại, thay vì tham số hàm. Đến từ C++, điều này thật sự rất tệ với tôi.Làm cách nào để chuyển đối tượng theo giá trị?

Có vẻ như có một từ khóa ref để bắt buộc tham chiếu cho các hàm chấp nhận struct s. Có tương đương như vậy để chuyển số class es theo giá trị không?

Ví dụ: giả sử tôi muốn tạo hàm chức năng trả về bản sao được sắp xếp của một lớp chứa tùy chỉnh. Trong C++, điều đó đơn giản như sử dụng Foo Sorted(Foo Object), trái ngược với Foo Sort(Foo& Object). Tôi thấy không có cách nào để làm điều này trong D mà không cần sao chép thủ công đối tượng.

+1

ngay cả với các đối tượng của lớp học, nó vẫn là giá trị theo từng giá trị, vì đó là tham chiếu bạn đang chuyển, theo giá trị – newacct

+3

@newacct Tôi nghĩ mọi người đều biết ý nghĩa của "giá trị theo giá trị". – Maxpm

Trả lời

11

Các lớp là loại tham chiếu theo thiết kế. Chúng không được chuyển qua giá trị. Nó chính xác giống với Java và C#. Tuy nhiên, không giống như Java và C#, D cũng có các loại giá trị do người dùng định nghĩa chính xác, vì nó có cấu trúc (C# cũng có cấu trúc, nhưng chúng là nhiều hơn nhiều hạn chế hơn). Thực tế là C++ conflates hai gây ra vấn đề như object slicing.

Bây giờ, hiển nhiên là có lần khi bạn muốn sao chép loại tham chiếu. Giải pháp cho điều đó là cloning. Bạn cung cấp cho lớp của bạn một hàm clone trả về một bản sao của đối tượng mà nó được gọi. Bằng cách đó, bạn có thể sao chép nó khi cần, và nó chỉ được sao chép khi bạn cần. Java và C# có hàm clone tiêu chuẩn mà hầu hết các loại thực hiện, nhưng vì bất kỳ lý do gì D không. Tôi cung không chăc tại sao. Nhưng nó vẫn đủ dễ dàng để tự khai báo một hàm như vậy cho các kiểu của riêng bạn. Nó sẽ không nằm trên Object, mà sẽ cho phép bạn sử dụng nó trên khá nhiều đối tượng lớp mà không quan tâm đến loại thực tế giống như bạn có thể làm trong Java và C#. Bạn luôn có thể tạo một hàm tạo bản sao thay vào đó, nếu bạn thích, nhưng nó ít linh hoạt hơn, bởi vì bạn phải biết kiểu đối tượng đang được sao chép, trong khi với clone, nó có thể là bất kỳ loại nào bắt nguồn từ kiểu trả về cloneObject trong trường hợp của Java và C# nhưng sẽ là bất cứ điều gì bạn quyết định trong D, vì hàm này không chuẩn).

+1

IIRC một vài điều trong D (mảng) có thuộc tính 'dup'. – BCS

+0

Có, nhưng các lớp học thường không thực hiện chức năng như vậy. Có thể mặc dù nó sẽ trở thành điển hình để thực hiện một hàm gọi là 'dup' chứ không phải là 'clone' mặc dù chưa có nhiều lớp trong thư viện chuẩn, vì vậy tôi không nghĩ rằng một hàm sao chép cụ thể đã ở tất cả các tiêu chuẩn được nêu ra). Bất kể, đó là cùng một khái niệm một trong hai cách. –

+0

Ah. Vâng. Tôi nên rõ ràng hơn: bởi vì những thứ khác sử dụng 'dup', có thể không nên gọi hàm 'clone'. Giữ tên giống nhau có thể làm cho mã mẫu sạch hơn. – BCS

4

Vâng, chỉ cần sử dụng cấu trúc thay vì một lớp.

Nhưng nếu bạn muốn sao chép một đối tượng , thì bạn phải thực hiện nhân bản chính mình. Lưu ý rằng các nhà thiết kế D đã không thực hiện điều này; nó giống hệt như trong C#, và khá giống với Java. Mục đích là để ngăn chặn các đối tượng bị sao chép quá mức, được xem như một nhược điểm của C++ (vì nó rất ẩn trong mã).

+0

Xem chỉnh sửa. [15char] – Maxpm

+1

@Maxpm: Xem câu thứ nhất của đoạn thứ 2 của tôi. – Mehrdad

3

Ngay cả trong C++ này:

Foo Sorted(Foo Object) 

không phải là hữu ích. Điều gì nếu Object đã được sắp xếp và bạn không cần phải tạo một bản sao?

Trong D, bạn cần cung cấp clone() một số thứ như vậy cho lớp học của bạn và gọi nó nếu cần.

Nếu không, hãy sử dụng các cấu trúc như Mehrdad đã đề cập.

Chỉnh sửa: Không rõ chính xác "sao chép đối tượng" sẽ làm gì. Nếu nó có mảng các đối tượng bên trong thì nó sẽ sao chép mảng đó? Và những gì về tham chiếu đối tượng nó chứa? Nó thực sự là tốt mà monsieur Walter Bright, tác giả của D, đã không cung cấp sao chép các trường hợp lớp theo mặc định.

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