Dlaczego nie mogę utworzyć obiektu ostream?

0

Witam

Tak jak w temacie. Dlaczego utworzenie obiektu ostream jest niedozwolone? Kompilator wyrzuca błąd: cannot access private member declared in class 'std::basic_ostream<_Elem,_Traits>'. czyli że jest to prywatny element klasy, ale nie rozumiem dlaczego jest prywatny... Poniżej zamieściłem funkcję zaprzyjaźnioną która ma zwracać kopie obiektu ostream, oczywiście nie chce działać. Natomiast kompilator w ogóle nie protestuje gdy w scopie tej funkcji tworzy się zmienna automatyczna ostream os... Wiem, że należałoby użyć referencji ale chce zrozumieć dlaczego to nie działa bez referencji.
Dzięki za wszelką pomoc:)

ostream operator<<(ostream os, const Time & t)
{
    os << t.hours << " godzin, " << t.minutes << " minut";
    return os;
}

0

Tak zdecydowano, aby korzystać z referencji do obiektu i zwracać też referencję do niego.
Umożliwia to konstrukcje jak:

Time t;
std::cout << t << "jeszcze coś" << /*jakiś inny obiekt*/;

Natomiast zwrócenie przez wartość (czyli kopiowanie) jest niedozwolone,
ponieważ konstruktor kopiujący jest usunięty (delete lub private - zależy od implementacji).
Możesz skorzystać z move ctor.
http://www.cplusplus.com/reference/ostream/ostream/ostream/

3

Zastanówmy się, czym miałaby być kopia strumienia.

Jeśli strumień zapisuje do pliku, to kopia miałaby zapisywać do drugiego pliku? Jakiego i po co? A jeśli do tego samego, to po co kopiować strumień?

Jeśli do konsoli, to kopia ma działać na drugiej konsoli? Czy na tej samej? Jeśli na tej samej itd.

Jeśli to tylko bufor w pamięci, to kopia strumienia ma tworzyć nowy bufor? A co z zapisanymi już danymi?

Strumień to nie plik. I nie konsola. To „urządzenie” wysyłające gdzieś dane - i, poza jakimś tymczasowym buforowaniem - nie pamięta nawet co wysłał wcześniej.
Słowem: nie można kopiować strumienia bo to nie ma logicznego sensu.

0

To dlaczego kompilator pozwala na utworzenie w scope funkcji parametr ostream os?

0

No ale nie pozwala przecież:

#include <iostream>

using namespace std;

struct point
{
    int x{ 0 };
    int y{ 0 };
};

ostream operator<<(ostream os, const point& p)
{
    os << p.x << " " << p.y;
    return os;
}

int main()
{
    point p;
    
    std::cout << p;
}
prog.cc:14:12: error: calling a protected constructor of class 'std::__1::basic_ostream<char>'
    return os;
           ^
/opt/wandbox/clang-head/include/c++/v1/ostream:170:5: note: declared protected here
    basic_ostream(basic_ostream&& __rhs);
    ^
prog.cc:21:5: error: call to deleted constructor of 'std::__1::ostream' (aka 'basic_ostream<char>')
    std::cout << p;
    ^~~~~~~~~
/opt/wandbox/clang-head/include/c++/v1/ostream:181:5: note: 'basic_ostream' has been explicitly marked deleted here
    basic_ostream           (const basic_ostream& __rhs) = delete;
    ^
prog.cc:11:28: note: passing argument to parameter 'os' here
ostream operator<<(ostream os, const point& p)
                           ^
2 errors generated.

prog.cc:21:5: error: call to deleted constructor of 'std::__1::ostream' (aka 'basic_ostream<char>')
...
prog.cc:11:28: note: passing argument to parameter 'os' here
ostream operator<<(ostream os, const point& p)
^

1 użytkowników online, w tym zalogowanych: 0, gości: 1