OK, đây là những gì tôi đã tìm thấy.
Thực ra, I/O cuối cùng được thực hiện bởi các cuộc gọi và chức năng hệ thống gốc.
Bây giờ, hãy lấy Microsoft Windows làm ví dụ. Trên thực tế, có các tay cầm có sẵn cho STDIN
, STDIO
vv (xem here). Về cơ bản, cả hai hàm C++ iostream
và C stdio
đều gọi hàm gốc, C++ iostream
không bọc các hàm I/O của C (trong các triển khai hiện đại). Nó gọi các phương thức hệ thống riêng trực tiếp.
Ngoài ra, tôi thấy điều này:
Khi stdin, stdout, và stderr được chuyển hướng, chức năng C chuẩn như printf() và được() có thể được sử dụng, mà không cần thay đổi, để giao tiếp với Win32 giao diện điều khiển. Nhưng những gì về C + + I/O suối? Vì cin, cout, cerr và clog có liên quan chặt chẽ với stdin, stdout và stderr của C, bạn có thể mong đợi chúng hoạt động tương tự. Điều này là một nửa bên phải.
Dòng C++ I/O thực sự có hai loại: mẫu và không phải mẫu. Phiên bản I/O cũ không có mẫu của các luồng I/O đang dần được thay thế bằng một kiểu luồng mới hơn được định nghĩa bởi Thư viện mẫu chuẩn (STL) và hiện đang được hấp thụ vào tiêu chuẩn ANSI C++. Visual C++ v5 cung cấp cả hai loại và cho phép bạn chọn giữa hai loại này bằng cách bao gồm các tệp tiêu đề khác nhau. Các luồng I/O STL hoạt động như bạn mong đợi, tự động sử dụng bất kỳ xử lý stdio mới được chuyển hướng nào. Tuy nhiên, các luồng I/O không phải mẫu không hoạt động như mong đợi. Để khám phá lý do tại sao, tôi nhìn vào mã nguồn, thuận tiện được cung cấp trên đĩa CD-ROM Visual C++.
Vấn đề là các luồng I/O cũ hơn được thiết kế để sử dụng "mô tả tập tin kiểu UNIX", trong đó các số nguyên được sử dụng thay vì xử lý (0 cho stdin, 1 cho stdout, vv). Điều đó thuận tiện cho việc triển khai UNIX, nhưng trình biên dịch Win32 C phải cung cấp thêm một lớp I/O khác để biểu diễn kiểu I/O đó, vì Win32 không cung cấp một bộ các hàm tương thích. Trong bất kỳ trường hợp nào, khi bạn gọi hàm _open_osfhandle() để liên kết một trình xử lý Win32 mới với (ví dụ) stdout, nó không có hiệu lực trên lớp I/O khác. Do đó, bộ mô tả tập tin 1 sẽ tiếp tục sử dụng cùng một trình xử lý Win32 cơ bản như trước đây và việc gửi đầu ra tới cout sẽ không tạo ra hiệu ứng mong muốn.
May thay, các nhà thiết kế gói luồng I/O ban đầu đã dự đoán được vấn đề này và cung cấp giải pháp sạch và hữu ích. Lớp ios cơ sở cung cấp một hàm tĩnh, sync_with_stdio(), làm cho thư viện thay đổi các mô tả tệp cơ bản của nó để phản ánh bất kỳ thay đổi nào trong lớp I/O tiêu chuẩn. Mặc dù điều này là không cần thiết cho các luồng I/O STL, nó không gây hại và cho phép tôi viết mã hoạt động chính xác với dạng luồng I/O mới hoặc cũ.
(source)
Do đó gọi sync_with_stdio()
thực sự thay đổi các file descriptor cơ bản. Thực tế nó được các nhà thiết kế thêm vào để đảm bảo khả năng tương thích của C++ I/O cũ hơn với các hệ thống như Windows-32 sử dụng các chốt xử lý thay vì các số nguyên.
Lưu ý rằng việc sử dụng sync_with_stdio()
là không cần thiết với C++ STL I/O dựa trên mẫu C++ hiện đại.
+1, woah Tôi luôn nghĩ rằng C++ 'iostream' là một trình bao bọc của C' stdio'. – ApprenticeHacker