2010-08-14 30 views
13

Tôi sẽ xem toàn bộ hướng dẫn tại cplusplus.com, viết mã và biên dịch từng ví dụ theo cách thủ công. Thường xuyên, tôi vấp phải thứ gì đó khiến tôi bối rối.Sự khác nhau giữa hàm (myVar) và (function) myVar là gì?

Tôi hiện đang học phần này: http://www.cplusplus.com/doc/tutorial/structures/. Có một số tinh tế có thể dễ dàng bị bỏ qua bằng cách chỉ đọc hướng dẫn. Lợi thế của việc gõ tất cả mọi thứ bằng tay là những chi tiết đó làm nổi bật.

Trong trang ở trên, có hai chương trình mẫu. Một có dòng này:

stringstream(mystr) >> yours.year; 

Một trong những khác có dòng này:

(stringstream) mystr >> pmovie->year; 

Những gì tôi không hiểu là phần chênh lệch (nếu có) giữa function (myVar) = x;(function) myVar = x;.

Tôi không làm toàn bộ hướng dẫn theo thứ tự tuần tự. Tôi đã kiểm tra nhưng không tìm thấy địa chỉ này ở bất cứ nơi nào, mặc dù tôi có thể đã bỏ lỡ nó.

  • Có sự khác biệt nào không?
  • Có cách nào ưu tiên để thực hiện theo cách này thay vì cách khác không?
+12

không phải là chức năng mà là một lớp học. cuộc gọi đầu tiên là cuộc gọi hàm tạo, cuộc gọi thứ hai là cuộc gọi của nhà điều hành chuyển đổi. – KeatsPeeks

Trả lời

55

Không có sự khác biệt giữa type(x)(type)x.Hai cái này hoàn toàn tương đương nhau. Hầu hết mọi người thích type(x) cho các lớp học và (type)x cho các loại không phải lớp học, nhưng đó hoàn toàn là sự lựa chọn của riêng mình. Cả hai nhà xây dựng cuộc gọi cho các lớp học với một đối số x.

Cách ưa thích cho các lớp là type(x), vì điều này cho phép chuyển nhiều hơn một đối số cho hàm tạo, như trong type(x, y). Cố gắng áp dụng các hình thức khác, (type)x, y sẽ không hoạt động: Nó phôi x và sau đó áp dụng toán tử dấu phẩy và đánh giá y cách ly. Dấu ngoặc đơn như (type)(x, y) không trợ giúp: Việc này sẽ đánh giá xy cách ly bằng toán tử dấu phẩy và sau đó truyền y đến type.

Đối với các loại không thuộc loại, dàn diễn viên thường quá mạnh. C++ có static_cast<type>(x) để thực hiện đảo ngược chuyển đổi ngầm (chẳng hạn như đúc lớp cơ sở cho các lớp dẫn xuất và đúc void* đến một con trỏ khác), thường là những gì phù hợp. Xem When should static_cast, dynamic_cast and reinterpret_cast be used?. Tuy nhiên,

stringstream không phải là chức năng. Làm function(x) sẽ gọi nó là hàm, nhưng làm (function)x là bất hợp pháp, beause có hai biểu thức bên cạnh nhau, không có toán tử ở giữa.


Đối với những người không tin câu trả lời này, và downvote nó trên cảm giác ruột, hãy tham khảo tiêu chuẩn tại 5.2.3/1

Một đơn giản-type-specifier (7.1.5) theo sau là một danh sách biểu thức được lồng trong ngoặc đơn xây dựng giá trị của loại được chỉ định cho danh sách biểu thức. Nếu danh sách biểu thức là một biểu thức duy nhất, biểu thức chuyển đổi kiểu là tương đương (trong định nghĩa và nếu được định nghĩa trong nghĩa) cho biểu thức truyền tương ứng (5.4).

+0

Tôi sẽ không nói nó chỉ là một metter của phong cách mã hóa: một là một diễn viên khác là một cuộc gọi constructor, họ là hai khái niệm khác nhau. – nico

+1

@nico nó không phải là vấn đề của ý kiến. Tiêu chuẩn xác định những gì là tương đương và những gì không. Nó định nghĩa hai cái này là tương đương, vì vậy nó tùy thuộc vào các kiểu mã hóa để nói những gì được sử dụng trong trường hợp nào. –

+0

Chúng tạo ra kết quả tương đương, điều đó không có nghĩa là chúng giống nhau, và trên thực tế, tiêu chuẩn không nói chúng giống nhau, chỉ là kết quả của chúng tương đương nhau. Có lẽ là vấn đề ngữ nghĩa, nhưng tôi nghĩ câu hỏi này là về ngữ nghĩa. – nico

4

Trang bạn trích dẫn không phải là những gì tôi sẽ xem xét thẩm quyền trên C++ nói chung.

Dù sao,

(stringstream) mystr >> pmovie-> năm;

phôi std::string cho đối tượng std::stringstream. Đây là dàn diễn viên kiểu C. Khá nguy hiểm nếu bạn không biết mình đang làm gì. Điều này sẽ tạo đối tượng stringstream và giá trị được trích xuất thành pmovie->year tiếp theo.

stringstream (mystr) >> yours.year;

Tạo một đối tượng ẩn danh std::stringstream và khởi tạo nó với mystr và sau đó giá trị được chiết xuất để pmovie->year. Đối tượng biến mất ở cuối phạm vi từ vựng của nó, trong trường hợp này sẽ là ; ở cuối dòng.

Không có nhiều sự khác biệt (như những người khác đã lưu ý cho đến nay) trong số hai đối tượng lớp w.r.t.

Mặt khác, với số nhận dạng (của hàm/macro) điều này trở nên phức tạp: function (myVar) = x; hoạt động bất kể function là hàm thực tế hay macro. Tuy nhiên, (function) (myVar) = x; chỉ hoạt động cho các chức năng thực.

Một số mã định danh thư viện chuẩn được phép có cả hai biểu mẫu (đáng chú ý nhất là tolower và bạn bè) và do đó nếu bạn muốn gọi hàm luôn thì bạn nên đi trước.

+1

có vấn đề gì với cplusplus.com? Tôi sử dụng tài liệu tham khảo của họ mọi lúc. – rubenvb

+1

Đó là một ý kiến ​​cá nhân, tất nhiên. Và câu hỏi của OP là một trường hợp tại điểm. – dirkgently

+1

Câu trả lời của bạn cho thấy có sự khác biệt giữa cả hai biểu mẫu, nhưng không chi tiết về sự khác biệt đó. Nó cũng cho thấy biểu thức không đúng dạng '(function) myVar' sẽ hợp lệ (trái ngược với' (function) (myVar) '). –

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