CSE 428S: Studio 11

Copy and Move Semantics


Today's lecture and studio focus on copy and move semantics, addressing issues that may arise when objects of a class act mostly like values (for which copy semantics is the main issue) versus those of another class that may act mostly like pointers (for which copy or move semantics may be relevant). We will discuss how to ask the compiler explicitly to synthesize member functions using = default and also how to prevent them from being synthesized using = delete. We will also cover lvalues and rvalues, and lvalue references and rvalue references, which establish foundations for move semantics (in which an object's implementation is stolen rather than copied).


Please complete the following required exercises. I encourage you to please work in groups of 2 or 3 people on each studio (and the groups are allowed to change from studio to studio) though if you would prefer to complete any studio by yourself that is also allowed.

As you work through these exercises, please record your answers, and when you finish them please log into Canvas, select this course in this semester, and then upload a .txt file containing your answers on the Canvas page for this studio assignment. Only one submission per team, please, and if you need to re-submit it the person who originally submitted the studio should please be the one to do that.

Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.


Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.
  2. First, ssh into shell.cec.wustl.edu using your WUSTL Key id and password and then use qlogin to log into one of the Linux Lab machines and then confirm that the version of g++ there is correct (as you did in Studio 0). Then cd into your directory for this course this semester, create a new subdirectory for this studio, and cd into it.

    Copy the Makefile from one of your previous studios into that directory, and add a source file for your program's main function. As you work on this studio, please update the Makefile as needed so that it will build an executable program called studio11 from the files in that directory.

    Add a header file to your directory, and in it declare a class that at first only has a private member variable of type string.

    In your program's main function, declare an object of that class type on the stack, copy construct another object of that type from it, and then return a descriptively named symbol whose value is 0 to indicate success.

    Build and run your program, and as the answer to this exercise please show your declaration of the class.

  3. Declare and (in a source file you should please add to your directory for this studio) define a public copy constructor for your class, which initializes its private member variable using the private member variable of the object from which it is being copy constructed, in its base/member initialization list. In the body of the copy constructor, print out the addresses of the object that is being constructed and of the object from which it is being constructed.

    Try to build your program, which should fail because the presence of the copy constructor causes the compiler not to synthesize a default constructor automatically. Declare (but do not define) a default constructor for your class using = default to ask the compiler to synthesize one for you.

    Compile and run your program, and as the answer to this exercise please show the output it produced.

  4. Modify the body of your copy constructor so that it in addition to the addresses of the objects involved it also prints out the private member variable of the object that is being constructed.

    Declare and define a constructor that takes in a const reference to a string and uses that to initialize the private member variable in the base/member initialization list. In the body of that constructor please have it print out the address and the private member variable of the object being constructed.

    Also declare and define a destructor that prints out the address and the private member variable of the object being destroyed.

    In your main function, replace the line that default constructs an object of the class type with one that initializes it with a C-style string (e.g., "hello").

    Compile and run your program, and as the answer to this exercise please show the output it produced.

  5. Declare and define a public assignment operator for your class, which takes a const reference to an object of the class type and returns a non-const reference to an object of the class type. That operator should (1) first print out the address and private member variable of the object on which it is being called, followed by the address and private member variable of the object that was passed into it; (2) assign its private member variable the private member variable of the object that was passed into it; and then (3) return a (non-const) reference to the object on which it was invoked.

    In your main function, use different C-style strings to construct at least three different objects and then in a single statement use the assignment operator twice to assign the first object to the second object and the second object to the third one (e.g., c = b = a;.

    Compile and run your program, and as the answer to this exercise please show the output it produced.

  6. Remove the contents of your main function, except for the statement at the end that returns a value indicating success.

    In your main function, declare a unique_ptr that is parameterized with your class type, and initialize it with a call to new that dynamically constructs an object of your class type from a C-style string, and then declare another unique_ptr that is parameterized with your class type, and initialize it with the first unique_ptr.

    Try to build your program (which should fail since the copy constructor for unique_ptr is deleted). Then, modify the initialization of the second unique_ptr so that it wraps the other unique_ptr with a call to std::move.

    Build and run your program, and as the answer to this exercise, please show the output that was produced.

  7. In the header and source files for your class, declare and define a public virtual member function that prints to the standard output stream the object's address and its private member variable. Also modify the declaration of the destructor so that it is virtual as well.

    In the source file where you defined your program's main function, define a function with a void return type that takes a unique_ptr to your class type by value, and uses it to invoke the public virtual member function of the object to which the unique_ptr points.

    In your program's main function, pass the second unique_ptr (not the first one, which is no longer safe to use because of your use of std::move to transfer ownership of the object of your class type to the second unique_ptr) into a call to the function you just defined.

    Try to build your program (which again should fail since the copy constructor for unique_ptr is deleted). Then, modify the call to the function so that it wraps the second unique_ptr with a call to std::move.

    Build and run your program, and as the answer to this exercise, please show the output that was produced.

  8. In the source file where you defined your program's main function, change the function you defined in the previous exercise so that it returns by value the unique_ptr that is passed into it. In your main function, assign the value that is returned by that function to the first unique_ptr, and then use the first unique_ptr to invoke the virtual public member function of the object that it points to.

    Build and run your program, and as the answer to this exercise, please show the output that the program produced.

Things to Turn In:

For this studio, please turn in the following:


Page posted Tuesday October 4, 2022, by Chris Gill.