0

This is the full example (source book: C++ From Ground Up, 3rd Edition, page 219-320):

class sample {
    char *s;
    public:
        sample(); // normal constructor
        sample(const sample &ob); // copy constructor
        ~sample( ) { cout << "s: " << s <<" ,Freeing s\n"; if(s) delete [] s;}
        void show() { cout << s << "\n"; }
        void set(char *str);
        sample operator=(const sample &ob); // overload assignment
};
// Normal constructor.
sample::sample() {
    s = new char('\0'); // s points to a null string.
    cout << "Normal constructor: s: " << strlen(s) << endl;
}
// Copy constructor.
sample::sample(const sample &ob) {
    cout << "Copy constructor: ob.s: "<< ob.s << " ,strlen(ob.s): " <<  strlen(ob.s) << "\n";
    s = new char[strlen(ob.s)+1];
    strcpy(s, ob.s);
}
// Load a string.
void sample::set(char *str) {
    s = new char[strlen(str)+1];
    strcpy(s, str);
}
// Overload assignment operator.
sample sample::operator=(const sample &ob) {
    /* If the target memory is not large enough
    then allocate new memory. */
    cout << "operator= strlen(ob.s): " << strlen(ob.s) << " ,strlen(s): " << strlen(s) << endl;

    if(strlen(ob.s) > strlen(s)) {
        cout << "operator= Larger memory of target object. Deleting current...\n";
        delete [] s;
        s = new char[strlen(ob.s)+1];
    }
    strcpy(s, ob.s);

    return *this;
}
// Return an object of type sample.
sample input() {
    char instr[80];
    static sample str;
    cout << "Enter a string: ";
    cin >> instr;
    str.set(instr);

    return str;
}

int main() {
    sample ob;
    // assign returned object to ob
    ob=input(); // This is now OK
    ob.show();

    return 0;
}

However I do not get why TWO times copy constructor is called. (output once code is ran)

Normal constructor: s: 
Normal constructor: s: 
Enter a string: Hello
Copy constructor: ob.s: Hello ,strlen(ob.s): 5
operator= strlen(ob.s): 5 strlen(s): 0
operator= Larger memory of target object. Deleting current...
Copy constructor: ob.s: Hello ,strlen(ob.s): 5 
s: Hello, Freeing s
s: Hello, Freeing s
Hello
s: Hello, Freeing s
s: Hello, Freeing s

I know it is called when input() function returns, and create temporary object (by calling copy constructor), but I do not get why second time since, as much as I know (but maybe I am wrong) copy constructors are NOT called for assignment operations, but it looks like, despite of that, when return *this; is called (when overloaded operator returns value), copy constructor is called? What did I missed?

Thankx

Creator
  • 21
  • 1
  • 6
  • 2
    This whole `new`/`delete` business is not best practice. You might want to invest in a [better book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Baum mit Augen Jun 11 '15 at 12:07
  • 5
    Is this really a sample from a book? It's quite terrible code. Using a static variable for no reason, memory leak if `set` is called twice, Mismatched `new` with `delete[]`, manual memory management, etc. – interjay Jun 11 '15 at 12:08
  • It is a "Schild" book (and to add insult to injury - an old edition), they manage to get bottom review scores whenever someone knowledgeable looks at them. As @BaummitAugen recommands, get a better book! – Fabio Fracassi Jun 11 '15 at 12:20
  • Actually static is mistakenly typed by my self (but it was reason for one additional copy constructor call). However, original example even wont to compile, since it has no const in overload assignment declaration/definiton. Only when I added this keyword it wanted to compile. – Creator Jun 11 '15 at 12:24

1 Answers1

1

The code is really terrible. Not to mention other bugs, here is why copy constructor is called twice.

  1. First time it's called when an object is returned from input() since it's static and returned by value, so no RVO can be applied.

  2. The second call happens as a result of return *this; in operator=() because for some reason it's returning an object also by value:

    sample operator=(const sample &ob);
    // ^^^
    
Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • Hi, thanx for observation. As I described in former comment, static was accidentally added by me, but example even did not want to compile with original code from the book. However, I thought that "The copy constructor applies only to initializations, it does not apply to assignments" (at least that is written also in the book I read, and I found few confirms of that statement here in stackoverflow). So actually that is wrong? Even if operator overload function returns object of the same type, copy constructor will be called? – Creator Jun 11 '15 at 12:29
  • @Creator If a full code example will not run in a modern compiler it is time to through out that book. It does you no good learning something broken. There are some very good books [here](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) that you should look at using instead of what you have. – NathanOliver Jun 11 '15 at 12:44