0
#include <iostream>
using namespace std;
class A {
public:
    int first;
    int last;
    A(int x = 0, int y = 0):first(x), last(y){}
    A(A&a) { cout << "c ctor \n"; }
};
ostream& operator<<(ostream& os, A b) {
    os << "first:" << b.first << "  last:" << b.last << endl;
    return os;
}
istream& operator>>(istream& is, A a) {
    is >> a.first >> a.last;
    return is;
}
int main()
{
    A i;
    cout << "enter first and last: \n";
    cin >> i;
    cout << i;
    system("pause");
    return 0;
}

A a is a new A object in the >> overload, and if we enter 6 4 into it, the program will remember it in the << overload function, and print what we entered into it. Can someone explain why? Thanks.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Steve_
  • 1
  • Your program is buggy due to the `A` copy constructor not actually making copies. – PaulMcKenzie Feb 06 '20 at 21:00
  • But the program runs fine. The copy constructor doesn't copy the values of i into a, but a still exists as an A object, and I can enter values into it in the >>overload function(where it's created) – Steve_ Feb 06 '20 at 21:02
  • Welcome to undefined behavior land. Anything can happen there – NathanOliver Feb 06 '20 at 21:03
  • 1
    @Steve_ Your program is passing `A` by value, thus a copy will be made. But you overrode the compiler's default copy constructor with your own buggy version that doesn't make copies. One of the hardest bugs to track down is the one you are making right now, and that is a program that makes bogus copies. – PaulMcKenzie Feb 06 '20 at 21:03
  • @PaulMcKenzie that should probably be an answer. I'll upvote it – Aykhan Hagverdili Feb 06 '20 at 21:06
  • So why does the program 'remember' the numbers I entered into a, and prints them in the << operator? How does it know about the numbers I entered, if they weren't entered into 'i'? – Steve_ Feb 06 '20 at 21:06
  • Btw It's buggy on purpose; It's a question from a test; – Steve_ Feb 06 '20 at 21:07
  • *So why does the program 'remember' the numbers I entered into a, and prints them in the << operator?* -- Are you familiar with what "undefined behavior" is in C++? – PaulMcKenzie Feb 06 '20 at 21:08
  • @Steve_ in `A(A&a) { cout << "c ctor \n"; }` you don't actually initialize anything. Then you try to read the memory you never initialized, which causes undefined behavior. – Aykhan Hagverdili Feb 06 '20 at 21:09
  • Never heard of that... – Steve_ Feb 06 '20 at 21:10
  • 2
    Undefined behavior means anything can happen. That "anything" could be that the program works today, and bombs out next week. – PaulMcKenzie Feb 06 '20 at 21:11
  • Thanks, I appreciate the detailed answer – Steve_ Feb 06 '20 at 21:13
  • `stream& operator>>(istream& is, A a)` should be `stream& operator>>(istream& is, A& a)` – Richard Critten Feb 06 '20 at 21:21
  • I didnt find a good duplicate, but here is a quite comprehensive list of causes of UB: https://stackoverflow.com/a/367662/4117728 – 463035818_is_not_an_ai Feb 06 '20 at 21:23
  • If you want some explanation of what's happening beyond 'It's undefined behavior' you can look at the actual code your compiler has generated, all you answers will be there. – Pete Fordham Feb 07 '20 at 01:01

1 Answers1

2

This is a wrong statement relative to your presented code because the operator >> deals with a copy of the original object used as an argument of the operator.

The operator should be declared like

istream& operator>>(istream& is, A &a) {
    is >> a.first >> a.last;
    return is;
}

And moreover the copy constructor does not copies data members.

So the program has undefined behavior. For example running it using clang HEAD 11.0.0 you can get the following result

prog.cc:8:9: warning: unused parameter 'a' [-Wunused-parameter]
    A(A&a) { cout << "c ctor \n"; }
        ^
1 warning generated.
enter first and last: 
c ctor 
c ctor 
first:4202496  last:0

That is the program outputs the variables first and last with indeterminate values because the data members of the created object b in the operator << were not initialized.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I know, I just want to understand why the numbers I enter in the >> operator get saved, and printed in the << operator function. – Steve_ Feb 06 '20 at 21:04
  • @Steve_ As you can see [here](https://wandbox.org/permlink/7JpEoZARZErOz3w6) and [here](https://wandbox.org/permlink/OHnUuIFNoLJd7Wh1) they aren't saved. It's undefined behavior. Anything can happen. Different compilers generate different code. – Thomas Sablik Feb 06 '20 at 21:28
  • not using parameter `a` is not what causes UB, the warning could be silenced via `A(A& a) { cout << a; }`, while the UB would be gone with `A(A& a) : first(0),last(0) {}` – 463035818_is_not_an_ai Feb 06 '20 at 21:28
  • @idclev463035818 The problem is that the data members are not initialized. – Vlad from Moscow Feb 06 '20 at 21:30
  • i know, I am just saying that `A(A& a) : first(0),last(0) {}` does initialize them but still does not make a copy – 463035818_is_not_an_ai Feb 06 '20 at 21:30