2011-08-03 30 views

Trả lời

13

Với tôi, mẫu C++ đã sử dụng ý tưởng nhập vịt, đúng không?

Không, mẫu C++ được sử dụng để triển khai mã chung. Tức là, nếu bạn có mã có thể hoạt động với nhiều loại, bạn không phải sao chép mã đó cho từng loại. Những thứ như std::vectorstd::list là những ví dụ rõ ràng về hành động này. Các mẫu C++ have been abused làm những việc khác, nhưng tính tổng quát là ý định ban đầu.

Có phải tất cả các loại chung được tham chiếu trong lớp mẫu hoặc phương pháp là loại vịt?

Không, chúng chỉ là các loại "bình thường" giống như mọi loại khác trong C++. Chúng chỉ không được biết cho đến khi mẫu thực sự được khởi tạo.

Tuy nhiên, mẫu có thể được sử dụng để triển khai thực hiện một cái gì đó như nhập vịt. Iterator là một ví dụ. Xem xét chức năng này:

template<class InputIterator, class OutputIterator> 
    OutputIterator copy(InputIterator first, InputIterator last, 
         OutputIterator result) 
{ 
    while (first!=last) *result++ = *first++; 
    return result; 
} 

Lưu ý rằng copy chức năng có thể chấp nhận lý lẽ của bất kỳ loại, như dọc vì nó thực hiện các hành bất bình đẳng, các toán tử tham chiếu, và các nhà điều hành tăng postfix. Đây có lẽ là gần như gõ vịt như bạn sẽ nhận được trong C + +.

+7

Từ sự hiểu biết hạn chế của tôi về cách gõ vịt, mô tả của bạn về chức năng sao chép có âm thanh chính xác như thể nó sử dụng kiểu gõ vịt. Điều gì là chính xác mà characterizes gõ vịt mà không phải là "hoàn thành" bởi C + + mẫu? – aioobe

+5

@aioobe: Như tôi đã hiểu, việc gõ vịt là một điều xảy ra trong thời gian chạy như trái ngược với thời gian biên dịch. Tôi nói nó giống như gõ vịt bởi vì trình biên dịch vẫn thực hiện kiểm tra kiểu tại thời gian biên dịch như thể nó không làm bất kỳ kiểu gõ vịt nào. Nó chỉ là các loại không được biết đến cho đến khi một trong những thực sự sử dụng các mẫu. –

+0

Từ quan điểm của việc khởi tạo mẫu, thời gian biên dịch/thời gian chạy-phân biệt tương ứng với việc khởi tạo trước và sau khi khởi tạo. IMHO sự phân biệt thời gian biên dịch/thời gian chạy có lẽ tốt hơn là suy nghĩ như là một thể hiện của sự phân biệt thời gian biên dịch/thời gian biên dịch (tức là 'hành vi được biết/quyết định tại hoặc trước thời gian biên dịch' vs 'sau đó') . Ví dụ: python kiểm tra khi gọi object.hello(), không phải khi biên dịch sang bytecode, C++ sẽ kiểm tra khi cố gắng biên dịch Type1 & object :: hello (Type1 x, Type2 y) {return x + y; } thay vì khi chuyển c = object.hello (a, b); vào điều này. –

3

Vâng, loại - ví dụ nếu loại XAddRef(), Release()QueryInterface() phương pháp có chữ ký thích hợp nó có thể được sử dụng như là một đối tượng COM với CComPtr lớp mẫu. Nhưng đây không phải là kiểu gõ vịt hoàn chỉnh - việc kiểm tra kiểu vẫn được thực thi cho các tham số.

2

Không, đây là một khái niệm khác. gõ vịt là một phương pháp để tìm ra loại của một container năng động đánh máy. Các mẫu C++ không được nhập động, chúng được khởi tạo với một kiểu cụ thể.

4

Không chính xác. Các loại vịt (kiểu kiểu động) sẽ không bao giờ tạo ra các lỗi kiểu thời gian biên dịch vì chúng không có bất kỳ kiểu nào. Với mẫu, bạn không có loại cho đến khi bạn tạo mẫu. Khi bạn thực hiện, các biến có các loại riêng biệt và bạn thực sự sẽ nhận được các lỗi biên dịch.

Ngoài ra, với các loại vịt, bạn có thể có một điểm biến đối với các loại đối tượng khác nhau, vì các biến chỉ không có loại. Điều đó là không thể với các mẫu - khi bạn khởi tạo chúng, các biến có một kiểu cụ thể duy nhất.

Chúng tương tự, tuy nhiên, trong các ràng buộc đó là ẩn: chỉ các tính năng thực sự được sử dụng mới được chọn. Ngược lại, nói, các con trỏ đa hình, loại thực tế không quan trọng.

59

Đối với tôi, mẫu C++ là phiên bản biên dịch kiểu gõ vịt. Trình biên dịch sẽ biên dịch, ví dụ: Class và miễn là Duck của bạn có tất cả các loại cần thiết, nó sẽ khởi tạo một lớp.

Nếu có điều gì đó không chính xác (ví dụ: nhà xây dựng bản sao bị thiếu) thì quá trình biên dịch không thành công. Các đối tác trong ducktyping thực là một thất bại khi bạn gọi một chức năng với một loại không vịt. Và ở đây nó sẽ xảy ra trong thời gian chạy.

+0

hmm .. hiểu biết của tôi từ việc nhập vịt là bạn cố gắng tìm ra loại. Điều đó có nghĩa là bạn gặp phải một đối tượng động và bạn không chắc chắn về loại đó. Trong các mẫu C++ bạn phải chắc chắn về kiểu, để khởi tạo nó. – duedl0r

+4

-1. Việc nhập Duck không nhất thiết ngụ ý nhập liệu động hoặc kiểm tra thời gian chạy. Cách gõ vịt thời gian biên dịch vẫn là kiểu gõ vịt. –

+0

Mẫu C++ ban đầu được dựa trên phát lại mã thông báo. Điều đó vẫn cho thấy trong loại vịt của nó giống như tài sản. –

10

Nhập liệu có nghĩa là vịt ", nếu nó giống như vịt và đi như vịt, thì đó là vịt". Nó không có một định nghĩa chính thức trong khoa học máy tính để chúng ta so sánh C++.

C++ không giống với (ví dụ) Python, tất nhiên, nhưng cả hai đều có khái niệm về giao diện ngầm định. Giao diện yêu cầu của một đối tượng được sử dụng như một đối số hàm Python là bất kỳ hàm nào thực hiện với nó. Giao diện được yêu cầu của một kiểu được sử dụng như là một đối số mẫu C++ là bất kể mẫu nào làm với các đối tượng thuộc loại đó. Đó là sự giống nhau, và đó là nền tảng mà trên đó các mẫu C++ cần được đánh giá.

Hơn nữa, vì trích dẫn đối số mẫu, trong C++, bạn có thể thử truyền bất kỳ đối tượng cũ nào và trình biên dịch sẽ tìm hiểu xem nó có thể khởi tạo mẫu chức năng hay không.

Một khác biệt là trong C++, nếu đối số không quack, thì đối tượng trình biên dịch. Trong Python, chỉ các đối tượng thời gian chạy (và chỉ khi hàm thực sự được gọi, nếu có các điều kiện trong mã). Đây là một sự khác biệt về bản chất của giao diện được yêu cầu của một đối tượng/kiểu - trong C++ hoặc khuôn mẫu yêu cầu một biểu thức cụ thể là hợp lệ, hoặc nó không yêu cầu điều đó. Trong Python, các biểu thức hợp lệ cần thiết có thể phụ thuộc vào các giá trị thời gian chạy của các biểu thức cần thiết trước đó. Vì vậy, trong Python bạn có thể yêu cầu một đối tượng hoặc là quacks to hoặc lặng lẽ, và nếu nó quests loudly nó cần phải đi bộ quá. Trong C++, bạn có thể thực hiện điều đó theo điều kiện dynamic_cast và nếu âm lượng là hằng số biên dịch, bạn có thể thực hiện mẫu chuyên môn, nhưng bạn không thể sử dụng tính năng nhập tĩnh để nói rằng vịt chỉ cần đi bộ nếu quack_volume() trả về loud. Và dĩ nhiên trong Python giao diện được yêu cầu có thể không thực sự là "bắt buộc" - hành vi nếu một phương thức không có mặt là ném ngoại lệ và có thể tài liệu và đảm bảo hành vi của người gọi nếu điều đó xảy ra.

Tùy thuộc vào bạn cho dù bạn xác định "nhập từ vịt" để sự khác biệt này có nghĩa là C++ không có.

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