2011-08-02 25 views
9

Tôi đang sử dụng lớp trừu tượng std :: ostream. Có tham chiếu sau đây:Tại sao gán cho một tham chiếu đến std :: ostream không biên dịch?

std::ostream &o = std::cout; 

Nếu đáp ứng bất kỳ điều kiện nào, tôi cần khởi tạo o để đầu ra sẽ được chuyển hướng đến std :: cout. Nếu không, đầu ra sẽ được chuyển hướng đến tệp

if (!condition) 
    o = file; //Not possible 

Làm thế nào để viết mã chính xác?

+0

Vấn đề này là nhiều hơn về việc tham chiếu lại so với std :: ostream, tôi khuyên bạn nên thay đổi tiêu đề. Bởi vì câu hỏi là một câu hỏi hay. – daramarak

+0

Bạn cần hiểu tham chiếu trong C++ chỉ có nghĩa là một bí danh. Vì vậy, khi tài liệu tham khảo đã được khởi tạo, bất kỳ toán tử thêm nào = để nó có nghĩa là chỉ thay đổi mục gốc mà tham chiếu đã đề cập đến. Một ví dụ tốt có thể được tìm thấy trong câu trả lời của Steve dưới đây. – Gob00st

Trả lời

5

Bạn không thể đặt lại tham chiếu.

Đây là một sự thay thế mặc dù:

std::ostream &o = (!condition) ? file : std::cout; 
16

Hoặc:

std::ostream &o = condition ? std::cout : file; 

hoặc nếu có mã trong giữa hai đoạn mã của bạn:

std::ostream *op = &std::cout; 
// more code here 
if (!condition) { 
    op = &file; 
} 
std::ostream &o = *op; 

Vấn đề không phải là đặc biệt để làm với lớp trừu tượng, đó là các tham chiếu không thể được reseated.

Ý nghĩa của biểu thức o = file không phải là "làm o tham khảo file", nó được "sao chép giá trị của file vào referand của o". May mắn cho bạn, std::ostream không có operator= và do đó không thể biên dịch và std::cout không được sửa đổi. Nhưng hãy xem xét điều gì xảy ra với một loại khác:

#include <iostream> 

int global_i = 0; 

int main() { 
    int &o = global_i; 
    int file = 1; 
    o = file; 
    std::cout << global_i << "\n"; // prints 1, global_i has changed 
    file = 2; 
    std::cout << o << "\n"; // prints 1, o still refers to global_i, not file 
} 
+0

+1 cho lời giải thích tuyệt vời và tốt đẹp của Steve! – Gob00st

+0

@Steve: Vấn đề không chỉ là các tham chiếu không thể được thiết lập lại, trong trường hợp của OP 'o = file' cũng sẽ không biên dịch, [vì' std :: ostream' hoặc bất kỳ luồng nào trong C++ không thể được gán (hoặc sao chép).] (http://stackoverflow.com/questions/6010864/why-copying-stringstream-is-not-allowed/6010930#6010930) – Nawaz

+0

@Nawaz: Tôi đề cập đến điều đó, nhưng IMO nó không phải là một vấn đề. Tôi không nghĩ rằng người hỏi thực sự muốn chuyển hướng 'stdout' chính nó vào một tập tin, đó là hiệu ứng duy nhất tôi có thể nghĩ rằng' operator = 'sẽ có nếu nó đã tồn tại. –

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