1

The below is an exam question:

    /* 1 */ string s1 = "FRED";
    /* 2 */ string s2 = s1;
    /* 3 */ string s3 = "DERF";
    /* 4 */ s3 = s1;

For the second and the fourth lines above, name what type of statement that line is. Will they call the same member function of class string? [5 marks]

So my answer:

  • Line 2 is initializing a new string object s2 using the copy constructor to copy over all the member variables from s1 into the s2.
  • Line 4 is also copying over all the member variables from s1 into s2, but it is overloading the assignment operator (operator=) to do so.

Therefore they both are calling 2 different member functions.

Is the above an acceptable answer? Is there anything I can add of do I have the wrong idea?

Martin York
  • 257,169
  • 86
  • 333
  • 562
Sun
  • 2,658
  • 6
  • 28
  • 33

2 Answers2

3

About your answer regarding Line #4

You cannot be certain that it actually makes use of the copy constructor, and it absolutely shouldn't.

Why create a temporary object inside std::string::operator= when you could copy the data from s1 into s3 directly?

What you wrote about operator= is correct, but leave out what you wrote about the copy-constructor there. There is no initialization of a new object, therefor no constructor should be called.


You should also leave out the statement regarding making copies of all the member variables, that doesn't have to be true.

And when it comes to objects such as std::string there are pointers as members that aren't copied, but the memory where they point are being copied into a new memory space (to be used by the destination object).


Post OP edit of his/hers post..

OP just changed his post deleting what I made a remark on in the first part of this post.

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
  • I made a quick edit because I read through what I just wrote and new that the copy constructor remark was incorrect for line 4. So I can assume that the answer I gave is correct? – Sun Dec 23 '11 at 15:49
  • So would this be a better answer: Line 4 is copying over the memory location where the member variables (pointers) of s1 are pointing to through the the use of the assignment operator (operator=). – Sun Dec 23 '11 at 16:11
  • You are writing a too elaborate answer, you can answer; "line 4" uses the assignment operator (`operator=`), and be happy with that. If you want to write something more you could say "operator= will copy the internal state of `s1` to make `s2` the same (from a programmers perspective, internally they might be different since the data of a string is probably allocated on the heap, and therefor requires pointers.. and the two strings should not be sharing the same allocated memory, that will make modifications of one but not the other impossible)". – Filip Roséen - refp Dec 23 '11 at 16:13
2

.Line 4 is also using the copy constructor to copy over all the member variables from s1 into s2

No. Line 4 is invoking copy-assignment operator, not the copy-constructor.

A constructor is invoked when an object is being initialized in its declaration. Line 4 doesn't declare anything, so it invokes copy-assignment which is operator=. Even if the class doesn't overload operator=, the compiler will generate one for you, and then it will be invoked. So in any case, the line 4 cannot invoke copy-constructor.

Note that you can disable operator= for your class if you think the copy-assignment of objects of your class doesn't make sense. To disable this, all you need to do is, declare the operator= in the private section of your class, and then don't provide any definition for it. Something like this:

struct A
{
       A(A const &) {} //copy through copy-constructor is allowed
   private:
       A& operator=(A const &);//copy through copy-assignment is disallowed
};

A x
A y(x); //ok  - copy-constructor is allowed
y = x;  //error - copy-assignment is disallowed

Likewise, you can disable both : copy-constructor and copy-assignment. For example, the standard library has disabled copy-semantics for all stream classes.

In C++11, you can disable copy-semantic explicitly as:

struct B
{
   private:
       B(B const &) = delete;
       B& operator=(B const &) = delete;
};

Copy-semantic is disabled for class B, and the usage of =delete makes it explicit. It also increases the readability of the code and reveals the programmer's intention clearly.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851