Write to the ostream constant link

I am reading a C ++ primer. I came across the following code:

#include <iostream>
#include <string>

using namespace std;

class PrintString {
public:
    PrintString(ostream &o = cout, char c = ' '): os(o), sep(c) {}
    void operator() (const string &s) const { os << s << sep; }
private:
    ostream &os;
    char sep;
};


int main() {
    const PrintString printer;

    printer("ABC");

    return 0;
}

This code works, but I don’t know why. Below I think it would be great if someone could indicate where I am mistaken ...

Here, "printer" is an const PrintString object, so its data members are constants, so "printer.os" is a const reference to cout. Therefore, we will not be able to write to "printer.os", since writing to cout changes it.

Thanks in advance!

+4
source share
3 answers

Your confusion with const-ness is better explained by a pointer rather than a link.

Say what you have:

struct A {int data;};

struct B
{
   B(A* ptr) : aPtr(ptr) {}
   A* aPtr;
};    

int main()
{
   A a1;
   A a2;
   const B b(&a1);
   // This makes b a const object.
   // This makes b.aPtr a const pointer. That means, you cannot change where it points to
   // but you can still change the value of what it points to.
   b.aPtr = &a2; // Not ok.
   b.aPtr->data = 10; // OK.    
}

b.aPtr , , .

int main()
{
   A a1;
   A a2;
   A* const aPtr1 = &a1;
   // This makes aPtr1 a const pointer. That means, you cannot change where it points to
   // but you can still change the value of what it points to.
   aPtr1 = &a2; // Not ok.
   aPtr1->data = 10; // OK.

   A const* aPtr2 = &a1;
   // This makes aPtr2 a pointer to a const object. That means, you can change where it points to
   // but you cannot change the value of what it points to.
   aPtr2 = &a2; // ok.
   aPtr2->data = 10; // Not ok.
}

, , . , const. , , .

A a1;
A& ref = a1;  // ref cannot be changed to reference any other object.

const PrintString printer;

const - - PrintString::os. const ostream. :

const PrintString printer;
printer("ABC");
+2

, , . . int (int*), const int* const. , , . :

struct Foo
{
    int a;
    int* p = &a;

    void foo() const
    {
        p = new int; // ERROR! Not allowed to modify const pointer
        *p = 100; // OK, it a pointer to a non-const int
    }
};

os , , .

+4

-- , constness - const . , const, - , , . . , const ( const), .

#include <iostream>

struct S {
    int *p;
    int *const cp;
    int &ref;
};

int main() {
    using namespace std;

    int i = 10;
    const S s{&i, &i, i};

    // s.p = &i; // can't do this, s.p gets const

    *s.p = 20;  // changing the pointee
    cout << i << endl;

    // s.p = &i; // can't do this, s.p was const already, and would get if it weren't

    *s.cp = 30;  // changing the pointee
    cout << i << endl;

    // s.ref ?; // can't make a reference refer to other object

    s.ref = 40;  // changing the pointee
    cout << i << endl;
}
+1

All Articles